Re: [lwip-users] TCP retransmissions although packet has been recieved

2018-10-05 Thread Inderjit Singh
So,

I have updated reception code (from the contrib examples httpd_raw) and still 
the behaviour is the same (code at bottom).

I did a quick and ugly test by calling tcp_ack_now and tcp_output at the end of 
the function and then the behaviour dramatically improved as ACKs are being 
sent back and there is no RST from server (as expected).
I might also add that each http request I am sending is a blocking call (and 
awaits a response) with timeout at application level. So practically I am only 
handling one full transaction at a time. The transactions are deterministic and 
small in size.

So this for me boils down to TCP_WND setting. The http requests I'm sending is 
roughly at 200 bytes and reception is in equal side so they are fairly small. 
Is there a guidance on how to set LWIPOPTS variables regarding TCP for this 
kind of behaviour? Right now my settings are:
LWIPOPTS.H
#define TCP_MSS1460

/**
 * TCP_WND: The size of a TCP window.  This must be at least
 * (2 * TCP_MSS) for things to work well
 */
#define TCP_WND(2 * TCP_MSS)

/**
 * TCP_SND_BUF: TCP sender buffer space (bytes).
 * To achieve good performance, this should be at least 2 * TCP_MSS.
 */
#define TCP_SND_BUF(2 * TCP_MSS)

Reception Code:
err_t tcp_tx_resp_cb(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
eth_ctx_t* ctx = (eth_ctx_t*)arg;
uint8_t* data;

if ((err != ERR_OK) || (p == NULL)) {

DBG_W(EINVAL, "Ignoring response err '%d'.", err);

/* error or closed by other side? */
if (p != NULL) {
/* Inform TCP that we have taken the data. */
tcp_recved(tpcb, p->tot_len);
pbuf_free(p);
}

tcp_close(tpcb);
return ERR_OK;
}

if (p->len != p->tot_len) {
DBG_E(ECOMM, "Received message is incomplete %d<%d.", p->len, 
p->tot_len);
}

/* Acknowledge that we have received the packet */
tcp_recved(pcb_tcp, p->tot_len);

if (ctx->recv_buf == NULL){
DBG_W(EINVAL, "Cannot transfer received buffer. No buffer given.");

return ERR_OK;
}

/*** Parse data ***/

if(p != NULL) {
pbuf_free(p);
}

return ERR_OK;
}
___
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

[lwip-users] TCP retransmissions although packet has been recieved

2018-10-02 Thread Inderjit Singh
Hi,

I have the following configuration:

H/W
ATMEL SAM4E ARM Cortex-M4 with KSZ8081MNXRNB Ethernet phy.
LWIP:
1.4.1
Config (extract. See attached file for full config):
#define NO_SYS  1
#define MEMP_NUM_TCP_PCB2
#define MEMP_NUM_TCP_PCB_LISTEN 1
#define MEMP_NUM_TCP_SEG8

Problem:
I am sending HTTP/1.1 packets to server and receiving replies as expected. But 
it seems that the server keeps sending re-transmissions as local hardware 
doesn't seem to send an ACK back (3-way handshake?). After some time the server 
resets the connection and my next http request get's blocked. Should LWIP layer 
send an ACK back as the app has received the packet?
pcap capture is attatched.

Here is the code snippet when packets is received:

err_t tcp_tx_resp_cb(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
struct pbuf* temp_p;
eth_ctx_t* ctx = (eth_ctx_t*)arg;
uint16_t len;

if(err < 0)
{
DBG_W(EINVAL, "Ignoring response err '%d'. err");
return err;
}

len = 0;
/*retrieve data */
if ((err == ERR_OK) && (p != NULL)) {
/* get response status value */
ctx->status = http_get_status(p->payload);

while (p != NULL) {
if (ctx->recv_buf != NULL) {
memcpy(>recv_buf[len], p->payload, p->len);
}

temp_p = p->next;
len += p->len;
pbuf_free(p);
p = temp_p;
}
/* Terminate it for parsing it more easily */
ctx->recv_buf[len] = 0;

if (ctx->recv_buf != NULL) {
ctx->recv_size = http_get_data(ctx->recv_buf, ctx->recv_buf);
}

DBG_I("TCP RESPONSE:  status:%03d. data_size: %d bytes. err: %d.",
  ctx->status, ctx->recv_size, err);
}

return ERR_OK;
}

