From ad3ea72ff51f6a18e01f8fce1b57fd5ab5a0afcc Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 29 Jun 2017 10:55:01 -0600 Subject: [PATCH 1/6] Update a README; refresh some configurations. --- configs/clicker2-stm32/README.txt | 12 ++++++++++-- configs/clicker2-stm32/mrf24j40-6lowpan/defconfig | 8 ++++++-- configs/sim/sixlowpan/defconfig | 8 ++++++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/configs/clicker2-stm32/README.txt b/configs/clicker2-stm32/README.txt index b645cd33720..c5d579ee1b4 100644 --- a/configs/clicker2-stm32/README.txt +++ b/configs/clicker2-stm32/README.txt @@ -649,17 +649,25 @@ Configurations Where is the IP address of the E1 endpoint. + Similarly for the UDP test: + + E1: nsh> udpserver & + E2: nsh> udpclient & + The nsh> dmesg command can be use at any time on any node to see any debug output that you have selected. - Telenet sessions may be initiated from the hub: + Telenet sessions may be initiated only from the hub to a star + endpoint: C: nsh> telnet <-- Runs the Telnet client Where is the IP address of either the E1 or I2 endpoints. STATUS: - 2017-06-29: Configurations added but not yet tested. + 2017-06-29: Configurations added. Initial testing was not very + fruitful: There is error in the i8sak acceptaccept logic that + currently will not support multiple endpoints. nsh: diff --git a/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig index dae73e4ea3f..7a3d03e4415 100644 --- a/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig +++ b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig @@ -992,9 +992,7 @@ CONFIG_NET_6LOWPAN_MAXAGE=20 CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS=4 CONFIG_NET_6LOWPAN_MTU=1294 CONFIG_NET_6LOWPAN_TCP_RECVWNDO=1220 -CONFIG_NET_HAVE_STAR=y # CONFIG_NET_IPFORWARD is not set -# CONFIG_NET_STAR is not set # # Socket Support @@ -1060,6 +1058,12 @@ CONFIG_NET_UDP_READAHEAD=y # CONFIG_NET_ARCH_INCR32 is not set # CONFIG_NET_ARCH_CHKSUM is not set CONFIG_NET_STATISTICS=y +CONFIG_NET_HAVE_STAR=y + +# +# Network Topologies +# +# CONFIG_NET_STAR is not set # # Routing Table Configuration diff --git a/configs/sim/sixlowpan/defconfig b/configs/sim/sixlowpan/defconfig index 4360a71b20d..1de2f5c302e 100644 --- a/configs/sim/sixlowpan/defconfig +++ b/configs/sim/sixlowpan/defconfig @@ -556,9 +556,7 @@ CONFIG_NET_6LOWPAN_MAXAGE=20 CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS=4 CONFIG_NET_6LOWPAN_MTU=1294 CONFIG_NET_6LOWPAN_TCP_RECVWNDO=102 -CONFIG_NET_HAVE_STAR=y # CONFIG_NET_IPFORWARD is not set -# CONFIG_NET_STAR is not set # # Socket Support @@ -625,6 +623,12 @@ CONFIG_NET_UDP_READAHEAD=y # CONFIG_NET_ARCH_INCR32 is not set # CONFIG_NET_ARCH_CHKSUM is not set CONFIG_NET_STATISTICS=y +CONFIG_NET_HAVE_STAR=y + +# +# Network Topologies +# +# CONFIG_NET_STAR is not set # # Routing Table Configuration From af8c5c86f31af7e63fc2aad6f9e63b5a706a728f Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 30 Jun 2017 09:32:17 -0600 Subject: [PATCH 2/6] 6LowPan: Change how the destination node address is handled in the start endpoint configuration. When the star endpoint sent the IPv6 destination address, the HC06 compression logic elided the address -- meaning that it could be reconstructed by the recipient based on the receiver's assigned short address. However, when intercepted by the hub, the uncompressed address does not know the short address of the recipient and instead uses the short address of the hub. This means two things: (1) it looks like the hub address is the destination address, and (2) the uncompressed UDP packet has a bad checksum. This change assures that the destination IPv6 address is not elided in the case of the star endpoint configuration. --- configs/clicker2-stm32/README.txt | 23 ++- net/sixlowpan/README.txt | 33 ++++ net/sixlowpan/sixlowpan_framelist.c | 18 +-- net/sixlowpan/sixlowpan_input.c | 8 +- net/sixlowpan/sixlowpan_internal.h | 72 ++------- net/sixlowpan/sixlowpan_tcpsend.c | 20 ++- net/sixlowpan/sixlowpan_udpsend.c | 27 +++- net/sixlowpan/sixlowpan_utils.c | 243 +++++++++++++++++----------- 8 files changed, 259 insertions(+), 185 deletions(-) diff --git a/configs/clicker2-stm32/README.txt b/configs/clicker2-stm32/README.txt index c5d579ee1b4..110180f74cb 100644 --- a/configs/clicker2-stm32/README.txt +++ b/configs/clicker2-stm32/README.txt @@ -603,7 +603,7 @@ Configurations CONFIG_NET_STAR=y CONFIG_NET_STARPOINT=y - The CONFIG_NET_STARPOINT selection informs the endpoint that is + The CONFIG_NET_STARPOINT selection informs the endpoint that it must send all frames to the hub of the star, rather than directly to the recipient. @@ -665,9 +665,24 @@ Configurations Where is the IP address of either the E1 or I2 endpoints. STATUS: - 2017-06-29: Configurations added. Initial testing was not very - fruitful: There is error in the i8sak acceptaccept logic that - currently will not support multiple endpoints. + 2017-06-29: Configurations added. Initial testing indicates that + the TCP Telnet client can successfully establish sessions with + the two star endpoints. When testing communications between the + two star endpoints via the hub, the frames are correctly directed + to the hub. However, they are not being forwarded to the other + endpoint. + 2017-06-30: The failure to forward is understood: When the star + endpoint sent the IPv6 destination address, the HC06 compression + logic elided the address -- meaning that it could be reconstructed + based on the receiver's assigned short address. However, when + intercepted by the hub, the uncompressed address does not know + the short address of the recipient and instead uses the short + address of the hub. This means two things: (1) it looks like + the hub address is the destination address, and (2) the + uncompressed UDP packet has a bad checksum. + + This required a change to assure that the destination IPv6 address + is not elided in the case of the star endpoint configuration. nsh: diff --git a/net/sixlowpan/README.txt b/net/sixlowpan/README.txt index 4c654caef14..7de217530b1 100644 --- a/net/sixlowpan/README.txt +++ b/net/sixlowpan/README.txt @@ -1,3 +1,11 @@ +6LoWPAN Contents +---------------- + + o 6LoWPAN Addressing + o IPv6 Neighbor Discovery + o Optimal 6LoWPAN Configuration + o Star Configuration + 6LoWPAN Addressing ------------------ @@ -142,3 +150,28 @@ The payload length is encoded in the LS 11-bits of the first 16-bit value: In this example the payload size is 0x050e or 1,294. The tag is 0x000b. In the second frame, the fifth byte contains the offset 0x0d which is 13 << 3 = 104 bytes, the size of the payload on the first packet. + +Star Configuration +------------------ + +The 6LoWPAN stack can be specially configured as member in a star topology; +either as a endpoint on the star os the star hub. The endpoint is +created with the following settings in the configuration file: + + CONFIG_NET_STAR=y + CONFIG_NET_STARPOINT=y + +The CONFIG_NET_STARPOINT selection informs the endpoint 6LoWPAN stack that +it must send all frames to the hub of the star, rather than directly to the +recipient. The star hub is assumed to be the cooordinator. + +The star hub configuration, on the other hand, uses these setting: + + CONFIG_NET_STAR=y + CONFIG_NET_STARHUB=y + CONFIG_NET_IPFORWARD=y + +The CONFIG_NET_IPFORWARD selection informs the hub that if it receives any +packets that are not destined for the hub, it should forward those packets +appropriately. This affects the behavior of IPv6 packet reception logic but +does not change the behavior of the 6LoWPAN stack. diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index 2f7b1398178..c15b968909f 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -324,22 +324,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, &ieee->i_dev.d_mac.ieee802154); #endif -#ifdef CONFIG_NET_STARPOINT - /* If this node is a "point" in a star topology, then the destination - * MAC address is the address of the hub/PAN coordinator. - */ - - if (destmac->extended) - { - pktmeta.dextended = TRUE; - ret = sixlowpan_coord_eaddr(ieee, pktmeta.dest.eaddr.u8); - } - else - { - ret = sixlowpan_coord_saddr(ieee, pktmeta.dest.saddr.u8); - } -#else - /* Otherwise, it is the actual destination node address */ + /* Copy the destination node address into the meta data */ if (destmac->extended) { @@ -350,7 +335,6 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, { sixlowpan_saddrcopy(pktmeta.dest.saddr.u8, destmac->u.saddr.u8); } -#endif /* Get the destination PAN ID. * diff --git a/net/sixlowpan/sixlowpan_input.c b/net/sixlowpan/sixlowpan_input.c index d9074fab276..6a784cb2339 100644 --- a/net/sixlowpan/sixlowpan_input.c +++ b/net/sixlowpan/sixlowpan_input.c @@ -830,7 +830,13 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee, * address. */ - sixlowpan_addrfromip(ipv6hdr->destipaddr, &destmac); + ret = sixlowpan_destaddrfromip(ieee, ipv6hdr->destipaddr, + &destmac); + if (ret < 0) + { + nerr("ERROR: Failed to dest MAC address: %d\n", ret); + goto drop; + } /* The data payload should follow the IPv6 header plus * the protocol header. diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index 221d3ad2ef3..ccc7e04a5a8 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -536,25 +536,28 @@ int sixlowpan_uncompresshdr_hc1(FAR const struct ieee802154_data_ind_s *ind, #endif /**************************************************************************** - * Name: sixlowpan_islinklocal, sixlowpan_addrfromip, and + * Name: sixlowpan_islinklocal, sixlowpan_destaddrfromip, and * sixlowpan_ismacbased * * Description: - * sixlowpan_{s|e]addrfromip(): Extract the IEEE 802.15.14 address from a - * MAC-based IPv6 address. sixlowpan_addrfromip() is intended to handle a - * tagged address; sixlowpan_saddrfromip() and sixlowpan_eaddrfromip() - * specifically handle short and extended addresses, respectively. + * sixlowpan_destaddrfromip(): Extract the IEEE 802.15.14 destination + * address from a MAC-based destination IPv6 address. This function + * handles a tagged address union which may either a short or and + * extended destination address. + * + * In the case there the IEEE 802.15.4 node functions as an endpoint in a + * start topology, the destination address will, instead, be the address + * of the star hub (which is assumed to be the address of the cooordinator). * * sixlowpan_ipfrom[s|e]addr(): Create a link-local, MAC-based IPv6 * address from an IEEE802.15.4 short address (saddr) or extended address * (eaddr). * * sixlowpan_islinklocal() and sixlowpan_ismacbased() will return true for - * address created in this fashion. sixlowpan_addrfromip() is intended to - * handle a tagged address or any size; sixlowpan_issaddrbased() and - * sixlowpan_iseaddrbased() specifically handle short and extended - * addresses. Local addresses are of a fixed but configurable size and - * sixlowpan_isaddrbased() is for use with such local addresses. + * address created in this fashion. sixlowpan_destaddrfromip() is intended to + * handle a tagged address or any size. Local addresses are of a fixed but + * configurable size and sixlowpan_isaddrbased() is for use with such local + * addresses. * * 128 112 96 80 64 48 32 16 * ---- ---- ---- ---- ---- ---- ---- ---- @@ -565,12 +568,9 @@ int sixlowpan_uncompresshdr_hc1(FAR const struct ieee802154_data_ind_s *ind, #define sixlowpan_islinklocal(ipaddr) ((ipaddr)[0] == NTOHS(0xfe80)) -void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr, - FAR struct sixlowpan_saddr_s *saddr); -void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr, - FAR struct sixlowpan_eaddr_s *eaddr); -void sixlowpan_addrfromip(const net_ipv6addr_t ipaddr, - FAR struct sixlowpan_tagaddr_s *addr); +int sixlowpan_destaddrfromip(FAR struct ieee802154_driver_s *ieee, + const net_ipv6addr_t ipaddr, + FAR struct sixlowpan_tagaddr_s *addr); void sixlowpan_ipfromsaddr(FAR const uint8_t *saddr, FAR net_ipv6addr_t ipaddr); @@ -593,46 +593,6 @@ bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr, bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr, FAR const struct sixlowpan_tagaddr_s *addr); -/**************************************************************************** - * Name: sixlowpan_coord_eaddr - * - * Description: - * Get the extended address of the PAN coordinator. - * - * Input parameters: - * ieee - A reference IEEE802.15.4 MAC network device structure. - * eaddr - The location in which to return the extended address. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_NET_STARPOINT -int sixlowpan_coord_eaddr(FAR struct ieee802154_driver_s *ieee, - FAR uint8_t *eaddr); -#endif - -/**************************************************************************** - * Name: sixlowpan_coord_saddr - * - * Description: - * Get the short address of the PAN coordinator. - * - * Input parameters: - * ieee - A reference IEEE802.15.4 MAC network device structure. - * saddr - The location in which to return the short address. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_NET_STARPOINT -int sixlowpan_coord_saddr(FAR struct ieee802154_driver_s *ieee, - FAR uint8_t *saddr); -#endif - /**************************************************************************** * Name: sixlowpan_src_panid * diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index eac31b90261..cc7d902b0f3 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -835,7 +835,13 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, * an encoding of the MAC address in the IPv6 address. */ - sixlowpan_addrfromip(conn->u.ipv6.raddr, &destmac); + ret = sixlowpan_destaddrfromip((FAR struct ieee802154_driver_s *)dev, + conn->u.ipv6.raddr, &destmac); + if (ret < 0) + { + nerr("ERROR: Failed to dest MAC address: %d\n", ret); + return (ssize_t)ret; + } /* Set the socket state to sending */ @@ -859,7 +865,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, nerr("ERROR: sixlowpan_send_packet() failed: %d\n", ret); psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE); - return (ssize_t)buflen; + return (ssize_t)ret; } /* Set the socket state to idle */ @@ -942,12 +948,19 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev, FAR uint8_t *buf; uint16_t hdrlen; uint16_t buflen; + int ret; /* Get the IEEE 802.15.4 MAC address of the destination. This * assumes an encoding of the MAC address in the IPv6 address. */ - sixlowpan_addrfromip(ipv6hdr->ipv6.destipaddr, &destmac); + ret = sixlowpan_destaddrfromip((FAR struct ieee802154_driver_s *)dev, + ipv6hdr->ipv6.destipaddr, &destmac); + if (ret < 0) + { + nerr("ERROR: Failed to dest MAC address: %d\n", ret); + goto drop; + } /* Get the IPv6 + TCP combined header length. The size of the TCP * header is encoded in the top 4 bits of the tcpoffset field (in @@ -977,6 +990,7 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev, } } +drop: dev->d_len = 0; } diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index c7a7d5e8f60..de8681baa79 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -297,15 +297,21 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, g_netstats.udp.sent++; #endif - /* Set the socket state to sending */ - - psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND); - /* Get the IEEE 802.15.4 MAC address of the destination This assumes an * encoding of the MAC address in the IPv6 address. */ - sixlowpan_addrfromip(to6->sin6_addr.in6_u.u6_addr16, &destmac); + ret = sixlowpan_destaddrfromip((FAR struct ieee802154_driver_s *)dev, + to6->sin6_addr.in6_u.u6_addr16, &destmac); + if (ret < 0) + { + nerr("ERROR: Failed to dest MAC address: %d\n", ret); + return (ssize_t)ret; + } + + /* Set the socket state to sending */ + + psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND); /* If routable, then call sixlowpan_send() to format and send the 6LoWPAN * packet. @@ -328,7 +334,7 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, /* Set the socket state to idle */ psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE); - return ret; + return (ssize_t)ret; } /**************************************************************************** @@ -470,7 +476,13 @@ void sixlowpan_udp_send(FAR struct net_driver_s *dev, * assumes an encoding of the MAC address in the IPv6 address. */ - sixlowpan_addrfromip(ipv6udp->ipv6.destipaddr, &destmac); + ret = sixlowpan_destaddrfromip((FAR struct ieee802154_driver_s *)dev, + ipv6udp->ipv6.destipaddr, &destmac); + if (ret < 0) + { + nerr("ERROR: Failed to dest MAC address: %d\n", ret); + goto drop; + } /* Get the IPv6 + UDP combined header length. */ @@ -497,6 +509,7 @@ void sixlowpan_udp_send(FAR struct net_driver_s *dev, } } +drop: dev->d_len = 0; } #endif diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c index b404d37fa69..26046cfe061 100644 --- a/net/sixlowpan/sixlowpan_utils.c +++ b/net/sixlowpan/sixlowpan_utils.c @@ -64,17 +64,17 @@ #ifdef CONFIG_NET_6LOWPAN /**************************************************************************** - * Public Functions + * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: sixlowpan_{s|e]addrfromip + * Name: sixlowpan_[s|e]addrfromip * * Description: - * sixlowpan_{s|e]addrfromip(): Extract the IEEE 802.15.14 address from a - * MAC-based IPv6 address. sixlowpan_addrfromip() is intended to handle a - * tagged address; sixlowpan_saddrfromip() and sixlowpan_eaddrfromip() - * specifically handle short and extended addresses, respectively. + * sixlowpan_[s|e]addrfromip(): Extract the IEEE 802.15.14 address from a + * MAC-based IPv6 address. sixlowpan_saddrfromip() and + * sixlowpan_eaddrfromip() handle short and extended addresses, + * respectively. * * 128 112 96 80 64 48 32 16 * ---- ---- ---- ---- ---- ---- ---- ---- @@ -83,8 +83,9 @@ * ****************************************************************************/ -void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr, - FAR struct sixlowpan_saddr_s *saddr) +#ifndef CONFIG_NET_STARPOINT +static void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr, + FAR struct sixlowpan_saddr_s *saddr) { DEBUGASSERT(ipaddr[0] == HTONS(0xfe80)); @@ -95,8 +96,8 @@ void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr, saddr->u8[0] ^= 0x02; } -void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr, - FAR struct sixlowpan_eaddr_s *eaddr) +static void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr, + FAR struct sixlowpan_eaddr_s *eaddr) { FAR uint8_t *eptr = eaddr->u8; int i; @@ -113,22 +114,147 @@ void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr, eaddr->u8[0] ^= 0x02; } +#endif /* !CONFIG_NET_STARPOINT */ -void sixlowpan_addrfromip(const net_ipv6addr_t ipaddr, - FAR struct sixlowpan_tagaddr_s *addr) +/**************************************************************************** + * Name: sixlowpan_coord_eaddr + * + * Description: + * Get the extended address of the PAN coordinator. + * + * Input parameters: + * ieee - A reference IEEE802.15.4 MAC network device structure. + * eaddr - The location in which to return the extended address. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NET_STARPOINT) && defined(CONFIG_NET_6LOWPAN_EXTENDEDADDR) +static int sixlowpan_coord_eaddr(FAR struct ieee802154_driver_s *ieee, + FAR struct sixlowpan_eaddr_s *eaddr) { + FAR struct net_driver_s *dev = &ieee->i_dev; + struct ieee802154_netmac_s arg; + int ret; + + memcpy(arg.ifr_name, ieee->i_dev.d_ifname, IFNAMSIZ); + arg.u.getreq.attr = IEEE802154_ATTR_MAC_COORD_EADDR ; + ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST, + (unsigned long)((uintptr_t)&arg)); + if (ret < 0) + { + nerr("ERROR: MAC802154IOC_MLME_GET_REQUEST failed: %d\n", ret); + return ret; + } + + IEEE802154_EADDRCOPY(eaddr->u8, arg.u.getreq.attrval.mac.eaddr); + return OK; +} +#endif + +/**************************************************************************** + * Name: sixlowpan_coord_saddr + * + * Description: + * Get the short address of the PAN coordinator. + * + * Input parameters: + * ieee - A reference IEEE802.15.4 MAC network device structure. + * saddr - The location in which to return the short address. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NET_STARPOINT) && !defined(CONFIG_NET_6LOWPAN_EXTENDEDADDR) +static int sixlowpan_coord_saddr(FAR struct ieee802154_driver_s *ieee, + FAR struct sixlowpan_saddr_s *saddr) +{ + FAR struct net_driver_s *dev = &ieee->i_dev; + struct ieee802154_netmac_s arg; + int ret; + + memcpy(arg.ifr_name, ieee->i_dev.d_ifname, IFNAMSIZ); + arg.u.getreq.attr = IEEE802154_ATTR_MAC_COORD_SADDR ; + ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST, + (unsigned long)((uintptr_t)&arg)); + if (ret < 0) + { + nerr("ERROR: MAC802154IOC_MLME_GET_REQUEST failed: %d\n", ret); + return ret; + } + + IEEE802154_SADDRCOPY(saddr->u8, arg.u.getreq.attrval.mac.saddr); + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sixlowpan_destaddrfromip + * + * Description: + * sixlowpan_destaddrfromip(): Extract the IEEE 802.15.14 destination + * address from a MAC-based destination IPv6 address. This function + * handles a tagged address union which may either a short or and + * extended destination address. + * + * 128 112 96 80 64 48 32 16 + * ---- ---- ---- ---- ---- ---- ---- ---- + * xxxx 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC + * xxxx 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64 + * + * In the case there the IEEE 802.15.4 node functions as an endpoint in a + * start topology, the destination address will, instead, be the address + * of the star hub (which is assumed to be the address of the cooordinator). + * + ****************************************************************************/ + +int sixlowpan_destaddrfromip(FAR struct ieee802154_driver_s *ieee, + const net_ipv6addr_t ipaddr, + FAR struct sixlowpan_tagaddr_s *destaddr) +{ +#ifdef CONFIG_NET_STARPOINT + int ret; + + /* If this node is a "point" in a star topology, then the destination + * MAC address is the address of the hub/PAN coordinator. + */ + +#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR + ret = sixlowpan_coord_eaddr(ieee, &destaddr->u.eaddr); + destaddr->extended = true; +#else + memset(destaddr, 0, sizeof(struct sixlowpan_tagaddr_s)); + ret = sixlowpan_coord_saddr(ieee, &destaddr->u.saddr); +#endif + + return ret; + +#else DEBUGASSERT(ipaddr[0] == HTONS(0xfe80)); + /* Otherwise, the destination MAC address is encoded in the IP address */ + if (SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(ipaddr)) { - memset(addr, 0, sizeof(struct sixlowpan_tagaddr_s)); - sixlowpan_saddrfromip(ipaddr, &addr->u.saddr); + memset(destaddr, 0, sizeof(struct sixlowpan_tagaddr_s)); + sixlowpan_saddrfromip(ipaddr, &destaddr->u.saddr); } else { - sixlowpan_eaddrfromip(ipaddr, &addr->u.eaddr); - addr->extended = true; + sixlowpan_eaddrfromip(ipaddr, &destaddr->u.eaddr); + destaddr->extended = true; } + + return OK; +#endif } /**************************************************************************** @@ -179,11 +305,10 @@ void sixlowpan_ipfromeaddr(FAR const uint8_t *eaddr, * * Description: * sixlowpan_ismacbased() will return true for IP addresses formed from - * IEEE802.15.4 MAC addresses. sixlowpan_addrfromip() is intended to - * handle a tagged address or any size; sixlowpan_issaddrbased() and - * sixlowpan_iseaddrbased() specifically handle short and extended - * addresses. Local addresses are of a fixed but configurable size and - * sixlowpan_isaddrbased() is for use with such local addresses. + * IEEE802.15.4 MAC addresses. sixlowpan_destaddrfromip() is intended to + * handle a tagged address or any size. Local addresses are of a fixed + * but configurable size and sixlowpan_isaddrbased() is for use with such + * local addresses. * * * 128 112 96 80 64 48 32 16 @@ -227,82 +352,6 @@ bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr, } } -/**************************************************************************** - * Name: sixlowpan_coord_eaddr - * - * Description: - * Get the extended address of the PAN coordinator. - * - * Input parameters: - * ieee - A reference IEEE802.15.4 MAC network device structure. - * eaddr - The location in which to return the extended address. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_NET_STARPOINT -int sixlowpan_coord_eaddr(FAR struct ieee802154_driver_s *ieee, - FAR uint8_t *eaddr) -{ - FAR struct net_driver_s *dev = &ieee->i_dev; - struct ieee802154_netmac_s arg; - int ret; - - memcpy(arg.ifr_name, ieee->i_dev.d_ifname, IFNAMSIZ); - arg.u.getreq.attr = IEEE802154_ATTR_MAC_COORD_EADDR ; - ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST, - (unsigned long)((uintptr_t)&arg)); - if (ret < 0) - { - nerr("ERROR: MAC802154IOC_MLME_GET_REQUEST failed: %d\n", ret); - return ret; - } - - IEEE802154_EADDRCOPY(eaddr, arg.u.getreq.attrval.mac.eaddr); - return OK; -} -#endif - -/**************************************************************************** - * Name: sixlowpan_coord_saddr - * - * Description: - * Get the short address of the PAN coordinator. - * - * Input parameters: - * ieee - A reference IEEE802.15.4 MAC network device structure. - * saddr - The location in which to return the short address. - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_NET_STARPOINT -int sixlowpan_coord_saddr(FAR struct ieee802154_driver_s *ieee, - FAR uint8_t *saddr) -{ - FAR struct net_driver_s *dev = &ieee->i_dev; - struct ieee802154_netmac_s arg; - int ret; - - memcpy(arg.ifr_name, ieee->i_dev.d_ifname, IFNAMSIZ); - arg.u.getreq.attr = IEEE802154_ATTR_MAC_COORD_SADDR ; - ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST, - (unsigned long)((uintptr_t)&arg)); - if (ret < 0) - { - nerr("ERROR: MAC802154IOC_MLME_GET_REQUEST failed: %d\n", ret); - return ret; - } - - IEEE802154_SADDRCOPY(saddr, arg.u.getreq.attrval.mac.saddr); - return OK; -} -#endif - /**************************************************************************** * Name: sixlowpan_src_panid * From 76e6dba2e4bfab9515bef2866c5c59fd2a2f0fa0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 30 Jun 2017 10:08:44 -0600 Subject: [PATCH 3/6] 6LoWPAN: Fix a misconception about HC06 16-bit IPv6 address compression. --- net/sixlowpan/sixlowpan_hc06.c | 47 +++++----------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c index ec9577e1dc6..6b28adc56a3 100644 --- a/net/sixlowpan/sixlowpan_hc06.c +++ b/net/sixlowpan/sixlowpan_hc06.c @@ -354,7 +354,6 @@ static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, FAR net_ipv6addr_t ipaddr) { FAR const uint8_t *srcptr; - bool fullmac = false; bool usemac = (prefpost & 0x0100) != 0; uint8_t prefcount = (prefpost >> 4) & 0xf; uint8_t postcount = prefpost & 0x0f; @@ -384,12 +383,6 @@ static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, { postcount = addrsize; } - - /* If we are converting the entire MAC address, then we need to some some - * special bit operations. - */ - - fullmac = (postcount == addrsize); } /* Copy any prefix */ @@ -412,6 +405,9 @@ static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, if (postcount > 0) { + FAR uint8_t *destptr = (FAR uint8_t *)&ipaddr[0]; + int offset = 16 - postcount; + if (postcount == 2 && prefcount < 11) { /* 16 bits uncompression ipaddr=0000:00ff:fe00:XXXX */ @@ -420,36 +416,7 @@ static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, ipaddr[6] = HTONS(0xfe00); } - /* If the postcount is even then take extra care with endian-ness */ - - if ((postcount & 1) == 0) - { - int destndx = 8 - (postcount >> 1); - int i; - - for (i = destndx; i < 8; i++) - { - ipaddr[i] = (uint16_t)srcptr[0] << 8 | (uint16_t)srcptr[1]; - srcptr += 2; - } - - /* If the was a standard MAC based address then toggle */ - - if (fullmac) - { - ipaddr[destndx] ^= 0x200; - } - } - - /* postcount is odd... */ - - else - { - FAR uint8_t *destptr = (FAR uint8_t *)&ipaddr[0]; - int offset = 16 - postcount; - - memcpy(&destptr[offset], srcptr, postcount); - } + memcpy(&destptr[offset], srcptr, postcount); /* If we took the data from packet, then update the packet pointer */ @@ -849,13 +816,13 @@ int sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, { /* Elide the prefix */ - iphc1 |= SIXLOWPAN_IPHC_DAC; + iphc1 |= SIXLOWPAN_IPHC_DAC; iphc[2] |= addrcontext->number; /* Compession compare with link adress (destination) */ - iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac, - SIXLOWPAN_IPHC_DAM_BIT); + iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac, + SIXLOWPAN_IPHC_DAM_BIT); } /* No address context found for this address */ From e19c52ed6e3db44ceeef7f581683c046bfacf602 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 30 Jun 2017 10:13:31 -0600 Subject: [PATCH 4/6] 6LoWPAN fix compile issue in star hub configuration. --- net/sixlowpan/sixlowpan_udpsend.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index de8681baa79..686ae660ca7 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -471,6 +471,7 @@ void sixlowpan_udp_send(FAR struct net_driver_s *dev, FAR uint8_t *buf; uint16_t hdrlen; uint16_t buflen; + int ret; /* Get the IEEE 802.15.4 MAC address of the destination. This * assumes an encoding of the MAC address in the IPv6 address. From 7de86f1ab4c468cb206b8b95394ae3b17979e7c7 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 30 Jun 2017 12:39:00 -0600 Subject: [PATCH 5/6] This change backs out the 'misconception' fix of 76e6dba2e4bfab9515bef2866c5c59fd2a2f0fa0 and reimplements it in a way that actually seems to work. --- net/sixlowpan/sixlowpan_hc06.c | 58 +++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c index 6b28adc56a3..4676cfaf42b 100644 --- a/net/sixlowpan/sixlowpan_hc06.c +++ b/net/sixlowpan/sixlowpan_hc06.c @@ -251,16 +251,23 @@ static uint8_t compress_ipaddr(FAR const net_ipv6addr_t ipaddr, uint8_t bitpos) { /* Compress IID to 16 bits: xxxx:xxxx:xxxx:xxxx:0000:00ff:fe00:XXXX */ - memcpy(g_hc06ptr, &ipaddr[7], 2); - g_hc06ptr += 2; + *g_hc06ptr++ = ipaddr[7] >> 8; /* Big-endian, network order */ + *g_hc06ptr++ = ipaddr[7] & 0xff; + return 2 << bitpos; /* 16-bits */ } else { + int i; + /* Do not compress IID: xxxx:xxxx:xxxx:xxxx:IID:IID:IID:IID */ - memcpy(g_hc06ptr, &ipaddr[4], 8); - g_hc06ptr += 8; + for (i = 4; i < 8; i++) + { + *g_hc06ptr++ = ipaddr[i] >> 8; /* Big-endian, network order */ + *g_hc06ptr++ = ipaddr[i] & 0xff; + } + return 1 << bitpos; /* 64-bits */ } } @@ -354,6 +361,7 @@ static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, FAR net_ipv6addr_t ipaddr) { FAR const uint8_t *srcptr; + bool fullmac = false; bool usemac = (prefpost & 0x0100) != 0; uint8_t prefcount = (prefpost >> 4) & 0xf; uint8_t postcount = prefpost & 0x0f; @@ -383,6 +391,12 @@ static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, { postcount = addrsize; } + + /* If we are converting the entire MAC address, then we need to some some + * special bit operations. + */ + + fullmac = (postcount == addrsize); } /* Copy any prefix */ @@ -405,9 +419,6 @@ static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, if (postcount > 0) { - FAR uint8_t *destptr = (FAR uint8_t *)&ipaddr[0]; - int offset = 16 - postcount; - if (postcount == 2 && prefcount < 11) { /* 16 bits uncompression ipaddr=0000:00ff:fe00:XXXX */ @@ -416,7 +427,38 @@ static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, ipaddr[6] = HTONS(0xfe00); } - memcpy(&destptr[offset], srcptr, postcount); + /* If the postcount is even then take extra care with endian-ness */ + + if ((postcount & 1) == 0) + { + int destndx = 8 - (postcount >> 1); + int i; + + for (i = destndx; i < 8; i++) + { + /* Big-endian, network order */ + + ipaddr[i] = (uint16_t)srcptr[0] << 8 | (uint16_t)srcptr[1]; + srcptr += 2; + } + + /* If the was a standard MAC based address then toggle */ + + if (fullmac) + { + ipaddr[destndx] ^= 0x0200; + } + } + + /* postcount is odd... REVISIT: I am not sure about bye ordering. */ + + else + { + FAR uint8_t *destptr = (FAR uint8_t *)&ipaddr[0]; + int offset = 16 - postcount; + + memcpy(&destptr[offset], srcptr, postcount); + } /* If we took the data from packet, then update the packet pointer */ From ae1771454a7350837a0fddc9b751483fc4ba89a2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 30 Jun 2017 16:07:51 -0600 Subject: [PATCH 6/6] 6LoWPAN: TCP send logic was returning a failure in one case when, in fact, the send was successful. --- configs/clicker2-stm32/README.txt | 5 ++++- net/sixlowpan/sixlowpan_tcpsend.c | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/configs/clicker2-stm32/README.txt b/configs/clicker2-stm32/README.txt index 110180f74cb..b2dc89257c6 100644 --- a/configs/clicker2-stm32/README.txt +++ b/configs/clicker2-stm32/README.txt @@ -682,7 +682,10 @@ Configurations uncompressed UDP packet has a bad checksum. This required a change to assure that the destination IPv6 address - is not elided in the case of the star endpoint configuration. + is not elided in the case of the star endpoint configuration. After + some additional fixes for byte ordering in 16-bit and 64-bit + compressed IPv6 addresses, the all tests are working as expectedd: + TCP, UDP, Telnet. nsh: diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index cc7d902b0f3..be1f04055b1 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -417,6 +417,7 @@ static uint16_t tcp_send_interrupt(FAR struct net_driver_s *dev, * actually sent. */ + sinfo->s_result = sinfo->s_sent; goto end_wait; }