Merge remote-tracking branch 'origin/master' into ieee802154

This commit is contained in:
Gregory Nutt 2017-04-16 12:20:59 -06:00
commit edb8e6302d
9 changed files with 193 additions and 143 deletions

15
TODO
View File

@ -19,7 +19,7 @@ nuttx/:
(8) Kernel/Protected Build (8) Kernel/Protected Build
(3) C++ Support (3) C++ Support
(6) Binary loaders (binfmt/) (6) Binary loaders (binfmt/)
(15) Network (net/, drivers/net) (14) Network (net/, drivers/net)
(4) USB (drivers/usbdev, drivers/usbhost) (4) USB (drivers/usbdev, drivers/usbhost)
(0) Other drivers (drivers/) (0) Other drivers (drivers/)
(12) Libraries (libc/, libm/) (12) Libraries (libc/, libm/)
@ -1006,8 +1006,8 @@ o Network (net/, drivers/net)
however. Others support the address filtering interfaces but however. Others support the address filtering interfaces but
have never been verifed: have never been verifed:
C5471, LM3X, ez80, DM0x90 NIC, PIC: Do not support address C5471, LM3S, ez80, DM0x90 NIC, PIC: Do not support address
filteringing. filtering.
Kinetis, LPC17xx, LPC43xx: Untested address filter support Kinetis, LPC17xx, LPC43xx: Untested address filter support
Status: Open Status: Open
@ -1089,15 +1089,6 @@ o Network (net/, drivers/net)
Status: Open Status: Open
Priority: Low Priority: Low
Title: REMOVE CONFIG_NET_MULTIBUFFER
Description: The CONFIG_NET_MULTIBUFFER controls some details in the layout
of the network device structure. This is really a unnecessary
complexity and should be removed. The cost for those network
drivers that currently do not support CONFIG_NET_MULTIBUFFER
is the size of one pointer.
Status: Open
Priority: Low
Title: ETHERNET WITH MULTIPLE LPWORK THREADS Title: ETHERNET WITH MULTIPLE LPWORK THREADS
Description: Recently, Ethernet drivers were modified to support multiple Description: Recently, Ethernet drivers were modified to support multiple
work queue structures. The question was raised: "My only work queue structures. The question was raised: "My only

View File

@ -1625,6 +1625,7 @@ config STM32_STM32F429
select STM32_HAVE_UART7 select STM32_HAVE_UART7
select STM32_HAVE_UART8 select STM32_HAVE_UART8
select STM32_HAVE_TIM1 select STM32_HAVE_TIM1
select STM32_HAVE_TIM5
select STM32_HAVE_TIM6 select STM32_HAVE_TIM6
select STM32_HAVE_TIM7 select STM32_HAVE_TIM7
select STM32_HAVE_TIM8 select STM32_HAVE_TIM8

View File

@ -160,14 +160,22 @@
/* 6lowpan dispatches */ /* 6lowpan dispatches */
#define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */ #define SIXLOWPAN_DISPATCH_NALP 0x00 /* 00xxxxxx Not a LoWPAN packet */
#define SIXLOWPAN_DISPATCH_HC1 0x42 /* 01000010 = 66 */ #define SIXLOWPAN_DISPATCH_NALP_MASK 0xc0 /* 11000000 */
#define SIXLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx */ #define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 Uncompressed IPv6 addresses */
#define SIXLOWPAN_DISPATCH_HC1 0x42 /* 01000010 HC1 Compressed IPv6 header */
#define SIXLOWPAN_DISPATCH_BC0 0x50 /* 01010000 BC0 Broadcast header */
#define SIXLOWPAN_DISPATCH_ESC 0x7f /* 01111111 Additional Dispatch octet follows */
#define SIXLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx IP Header Compression (IPHC)*/
#define SIXLOWPAN_DISPATCH_IPHC_MASK 0xe0 /* 11100000 */ #define SIXLOWPAN_DISPATCH_IPHC_MASK 0xe0 /* 11100000 */
#define SIXLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */ #define SIXLOWPAN_DISPATCH_MESH 0x80 /* 10xxxxxx Mesh routing header */
#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */ #define SIXLOWPAN_DISPATCH_MESH_MASK 0xc0 /* 11000000 */
#define SIXLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx Fragmentation header (first) */
#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx Fragmentation header (subsequent) */
#define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf8 /* 11111000 */ #define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf8 /* 11111000 */
/* HC1 encoding */ /* HC1 encoding */

