6loWPAN: Updates/fixes from early testing with the IEEE802.15.4 loopback driver.

This commit is contained in:
Gregory Nutt 2017-04-03 12:01:04 -06:00
parent e9d831ac60
commit 2c06f8ab78
6 changed files with 177 additions and 38 deletions

View File

@ -159,7 +159,7 @@ CONFIG_ARCH_BOARD="sim"
#
# CONFIG_BOARD_CRASHDUMP is not set
CONFIG_LIB_BOARDCTL=y
# CONFIG_BOARDCTL_POWEROFF is not set
CONFIG_BOARDCTL_POWEROFF=y
# CONFIG_BOARDCTL_UNIQUEID is not set
# CONFIG_BOARDCTL_TSCTEST is not set
# CONFIG_BOARDCTL_GRAPHICS is not set
@ -873,26 +873,17 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=2048
# CONFIG_EXAMPLES_MODBUS is not set
# CONFIG_EXAMPLES_MOUNT is not set
CONFIG_EXAMPLES_NETTEST=y
# CONFIG_EXAMPLES_NETTEST_SERVER is not set
CONFIG_EXAMPLES_NETTEST_STACKSIZE=4096
CONFIG_EXAMPLES_NETTEST_PRIORITY=100
CONFIG_EXAMPLES_NETTEST_LOOPBACK=y
CONFIG_EXAMPLES_NETTEST_SERVER_STACKSIZE=4096
CONFIG_EXAMPLES_NETTEST_SERVER_PRIORITY=100
# CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set
CONFIG_EXAMPLES_NETTEST_IPv6=y
# CONFIG_EXAMPLES_NETTEST_INIT is not set
#
# Target IPv6 address
#
#
# Client IPv6 address
#
CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_1=0xfc00
CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_2=0x0000
CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_3=0x0000
CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_4=0x0000
CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_5=0x0000
CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_6=0x0000
CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_7=0x0000
CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_8=0x0001
CONFIG_EXAMPLES_NSH=y
# CONFIG_EXAMPLES_NULL is not set
# CONFIG_EXAMPLES_NX is not set
@ -1034,6 +1025,7 @@ CONFIG_NSH_DISABLE_LOSMART=y
# CONFIG_NSH_DISABLE_MV is not set
# CONFIG_NSH_DISABLE_MW is not set
# CONFIG_NSH_DISABLE_NSLOOKUP is not set
# CONFIG_NSH_DISABLE_POWEROFF is not set
CONFIG_NSH_DISABLE_PRINTF=y
# CONFIG_NSH_DISABLE_PS is not set
# CONFIG_NSH_DISABLE_PUT is not set
@ -1042,6 +1034,7 @@ CONFIG_NSH_DISABLE_PRINTF=y
# CONFIG_NSH_DISABLE_RMDIR is not set
# CONFIG_NSH_DISABLE_SET is not set
# CONFIG_NSH_DISABLE_SH is not set
CONFIG_NSH_DISABLE_SHUTDOWN=y
# CONFIG_NSH_DISABLE_SLEEP is not set
# CONFIG_NSH_DISABLE_TIME is not set
# CONFIG_NSH_DISABLE_TEST is not set

View File

