From 2c06f8ab789d3dd8959315a85fc762515bdae0ff Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 3 Apr 2017 12:01:04 -0600 Subject: [PATCH] 6loWPAN: Updates/fixes from early testing with the IEEE802.15.4 loopback driver. --- configs/sim/sixlowpan/defconfig | 23 +++----- net/devif/devif_poll.c | 74 ++++++++++++++++++++++++ net/devif/ipv6_input.c | 23 +++++--- net/sixlowpan/sixlowpan.h | 13 +++-- net/sixlowpan/sixlowpan_tcpsend.c | 17 ++++-- wireless/ieee802154/mac802154_loopback.c | 65 +++++++++++++++++++-- 6 files changed, 177 insertions(+), 38 deletions(-) diff --git a/configs/sim/sixlowpan/defconfig b/configs/sim/sixlowpan/defconfig index dbf6981155..d3c4c9d54c 100644 --- a/configs/sim/sixlowpan/defconfig +++ b/configs/sim/sixlowpan/defconfig @@ -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 diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c index 4a5d325d43..bde0cabb7a 100644 --- a/net/devif/devif_poll.c +++ b/net/devif/devif_poll.c @@ -45,6 +45,7 @@ #include #include #include +#include #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); diff --git a/net/devif/ipv6_input.c b/net/devif/ipv6_input.c index d55b0739ad..24be107a47 100644 --- a/net/devif/ipv6_input.c +++ b/net/devif/ipv6_input.c @@ -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 */ diff --git a/net/sixlowpan/sixlowpan.h b/net/sixlowpan/sixlowpan.h index c9f54154b5..05ce9496c9 100644 --- a/net/sixlowpan/sixlowpan.h +++ b/net/sixlowpan/sixlowpan.h @@ -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 diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index 3fd541999d..933a7f6361 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -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; diff --git a/wireless/ieee802154/mac802154_loopback.c b/wireless/ieee802154/mac802154_loopback.c index 595c085e8f..1f8dc4e8c3 100644 --- a/wireless/ieee802154/mac802154_loopback.c +++ b/wireless/ieee802154/mac802154_loopback.c @@ -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;