static int lo_txpoll(FAR struct net_driver_s *dev) { FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private; /* Loop while there is data "sent", i.e., while d_len > 0. That should be * the case upon entry here and while the processing of the IPv4/6 packet * generates a new packet to be sent. Sending, of course, just means * relaying back through the network for this driver. */ while (priv->lo_dev.d_len > 0) { NETDEV_TXPACKETS(&priv->lo_dev); NETDEV_RXPACKETS(&priv->lo_dev); #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ pkt_input(&priv->lo_dev); #endif /* We only accept IP packets of the configured type and ARP packets */ #ifdef CONFIG_NET_IPv4 if ((IPv4BUF->vhl & IP_VERSION_MASK) == IPv4_VERSION) { nllvdbg("IPv4 frame\n"); NETDEV_RXIPV4(&priv->lo_dev); ipv4_input(&priv->lo_dev); } else #endif #ifdef CONFIG_NET_IPv6 if ((IPv6BUF->vtc & IP_VERSION_MASK) == IPv6_VERSION) { nllvdbg("Iv6 frame\n"); NETDEV_RXIPV6(&priv->lo_dev); ipv6_input(&priv->lo_dev); } else #endif { ndbg("WARNING: Unrecognized packet type dropped: %02x\n", IPv4BUF->vhl); NETDEV_RXDROPPED(&priv->lo_dev); priv->lo_dev.d_len = 0; } priv->lo_txdone = true; NETDEV_TXDONE(&priv->lo_dev); } return 0; }
static int slip_rxtask(int argc, FAR char *argv[]) { FAR struct slip_driver_s *priv; unsigned int index = *(argv[1]) - '0'; net_lock_t flags; int ch; nerr("index: %d\n", index); DEBUGASSERT(index < CONFIG_NET_SLIP_NINTERFACES); /* Get our private data structure instance and wake up the waiting * initialization logic. */ priv = &g_slip[index]; slip_semgive(priv); /* Loop forever */ for (; ; ) { /* Wait for the next character to be available on the input stream. */ ninfo("Waiting...\n"); ch = slip_getc(priv); /* Ignore any input that we receive before the interface is up. */ if (!priv->bifup) { continue; } /* We have something... * * END characters may appear at packet boundaries BEFORE as well as * after the beginning of the packet. This is normal and expected. */ if (ch == SLIP_END) { priv->rxlen = 0; } /* Otherwise, we are in danger of being out-of-sync. Apparently the * leading END character is optional. Let's try to continue. */ else { priv->rxbuf[0] = (uint8_t)ch; priv->rxlen = 1; } /* Copy the data data from the hardware to priv->rxbuf until we put * together a whole packet. */ slip_receive(priv); NETDEV_RXPACKETS(&priv->dev); /* All packets are assumed to be IP packets (we don't have a choice.. * there is no Ethernet header containing the EtherType). So pass the * received packet on for IP processing -- but only if it is big * enough to hold an IP header. */ if (priv->rxlen >= IPv4_HDRLEN) { NETDEV_RXIPV4(&priv->dev); /* Handle the IP input. Get exclusive access to the network. */ slip_semtake(priv); priv->dev.d_buf = priv->rxbuf; priv->dev.d_len = priv->rxlen; flags = net_lock(); ipv4_input(&priv->dev); /* If the above function invocation resulted in data that should * be sent out on the network, the field d_len will set to a * value > 0. NOTE that we are transmitting using the RX buffer! */ if (priv->dev.d_len > 0) { slip_transmit(priv); kill(priv->txpid, SIGALRM); } net_unlock(flags); slip_semgive(priv); } else { NETDEV_RXERRORS(&priv->dev); } } /* We won't get here */ return OK; }