static inline void recvfrom_newtcpdata(FAR struct uip_driver_s *dev, FAR struct recvfrom_s *pstate) { /* Take as much data from the packet as we can */ size_t recvlen = recvfrom_newdata(dev, pstate); /* If there is more data left in the packet that we could not buffer, than * add it to the read-ahead buffers. */ if (recvlen < dev->d_len) { #if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 FAR struct uip_conn *conn = (FAR struct uip_conn *)pstate->rf_sock->s_conn; FAR uint8_t *buffer = (FAR uint8_t *)dev->d_appdata + recvlen; uint16_t buflen = dev->d_len - recvlen; #ifdef CONFIG_DEBUG_NET uint16_t nsaved; nsaved = uip_datahandler(conn, buffer, buflen); #else (void)uip_datahandler(conn, buffer, buflen); #endif /* There are complicated buffering issues that are not addressed fully * here. For example, what if up_datahandler() cannot buffer the * remainder of the packet? In that case, the data will be dropped but * still ACKed. Therefore it would not be resent. * * This is probably not an issue here because we only get here if the * read-ahead buffers are empty and there would have to be something * serioulsy wrong with the configuration not to be able to buffer a * partial packet in this context. */ #ifdef CONFIG_DEBUG_NET if (nsaved < buflen) { ndbg("ERROR: packet data not saved (%d bytes)\n", buflen - nsaved); } #endif #else ndbg("ERROR: packet data lost (%d bytes)\n", dev->d_len - recvlen); #endif } /* Indicate no data in the buffer */ dev->d_len = 0; }
static inline uint16_t uip_dataevent(FAR struct uip_driver_s *dev, FAR struct uip_conn *conn, uint16_t flags) { uint16_t ret; /* Assume that we will ACK the data. The data will be ACKed if it is * placed in the read-ahead buffer -OR- if it zero length */ ret = (flags & ~UIP_NEWDATA) | UIP_SNDACK; /* Is there new data? With non-zero length? (Certain connection events * can have zero-length with UIP_NEWDATA set just to cause an ACK). */ if (dev->d_len > 0) { #ifdef CONFIG_NET_TCP_READAHEAD uint8_t *buffer = dev->d_appdata; int buflen = dev->d_len; uint16_t recvlen; #endif nllvdbg("No listener on connection\n"); #ifdef CONFIG_NET_TCP_READAHEAD /* Save as much data as possible in the read-ahead buffers */ recvlen = uip_datahandler(conn, buffer, buflen); /* There are several complicated buffering issues that are not addressed * properly here. For example, what if we cannot buffer the entire * packet? In that case, some data will be accepted but not ACKed. * Therefore it will be resent and duplicated. Fixing this could be tricky. */ if (recvlen < buflen) #endif { /* There is no handler to receive new data and there are no free * read-ahead buffers to retain the data -- drop the packet. */ nllvdbg("Dropped %d bytes\n", dev->d_len); #ifdef CONFIG_NET_STATISTICS uip_stat.tcp.syndrop++; uip_stat.tcp.drop++; #endif /* Clear the UIP_SNDACK bit so that no ACK will be sent */ ret &= ~UIP_SNDACK; } } /* In any event, the new data has now been handled */ dev->d_len = 0; return ret; }