@ -45,6 +45,7 @@
#include <nuttx/clock.h>
#include <nuttx/net/netconfig.h>
#include <nuttx/net/netdev.h>
#include <nuttx/net/net.h>
#include "devif/devif.h"
#include "arp/arp.h"
@ -55,6 +56,7 @@
#include "icmp/icmp.h"
#include "icmpv6/icmpv6.h"
#include "igmp/igmp.h"
#include "sixlowpan/sixlowpan.h"
/****************************************************************************
* Public Data
@ -68,6 +70,50 @@ systime_t g_polltime;
* Private Functions
****************************************************************************/
/****************************************************************************
* Function: devif_packet_conversion
*
* Description:
* TCP output comes through three different mechansims. Either from:
*
* 1. TCP socket output. For the case of TCP output to an
* IEEE802.15.4, the TCP output is caught in the socket
* send()/sendto() logic and and redirected to 6loWPAN logic.
* 2. TCP output from the TCP state machine. That will occur
* during TCP packet processing by the TCP state meachine.
* 3. TCP output resulting from TX or timer polling
*
* Cases 2 is handled here. Logic here detected if (1) an attempt
* to return with d_len > 0 and (2) that the device is an
* IEEE802.15.4 MAC network driver. Under those conditions, 6loWPAN
* logic will be called to create the IEEE80215.4 frames.
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN
static inline void devif_packet_conversion(FAR struct net_driver_s *dev)
{
#ifdef CONFIG_NET_MULTILINK
/* Handle the case where multiple link layer protocols are supported */
if (dev->d_len > 0 && dev->d_lltype == NET_LL_IEEE802154)
#else
if (dev->d_len > 0)
#endif
{
/* Let 6loWPAN convert output into the IEEE802.15.4 frames */
sixlowpan_tcp_send(dev);
dev->d_len = 0;
}
}
#else
# define devif_packet_conversion(dev)
#endif /* CONFIG_NET_6LOWPAN */
/****************************************************************************
* Function: devif_poll_pkt_connections
*
@ -95,6 +141,10 @@ static int devif_poll_pkt_connections(FAR struct net_driver_s *dev,
pkt_poll(dev, pkt_conn);
/* Perform any necessary conversions on outgoing packets */
devif_packet_conversion(dev);
/* Call back into the driver */
bstop = callback(dev);
@ -120,6 +170,10 @@ static inline int devif_poll_icmp(FAR struct net_driver_s *dev,
icmp_poll(dev);
/* Perform any necessary conversions on outgoing packets */
devif_packet_conversion(dev);
/* Call back into the driver */
return callback(dev);
@ -142,6 +196,10 @@ static inline int devif_poll_icmpv6(FAR struct net_driver_s *dev,
icmpv6_poll(dev);
/* Perform any necessary conversions on outgoing packets */
devif_packet_conversion(dev);
/* Call back into the driver */
return callback(dev);
@ -168,6 +226,10 @@ static inline int devif_poll_igmp(FAR struct net_driver_s *dev,
igmp_poll(dev);
/* Perform any necessary conversions on outgoing packets */
devif_packet_conversion(dev);
/* Call back into the driver */
return callback(dev);
@ -201,6 +263,10 @@ static int devif_poll_udp_connections(FAR struct net_driver_s *dev,
udp_poll(dev, conn);
/* Perform any necessary conversions on outgoing packets */
devif_packet_conversion(dev);
/* Call back into the driver */
bstop = callback(dev);
@ -237,6 +303,10 @@ static inline int devif_poll_tcp_connections(FAR struct net_driver_s *dev,
tcp_poll(dev, conn);
/* Perform any necessary conversions on outgoing packets */
devif_packet_conversion(dev);
/* Call back into the driver */
bstop = callback(dev);
@ -277,6 +347,10 @@ static inline int devif_poll_tcp_timer(FAR struct net_driver_s *dev,
tcp_timer(dev, conn, hsec);
/* Perform any necessary conversions on outgoing packets */
devif_packet_conversion(dev);
/* Call back into the driver */
bstop = callback(dev);

View File

@ -261,24 +261,29 @@ int ipv6_input(FAR struct net_driver_s *dev)
tcp_ipv6_input(dev);
#ifdef CONFIG_NET_6LOWPAN
/* TCP output comes through two different mechansims. Either from:
/* TCP output comes through three different mechansims. Either from:
*
* 1. TCP socket output. For the case of TCP output to an
* IEEE802.15.4, the TCP output is caught in the socket
* send()/sendto() logic and and redirected to 6loWPAN logic.
* 2. TCP output from the TCP state machine. That will pass
* here and can be detected if d_len > 0. It will be redirected
* to 6loWPAN logic here.
* 2. TCP output from the TCP state machine. That will occur
* during TCP packet processing by the TCP state meachine.
* 3. TCP output resulting from TX or timer polling
*
* Cases 2 is handled here. Logic here detected if (1) an attempt
* to return with d_len > 0 and (2) that the device is an
* IEEE802.15.4 MAC network driver. Under those conditions, 6loWPAN
* logic will be called to create the IEEE80215.4 frames.
*/
#ifdef CONFIG_NET_MULTILINK
/* Handle the case where multiple link layer protocols are supported */
/* Handle the case where multiple link layer protocols are supported */
if (dev->d_len > 0 && dev->d_lltype == CONFIG_NET_6LOWPAN)
if (dev->d_len > 0 && dev->d_lltype == CONFIG_NET_6LOWPAN)
#else
if (dev->d_len > 0)
if (dev->d_len > 0)
#endif
{
{
/* Let 6loWPAN handle the TCP output */
sixlowpan_tcp_send(dev);
@ -286,7 +291,7 @@ int ipv6_input(FAR struct net_driver_s *dev)
/* Drop the packet in the d_buf */
goto drop;
}
}
#endif /* CONFIG_NET_6LOWPAN */
break;
#endif /* NET_TCP_HAVE_STACK */

View File

@ -110,15 +110,20 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
* Function: sixlowpan_tcp_send
*
* Description:
* TCP output comes through two different mechansims. Either from:
* TCP output comes through three different mechansims. Either from:
*
* 1. TCP socket output. For the case of TCP output to an
* IEEE802.15.4, the TCP output is caught in the socket
* send()/sendto() logic and and redirected to psock_6lowpan_tcp_send().
* 2. TCP output from the TCP state machine. That will occur
* during TCP packet processing by the TCP state meachine. It
* is detected there when ipv6_tcp_input() returns with d_len > 0. This
* will be redirected here.
* during TCP packet processing by the TCP state meachine.
* 3. TCP output resulting from TX or timer polling
*
* Cases 2 and 3 will be handled here. Logic in ipv6_tcp_input(),
* devif_poll(), and devif_timer() detect if (1) an attempt to return with
* d_len > 0 and (2) that the device is an IEEE802.15.4 MAC network
* driver. Under those conditions, this function will be called to create
* the IEEE80215.4 frames.
*
* Parameters:
* dev - An instance of nework device state structure

View File

@ -155,6 +155,8 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
uint16_t iplen;
int ret;
ninfo("buflen %lu\n", (unsigned long)buflen);
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
DEBUGASSERT(psock->s_type == SOCK_STREAM);
@ -333,15 +335,20 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
* Function: sixlowpan_tcp_send
*
* Description:
* TCP output comes through two different mechansims. Either from:
* TCP output comes through three different mechansims. Either from:
*
* 1. TCP socket output. For the case of TCP output to an
* IEEE802.15.4, the TCP output is caught in the socket
* send()/sendto() logic and and redirected to psock_6lowpan_tcp_send().
* 2. TCP output from the TCP state machine. That will occur
* during TCP packet processing by the TCP state meachine. It
* is detected there when ipv6_tcp_input() returns with d_len > 0. This
* will be redirected here.
* during TCP packet processing by the TCP state meachine.
* 3. TCP output resulting from TX or timer polling
*
* Cases 2 and 3 will be handled here. Logic in ipv6_tcp_input(),
* devif_poll(), and devif_timer() detect if (1) an attempt to return with
* d_len > 0 and (2) that the device is an IEEE802.15.4 MAC network
* driver. Under those conditions, this function will be called to create
* the IEEE80215.4 frames.
*
* Parameters:
* dev - An instance of nework device state structure
@ -360,6 +367,8 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
/* Double check */
ninfo("d_len %u\n", dev->d_len);
if (dev != NULL && dev->d_len > 0)
{
FAR struct ipv6_hdr_s *ipv6hdr;

View File

@ -162,6 +162,22 @@ static int lo_txpoll(FAR struct net_driver_s *dev)
FAR struct iob_s *iob;
int ret;
if (dev->d_len > 0 || priv->lo_ieee.i_framelist != NULL)
{
ninfo("d_len: %u i_framelist: %p\n",
dev->d_len, priv->lo_ieee.i_framelist);
/* The only two valid settings are:
*
* 1. Nothing to send:
* dev->d_len == 0 && priv->lo_ieee.i_framelist == NULL
* 2. Outgoing packet has been converted to IEEE802.15.4 frames:
* dev->d_len == 0 && priv->lo_ieee.i_framelist != NULL
*/
DEBUGASSERT(dev->d_len == 0 && priv->lo_ieee.i_framelist != NULL);
}
/* Remove the queued IOBs from driver structure */
head = priv->lo_ieee.i_framelist;
@ -298,6 +314,11 @@ static void lo_poll_expiry(int argc, wdparm_t arg, ...)
{
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)arg;
if (!work_available(&priv->lo_work))
{
nwarn("WARNING: lo_work NOT available\n");
}
/* Schedule to perform the interrupt processing on the worker thread. */
work_queue(LPBKWORK, &priv->lo_work, lo_poll_work, priv, 0);
@ -324,14 +345,22 @@ static int lo_ifup(FAR struct net_driver_s *dev)
{
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private;
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
ninfo("Bringing up: Rime %02x:%02x PANID=%04x\n",
dev->d_ipv6addr[0], dev->d_ipv6addr[1], priv->lo_ieee.i_panid);
#elif CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 8
ninfo("Bringing up: Rime %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x PANID=%04x\n",
ninfo("Bringing up: IPv6 %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2],
dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5],
dev->d_ipv6addr[6], dev->d_ipv6addr[7], priv->lo_ieee.i_panid);
dev->d_ipv6addr[6], dev->d_ipv6addr[7]);
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
ninfo(" Node: %02x:%02x PANID=%04x\n",
priv->lo_ieee.i_nodeaddr.u8[0], priv->lo_ieee.i_nodeaddr.u8[1],
priv->lo_ieee.i_panid);
#else /* CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 8 */
ninfo(" Node: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x PANID=%04x\n",
priv->lo_ieee.i_nodeaddr.u8[0], priv->lo_ieee.i_nodeaddr.u8[1],
priv->lo_ieee.i_nodeaddr.u8[2], priv->lo_ieee.i_nodeaddr.u8[3],
priv->lo_ieee.i_nodeaddr.u8[4], priv->lo_ieee.i_nodeaddr.u8[5],
priv->lo_ieee.i_nodeaddr.u8[6], priv->lo_ieee.i_nodeaddr.u8[7],
priv->lo_ieee.i_panid);
#endif
/* Set and activate a timer process */
@ -363,6 +392,8 @@ static int lo_ifdown(FAR struct net_driver_s *dev)
{
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private;
ninfo("IP up: %u\n", priv->lo_bifup);
/* Cancel the TX poll timer and TX timeout timers */
wd_cancel(priv->lo_polldog);
@ -394,6 +425,8 @@ static void lo_txavail_work(FAR void *arg)
{
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)arg;
ninfo("IP up: %u\n", priv->lo_bifup);
/* Ignore the notification if the interface is not yet up */
net_lock();
@ -435,6 +468,8 @@ static int lo_txavail(FAR struct net_driver_s *dev)
{
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private;
ninfo("Available: %u\n", work_available(&priv->lo_work));
/* Is our single work structure available? It may not be if there are
* pending interrupt actions and we will have to ignore the Tx
* availability action.
@ -471,6 +506,14 @@ static int lo_txavail(FAR struct net_driver_s *dev)
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
{
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
ninfo("MAC: %02x:%02x\n",
mac[0], mac[1]);
#else /* CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 8 */
ninfo("MAC: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]);
#endif
/* There is no multicast support in the loopback driver */
return OK;
@ -498,6 +541,14 @@ static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
#ifdef CONFIG_NET_IGMP
static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
{
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
ninfo("MAC: %02x:%02x\n",
mac[0], mac[1]);
#else /* CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 8 */
ninfo("MAC: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]);
#endif
/* There is no multicast support in the loopback driver */
return OK;
@ -529,6 +580,8 @@ int ieee8021514_loopback(void)
FAR struct lo_driver_s *priv;
FAR struct net_driver_s *dev;
ninfo("Initializing\n");
/* Get the interface structure associated with this interface number. */
priv = &g_loopback;