Tanks in advance,
Inderjit
/***
 * @file   lwipopts.h
 * @author Inderjit Singh 
 * @brief  TODO: TBD
 *
 * TBD
 **/


#ifndef _LWIPOPTS_H_
#define _LWIPOPTS_H_

/* Include Ethernet configuration first */
#include "conf_eth.h"
#include "gmac.h"


/**
 * NO_SYS==1:   NO OS. Provides VERY minimal functionality.  RAW API only
 * NO_SYS==0:   Use lwIP facilities.
 */
#define NO_SYS  1
/**
 * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an 
interface
 * changes its up/down status (i.e., due to DHCP IP acquisition)
 */
#define LWIP_NETIF_STATUS_CALLBACK  1

/**
 * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
 * Used to implement custom transport protocol (!= than Raw API).
 */
#define LWIP_RAW0

/**
 * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
 * critical regions during buffer allocation, deallocation and memory
 * allocation and deallocation.
 */
#define SYS_LIGHTWEIGHT_PROT0

/* These are not available when using "NO_SYS" */
#define LWIP_NETCONN0
#define LWIP_SOCKET 0

/* Uncomment following line to use DHCP instead of fixed IP */
#define DHCP_USED

/***
 *Memory options
 **/

/**
 * MEM_ALIGNMENT: should be set to the alignment of the CPU
 *4 byte alignment -> #define MEM_ALIGNMENT 4
 *2 byte alignment -> #define MEM_ALIGNMENT 2
 */
#define MEM_ALIGNMENT   4

/**
 * MEM_SIZE: the size of the heap memory. If the application will send
 * a lot of data that needs to be copied, this should be set high.
 */
#define MEM_SIZE(4 * 1024)

/**
 * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
 * per active UDP "connection".
 * (requires the LWIP_UDP option)
 */
#define MEMP_NUM_UDP_PCB2

/**
 * MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections.
 * (requires the LWIP_TCP option)
 */
#define MEMP_NUM_TCP_PCB2

/**
 * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
 * (requires the LWIP_TCP option)
 */
#define MEMP_NUM_TCP_PCB_LISTEN 1

/**
 * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
 * (requires the LWIP_TCP option)
 */
#define MEMP_NUM_TCP_SEG8

/**
 * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for
 * reassembly (whole packets, not fragments!)
 */
#define MEMP_NUM_REASSDATA  2

