diff --git a/configs/clicker2-stm32/README.txt b/configs/clicker2-stm32/README.txt index 260137c1522..4ceae509e59 100644 --- a/configs/clicker2-stm32/README.txt +++ b/configs/clicker2-stm32/README.txt @@ -453,6 +453,19 @@ Configurations NOTE: There is no way to stop the UDP test once it has been started other than by resetting the board. + Cheat Sheet. Here is a concise summary of all all the steps needed to + run the UDP test (C=Coordinator; E=Endpoint): + + C: nsh> i8 /dev/ieee0 startpan + C: nsh> 8 acceptassoc + E: nsh> i8 assoc + C: nsh> ifup wpan0 + C: nsh> ifconfig <-- To get the + E: nsh> ifup wpan0 + C: nsh> udpserver & + E: nsh> udpclient & + E: nsh> dmesg + STATUS: 2017-06-19: The Telnet Daemon does not start. This is simply because the daemon is started too early in the sequence... before the network @@ -460,7 +473,27 @@ Configurations telnetd_daemon: ERROR: socket failure: 106 - 2017-06-20: Debug underway.. not yet functional. + 2017-06-21: Basic functionality has been achieved. The following + configurations have been tested: + + DATE + COMPRESSION ADDRESSING UDP TCP + ----------- ---------- ---- ---- + hc06 short 6/21 --- + extended 6/22 --- + hc1 short --- --- + extended --- --- + ipv6 short --- --- + extended --- --- + + Other configuration options have not been specifically addressed + (such non-compressable ports, non-MAC based IPv6 addresses, etc.) + + One limitation of this test is that it only tests NuttX 6LoWPAN + against NuttX 6LoWPAN. It does not prove that NuttX 6LoWPAN is + compatible with other implementations of 6LoWPAN. The tests could + potentially be verifying only that the design is implemented + incorrectly in compatible way on both the client and server sides. nsh: diff --git a/configs/sim/sixlowpan/defconfig b/configs/sim/sixlowpan/defconfig index 01751fb2436..b3b1a729303 100644 --- a/configs/sim/sixlowpan/defconfig +++ b/configs/sim/sixlowpan/defconfig @@ -712,6 +712,7 @@ CONFIG_WIRELESS_IEEE802154=y CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef CONFIG_MAC802154_HPWORK=y CONFIG_MAC802154_NTXDESC=3 +CONFIG_MAC802154_NNOTIF=3 CONFIG_IEEE802154_IND_PREALLOC=20 CONFIG_IEEE802154_IND_IRQRESERVE=10 # CONFIG_IEEE802154_MACDEV is not set diff --git a/include/nuttx/net/ip.h b/include/nuttx/net/ip.h index 84df3520740..9950ea17446 100644 --- a/include/nuttx/net/ip.h +++ b/include/nuttx/net/ip.h @@ -553,7 +553,7 @@ bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1, * Name: net_is_addr_unspecified * * Description: - * Is Ithe Pv6 address the unspecified address? + * Is Ithe IPv6 address the unspecified address? * ****************************************************************************/ diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index 18ea2379450..7c34217ae9b 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -3,7 +3,7 @@ * Defines architecture-specific device driver interfaces to the NuttX * network. * - * Copyright (C) 2007, 2009, 2011-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Derived largely from portions of uIP with has a similar BSD-styple license: diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index ed6d2d82edd..dbd902a1cfd 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -236,7 +236,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, #endif int ret; - ninfo("buflen=%lu", (unsigned long)buflen); + ninfo("buflen=%lu\n", (unsigned long)buflen); /* Initialize global data. Locking the network guarantees that we have * exclusive use of the global values for intermediate calculations. diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c index c6681b2724e..4575a301ed5 100644 --- a/net/sixlowpan/sixlowpan_hc06.c +++ b/net/sixlowpan/sixlowpan_hc06.c @@ -109,43 +109,58 @@ static FAR uint8_t *g_hc06ptr; /* Uncompression of linklocal * * 0 -> 16 bytes from packet - * 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet - * 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet - * 3 -> 2 bytes from prefix - infer 8 bytes from MAC address + * 1 -> 2 bytes from prefix - 16 bytes from packet + * 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX and 2 bytes from packet + * 3 -> 2 bytes from prefix - Infer 2 or 8 bytes from MAC address * - * NOTE: => the uncompress function does change 0xf to 0x10 - * NOTE: 0x00 => no-autoconfig => unspecified + * NOTE: ipaddr=the uncompress function does change 0xf to 0x10 + * NOTE: 0x00 ipaddr=no-autoconfig ipaddr=unspecified */ -static const uint8_t g_unc_llconf[] = { 0x0f, 0x28, 0x22, 0x20 }; +static const uint16_t g_unc_llconf[] = +{ + 0x000f, 0x0028, 0x0022, 0x0120 +}; /* Uncompression of ctx-based * * 0 -> 0 bits from packet [unspecified / reserved] - * 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet - * 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX + 2 from packet - * 3 -> 8 bytes from prefix - infer 8 bytes from MAC address + * 1 -> 8 bytes from prefix - Bunch of zeroes and 8 bytes from packet + * 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX and 2 bytes from packet + * 3 -> 8 bytes from prefix - Infer 2 or 8 bytes from MAC address */ -static const uint8_t g_unc_ctxconf[] = { 0x00, 0x88, 0x82, 0x80 }; +static const uint16_t g_unc_ctxconf[] = +{ + 0x0000, 0x0088, 0x0082, 0x0180 +}; /* Uncompression of ctx-based * * 0 -> 0 bits from packet - * 1 -> 2 bytes from prefix - bunch of zeroes 5 from packet - * 2 -> 2 bytes from prefix - zeroes + 3 from packet - * 3 -> 2 bytes from prefix - infer 1 bytes from MAC address + * 1 -> 2 bytes from prefix - Bunch of zeroes 5 bytes from packet + * 2 -> 2 bytes from prefix - Zeroes + 3 bytes from packet + * 3 -> 2 bytes from prefix - Infer 1 bytes from MAC address */ -static const uint8_t g_unc_mxconf[] = { 0x0f, 0x25, 0x23, 0x21 }; +static const uint16_t g_unc_mxconf[] = +{ + 0x000f, 0x0025, 0x0023, 0x0121 +}; /* Link local prefix */ -static const uint8_t g_llprefix[] = { 0xfe, 0x80 }; +static const uint8_t g_llprefix[] = +{ + 0xfe, 0x80 +}; /* TTL uncompression values */ -static const uint8_t g_ttl_values[] = { 0, 1, 64, 255 }; +static const uint8_t g_ttl_values[] = +{ + 0, 1, 64, 255 +}; /**************************************************************************** @@ -184,7 +199,7 @@ static FAR struct sixlowpan_addrcontext_s * } /**************************************************************************** - * Name: find_addrcontext_bynumber + * Name: find_addrcontext_byprefix * * Description: * Find the address context corresponding to the prefix ipaddr. @@ -213,7 +228,7 @@ static FAR struct sixlowpan_addrcontext_s * } /**************************************************************************** - * Name: comporess_ipaddr, compress_tagaddr, and compress_laddr + * Name: compress_ipaddr, compress_tagaddr, and compress_laddr * * Description: * Uncompress addresses based on a prefix and a postfix with zeroes in @@ -221,7 +236,7 @@ static FAR struct sixlowpan_addrcontext_s * * to configure the IP address (autoconf style). * * prefpost takes a byte where the first nibble specify prefix count - * and the second postfix count (NOTE: 15/0xf => 16 bytes copy). + * and the second postfix count (NOTE: 15/0xf ipaddr=16 bytes copy). * * compress_tagaddr() accepts a remote, variable length, taged MAC address; * compress_laddr() accepts a local, fixed length MAC address. @@ -254,34 +269,71 @@ static uint8_t compress_tagaddr(FAR const net_ipv6addr_t ipaddr, FAR const struct sixlowpan_tagaddr_s *macaddr, uint8_t bitpos) { - ninfo("ipaddr=%p macaddr=%p extended=%u bitpos=%u g_hc06ptr=%p\n", - ipaddr, macaddr, macaddr->extended, bitpos, g_hc06ptr); + uint8_t tag; - if (sixlowpan_ismacbased(ipaddr, macaddr)) + ninfo("Compressing bitpos=%u extended=%u\n", bitpos, macaddr->extended); + ninfo(" ipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ipaddr[4], ipaddr[5], ipaddr[6], ipaddr[7]); + + if (macaddr->extended) { - return 3 << bitpos; /* 0-bits */ + ninfo(" eaddr=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + macaddr->u.eaddr.u8[0], macaddr->u.eaddr.u8[1], + macaddr->u.eaddr.u8[2], macaddr->u.eaddr.u8[3], + macaddr->u.eaddr.u8[4], macaddr->u.eaddr.u8[5], + macaddr->u.eaddr.u8[6], macaddr->u.eaddr.u8[7]); } else { - return compress_ipaddr(ipaddr, bitpos); + ninfo(" saddr=%02x:%02x\n", + macaddr->u.saddr.u8[0], macaddr->u.saddr.u8[1]); } + + if (sixlowpan_ismacbased(ipaddr, macaddr)) + { + tag = (3 << bitpos); /* 0-bits */ + } + else + { + tag = compress_ipaddr(ipaddr, bitpos); + } + + ninfo("Tag=%02x\n", tag); + return tag; } static uint8_t compress_laddr(FAR const net_ipv6addr_t ipaddr, FAR const struct sixlowpan_addr_s *macaddr, uint8_t bitpos) { - ninfo("ipaddr=%p macaddr=%p bitpos=%u g_hc06ptr=%p\n", - ipaddr, macaddr, bitpos, g_hc06ptr); + uint8_t tag; + + ninfo("Compressing bitpos=%u\n", bitpos); + ninfo(" ipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ipaddr[4], ipaddr[5], ipaddr[6], ipaddr[7]); + +#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR + ninfo(" eaddr=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + macaddr->u8[0], macaddr->u8[1], macaddr->u8[2], macaddr->u8[3], + macaddr->u8[4], macaddr->u8[5], macaddr->u8[6], macaddr->u8[7]); +#else + ninfo(" saddr=%02x:%02x\n", + macaddr->u8[0], macaddr->u8[1]); +#endif if (sixlowpan_isaddrbased(ipaddr, macaddr)) { - return 3 << bitpos; /* 0-bits */ + tag = (3 << bitpos); /* 0-bits */ } else { - return compress_ipaddr(ipaddr, bitpos); + tag = compress_ipaddr(ipaddr, bitpos); } + + ninfo("Tag=%02x\n", tag); + return tag; } /**************************************************************************** @@ -293,58 +345,130 @@ static uint8_t compress_laddr(FAR const net_ipv6addr_t ipaddr, * to configure the IP address (autoconf style). * * prefpost takes a byte where the first nibble specify prefix count - * and the second postfix count (NOTE: 15/0xf => 16 bytes copy). + * and the second postfix count (NOTE: 15/0xf ipaddr=16 bytes copy). * ****************************************************************************/ -static void uncompress_addr(FAR net_ipv6addr_t ipaddr, uint8_t const prefix[], - uint8_t prefpost) +static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, + FAR const uint8_t *prefix, uint16_t prefpost, + FAR net_ipv6addr_t ipaddr) { - uint8_t prefcount = prefpost >> 4; - uint8_t postcount = prefpost & 0x0f; + FAR const uint8_t *srcptr; + bool fullmac = false; + bool usemac = (prefpost & 0x0100) != 0; + uint8_t prefcount = (prefpost >> 4) & 0xf; + uint8_t postcount = prefpost & 0x0f; - /* Full nibble 15 => 16 */ + /* The value 16 is encoded as 0xf in the 4 bit-fields. */ prefcount = prefcount == 15 ? 16 : prefcount; postcount = postcount == 15 ? 16 : postcount; + /* Select the data source */ + + srcptr = g_hc06ptr; + if (usemac) + { + bool saddr = (addr->mode == IEEE802154_ADDRMODE_SHORT); + uint16_t addrsize = saddr ? NET_6LOWPAN_SADDRSIZE: NET_6LOWPAN_EADDRSIZE; + + /* Select the source the address data */ + + srcptr = saddr ? addr->saddr : addr->eaddr; + + /* If the provided postcount is zero and we are taking data from the + * MAC address, set postcount to the address length. + */ + + if (postcount == 0) + { + 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 */ + if (prefcount > 0) { memcpy(ipaddr, prefix, prefcount); } + /* Clear bytes between int prefcount and postcount */ + if (prefcount + postcount < 16) { - FAR uint8_t *iptr = (FAR uint8_t *)&ipaddr[0]; + FAR uint8_t *destptr = (FAR uint8_t *)&ipaddr[0]; - memset(&iptr[prefcount], 0, 16 - (prefcount + postcount)); + memset(&destptr[prefcount], 0, 16 - (prefcount + postcount)); } + /* Copy the remaining data from the source */ + if (postcount > 0) { - FAR uint8_t *iptr = (FAR uint8_t *)&ipaddr[0]; - - memcpy(&iptr[16 - postcount], g_hc06ptr, postcount); if (postcount == 2 && prefcount < 11) { - /* 16 bits uncompression => 0000:00ff:fe00:XXXX */ + /* 16 bits uncompression ipaddr=0000:00ff:fe00:XXXX */ - iptr[11] = 0xff; - iptr[12] = 0xfe; + ipaddr[5] = HTONS(0x00ff); + ipaddr[6] = HTONS(0xfe00); } - g_hc06ptr += 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++) + { + 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); + } + + /* If we took the data from packet, then update the packet pointer */ + + if (!usemac) + { + g_hc06ptr += postcount; + } } else if (prefcount > 0) { - /* No IID based configuration if no prefix and no data => unspec */ + /* No IID based configuration if no prefix and no data ipaddr=unspec */ nwarn("WARNING: No IID based configuration\n"); } - ninfo("Uncompressing %d + %d => %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - prefcount, postcount, ipaddr[0], ipaddr[2], ipaddr[3], ipaddr[5], - ipaddr[5], ipaddr[6], ipaddr[7]); + ninfo("Uncompressing %d + %d ipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + prefcount, postcount, + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ipaddr[4], ipaddr[5], ipaddr[6], ipaddr[7]); } /**************************************************************************** @@ -620,7 +744,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, if (net_is_addr_unspecified(ipv6->srcipaddr)) { - ninfo("Compressing unspecified. Setting SAC\n"); + ninfo("Compressing unspecified srcipaddr. Setting SAC\n"); iphc1 |= SIXLOWPAN_IPHC_SAC; iphc1 |= SIXLOWPAN_IPHC_SAM_128; @@ -642,11 +766,11 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, SIXLOWPAN_IPHC_SAM_BIT); } - /* No address context found for this address */ + /* No address context found for the source address */ else if (net_is_addr_linklocal(ipv6->srcipaddr) && - ipv6->destipaddr[1] == 0 && ipv6->destipaddr[2] == 0 && - ipv6->destipaddr[3] == 0) + ipv6->srcipaddr[1] == 0 && ipv6->srcipaddr[2] == 0 && + ipv6->srcipaddr[3] == 0) { iphc1 |= compress_laddr(ipv6->srcipaddr, &ieee->i_dev.d_mac.ieee802154, @@ -654,7 +778,12 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, } else { - /* Send the full address => SAC = 0, SAM = 00 */ + /* Send the full source address ipaddr: SAC = 0, SAM = 00 */ + + ninfo("Uncompressable srcipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + ipv6->srcipaddr[0], ipv6->srcipaddr[1], ipv6->srcipaddr[2], + ipv6->srcipaddr[3], ipv6->srcipaddr[4], ipv6->srcipaddr[5], + ipv6->srcipaddr[6], ipv6->srcipaddr[7]); iphc1 |= SIXLOWPAN_IPHC_SAM_128; /* 128-bits */ memcpy(g_hc06ptr, ipv6->srcipaddr, 16); @@ -726,9 +855,10 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac, SIXLOWPAN_IPHC_DAM_BIT); - - /* No address context found for this address */ } + + /* No address context found for this address */ + else if (net_is_addr_linklocal(ipv6->destipaddr) && ipv6->destipaddr[1] == 0 && ipv6->destipaddr[2] == 0 && ipv6->destipaddr[3] == 0) @@ -736,10 +866,11 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac, SIXLOWPAN_IPHC_DAM_BIT); } + + /* Send the full address */ + else { - /* Send the full address */ - iphc1 |= SIXLOWPAN_IPHC_DAM_128; /* 128-bits */ memcpy(g_hc06ptr, ipv6->destipaddr, 16); g_hc06ptr += 16; @@ -758,7 +889,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, FAR struct udp_hdr_s *udp = (FAR struct udp_hdr_s *)((FAR uint8_t *)ipv6 + IPv6_HDRLEN); - ninfo("Uncompressed UDP ports on send side: srcport=%04x destport=%04x\n", + ninfo("Uncompressed UDP ports: srcport=%04x destport=%04x\n", ntohs(udp->srcport), ntohs(udp->destport)); /* Mask out the last 4 bits can be used as a mask */ @@ -770,7 +901,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, *g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_11; - ninfo("Remove 12b of both source & dest with prefix 0xfob\n"); + ninfo("Remove 12b of both source & dest with prefix 0xf0b*\n"); *(g_hc06ptr + 1) = (uint8_t)((ntohs(udp->srcport) - SIXLOWPAN_UDP_4_BIT_PORT_MIN) << 4) + @@ -860,20 +991,22 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, * appropriate values * * Input Parmeters: - * iplen - Equal to 0 if the packet is not a fragment (IP length is then - * inferred from the L2 length), non 0 if the packet is a first - * fragment. - * iob - Pointer to the IOB containing the received frame. - * fptr - Pointer to frame to be compressed. - * bptr - Output goes here. Normally this is a known offset into d_buf, - * may be redirected to a "bitbucket" on the case of FRAGN frames. + * ind - MAC header meta data including node addressing information. + * iplen - Equal to 0 if the packet is not a fragment (IP length is then + * inferred from the L2 length), non 0 if the packet is a first + * fragment. + * iob - Pointer to the IOB containing the received frame. + * fptr - Pointer to frame to be compressed. + * bptr - Output goes here. Normally this is a known offset into d_buf, + * may be redirected to a "bitbucket" on the case of FRAGN frames. * * Returned Value: * None * ****************************************************************************/ -void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, +void sixlowpan_uncompresshdr_hc06(FAR const struct ieee802154_data_ind_s *ind, + uint16_t iplen, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr) { FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr; @@ -1014,8 +1147,9 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, * address. */ - uncompress_addr(ipv6->srcipaddr, - tmp != 0 ? addrcontext->prefix : NULL, g_unc_ctxconf[tmp]); + uncompress_addr(&ind->src, + tmp != 0 ? addrcontext->prefix : NULL, + g_unc_ctxconf[tmp], ipv6->srcipaddr); } else { @@ -1024,7 +1158,8 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, * address. */ - uncompress_addr(ipv6->srcipaddr, g_llprefix, g_unc_llconf[tmp]); + uncompress_addr(&ind->src, g_llprefix, g_unc_llconf[tmp], + ipv6->srcipaddr); } /* Destination address */ @@ -1059,7 +1194,8 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, g_hc06ptr++; } - uncompress_addr(ipv6->destipaddr, prefix, g_unc_mxconf[tmp]); + uncompress_addr(&ind->dest, prefix, g_unc_mxconf[tmp], + ipv6->destipaddr); } } else @@ -1082,13 +1218,17 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, return; } - uncompress_addr(ipv6->destipaddr, addrcontext->prefix, g_unc_ctxconf[tmp]); + uncompress_addr(&ind->dest, addrcontext->prefix, + g_unc_ctxconf[tmp], ipv6->destipaddr); } else { - /* Not address context based => link local M = 0, DAC = 0 - same as SAC */ + /* Not address context based ipaddr=link local M = 0, DAC = 0 - same + * as SAC. + */ - uncompress_addr(ipv6->destipaddr, g_llprefix, g_unc_llconf[tmp]); + uncompress_addr(&ind->dest,g_llprefix, g_unc_llconf[tmp], + ipv6->destipaddr); } } diff --git a/net/sixlowpan/sixlowpan_input.c b/net/sixlowpan/sixlowpan_input.c index 9f1490bce2d..dc17d652159 100644 --- a/net/sixlowpan/sixlowpan_input.c +++ b/net/sixlowpan/sixlowpan_input.c @@ -343,7 +343,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, */ fragptr = fptr + hdrsize; - switch ((GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0xf800) >> 8) + switch ((GETUINT16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0xf800) >> 8) { /* First fragment of new reassembly */ @@ -351,8 +351,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, { /* Set up for the reassembly */ - fragsize = GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff; - fragtag = GETHOST16(fragptr, SIXLOWPAN_FRAG_TAG); + fragsize = GETUINT16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff; + fragtag = GETUINT16(fragptr, SIXLOWPAN_FRAG_TAG); g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN; ninfo("FRAG1: fragsize=%d fragtag=%d fragoffset=%d\n", @@ -370,8 +370,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, /* Set offset, tag, size. Offset is in units of 8 bytes. */ fragoffset = fragptr[SIXLOWPAN_FRAG_OFFSET]; - fragtag = GETHOST16(fragptr, SIXLOWPAN_FRAG_TAG); - fragsize = GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff; + fragtag = GETUINT16(fragptr, SIXLOWPAN_FRAG_TAG); + fragsize = GETUINT16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff; g_frame_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN; ninfo("FRAGN: fragsize=%d fragtag=%d fragoffset=%d\n", @@ -532,7 +532,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, if ((hc1[SIXLOWPAN_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC) { ninfo("IPHC Dispatch\n"); - sixlowpan_uncompresshdr_hc06(fragsize, iob, fptr, bptr); + sixlowpan_uncompresshdr_hc06(ind, fragsize, iob, fptr, bptr); } else #endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */ diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index 397f2863a95..662c5e6e1d8 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -102,16 +102,11 @@ /* General helper macros ****************************************************/ -/* GET 16-bit data: source in network order, result in host order */ +/* GET 16-bit data: source in network order */ -#define GETHOST16(ptr,index) \ +#define GETUINT16(ptr,index) \ ((((uint16_t)((ptr)[index])) << 8) | ((uint16_t)(((ptr)[(index) + 1])))) -/* GET 16-bit data: source in network order, result in network order */ - -#define GETNET16(ptr,index) \ - ((((uint16_t)((ptr)[(index) + 1])) << 8) | ((uint16_t)(((ptr)[index])))) - /* PUT 16-bit data: source in host order, result in newtwork order */ #define PUTHOST16(ptr,index,value) \ @@ -446,13 +441,14 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, * appropriate values * * Input Parmeters: - * iplen - Equal to 0 if the packet is not a fragment (IP length is then - * inferred from the L2 length), non 0 if the packet is a first - * fragment. - * iob - Pointer to the IOB containing the received frame. - * fptr - Pointer to frame to be compressed. - * bptr - Output goes here. Normally this is a known offset into d_buf, - * may be redirected to a "bitbucket" on the case of FRAGN frames. + * ind - MAC header meta data including node addressing information. + * iplen - Equal to 0 if the packet is not a fragment (IP length is then + * inferred from the L2 length), non 0 if the packet is a first + * fragment. + * iob - Pointer to the IOB containing the received frame. + * fptr - Pointer to frame to be compressed. + * bptr - Output goes here. Normally this is a known offset into d_buf, + * may be redirected to a "bitbucket" on the case of FRAGN frames. * * Returned Value: * None @@ -460,7 +456,8 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, ****************************************************************************/ #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 -void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, +void sixlowpan_uncompresshdr_hc06(FAR const struct ieee802154_data_ind_s *ind, + uint16_t iplen, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr); #endif diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index f4324d16948..6e636bc68b5 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -223,7 +223,7 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, if (dev == NULL) #endif { - nwarn("WARNING: Not routable\n"); + nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n"); return (ssize_t)-ENETUNREACH; } #endif @@ -260,6 +260,8 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, net_ipv6addr_hdrcopy(ipv6udp.ipv6.destipaddr, to6->sin6_addr.in6_u.u6_addr16); #ifdef CONFIG_NETDEV_MULTINIC net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr, conn->u.ipv6.laddr); +#else + net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr, dev->d_ipv6addr); #endif ninfo("IPv6 length: %d\n", diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c index 97eb856b929..2ed73d609b4 100644 --- a/net/sixlowpan/sixlowpan_utils.c +++ b/net/sixlowpan/sixlowpan_utils.c @@ -89,6 +89,8 @@ void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr, { DEBUGASSERT(ipaddr[0] == HTONS(0xfe80)); + /* Big-endian uint16_t to byte order */ + saddr->u8[0] = ipaddr[7] >> 8; saddr->u8[1] = ipaddr[7] & 0xff; saddr->u8[0] ^= 0x02; @@ -97,9 +99,19 @@ void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr, void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr, FAR struct sixlowpan_eaddr_s *eaddr) { + FAR uint8_t *eptr = eaddr->u8; + int i; + DEBUGASSERT(ipaddr[0] == HTONS(0xfe80)); - memcpy(eaddr, &ipaddr[4], NET_6LOWPAN_EADDRSIZE); + for (i = 4; i < 8; i++) + { + /* Big-endian uint16_t to byte order */ + + *eptr++ = ipaddr[i] >> 8; + *eptr++ = ipaddr[i] & 0xff; + } + eaddr->u8[0] ^= 0x02; } @@ -144,8 +156,9 @@ bool sixlowpan_issaddrbased(const net_ipv6addr_t ipaddr, { FAR const uint8_t *byteptr = saddr->u8; - return (ipaddr[5] == HTONS(0x00ff) && ipaddr[6] == HTONS(0xfe00) && - ipaddr[7] == (GETNET16(byteptr, 0) ^ HTONS(0x0200))); + return (ipaddr[5] == HTONS(0x00ff) && + ipaddr[6] == HTONS(0xfe00) && + ipaddr[7] == (GETUINT16(byteptr, 0) ^ 0x0200)); } bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr, @@ -153,10 +166,10 @@ bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr, { FAR const uint8_t *byteptr = eaddr->u8; - return (ipaddr[4] == (GETNET16(byteptr, 0) ^ HTONS(0x0200)) && - ipaddr[5] == GETNET16(byteptr, 2) && - ipaddr[6] == GETNET16(byteptr, 4) && - ipaddr[7] == GETNET16(byteptr, 6)); + return (ipaddr[4] == (GETUINT16(byteptr, 0) ^ 0x0200) && + ipaddr[5] == GETUINT16(byteptr, 2) && + ipaddr[6] == GETUINT16(byteptr, 4) && + ipaddr[7] == GETUINT16(byteptr, 6)); } bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr, diff --git a/wireless/ieee802154/mac802154_loopback.c b/wireless/ieee802154/mac802154_loopback.c index 3e3b7c1123e..8f67e2b3ac9 100644 --- a/wireless/ieee802154/mac802154_loopback.c +++ b/wireless/ieee802154/mac802154_loopback.c @@ -118,7 +118,7 @@ static uint8_t g_iobuffer[CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE]; static uint8_t g_eaddr[IEEE802154_EADDRSIZE] = { - 0x00, 0xfa, 0xde, 0x00, 0xde, 0xad, 0xbe, 0xef + 0x0c, 0xfa, 0xde, 0x00, 0xde, 0xad, 0xbe, 0xef }; static uint8_t g_saddr[IEEE802154_SADDRSIZE] = @@ -131,6 +131,16 @@ static uint8_t g_panid[IEEE802154_PANIDSIZE] = 0xca, 0xfe }; +static const uint8_t g_src_eaddr[IEEE802154_EADDRSIZE] = +{ + 0x0a, 0xfa, 0xde, 0x00, 0xde, 0xad, 0xbe, 0xef +}; + +static const uint8_t g_src_saddr[IEEE802154_SADDRSIZE] = +{ + 0x12, 0x34 +}; + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -190,6 +200,12 @@ static int lo_req_data(FAR struct ieee802154_driver_s *netdev, #ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR static void lo_addr2ip(FAR struct net_driver_s *dev) { + /* Set the MAC address as the eaddr */ + + IEEE802154_EADDRCOPY(dev->d_mac.ieee802154.u8, g_eaddr); + + /* Set the IP address based on the eaddr */ + dev->d_ipv6addr[0] = HTONS(0xfe80); dev->d_ipv6addr[1] = 0; dev->d_ipv6addr[2] = 0; @@ -199,10 +215,18 @@ static void lo_addr2ip(FAR struct net_driver_s *dev) dev->d_ipv6addr[6] = (uint16_t)g_eaddr[4] << 8 | (uint16_t)g_eaddr[5]; dev->d_ipv6addr[7] = (uint16_t)g_eaddr[6] << 8 | (uint16_t)g_eaddr[6]; dev->d_ipv6addr[4] ^= 0x200; + + memcpy(dev->d_mac.ieee802154, g_eaddr, IEEE802154_EADDRSIZE); } #else static void lo_addr2ip(FAR struct net_driver_s *dev) { + /* Set the MAC address as the saddr */ + + IEEE802154_SADDRCOPY(dev->d_mac.ieee802154.u8, g_saddr); + + /* Set the IP address based on the saddr */ + dev->d_ipv6addr[0] = HTONS(0xfe80); dev->d_ipv6addr[1] = 0; dev->d_ipv6addr[2] = 0; @@ -275,8 +299,30 @@ static int lo_loopback(FAR struct net_driver_s *dev) FAR struct iob_s *iob; int ret; + /* Create some fake metadata */ + memset(&ind, 0, sizeof(struct ieee802154_data_ind_s)); +#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR + ind.src.mode = IEEE802154_ADDRMODE_EXTENDED; + ind.dest.mode = IEEE802154_ADDRMODE_EXTENDED; +#else + ind.src.mode = IEEE802154_ADDRMODE_SHORT; + ind.dest.mode = IEEE802154_ADDRMODE_SHORT; +#endif + + /* Only loopback the local address is the destination and some (arbitrary) + * address is the source. + */ + + IEEE802154_PANIDCOPY(ind.src.panid, g_panid); + IEEE802154_SADDRCOPY(ind.src.saddr, g_src_saddr); + IEEE802154_EADDRCOPY(ind.src.eaddr, g_src_eaddr); + + IEEE802154_PANIDCOPY(ind.dest.panid, g_panid); + IEEE802154_SADDRCOPY(ind.dest.saddr, g_saddr); + IEEE802154_EADDRCOPY(ind.dest.eaddr, g_eaddr); + /* Loop while there framelist to be sent, i.e., while the freme list is not * emtpy. Sending, of course, just means relaying back through the network * for this driver. diff --git a/wireless/ieee802154/mac802154_netdev.c b/wireless/ieee802154/mac802154_netdev.c index b48c6afcaaf..75b777e20ba 100644 --- a/wireless/ieee802154/mac802154_netdev.c +++ b/wireless/ieee802154/mac802154_netdev.c @@ -258,11 +258,13 @@ static int macnet_advertise(FAR struct net_driver_s *dev) } else { - /* Set the IP address based on the eaddr */ + /* Set the MAC address as the eaddr */ eaddr = arg.u.getreq.attrval.mac.eaddr; IEEE802154_EADDRCOPY(dev->d_mac.ieee802154.u8, eaddr); + /* Set the IP address based on the eaddr */ + dev->d_ipv6addr[0] = HTONS(0xfe80); dev->d_ipv6addr[1] = 0; dev->d_ipv6addr[2] = 0; @@ -270,7 +272,7 @@ static int macnet_advertise(FAR struct net_driver_s *dev) dev->d_ipv6addr[4] = (uint16_t)eaddr[0] << 8 | (uint16_t)eaddr[1]; dev->d_ipv6addr[5] = (uint16_t)eaddr[2] << 8 | (uint16_t)eaddr[3]; dev->d_ipv6addr[6] = (uint16_t)eaddr[4] << 8 | (uint16_t)eaddr[5]; - dev->d_ipv6addr[7] = (uint16_t)eaddr[6] << 8 | (uint16_t)eaddr[6]; + dev->d_ipv6addr[7] = (uint16_t)eaddr[6] << 8 | (uint16_t)eaddr[7]; dev->d_ipv6addr[4] ^= 0x200; return OK; } @@ -291,6 +293,8 @@ static int macnet_advertise(FAR struct net_driver_s *dev) } else { + /* Set the MAC address as the saddr */ + saddr = arg.u.getreq.attrval.mac.saddr; IEEE802154_SADDRCOPY(dev->d_mac.ieee802154.u8, saddr);