From 50fda0d748acaacba14e126749f79e1a09af4a2c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 19 Apr 2017 13:33:20 -0600 Subject: [PATCH] 6loWPAN: Fix a missing source address in header. Correct calculation of payload size. --- include/nuttx/net/netconfig.h | 4 ++-- net/sixlowpan/Kconfig | 9 -------- net/sixlowpan/README.txt | 21 +++++++++--------- net/sixlowpan/sixlowpan_framelist.c | 13 +++++++----- net/sixlowpan/sixlowpan_framer.c | 33 +++++++++++++++++++++-------- net/sixlowpan/sixlowpan_input.c | 4 +++- net/sixlowpan/sixlowpan_internal.h | 6 +++--- 7 files changed, 51 insertions(+), 39 deletions(-) diff --git a/include/nuttx/net/netconfig.h b/include/nuttx/net/netconfig.h index 99f00e3856..fbdd2772d5 100644 --- a/include/nuttx/net/netconfig.h +++ b/include/nuttx/net/netconfig.h @@ -309,7 +309,7 @@ #endif #ifdef CONFIG_NET_6LOWPAN -# define IEEE802154_UDP_MSS(h) (CONFIG_NET_6LOWPAN_MAXPAYLOAD - UDP_HDRLEN - (h)) +# define IEEE802154_UDP_MSS(h) (CONFIG_NET_6LOWPAN_MTU - UDP_HDRLEN - (h)) # ifndef CONFIG_NET_MULTILINK # define __MIN_UDP_MSS(h) IEEE802154_UDP_MSS(h) # define __MAX_UDP_MSS(h) IEEE802154_UDP_MSS(h) @@ -484,7 +484,7 @@ #endif #ifdef CONFIG_NET_6LOWPAN -# define IEEE802154_TCP_MSS(h) (CONFIG_NET_6LOWPAN_MAXPAYLOAD - TCP_HDRLEN - (h)) +# define IEEE802154_TCP_MSS(h) (CONFIG_NET_6LOWPAN_MTU - TCP_HDRLEN - (h)) # ifndef CONFIG_NET_MULTILINK # define __MIN_TCP_MSS(h) IEEE802154_TCP_MSS(h) # define __MAX_TCP_MSS(h) IEEE802154_TCP_MSS(h) diff --git a/net/sixlowpan/Kconfig b/net/sixlowpan/Kconfig index ad59e29055..021571fbd0 100644 --- a/net/sixlowpan/Kconfig +++ b/net/sixlowpan/Kconfig @@ -156,15 +156,6 @@ config NET_6LOWPAN_MAX_MACTRANSMITS layer should resend packets if no link-layer ACK wasreceived. This only makes sense with the csma_driver. -config NET_6LOWPAN_MAXPAYLOAD - int "Max packet size" - default 102 - ---help--- - NET_6LOWPAN_MAXPAYLOAD specifies the maximum size of packets - before they get fragmented. The default is 127 bytes (the maximum size - of a 802.15.4 frame) - 25 bytes (for the 802.15.4 MAClayer header). This - can be increased for systems with larger packet sizes. - config NET_6LOWPAN_MTU int "6LoWPAN packet buffer size" default 1294 diff --git a/net/sixlowpan/README.txt b/net/sixlowpan/README.txt index e325533474..7a65c77ade 100644 --- a/net/sixlowpan/README.txt +++ b/net/sixlowpan/README.txt @@ -33,7 +33,7 @@ Optimal 6loWPAN Configuration Fragmentation Headers --------------------- A fragment header is placed at the beginning of the outgoing packet just -after the FCF when the payload is too large to fit in a single IEEE 802.15.4 +after the MAC when the payload is too large to fit in a single IEEE 802.15.4 frame. The fragment header contains three fields: Datagram size, datagram tag and datagram offset. @@ -47,7 +47,7 @@ The length of the fragment header length is four bytes for the first header (FRAG1) and five bytes for all subsequent headers (FRAGN). For example, this is a HC1 compressed first frame of a packet - 01 08 01 0000 3412 ### 7-byte FCF header + 41 88 01 0000 3412 cdab ### 9-byte MAC header c50e 000b ### 4-byte FRAG1 header 42 ### SIXLOWPAN_DISPATCH_HC1 fb ### RIME_HC1_HC_UDP_HC1_ENCODING @@ -56,14 +56,15 @@ this is a HC1 compressed first frame of a packet 10 ### RIME_HC1_HC_UDP_PORTS 0000 ### RIME_HC1_HC_UDP_CHKSUM - 80 byte Payload follows: + 104 byte Payload follows: 4f4e452064617920 48656e6e792d7065 6e6e792077617320 7069636b696e6720 757020636f726e20 696e207468652063 6f726e7961726420 7768656e2d2d7768 - 61636b212d2d736f 6d657468696e6720 g + 61636b212d2d736f 6d657468696e6720 6869742068657220 75706f6e20746865 + 20686561642e2027 This is the second frame of the same transfer: - 01 08 01 0000 3412 ### 7-byte FCF header + 41 88 01 0000 3412 cdab ### 9-byte MAC header e50e 000b 0a ### 5 byte FRAGN header 42 ### SIXLOWPAN_DISPATCH_HC1 fb ### RIME_HC1_HC_UDP_HC1_ENCODING @@ -72,11 +73,11 @@ This is the second frame of the same transfer: 10 ### RIME_HC1_HC_UDP_PORTS 0000 ### RIME_HC1_HC_UDP_CHKSUM - 80 byte Payload follows: - 6869742068657220 75706f6e20746865 20686561642e2027 476f6f646e657373 - 2067726163696f75 73206d6521272073 6169642048656e6e 792d70656e6e793b - 202774686520736b 79277320612d676f - + 104 byte Payload follows: + 476f6f646e657373 2067726163696f75 73206d6521272073 6169642048656e6e + 792d70656e6e793b 202774686520736b 79277320612d676f 696e6720746f2066 + 616c6c3b2049206d 75737420676f2061 6e642074656c6c20 746865206b696e67 + 2e270a0a536f2073 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 diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index 23969c09f3..79e653d10b 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -281,6 +281,11 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, ninfo("Sending packet length %d\n", buflen); + /* Set the source and destinatino address */ + + rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_SENDER], &ieee->i_nodeaddr); + rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER], destmac); + /* Pre-calculate frame header length. */ framer_hdrlen = sixlowpan_send_hdrlen(ieee, ieee->i_panid); @@ -317,11 +322,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, ninfo("Header of length %d\n", g_frame_hdrlen); - rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER], destmac); - /* Check if we need to fragment the packet into several frames */ - if (buflen > (CONFIG_NET_6LOWPAN_MAXPAYLOAD - g_frame_hdrlen)) + if (buflen > (CONFIG_NET_6LOWPAN_FRAMELEN - g_frame_hdrlen)) { #ifdef CONFIG_NET_6LOWPAN_FRAG /* ieee->i_framelist will hold the generated frames; frames will be @@ -384,7 +387,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, * bytes. */ - paysize = (CONFIG_NET_6LOWPAN_MAXPAYLOAD - g_frame_hdrlen) & ~7; + paysize = (CONFIG_NET_6LOWPAN_FRAMELEN - g_frame_hdrlen) & ~7; memcpy(fptr + g_frame_hdrlen, buf, paysize); /* Set outlen to what we already sent from the IP payload */ @@ -457,7 +460,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Copy payload and enqueue */ /* Check for the last fragment */ - paysize = (CONFIG_NET_6LOWPAN_MAXPAYLOAD - fragn_hdrlen) & + paysize = (CONFIG_NET_6LOWPAN_FRAMELEN - fragn_hdrlen) & SIXLOWPAN_DISPATCH_FRAG_MASK; if (buflen - outlen < paysize) { diff --git a/net/sixlowpan/sixlowpan_framer.c b/net/sixlowpan/sixlowpan_framer.c index 746d6dc113..66f8a1c3fb 100644 --- a/net/sixlowpan/sixlowpan_framer.c +++ b/net/sixlowpan/sixlowpan_framer.c @@ -70,11 +70,11 @@ struct field_length_s { - uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */ - uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */ - uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */ - uint8_t src_addr_len; /**< Length (in bytes) of source address field */ - uint8_t aux_sec_len; /**< Length (in bytes) of aux security header field */ + uint8_t dest_pid_len; /* Length (in bytes) of destination PAN ID field */ + uint8_t dest_addr_len; /* Length (in bytes) of destination address field */ + uint8_t src_pid_len; /* Length (in bytes) of source PAN ID field */ + uint8_t src_addr_len; /* Length (in bytes) of source address field */ + uint8_t aux_sec_len; /* Length (in bytes) of aux security header field */ }; /**************************************************************************** @@ -179,10 +179,17 @@ static void sixlowpan_fieldlengths(FAR struct frame802154_s *finfo, (finfo->fcf.src_addr_mode & 3) != 0 && finfo->src_pid == finfo->dest_pid) { + /* Indicate source PANID compression */ + finfo->fcf.panid_compression = 1; - /* Compressed header, only do dest pid */ - /* flen->src_pid_len = 0; */ + /* Compressed header, only do dest pid. + * + * REVISIT: This was commented out in corresponding Contiki logic, but + * is needed to match sixlowpan_recv_hdrlen(). + */ + + flen->src_pid_len = 0; } /* Determine address lengths */ @@ -348,7 +355,7 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee, rimeaddr_copy((struct rimeaddr_s *)¶ms->dest_addr, g_pktaddrs[PACKETBUF_ADDR_RECEIVER].u8); - /* Use short address mode if so configured */ + /* Use short destination address mode if so configured */ #ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED params->fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; @@ -359,7 +366,15 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee, /* Set the source address to the node address assigned to the device */ - rimeaddr_copy((struct rimeaddr_s *)¶ms->src_addr, &ieee->i_nodeaddr.u8); + rimeaddr_copy((struct rimeaddr_s *)¶ms->src_addr, &ieee->i_nodeaddr); + + /* Use short soruce address mode if so configured */ + +#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED + params->fcf.src_addr_mode = FRAME802154_LONGADDRMODE; +#else + params->fcf.src_addr_mode = FRAME802154_SHORTADDRMODE; +#endif } /**************************************************************************** diff --git a/net/sixlowpan/sixlowpan_input.c b/net/sixlowpan/sixlowpan_input.c index 119dd4dfd2..bfa74da13a 100644 --- a/net/sixlowpan/sixlowpan_input.c +++ b/net/sixlowpan/sixlowpan_input.c @@ -167,7 +167,7 @@ int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr) } else if (addrmode == FRAME802154_LONGADDRMODE) { - /* 2 byte dest PAN + 6 byte dest long address */ + /* 2 byte dest PAN + 8 byte dest long address */ hdrlen += 10; } @@ -193,6 +193,8 @@ int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr) } else { + /* Add source PANID if PANIDs are not compressed */ + if ((fptr[0] & (1 << FRAME802154_PANIDCOMP_SHIFT)) == 0) { hdrlen += 2; diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index deede9d3b8..392bc376b7 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -221,9 +221,9 @@ struct frame802154_fcf_s struct frame802154_scf_s { - uint8_t security_level; /* 3 bit. security level */ - uint8_t key_id_mode; /* 2 bit. Key identifier mode */ - uint8_t reserved; /* 3 bit. Reserved bits */ + uint8_t security_level; /* 3 bit. security level */ + uint8_t key_id_mode; /* 2 bit. Key identifier mode */ + uint8_t reserved; /* 3 bit. Reserved bits */ }; /* 802.15.4 Aux security header */