Re: [lwip-users] TCP retransmissions although packet has been recieved
In addition to the correct answer from Jens: On 02.10.2018 11:45, Inderjit Singh wrote: [..] 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; } This loop is wrong. You're double-freeing many pbufs here! Simon ___ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users
Re: [lwip-users] TCP retransmissions although packet has been recieved
Hi I'll answer the standard reply to this question :) You're saying that "the app has received the packet" but are you really sure about that? A typical cause for this problem is that the driver stops receiving and/or forwarding packets to lwip properly, lwip can't ack what lwip doesn't receive. And 1.4.1 is pretty old, you should upgrade... Best regards Jens On 2018-10-02 11:45, Inderjit Singh wrote: 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_PCB 2 #define MEMP_NUM_TCP_PCB_LISTEN 1/ / #define MEMP_NUM_TCP_SEG 8 *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 ___ 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
[lwip-users] TCP retransmissions although packet has been recieved
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 /** * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent * (fragments, not whole packets!). * This is only used with
Re: [lwip-users] UDP and Raw API, lwip running with RTOS
Thanks Simon, I will try LWIP_ASSERT_CORE_LOCKED() also (good idea!). This also forces me to upgrade to 2.1.0 (running at 2.0.3 at the moment) -- Sent from: http://lwip.100.n7.nabble.com/lwip-users-f3.html ___ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users
Re: [lwip-users] UDP and Raw API, lwip running with RTOS
zulu4711 wrote: > Simon, > Sorry for that ! > My "everyday" reading of lwip topics is done on nabble, hence I did the > question there. There's no problem in using nabble, you just have to make sure the result is readable by everyone reading the list, not only by nabble users. If you want a response, that is... ;-) > Anyway, here is the original question, Hope it is readable now. Yes, it is readable now. I think your example looks correct. You might want to try the new hook LWIP_ASSERT_CORE_LOCKED() that checks for correct threading (added with 2.1.0). Simon ___ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users
Re: [lwip-users] UDP and Raw API, lwip running with RTOS
Simon, Sorry for that ! My "everyday" reading of lwip topics is done on nabble, hence I did the question there. Anyway, here is the original question, Hope it is readable now. I have lwip up and running in an embbeded system using a RTOS (Keil RTX kernel) and this seems to work alright. I'm testing with sockets and netconn UDP, all ok (over PPP).I'm also beginning to look at the raw API (this will fit the project best in the end), and this works also. Now, I know that the raw API is only to be called from one single thread.However, I need to be able to call send etc from several threads. I was wondering if the following code is ok for that, before using the raw API I call LOCK_TCPIP_CORE()/UNLOCK_TCPIP_CORE(). I followed the netconn API and it seems this is the way the locking is done there ? Am I right in this, and is this a "allowed" way of doing what I want ? Or, are there a better approach to this ? //--- // Callback function for received data //--- static void rxUDP(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { char str[128]; // if packet is valid if (p != NULL) { // WARNING: p can be a chain of buffers (in this example we pretend it is just a single buffer :)! if (p->len < sizeof(str)) { memcpy(str, p->payload, p->len); str[p->len]=0; messageDebug(DBG_WAR, __MODULE__, __LINE__, "UDP Packet Received! Payload: [%s], port=%i", str, port); } pbuf_free(p); } } //--- // Thread that sends UDP message every 1000 to 2000 mSec //--- void thRawUDP(void) { extern struct netif ppp_netif; err_t error; ip_addr_t ip_remote; struct udp_pcb *pUDPPCB; struct pbuf *pBuf; char data[] = "Hello world"; setNameRTXMON(__FUNCTION__); // wait for netif to come up (a little dirty) messageDebug(DBG_WAR, __MODULE__, __LINE__, "Waiting for PPP Netif to come up.."); while (netif_is_link_up(_netif)==0) OS_WAIT(1000); messageDebug(DBG_WAR, __MODULE__, __LINE__, "PPP Netif is up"); // Convert from ASCII "xxx.xxx.xxx.xxx" to IP ipaddr_aton(SERVER_IP_ADDR, _remote); // Lock the stack.. LOCK_TCPIP_CORE(); pUDPPCB = udp_new(); // Bind to any local port error = udp_bind(pUDPPCB, IP_ADDR_ANY, 0); messageDebug(DBG_WAR, __MODULE__, __LINE__, "udp_bind=%i", error); error = udp_connect(pUDPPCB, _remote, SERVER_PORT_NUM); messageDebug(DBG_WAR, __MODULE__, __LINE__, "udp_connect=%i", error); udp_recv(pUDPPCB, rxUDP, NULL); UNLOCK_TCPIP_CORE(); while (1) { // Allocate pbuf (might end up being a chain of buffers!) pBuf = pbuf_alloc(PBUF_TRANSPORT, sizeof(data), PBUF_POOL); if (!pBuf) { messageDebug(DBG_ERR, __MODULE__, __LINE__, "error allocating buffer"); OS_WAIT(1000); continue; } // The pBuf we get can be a chain of buffers int bytesLeft = sizeof(data); // Number of bytes we still need to move to buffer(s) struct pbuf *packetTempBuffer; // used to traverse the (possible) list of buffers int chunk; // NUmber of bytes we copy to the current buffer int index = 0; // Index into the source buffer packetTempBuffer = pBuf; while ( (bytesLeft) && (packetTempBuffer != NULL) ) { chunk = bytesLeft; if ( chunk > packetTempBuffer->len ) { chunk = packetTempBuffer->len; } // copy one part memcpy(packetTempBuffer->payload, [index], chunk); // next buffer in chain (if any) packetTempBuffer = packetTempBuffer->next; bytesLeft -= chunk; index += chunk; }; //memcpy(pBuf->payload, data, sizeof(data)); // WARNING: No gurantee that pbuf is not multiple buffers in order to hold the data! messageDebug(DBG_WAR, __MODULE__, __LINE__,"Sending"); // Lock stack LOCK_TCPIP_CORE(); udp_send(pUDPPCB, pBuf); UNLOCK_TCPIP_CORE(); pbuf_free(pBuf); OS_WAIT(1000+(rand()%1000)); } } -- Sent from: http://lwip.100.n7.nabble.com/lwip-users-f3.html ___ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users
Re: [lwip-users] UDP and Raw API, lwip running with RTOS
zulu4711 wrote: > Simon, > I access it here: > http://lwip.100.n7.nabble.com/UDP-and-Raw-API-lwip-running-with-RTOS-td33221.html Ok, so you're using nabble. That's fine for you. I'm using this list. By now, you may have noticed the difference ;-) In other words, the formatting of your mail is still messed up. If you want everyone being able to read your mails, not just nabble users, send correct mails. Plus (and that goes for all nabble users): on mailing lists, you normally include the text you reply to. In forums, you don't. That makes a difference regarding readability and I quickly skip mails where I can't find the context fast enough... Simon ___ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users
Re: [lwip-users] UDP and Raw API, lwip running with RTOS
Simon, I access it here: http://lwip.100.n7.nabble.com/UDP-and-Raw-API-lwip-running-with-RTOS-td33221.html -- Sent from: http://lwip.100.n7.nabble.com/lwip-users-f3.html ___ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users
Re: [lwip-users] UDP and Raw API, lwip running with RTOS
zulu4711 wrote: > I edited my post on the forum afterwards (as I also discovered that it was > unreadable). Which forum are you talking about? This is a mailing list and you cannot edit mails after you have sent them. > Anyway, I have included it here also, hope it works ? I'm not sure I understand that. Simon ___ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users
Re: [lwip-users] EXTERNAL: UDP and Raw API, lwip running with RTOS
Simon, I edited my post on the forum afterwards (as I also discovered that it was unreadable). Anyway, I have included it here also, hope it works ? -- Sent from: http://lwip.100.n7.nabble.com/lwip-users-f3.html ___ lwip-users mailing list lwip-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/lwip-users