View File

@ -32,10 +32,10 @@ Optimal 6loWPAN Configuration
Fragmentation Headers Fragmentation Headers
--------------------- ---------------------
A fragment header is placed at the beginning of the outgoing packet when the A fragment header is placed at the beginning of the outgoing packet just
payload is too large to fit in a single IEEE 802.15.4 frame. The fragment after the FCF when the payload is too large to fit in a single IEEE 802.15.4
header contains three fields: Datagram size, datagram tag and datagram frame. The fragment header contains three fields: Datagram size, datagram tag
offset. and datagram offset.
1. Datagram size describes the total (un-fragmented) payload. 1. Datagram size describes the total (un-fragmented) payload.
2. Datagram tag identifies the set of fragments and is used to match 2. Datagram tag identifies the set of fragments and is used to match
@ -47,25 +47,36 @@ 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, (FRAG1) and five bytes for all subsequent headers (FRAGN). For example,
this is a HC1 compressed first frame of a packet this is a HC1 compressed first frame of a packet
c50e 000b ### 4-byte FRAG1 header 01 08 01 0000 3412 ### 7-byte FCF header
01 08 01 0000 3412 ### 7-byte FCF header c50e 000b ### 4-byte FRAG1 header
42 ### SIXLOWPAN_DISPATCH_HC1 42 ### SIXLOWPAN_DISPATCH_HC1
fb ### RIME_HC1_HC_UDP_HC1_ENCODING fb ### RIME_HC1_HC_UDP_HC1_ENCODING
e0 ### RIME_HC1_HC_UDP_UDP_ENCODING e0 ### RIME_HC1_HC_UDP_UDP_ENCODING
00 ### RIME_HC1_HC_UDP_TTL 00 ### RIME_HC1_HC_UDP_TTL
10 ### RIME_HC1_HC_UDP_PORTS 10 ### RIME_HC1_HC_UDP_PORTS
0000 ### RIME_HC1_HC_UDP_CHKSUM 0000 ### RIME_HC1_HC_UDP_CHKSUM
4f4e452064617920 48656e6e792d7065 6e6e792077617320 7069636b696e6720 ### 80 byte payload
80 byte Payload follows:
4f4e452064617920 48656e6e792d7065 6e6e792077617320 7069636b696e6720
757020636f726e20 696e207468652063 6f726e7961726420 7768656e2d2d7768 757020636f726e20 696e207468652063 6f726e7961726420 7768656e2d2d7768
61636b212d2d736f 6d657468696e6720 g 61636b212d2d736f 6d657468696e6720 g
This is the second frame of the same transfer: This is the second frame of the same transfer:
e50e 000b 0a ### 5 byte FRAGN header 01 08 01 0000 3412 ### 7-byte FCF header
01 08 01 0000 3412 ### 7-byte FCF header e50e 000b 0a ### 5 byte FRAGN header
6869742068657220 75706f6e20746865 20686561642e2027 476f6f646e657373 ### 88 byte payload 42 ### SIXLOWPAN_DISPATCH_HC1
fb ### RIME_HC1_HC_UDP_HC1_ENCODING
e0 ### RIME_HC1_HC_UDP_UDP_ENCODING
00 ### RIME_HC1_HC_UDP_TTL
10 ### RIME_HC1_HC_UDP_PORTS
0000 ### RIME_HC1_HC_UDP_CHKSUM
80 byte Payload follows:
6869742068657220 75706f6e20746865 20686561642e2027 476f6f646e657373
2067726163696f75 73206d6521272073 6169642048656e6e 792d70656e6e793b 2067726163696f75 73206d6521272073 6169642048656e6e 792d70656e6e793b
202774686520736b 79277320612d676f 696e6720746f2066 202774686520736b 79277320612d676f
The payload length is encoded in the LS 11-bits of the first 16-bit value: 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 In this example the payload size is 0x050e or 1,294. The tag is 0x000b. In