/**
 * M

Re: [lwip-users] tcp_connection (no SYN packet on server side)

2018-06-05 Thread Inderjit Singh
Yeah, the procedure is exactly as you descript with address setting, netifadd, 
etc...

IP4_ADDR(, 192, 168, 100, 250);
IP4_ADDR(, 255, 255, 255, 0);
IP4_ADDR(, 192, 168, 100, 1);
if (NULL == netif_add(_netif, , , , NULL,
ethernetif_init, ethernet_input)) {
LWIP_ASSERT("NULL == netif_add", 0);
}

netif_set_default(_netif);
netif_set_status_callback(_netif, eth_cb_netif_status);
netif_set_up(_netif);

And both output low level functions are being called (catched by breakpoint). I 
presume you do mean (in my case):
ethernetif_output() -> etharp_output
ethernetif_linkoutput -> gmac_low_level_output
as they are set in netif:
netif->output = etharp_output;
netif->linkoutput = gmac_low_level_output;



From: lwip-users [lwip-users-bounces+inderjit.singh=evidente...@nongnu.org] on 
behalf of Sergio R. Caprile [scapr...@gmail.com]
Sent: 04 June 2018 18:18
To: lwip-users@nongnu.org
Subject: Re: [lwip-users] tcp_connection (no SYN packet on server side)

OK, so it seems you are correctly calling lwIP in the loop, and your
networking parameters look good.
However, I failed to ask how do you setup your netif. You don't tell.
You should do something like this before actually calling tcp_connect():

IP4_ADDR(, 192,168,100,1);
IP4_ADDR(, 192,168,100,250);
IP4_ADDR(, 255,255,255,0);

lwip_init();
netif_add(, , , , perhaps NULL,
ethernetif_init, ethernet_input);
netif_set_default();

Where your ethernetif_init() will properly init stuff...
netif->output = etharp_output;
netif->linkoutput = ethernetif_linkoutput;//driveroutputfunction

Can you fire a breakpoint at your ethernetif_output() and
ethernetif_linkoutput?

___
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users
___
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

Re: [lwip-users] tcp_connection (no SYN packet on server side)

2018-06-04 Thread Inderjit Singh
OK. i'll try that.


..
Inderjit Singh Senior Embedded Engineer, MSc

Evidente ES East AB
Warfvinges väg 34 SE-112 51 Stockholm Sweden

Mobile:  +46 (0)70 912 42 69
E-mail:   inderjit.si...@evidente.se<mailto:inderjit.si...@evidente.se>

<http://www.evidente.se/>
www.evidente.se<http://www.evidente.se/>

From: lwip-users [lwip-users-bounces+inderjit.singh=evidente...@nongnu.org] on 
behalf of Sarp Daltaban [sarpdalta...@gmail.com]
Sent: 04 June 2018 16:16
To: Mailing list for lwIP users
Subject: Re: [lwip-users] tcp_connection (no SYN packet on server side)

Do not delay, or make it lower as 3-5 ms.

2018-06-04 16:50 GMT+03:00 Inderjit Singh 
mailto:inderjit.si...@evidente.se>>:
Hi Sergio, thanks for the reply!

Bind I can remove, fair enough.

IP addressing is client (this development side):
   ip: 192.168.100.120
   netmask: 255.255.255.0
   gw: 192.168.100.1

The server (raspberry pi without any implementation, just monitoring packets)
   ip: 192.168.100.155
   netmask: 255.255.255.0
   gw: 192.168.100.1

Setting goes trough without any error (I have put assert after every setting)

The main loop is this:

while (1) {
udp_cb_called = tcp_cb_called = false;

IP4_ADDR(, ETH_CONF_IPADDR0, ETH_CONF_IPADDR1, ETH_CONF_IPADDR2, 155);
err = tcp_connect(pcb_tcp, , ETH_TCP_PORT_REM, tcp_connected_cb);
if (err != 0) {
LWIP_ASSERT("err != 0", 0);
}

while(udp_cb_called == false && tcp_cb_called == false) {
ethernetif_input(_netif);
sys_check_timeouts();
delay_ms(100);
}
}

Once the callback is called, I set the flags to true to redo the connect. Note, 
this is just for testing not for any other purpose. Once I can see SYN packet 
then I know I can start implementing properly...

......
Inderjit Singh Senior Embedded Engineer, MSc

Evidente ES East AB
Warfvinges väg 34 SE-112 51 Stockholm Sweden

Mobile: +46 (0)70 912 42 69
E-mail: inderjit.si...@evidente.se<mailto:inderjit.si...@evidente.se>

www.evidente.se<http://www.evidente.se>


From: lwip-users 
[lwip-users-bounces+inderjit.singh=evidente...@nongnu.org<mailto:evidente...@nongnu.org>]
 on behalf of Sergio R. Caprile [scapr...@gmail.com<mailto:scapr...@gmail.com>]
Sent: 04 June 2018 14:59
To: lwip-users@nongnu.org<mailto:lwip-users@nongnu.org>
Subject: Re: [lwip-users] tcp_connection (no SYN packet on server side)


No need to bind(), you are a client, you connect().
What is the value returned by tcp_connect() ? It should be ERR_OK
What do you do after that ? Do you properly call sys_check_timeouts() on
the main loop or you just sit waiting things to magically happen ?
TCP is a state machine, you just instructed it to start a several steps
process.

PS: I assume your IP addressing is fine...


___
lwip-users mailing list
lwip-users@nongnu.org<mailto:lwip-users@nongnu.org>
https://lists.nongnu.org/mailman/listinfo/lwip-users

___
lwip-users mailing list
lwip-users@nongnu.org<mailto:lwip-users@nongnu.org>
https://lists.nongnu.org/mailman/listinfo/lwip-users

___
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

Re: [lwip-users] tcp_connection (no SYN packet on server side)

2018-06-04 Thread Inderjit Singh
delay_ms is used throughout our bare metal implementation I can guarantee it's 
not blocking.
tcp_cb_called is called to the registered callback function yes. And sure, main 
loop as you suggest is functional as well yes. 
However I fail see why LWIP layer marks SYN_SENT state in pcb but I cannot see 
the packet's being transmitted/received on the datalink itself? LWIP doesn't 
signal any failures has been made during the process except the abort at error 
callback when the timeout is reached. 


From: lwip-users [lwip-users-bounces+inderjit.singh=evidente...@nongnu.org] on 
behalf of Sergio R. Caprile [scapr...@gmail.com]
Sent: 04 June 2018 16:58
To: lwip-users@nongnu.org
Subject: Re: [lwip-users] tcp_connection (no SYN packet on server side)

That may or may not work depending on what your _magic function_
"delay_ms" does. If it is blocking, you are busted.

A main loop is a main loop, you need to rx and you need to check
timeouts. Your accept callback will be called after the SYN is SYNACKed
and the SYNACK is ACKed back. For that, you need to have the stack
running, otherwise no one can send anything, and that is done by calling
sys_check_timeouts() as frequently as you can. And you need to rx for
the SYNACK, which is done by calling ethernetif_input() frequently
enough in order not to lose frames. That can't happen if you are blocking.

If you really want to sequentially check for whatever reason, you can do
this:

udp_cb_called = tcp_cb_called = false;

IP4_ADDR(, ETH_CONF_IPADDR0, ETH_CONF_IPADDR1, ETH_CONF_IPADDR2, 155);
err = tcp_connect(pcb_tcp, , ETH_TCP_PORT_REM, tcp_connected_cb);
if (err != ERR_OK) {
// Oops
}

while(udp_cb_called == false && tcp_cb_called == false) {
ethernetif_input(_netif);
sys_check_timeouts();
}

Your second attempt to call connect will fail as your pcb is being used,
so that won't work inside a loop (and a bit involved to explain in one
line). And I guess you'll set tcp_cb_called to "true" somewhere in your
tcp_connected_cb()

However, that is not much different from a real main loop:

while(1) {
ethernetif_input(_netif);
if(whatiamexpectinghashappened)
; // bingo!
sys_check_timeouts();
world_save();
stuff_do();
morestuff_moredo();
}


___
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

___
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users


Re: [lwip-users] tcp_connection (no SYN packet on server side)

2018-06-04 Thread Inderjit Singh
Hi Sergio, thanks for the reply!

Bind I can remove, fair enough.

IP addressing is client (this development side):
   ip: 192.168.100.120
   netmask: 255.255.255.0
   gw: 192.168.100.1

The server (raspberry pi without any implementation, just monitoring packets)
   ip: 192.168.100.155
   netmask: 255.255.255.0
   gw: 192.168.100.1

Setting goes trough without any error (I have put assert after every setting)

The main loop is this:

while (1) {
udp_cb_called = tcp_cb_called = false;

IP4_ADDR(, ETH_CONF_IPADDR0, ETH_CONF_IPADDR1, ETH_CONF_IPADDR2, 155);
err = tcp_connect(pcb_tcp, , ETH_TCP_PORT_REM, tcp_connected_cb);
if (err != 0) {
LWIP_ASSERT("err != 0", 0);
}

while(udp_cb_called == false && tcp_cb_called == false) {
ethernetif_input(_netif);
sys_check_timeouts();
delay_ms(100);
}
}

Once the callback is called, I set the flags to true to redo the connect. Note, 
this is just for testing not for any other purpose. Once I can see SYN packet 
then I know I can start implementing properly...

......
Inderjit Singh Senior Embedded Engineer, MSc

Evidente ES East AB
Warfvinges väg 34 SE-112 51 Stockholm Sweden

Mobile: +46 (0)70 912 42 69
E-mail: inderjit.si...@evidente.se

www.evidente.se


From: lwip-users [lwip-users-bounces+inderjit.singh=evidente...@nongnu.org] on 
behalf of Sergio R. Caprile [scapr...@gmail.com]
Sent: 04 June 2018 14:59
To: lwip-users@nongnu.org
Subject: Re: [lwip-users] tcp_connection (no SYN packet on server side)

No need to bind(), you are a client, you connect().
What is the value returned by tcp_connect() ? It should be ERR_OK
What do you do after that ? Do you properly call sys_check_timeouts() on
the main loop or you just sit waiting things to magically happen ?
TCP is a state machine, you just instructed it to start a several steps
process.

PS: I assume your IP addressing is fine...


___
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users
___
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users