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;
}
Esempio n. 2
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;
}