View File

@ -330,6 +330,8 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
FAR struct iob_s *qtail; FAR struct iob_s *qtail;
FAR uint8_t *frame1; FAR uint8_t *frame1;
FAR uint8_t *fragptr;
uint16_t frag1_hdrlen;
int verify; int verify;
/* The outbound IPv6 packet is too large to fit into a single 15.4 /* The outbound IPv6 packet is too large to fit into a single 15.4
@ -352,7 +354,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
* beginning of the frame. * beginning of the frame.
*/ */
memmove(fptr + SIXLOWPAN_FRAG1_HDR_LEN, fptr, g_frame_hdrlen); fragptr = fptr + framer_hdrlen;
memmove(fragptr + SIXLOWPAN_FRAG1_HDR_LEN, fragptr,
g_frame_hdrlen - framer_hdrlen);
/* Setup up the fragment header. /* Setup up the fragment header.
* *
@ -370,9 +374,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
*/ */
pktlen = buflen + g_uncomp_hdrlen; pktlen = buflen + g_uncomp_hdrlen;
PUTINT16(fptr, RIME_FRAG_DISPATCH_SIZE, PUTINT16(fragptr, RIME_FRAG_DISPATCH_SIZE,
((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen)); ((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen));
PUTINT16(fptr, RIME_FRAG_TAG, ieee->i_dgramtag); PUTINT16(fragptr, RIME_FRAG_TAG, ieee->i_dgramtag);
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN; g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
@ -385,8 +389,8 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Set outlen to what we already sent from the IP payload */ /* Set outlen to what we already sent from the IP payload */
iob->io_len = paysize + g_frame_hdrlen; iob->io_len = paysize + g_frame_hdrlen;
outlen = paysize; outlen = paysize;
ninfo("First fragment: length %d, tag %d\n", ninfo("First fragment: length %d, tag %d\n",
paysize, ieee->i_dgramtag); paysize, ieee->i_dgramtag);
@ -404,7 +408,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Create following fragments */ /* Create following fragments */
frame1 = iob->io_data; frame1 = iob->io_data;
frag1_hdrlen = g_frame_hdrlen;
while (outlen < buflen) while (outlen < buflen)
{ {
uint16_t fragn_hdrlen; uint16_t fragn_hdrlen;
@ -424,21 +430,27 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
iob->io_pktlen = 0; iob->io_pktlen = 0;
fptr = iob->io_data; fptr = iob->io_data;
/* Copy the frame header from first frame, into the correct /* Copy the frame header at the beginning of the frame. */
* location after the FRAGN header.
memcpy(fptr, frame1, framer_hdrlen);
/* Move HC1/HC06/IPv6 header the frame header from first
* frame, into the correct location after the FRAGN header
* of subsequent frames.
*/ */
memmove(fptr + SIXLOWPAN_FRAGN_HDR_LEN, fragptr = fptr + framer_hdrlen;
frame1 + SIXLOWPAN_FRAG1_HDR_LEN, memcpy(fragptr + SIXLOWPAN_FRAGN_HDR_LEN,
framer_hdrlen); frame1 + framer_hdrlen + SIXLOWPAN_FRAG1_HDR_LEN,
fragn_hdrlen = framer_hdrlen; frag1_hdrlen - framer_hdrlen);
fragn_hdrlen = frag1_hdrlen - SIXLOWPAN_FRAG1_HDR_LEN;
/* Setup up the FRAGN header at the beginning of the frame */ /* Setup up the FRAGN header after the frame header. */
PUTINT16(fptr, RIME_FRAG_DISPATCH_SIZE, PUTINT16(fragptr, RIME_FRAG_DISPATCH_SIZE,
((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen)); ((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen));
PUTINT16(fptr, RIME_FRAG_TAG, ieee->i_dgramtag); PUTINT16(fragptr, RIME_FRAG_TAG, ieee->i_dgramtag);
fptr[RIME_FRAG_OFFSET] = outlen >> 3; fragptr[RIME_FRAG_OFFSET] = outlen >> 3;
fragn_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN; fragn_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;

View File

@ -68,13 +68,10 @@
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define IPv6BUF(ieee) \
((FAR struct ipv6_hdr_s *)((ieee)->i_dev.d_buf))
#define UDPIPv6BUF(ieee) \ #define UDPIPv6BUF(ieee) \
((FAR struct udp_hdr_s *)&((ieee)->i_dev.d_buf[IPv6_HDRLEN])) ((FAR struct udp_hdr_s *)&((ieee)->i_dev.d_buf[IPv6_HDRLEN]))
@ -223,7 +220,7 @@ static FAR struct sixlowpan_addrcontext_s *
} }
/**************************************************************************** /****************************************************************************
* Name: uncompress_addr * Name: compress_addr_64
* *
* Description: * Description:
* Uncompress addresses based on a prefix and a postfix with zeroes in * Uncompress addresses based on a prefix and a postfix with zeroes in
@ -835,23 +832,23 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
* appropriate values * appropriate values
* *
* Input Parmeters: * Input Parmeters:
* ieee - A reference to the IEE802.15.4 network device state
* iplen - Equal to 0 if the packet is not a fragment (IP length is then * 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 * inferred from the L2 length), non 0 if the packet is a first
* fragment. * fragment.
* iob - Pointer to the IOB containing the received frame. * iob - Pointer to the IOB containing the received frame.
* fptr - Pointer to frame to be compressed. * 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: * Returned Value:
* None * None
* *
****************************************************************************/ ****************************************************************************/
void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee, void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
uint16_t iplen, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr)
FAR uint8_t *fptr)
{ {
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF(ieee); FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr;
FAR uint8_t *iphc; FAR uint8_t *iphc;
uint8_t iphc0; uint8_t iphc0;
uint8_t iphc1; uint8_t iphc1;
@ -1019,7 +1016,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
* *
* DAM 00: 128 bits * DAM 00: 128 bits
* DAM 01: 48 bits FFXX::00XX:XXXX:XXXX * DAM 01: 48 bits FFXX::00XX:XXXX:XXXX
* DAM 0: 32 bits FFXX::00XX:XXXX * DAM 10: 32 bits FFXX::00XX:XXXX
* DAM 11: 8 bits FF02::00XX * DAM 11: 8 bits FF02::00XX
*/ */
@ -1049,7 +1046,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
if (addrcontext == NULL) if (addrcontext == NULL)
{ {
ninfo("ERROR: Address context not found\n"); nerr("ERROR: Address context not found\n");
return; return;
} }
@ -1071,7 +1068,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
if ((iphc0 & SIXLOWPAN_IPHC_NH) != 0) if ((iphc0 & SIXLOWPAN_IPHC_NH) != 0)
{ {
FAR struct udp_hdr_s *udp = UDPIPv6BUF(ieee); FAR struct udp_hdr_s *udp = (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
/* The next header is compressed, NHC is following */ /* The next header is compressed, NHC is following */
@ -1195,7 +1192,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
if (ipv6->proto == IP_PROTO_UDP) if (ipv6->proto == IP_PROTO_UDP)
{ {
FAR struct udp_hdr_s *udp = UDPIPv6BUF(ieee); FAR struct udp_hdr_s *udp = (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
memcpy(&udp->udplen, &ipv6->len[0], 2); memcpy(&udp->udplen, &ipv6->len[0], 2);
} }
} }

View File

@ -57,15 +57,6 @@
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1 #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Buffer access helpers */
#define IPv6BUF(dev) ((FAR struct ipv6_hdr_s *)((dev)->d_buf))
#define UDPIPv6BUF(dev) ((FAR struct udp_hdr_s *)&(dev)->d_buf[IPv6_HDRLEN])
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -253,12 +244,13 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
* are set to the appropriate values * are set to the appropriate values
* *
* Input Parameters: * Input Parameters:
* ieee - A reference to the IEE802.15.4 network device state * iplen - Equal to 0 if the packet is not a fragment (IP length is then
* 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 1st
* inferred from the L2 length), non 0 if the packet is a 1st * fragment.
* fragment. * iob - Pointer to the IOB containing the received frame.
* iob - Pointer to the IOB containing the received frame. * fptr - Pointer to frame to be uncompressed.
* fptr - Pointer to frame to be uncompressed. * 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: * Returned Value:
* Zero (OK) is returned on success, on failure a negater errno value is * Zero (OK) is returned on success, on failure a negater errno value is
@ -266,11 +258,10 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
* *
****************************************************************************/ ****************************************************************************/
int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee, int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
uint16_t iplen, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr)
FAR uint8_t *fptr)
{ {
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF(&ieee->i_dev); FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr;
FAR uint8_t *hc1 = fptr + g_frame_hdrlen; FAR uint8_t *hc1 = fptr + g_frame_hdrlen;
/* Format the IPv6 header in the device d_buf */ /* Format the IPv6 header in the device d_buf */
@ -311,7 +302,7 @@ int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
#if CONFIG_NET_UDP #if CONFIG_NET_UDP
case SIXLOWPAN_HC1_NH_UDP: case SIXLOWPAN_HC1_NH_UDP:
{ {
FAR struct udp_hdr_s *udp = UDPIPv6BUF(&ieee->i_dev); FAR struct udp_hdr_s *udp = (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
FAR uint8_t *hcudp = fptr + g_frame_hdrlen; FAR uint8_t *hcudp = fptr + g_frame_hdrlen;
ipv6->proto = IP_PROTO_UDP; ipv6->proto = IP_PROTO_UDP;
@ -377,7 +368,7 @@ int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
if (ipv6->proto == IP_PROTO_UDP) if (ipv6->proto == IP_PROTO_UDP)
{ {
FAR struct udp_hdr_s *udp = UDPIPv6BUF(&ieee->i_dev); FAR struct udp_hdr_s *udp = (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN);
memcpy(&udp->udplen, &ipv6->len[0], 2); memcpy(&udp->udplen, &ipv6->len[0], 2);
} }
#endif #endif

View File

@ -83,11 +83,48 @@
#define NET_6LOWPAN_TIMEOUT SEC2TICK(CONFIG_NET_6LOWPAN_MAXAGE) #define NET_6LOWPAN_TIMEOUT SEC2TICK(CONFIG_NET_6LOWPAN_MAXAGE)
/* This is the size of a buffer large enough to hold the largest uncompressed
* HC06 or HC1 headers.
*/
#ifdef CONFIG_NET_TCP
/* The basic TCP header length is TCP_HDRLEN but could include up to 16
* additional 32-bit words of optional data.
*/
# define UNCOMP_MAXHDR (IPv6_HDRLEN + TCP_HDRLEN + 16*sizeof(uint32_t))
#elif defined(CONFIG_NET_UDP)
/* The UDP header length is always 8 bytes */
# define UNCOMP_MAXHDR (IPv6_HDRLEN + TCP_HDRLEN)
#elif defined(CONFIG_NET_ICMPv6)
/* The ICMPv6 header length is a mere 4 bytes */
# define UNCOMP_MAXHDR (IPv6_HDRLEN + ICMPv6_HDRLEN)
#else
/* No other header type is handled. */
# define UNCOMP_MAXHDR IPv6_HDRLEN
#endif
/* Buffer access helpers */ /* Buffer access helpers */
#define IPv6BUF(dev) ((FAR struct ipv6_hdr_s *)((dev)->d_buf)) #define IPv6BUF(dev) ((FAR struct ipv6_hdr_s *)((dev)->d_buf))
#define TCPBUF(dev) ((FAR struct tcp_hdr_s *)&(dev)->d_buf[IPv6_HDRLEN]) #define TCPBUF(dev) ((FAR struct tcp_hdr_s *)&(dev)->d_buf[IPv6_HDRLEN])
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_FRAG
/* This big buffer could be avoided with a little more effort */
static uint8_t g_bitbucket[UNCOMP_MAXHDR];
#endif
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -96,7 +133,7 @@
* Name: sixlowpan_recv_hdrlen * Name: sixlowpan_recv_hdrlen
* *
* Description: * Description:
* Get the length of the IEEE802.15.4 header on the received frame. * Get the length of the IEEE802.15.4 FCF header on the received frame.
* *
* Input Parameters: * Input Parameters:
* ieee - The IEEE802.15.4 MAC network driver interface. * ieee - The IEEE802.15.4 MAC network driver interface.
@ -112,26 +149,12 @@
int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr) int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr)
{ {
uint16_t hdrlen = 0; uint16_t hdrlen;
uint8_t addrmode; uint8_t addrmode;
uint8_t tmp;
/* Check for a fragment header preceding the IEEE802.15.4 FCF */
tmp = *fptr & SIXLOWPAN_DISPATCH_FRAG_MASK;
if (tmp == SIXLOWPAN_DISPATCH_FRAG1)
{
hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
}
else if (tmp == SIXLOWPAN_DISPATCH_FRAGN)
{
hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
}
/* Minimum header: 2 byte FCF + 1 byte sequence number */ /* Minimum header: 2 byte FCF + 1 byte sequence number */
fptr += hdrlen; hdrlen = 3;
hdrlen += 3;
/* Account for destination address size */ /* Account for destination address size */
@ -207,18 +230,18 @@ int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr)
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* *
* Input Parameters: * Input Parameters:
* ieee - The IEEE802.15.4 MAC network driver interface.
* fptr - Pointer to the beginning of the frame under construction * fptr - Pointer to the beginning of the frame under construction
* bptr - Output goes here. Normally this is a known offset into d_buf,
* may be redirected to g_bitbucket on the case of FRAGN frames.
* *
* Returned Value: * Returned Value:
* None * None
* *
****************************************************************************/ ****************************************************************************/
static void sixlowpan_uncompress_ipv6hdr(FAR struct ieee802154_driver_s *ieee, static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr, FAR uint8_t *bptr)
FAR uint8_t *fptr)
{ {
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF(&ieee->i_dev); FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr;
uint16_t protosize; uint16_t protosize;
/* Put uncompressed IPv6 header in d_buf. */ /* Put uncompressed IPv6 header in d_buf. */
@ -310,6 +333,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
FAR struct iob_s *iob) FAR struct iob_s *iob)
{ {
FAR uint8_t *fptr; /* Convenience pointer to beginning of the frame */ FAR uint8_t *fptr; /* Convenience pointer to beginning of the frame */
FAR uint8_t *bptr; /* Used to redirect uncompressed header to the bitbucket */
FAR uint8_t *hc1; /* Convenience pointer to HC1 data */ FAR uint8_t *hc1; /* Convenience pointer to HC1 data */
uint16_t fragsize = 0; /* Size of the IP packet (read from fragment) */ uint16_t fragsize = 0; /* Size of the IP packet (read from fragment) */
uint16_t paysize; /* Size of the data payload */ uint16_t paysize; /* Size of the data payload */
@ -318,6 +342,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
int hdrsize; /* Size of the IEEE802.15.4 header */ int hdrsize; /* Size of the IEEE802.15.4 header */
#ifdef CONFIG_NET_6LOWPAN_FRAG #ifdef CONFIG_NET_6LOWPAN_FRAG
FAR uint8_t *fragptr; /* Pointer to the fragmentation header */
bool isfrag = false; bool isfrag = false;
bool isfirstfrag = false; bool isfirstfrag = false;
uint16_t fragtag = 0; /* Tag of the fragment */ uint16_t fragtag = 0; /* Tag of the fragment */
@ -349,7 +374,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
* already includes the fragementation header, if presetn. * already includes the fragementation header, if presetn.
*/ */
switch ((GETINT16(fptr, RIME_FRAG_DISPATCH_SIZE) & 0xf800) >> 8) fragptr = fptr + hdrsize;
switch ((GETINT16(fragptr, RIME_FRAG_DISPATCH_SIZE) & 0xf800) >> 8)
{ {
/* First fragment of new reassembly */ /* First fragment of new reassembly */
@ -357,16 +383,17 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
{ {
/* Set up for the reassembly */ /* Set up for the reassembly */
fragsize = GETINT16(fptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff; fragsize = GETINT16(fragptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
fragtag = GETINT16(fptr, RIME_FRAG_TAG); fragtag = GETINT16(fragptr, RIME_FRAG_TAG);
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
ninfo("FRAG1: fragsize=%d fragtag=%d fragoffset=%d\n", ninfo("FRAG1: fragsize=%d fragtag=%d fragoffset=%d\n",
fragsize, fragtag, fragoffset); fragsize, fragtag, fragoffset);
/* Indicate the first fragment of the reassembly */ /* Indicate the first fragment of the reassembly */
isfirstfrag = true; isfirstfrag = true;
isfrag = true; isfrag = true;
} }
break; break;
@ -374,9 +401,10 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
{ {
/* Set offset, tag, size. Offset is in units of 8 bytes. */ /* Set offset, tag, size. Offset is in units of 8 bytes. */
fragoffset = fptr[RIME_FRAG_OFFSET]; fragoffset = fragptr[RIME_FRAG_OFFSET];
fragtag = GETINT16(fptr, RIME_FRAG_TAG); fragtag = GETINT16(fragptr, RIME_FRAG_TAG);
fragsize = GETINT16(fptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff; fragsize = GETINT16(fragptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
g_frame_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
ninfo("FRAGN: fragsize=%d fragtag=%d fragoffset=%d\n", ninfo("FRAGN: fragsize=%d fragtag=%d fragoffset=%d\n",
fragsize, fragtag, fragoffset); fragsize, fragtag, fragoffset);
@ -385,7 +413,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
/* Indicate that this frame is a another fragment for reassembly */ /* Indicate that this frame is a another fragment for reassembly */
isfrag = true; isfrag = true;
} }
break; break;
@ -397,6 +425,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
/* Check if we are currently reassembling a packet */ /* Check if we are currently reassembling a packet */
bptr = ieee->i_dev.d_buf;
if (ieee->i_accumlen > 0) if (ieee->i_accumlen > 0)
{ {
/* If reassembly timed out, cancel it */ /* If reassembly timed out, cancel it */
@ -470,12 +499,11 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
else else
{ {
/* Looks good. We are currently processing a reassembling sequence /* Looks good. We are currently processing a reassembling sequence
* and we recieved a valid FRAGN fragment. Skip the header * and we recieved a valid FRAGN fragment. Redirect the header
* compression dispatch logic. * uncompression to our bitbucket.
*/ */
g_uncomp_hdrlen = ieee->i_boffset; bptr = g_bitbucket;
goto copypayload;
} }
} }
@ -522,7 +550,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
if ((hc1[RIME_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC) if ((hc1[RIME_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC)
{ {
ninfo("IPHC Dispatch\n"); ninfo("IPHC Dispatch\n");
sixlowpan_uncompresshdr_hc06(ieee, fragsize, iob, fptr); sixlowpan_uncompresshdr_hc06(fragsize, iob, fptr, bptr);
} }
else else
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */ #endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */
@ -531,7 +559,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_HC1) if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_HC1)
{ {
ninfo("HC1 Dispatch\n"); ninfo("HC1 Dispatch\n");
sixlowpan_uncompresshdr_hc1(ieee, fragsize, iob, fptr); sixlowpan_uncompresshdr_hc1(fragsize, iob, fptr, bptr);
} }
else else
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */ #endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */
@ -539,30 +567,40 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_IPV6) if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_IPV6)
{ {
ninfo("IPv6 Dispatch\n"); ninfo("IPv6 Dispatch\n");
sixlowpan_uncompress_ipv6hdr(ieee, fptr); sixlowpan_uncompress_ipv6hdr(fptr, bptr);
} }
else else
{ {
/* Unknown or unsupported header */ /* Unknown or unsupported header */
nwarn("WARNING unknown dispatch: %u\n", hc1[RIME_HC1_DISPATCH]); nwarn("WARNING: Unknown dispatch: %u\n", hc1[RIME_HC1_DISPATCH]);
return OK; return OK;
} }
#ifdef CONFIG_NET_6LOWPAN_FRAG #ifdef CONFIG_NET_6LOWPAN_FRAG
/* Non-fragmented and FRAG1 frames pass through here. Remember the /* Is this the first fragment is a sequence? */
* offset from the beginning of d_buf where be begin placing the data
* payload.
*/
if (isfirstfrag) if (isfirstfrag)
{ {
/* Yes.. Remember the offset from the beginning of d_buf where we
* begin placing the data payload.
*/
ieee->i_boffset = g_uncomp_hdrlen; ieee->i_boffset = g_uncomp_hdrlen;
} }
/* We branch to here on all good FRAGN frames */ /* No.. is this a subsequent fragment in the same sequence? */
else if (isfrag)
{
/* Yes, recover the offset from the beginning of the d_buf where
* we began placing payload data.
*/
g_uncomp_hdrlen = ieee->i_boffset;
}
copypayload:
#endif /* CONFIG_NET_6LOWPAN_FRAG */ #endif /* CONFIG_NET_6LOWPAN_FRAG */
/* Copy "payload" from the rime buffer to the IEEE802.15.4 MAC driver's /* Copy "payload" from the rime buffer to the IEEE802.15.4 MAC driver's
@ -584,7 +622,7 @@ copypayload:
reqsize = g_uncomp_hdrlen + (fragoffset << 3) + paysize; reqsize = g_uncomp_hdrlen + (fragoffset << 3) + paysize;
if (reqsize > CONFIG_NET_6LOWPAN_MTU) if (reqsize > CONFIG_NET_6LOWPAN_MTU)
{ {
ninfo("Required buffer size: %u+%u+%u=%u Available=%u\n", nwarn("WARNING: Required buffer size: %u+%u+%u=%u Available=%u\n",
g_uncomp_hdrlen, (fragoffset << 3), paysize, g_uncomp_hdrlen, (fragoffset << 3), paysize,
reqsize, CONFIG_NET_6LOWPAN_MTU); reqsize, CONFIG_NET_6LOWPAN_MTU);
return -ENOMEM; return -ENOMEM;

View File

@ -497,12 +497,13 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
* appropriate values * appropriate values
* *
* Input Parmeters: * Input Parmeters:
* ieee - A reference to the IEE802.15.4 network device state
* iplen - Equal to 0 if the packet is not a fragment (IP length is then * 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 * inferred from the L2 length), non 0 if the packet is a first
* fragment. * fragment.
* iob - Pointer to the IOB containing the received frame. * iob - Pointer to the IOB containing the received frame.
* fptr - Pointer to frame to be uncompressed. * 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: * Returned Value:
* None * None
@ -510,9 +511,8 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee, void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
uint16_t iplen, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr);
FAR uint8_t *fptr);
#endif #endif
/**************************************************************************** /****************************************************************************
@ -530,7 +530,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
* ipv6 - The IPv6 header to be compressed * ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP * destmac - L2 destination address, needed to compress the IP
* destination field * destination field
* fptr - Pointer to frame to be compressed. * fptr - Pointer to frame to be compressed.
* *
* Returned Value: * Returned Value:
* None * None
@ -557,22 +557,23 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
* are set to the appropriate values * are set to the appropriate values
* *
* Input Parameters: * Input Parameters:
* ieee - A reference to the IEE802.15.4 network device state
* iplen - Equal to 0 if the packet is not a fragment (IP length is then * 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 * inferred from the L2 length), non 0 if the packet is a 1st
* fragment. * fragment.
* iob - Pointer to the IOB containing the received frame. * iob - Pointer to the IOB containing the received frame.
* fptr - Pointer to frame to be uncompressed. * fptr - Pointer to frame to be uncompressed.
* 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: * Returned Value:
* None * Zero (OK) is returned on success, on failure a negater errno value is
* returned.
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1 #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee, int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
uint16_t ip_len, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr);
FAR uint8_t *fptr);
#endif #endif
/**************************************************************************** /****************************************************************************