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

This commit is contained in:
Gregory Nutt 2017-04-07 15:49:03 -06:00
commit 7aff0f77d9
8 changed files with 264 additions and 181 deletions

View file

@ -744,7 +744,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y
# CONFIG_SENSORS is not set
CONFIG_SERIAL=y
CONFIG_SERIAL_REMOVABLE=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_SERIAL_CONSOLE is not set
# CONFIG_16550_UART is not set
# CONFIG_UART_SERIALDRIVER is not set
# CONFIG_UART0_SERIALDRIVER is not set
@ -774,9 +774,9 @@ CONFIG_STANDARD_SERIAL=y
# CONFIG_SERIAL_OFLOWCONTROL is not set
# CONFIG_SERIAL_DMA is not set
CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y
CONFIG_USART1_SERIAL_CONSOLE=y
# CONFIG_USART1_SERIAL_CONSOLE is not set
# CONFIG_OTHER_SERIAL_CONSOLE is not set
# CONFIG_NO_SERIAL_CONSOLE is not set
CONFIG_NO_SERIAL_CONSOLE=y
#
# USART1 Configuration

View file

@ -80,7 +80,7 @@
#define SIXLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */
#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */
#define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf1 /* 11111000 */
#define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf8 /* 11111000 */
/* HC1 encoding */
@ -398,6 +398,12 @@ struct ieee802154_driver_s
uint16_t i_reasstag;
/* i_boffset. Offset to the beginning of data in d_buf. As each fragment
* is received, data is placed at an appriate offset added to this.
*/
uint16_t i_boffset;
/* The source MAC address of the fragments being merged */
struct rimeaddr_s i_fragsrc;

View file

@ -101,17 +101,15 @@
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Input Parameters:
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
* destip - Pointer to the IPv6 header to "compress"
* fptr - Pointer to the beginning of the frame under construction
* ipv6hdr - Pointer to the IPv6 header to "compress"
* fptr - Pointer to the beginning of the frame under construction
*
* Returned Value:
* None
*
****************************************************************************/
static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *destip,
static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr,
FAR uint8_t *fptr)
{
/* Indicate the IPv6 dispatch and length */
@ -121,11 +119,93 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
/* Copy the IPv6 header and adjust pointers */
memcpy(&fptr[g_frame_hdrlen] , destip, IPv6_HDRLEN);
memcpy(&fptr[g_frame_hdrlen] , ipv6hdr, IPv6_HDRLEN);
g_frame_hdrlen += IPv6_HDRLEN;
g_uncomp_hdrlen += IPv6_HDRLEN;
}
/****************************************************************************
* Name: sixlowpan_copy_protohdr
*
* Description:
* The IPv6 header should have already been processed (as reflected in the
* g_uncomphdrlen). But we probably still need to copy the following
* protocol header.
*
* Input Parameters:
* ipv6hdr - Pointer to the IPv6 header to "compress"
* fptr - Pointer to the beginning of the frame under construction
*
* Returned Value:
* None. But g_frame_hdrlen and g_uncomp_hdrlen updated.
*
****************************************************************************/
static void sixlowpan_copy_protohdr(FAR const struct ipv6_hdr_s *ipv6hdr,
FAR uint8_t *fptr)
{
uint16_t combined;
uint16_t protosize;
uint16_t copysize;
/* What is the total size of the IPv6 + protocol header? */
switch (ipv6hdr->proto)
{
#ifdef CONFIG_NET_TCP
case IP_PROTO_TCP:
combined = sizeof(struct ipv6tcp_hdr_s);
protosize = sizeof(struct tcp_hdr_s);
break;
#endif
#ifdef CONFIG_NET_UDP
case IP_PROTO_UDP:
combined = sizeof(struct ipv6udp_hdr_s);
protosize = sizeof(struct udp_hdr_s);
break;
#endif
#ifdef CONFIG_NET_ICMPv6
case IP_PROTO_ICMP6:
combined = sizeof(struct ipv6icmp_hdr_s);
protosize = sizeof(struct icmpv6_hdr_s);
break;
#endif
default:
nwarn("WARNING: Unrecognized proto: %u\n", ipv6hdr->proto);
combined = sizeof(struct ipv6_hdr_s);
protosize = 0;
break;
}
/* Copy the remaining protocol header. */
if (g_uncomp_hdrlen > IPv6_HDRLEN)
{
nwarn("WARNING: Protocol header not copied: "
"g_uncomp_hdren=%u IPv6_HDRLEN=%u\n",
g_uncomp_hdrlen, IPv6_HDRLEN);
return;
}
copysize = combined - g_uncomp_hdrlen;
if (copysize != protosize)
{
nwarn("WARNING: Protocol header size mismatch: "
"g_uncomp_hdren=%u copysize=%u protosize=%u\n",
g_uncomp_hdrlen, copysize, protosize);
return;
}
memcpy(fptr + g_frame_hdrlen, (FAR uint8_t *)ipv6hdr + g_uncomp_hdrlen,
copysize);
g_frame_hdrlen += copysize;
g_uncomp_hdrlen += copysize;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -172,6 +252,8 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
FAR uint8_t *fptr;
int framer_hdrlen;
struct rimeaddr_s bcastmac;
uint16_t pktlen;
uint16_t paysize;
#ifdef CONFIG_NET_6LOWPAN_FRAG
uint16_t outlen = 0;
#endif
@ -267,7 +349,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
{
/* Small.. use IPv6 dispatch (no compression) */
sixlowpan_compress_ipv6hdr(ieee, destip, fptr);
sixlowpan_compress_ipv6hdr(destip, fptr);
}
ninfo("Header of length %d\n", g_frame_hdrlen);
@ -276,9 +358,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Check if we need to fragment the packet into several frames */
if ((int)buflen - (int)g_uncomp_hdrlen >
(int)CONFIG_NET_6LOWPAN_MAXPAYLOAD - framer_hdrlen -
(int)g_frame_hdrlen)
if (buflen > (CONFIG_NET_6LOWPAN_MAXPAYLOAD - g_frame_hdrlen))
{
#ifdef CONFIG_NET_6LOWPAN_FRAG
/* ieee->i_framelist will hold the generated frames; frames will be
@ -286,6 +366,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
*/
FAR struct iob_s *qtail;
FAR uint8_t *frame1;
int verify;
/* The outbound IPv6 packet is too large to fit into a single 15.4
@ -295,7 +376,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
* The following fragments contain only the fragn dispatch.
*/
ninfo("Fragmentation sending packet length %d\n", buflen);
ninfo("Sending fragmented packet length %d\n", buflen);
/* Create 1st Fragment */
/* Add the frame header using the pre-allocated IOB. */
@ -304,7 +385,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
DEBUGASSERT(verify == framer_hdrlen);
UNUSED(verify);
/* Move HC1/HC06/IPv6 header */
/* Move HC1/HC06/IPv6 header to make space for the FRAG1 header at the
* beginning of the frame.
*/
memmove(fptr + SIXLOWPAN_FRAG1_HDR_LEN, fptr, g_frame_hdrlen);
@ -323,27 +406,31 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
* bytes for all subsequent headers.
*/
pktlen = buflen + g_uncomp_hdrlen;
PUTINT16(fptr, RIME_FRAG_DISPATCH_SIZE,
((SIXLOWPAN_DISPATCH_FRAG1 << 8) | buflen));
((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen));
PUTINT16(fptr, RIME_FRAG_TAG, ieee->i_dgramtag);
ieee->i_dgramtag++;
/* Copy payload and enqueue */
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
g_rime_payloadlen =
(CONFIG_NET_6LOWPAN_MAXPAYLOAD - framer_hdrlen - g_frame_hdrlen) & 0xf8;
/* Copy protocol header that follows the IPv6 header */
memcpy(fptr + g_frame_hdrlen,
(FAR uint8_t *)destip + g_uncomp_hdrlen, g_rime_payloadlen);
iob->io_len += g_rime_payloadlen + g_frame_hdrlen;
sixlowpan_copy_protohdr(destip, fptr);
/* Copy payload and enqueue. NOTE that the size is a multiple of eight
* bytes.
*/
paysize = (CONFIG_NET_6LOWPAN_MAXPAYLOAD - g_frame_hdrlen) & ~7;
memcpy(fptr + g_frame_hdrlen, buf, paysize);
/* Set outlen to what we already sent from the IP payload */
outlen = g_rime_payloadlen + g_uncomp_hdrlen;
iob->io_len = paysize + g_frame_hdrlen;
outlen = paysize;
ninfo("First fragment: length %d, tag %d\n",
g_rime_payloadlen, ieee->i_dgramtag);
paysize, ieee->i_dgramtag);
sixlowpan_dumpbuffer("Outgoing frame",
(FAR const uint8_t *)iob->io_data, iob->io_len);
@ -358,10 +445,11 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Create following fragments */
g_frame_hdrlen = SIXLOWPAN_FRAGN_HDR_LEN;
frame1 = iob->io_data;
while (outlen < buflen)
{
uint16_t fragn_hdrlen;
/* Allocate an IOB to hold the next fragment, waiting if
* necessary.
*/
@ -377,47 +465,45 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
iob->io_pktlen = 0;
fptr = iob->io_data;
/* Add the frame header */
/* Copy the frame header from first frame, into the correct
* location after the FRAGN header.
*/
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
DEBUGASSERT(verify == framer_hdrlen);
UNUSED(verify);
memmove(fptr + SIXLOWPAN_FRAGN_HDR_LEN,
frame1 + SIXLOWPAN_FRAG1_HDR_LEN,
framer_hdrlen);
fragn_hdrlen = framer_hdrlen;
/* Move HC1/HC06/IPv6 header */
memmove(fptr + SIXLOWPAN_FRAGN_HDR_LEN, fptr, g_frame_hdrlen);
/* Setup up the fragment header */
/* Setup up the FRAGN header at the beginning of the frame */
PUTINT16(fptr, RIME_FRAG_DISPATCH_SIZE,
((SIXLOWPAN_DISPATCH_FRAGN << 8) | buflen));
((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen));
PUTINT16(fptr, RIME_FRAG_TAG, ieee->i_dgramtag);
fptr[RIME_FRAG_OFFSET] = outlen >> 3;
fragn_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
/* Copy payload and enqueue */
/* Check for the last fragment */
if (buflen - outlen < g_rime_payloadlen)
paysize = (CONFIG_NET_6LOWPAN_MAXPAYLOAD - fragn_hdrlen) &
SIXLOWPAN_DISPATCH_FRAG_MASK;
if (buflen - outlen < paysize)
{
/* Last fragment */
/* Last fragment, truncate to the correct length */
g_rime_payloadlen = buflen - outlen;
}
else
{
g_rime_payloadlen =
(CONFIG_NET_6LOWPAN_MAXPAYLOAD - framer_hdrlen - g_frame_hdrlen) & 0xf8;
paysize = buflen - outlen;
}
memcpy(fptr + g_frame_hdrlen, (FAR uint8_t *)destip + outlen,
g_rime_payloadlen);
iob->io_len = g_rime_payloadlen + g_frame_hdrlen;
memcpy(fptr + fragn_hdrlen, buf + outlen, paysize);
/* Set outlen to what we already sent from the IP payload */
outlen += (g_rime_payloadlen + g_uncomp_hdrlen);
iob->io_len = paysize + fragn_hdrlen;
outlen += paysize;
ninfo("sixlowpan output: fragment offset %d, length %d, tag %d\n",
outlen >> 3, g_rime_payloadlen, ieee->i_dgramtag);
ninfo("Fragment offset=%d, paysize=%d, i_dgramtag=%d\n",
outlen >> 3, paysize, ieee->i_dgramtag);
sixlowpan_dumpbuffer("Outgoing frame",
(FAR const uint8_t *)iob->io_data,
iob->io_len);
@ -425,11 +511,16 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Add the next frame to the tail of the IOB queue */
qtail->io_flink = iob;
qtail = iob;
/* Keep track of the total amount of data queue */
ieee->i_framelist->io_pktlen += iob->io_len;
}
/* Update the datagram TAG value */
ieee->i_dgramtag++;
#else
nerr("ERROR: Packet too large: %d\n", buflen);
nerr(" Cannot to be sent without fragmentation support\n");
@ -452,11 +543,14 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
DEBUGASSERT(verify == framer_hdrlen);
UNUSED(verify);
/* Copy protocol header that follows the IPv6 header */
sixlowpan_copy_protohdr(destip, fptr);
/* Copy the payload and queue */
memcpy(fptr + g_frame_hdrlen, (FAR uint8_t *)destip + g_uncomp_hdrlen,
buflen - g_uncomp_hdrlen);
iob->io_len = buflen - g_uncomp_hdrlen + g_frame_hdrlen;
memcpy(fptr + g_frame_hdrlen, buf, buflen);
iob->io_len = buflen + g_frame_hdrlen;
ninfo("Non-fragmented: length %d\n", iob->io_len);
sixlowpan_dumpbuffer("Outgoing frame",

View file

@ -54,15 +54,6 @@
* during that processing
*/
/* The length of the payload in the Rime buffer.
*
* The payload is what comes after the compressed or uncompressed headers
* (can be the IP payload if the IP header only is compressed or the UDP
* payload if the UDP header is also compressed)
*/
uint8_t g_rime_payloadlen;
/* g_uncomp_hdrlen is the length of the headers before compression (if HC2
* is used this includes the UDP header in addition to the IP header).
*/

View file

@ -111,12 +111,26 @@
int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr)
{
uint16_t hdrlen;
uint16_t hdrlen = 0;
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 */
hdrlen = 3;
fptr += hdrlen;
hdrlen += 3;
/* Account for destination address size */
@ -209,10 +223,9 @@ int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr)
static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
FAR struct iob_s *iob)
{
FAR uint8_t *payptr; /* Pointer to the frame payload */
FAR uint8_t *hc1; /* Convenience pointer to HC1 data */
uint16_t fragsize = 0; /* Size of the IP packet (read from fragment) */
uint16_t paysize; /* Size of the data payload */
uint8_t fragoffset = 0; /* Offset of the fragment in the IP packet */
int reqsize; /* Required buffer size */
int hdrsize; /* Size of the IEEE802.15.4 header */
@ -220,12 +233,13 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
#ifdef CONFIG_NET_6LOWPAN_FRAG
bool isfrag = false;
bool isfirstfrag = false;
bool islastfrag = false;
uint16_t fragtag = 0; /* Tag of the fragment */
systime_t elapsed; /* Elapsed time */
#endif /* CONFIG_NET_6LOWPAN_FRAG */
/* Get a pointer to the payload following the IEEE802.15.4 frame header. */
/* Get a pointer to the payload following the IEEE802.15.4 frame header(s).
* This size includes both fragmentation and FCF headers.
*/
hdrsize = sixlowpan_recv_hdrlen(iob->io_data);
if (hdrsize < 0)
@ -241,16 +255,13 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
g_uncomp_hdrlen = 0;
g_frame_hdrlen = hdrsize;
/* Payload starts after the IEEE802.15.4 header */
payptr = &iob->io_data[hdrsize];
#ifdef CONFIG_NET_6LOWPAN_FRAG
/* Since we don't support the mesh and broadcast header, the first header
* we look for is the fragmentation header
* we look for is the fragmentation header. NOTE that g_frame_hdrlen
* already includes the fragementation header, if presetn.
*/
switch ((GETINT16(payptr, RIME_FRAG_DISPATCH_SIZE) & 0xf800) >> 8)
switch ((GETINT16(iob->io_data, RIME_FRAG_DISPATCH_SIZE) & 0xf800) >> 8)
{
/* First fragment of new reassembly */
@ -258,15 +269,12 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
{
/* Set up for the reassembly */
fragoffset = 0;
fragsize = GETINT16(payptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
fragtag = GETINT16(payptr, RIME_FRAG_TAG);
fragsize = GETINT16(iob->io_data, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
fragtag = GETINT16(iob->io_data, RIME_FRAG_TAG);
ninfo("FRAG1: size %d, tag %d, offset %d\n",
ninfo("FRAG1: fragsize=%d fragtag=%d fragoffset=%d\n",
fragsize, fragtag, fragoffset);
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
/* Indicate the first fragment of the reassembly */
isfirstfrag = true;
@ -278,32 +286,18 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
{
/* Set offset, tag, size. Offset is in units of 8 bytes. */
fragoffset = payptr[RIME_FRAG_OFFSET];
fragtag = GETINT16(payptr, RIME_FRAG_TAG);
fragsize = GETINT16(payptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
fragoffset = iob->io_data[RIME_FRAG_OFFSET];
fragtag = GETINT16(iob->io_data, RIME_FRAG_TAG);
fragsize = GETINT16(iob->io_data, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
ninfo("FRAGN: size %d, tag %d, offset %d\n",
ninfo("FRAGN: fragsize=%d fragtag=%d fragoffset=%d\n",
fragsize, fragtag, fragoffset);
g_frame_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
ninfo("FRAGN: i_accumlen %d g_rime_payloadlen %d fragsize %d\n",
ninfo("FRAGN: i_accumlen=%d paysize=%u fragsize=%u\n",
ieee->i_accumlen, iob->io_len - g_frame_hdrlen, fragsize);
/* Indicate that this frame is a another fragment for reassembly */
isfrag = true;
/* Check if it is the last fragement to be processed.
*
* If this is the last fragment, we may shave off any extrenous
* bytes at the end. We must be liberal in what we accept.
*/
if (ieee->i_accumlen + iob->io_len - g_frame_hdrlen >= fragsize)
{
islastfrag = true;
}
}
break;
@ -392,6 +386,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
* compression dispatch logic.
*/
g_uncomp_hdrlen = ieee->i_boffset;
goto copypayload;
}
}
@ -412,29 +407,22 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
return OK;
}
/* Start reassembly if we received a non-zero length, first fragment */
/* Drop the packet if it cannot fit into the d_buf */
if (fragsize > 0)
if (fragsize > CONFIG_NET_6LOWPAN_MTU)
{
/* Drop the packet if it cannot fit into the d_buf */
if (fragsize > CONFIG_NET_6LOWPAN_MTU)
{
nwarn("WARNING: Reassembled packet size exeeds CONFIG_NET_6LOWPAN_MTU\n");
return OK;
}
/* Set up for the reassembly */
ieee->i_pktlen = fragsize;
ieee->i_reasstag = fragtag;
ieee->i_time = clock_systimer();
ninfo("Starting reassembly: i_pktlen %d, i_pktlen %d\n",
ieee->i_pktlen, ieee->i_reasstag);
rimeaddr_copy(&ieee->i_fragsrc, &g_pktaddrs[PACKETBUF_ADDR_SENDER]);
nwarn("WARNING: Reassembled packet size exeeds CONFIG_NET_6LOWPAN_MTU\n");
return OK;
}
ieee->i_pktlen = fragsize;
ieee->i_reasstag = fragtag;
ieee->i_time = clock_systimer();
ninfo("Starting reassembly: i_pktlen %u, i_reasstag %d\n",
ieee->i_pktlen, ieee->i_reasstag);
rimeaddr_copy(&ieee->i_fragsrc, &g_pktaddrs[PACKETBUF_ADDR_SENDER]);
}
#endif /* CONFIG_NET_6LOWPAN_FRAG */
@ -445,7 +433,13 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
if ((hc1[RIME_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC)
{
FAR uint8_t *payptr;
ninfo("IPHC Dispatch\n");
/* Payload starts after the IEEE802.15.4 header(s) */
payptr = &iob->io_data[g_frame_hdrlen];
sixlowpan_uncompresshdr_hc06(ieee, fragsize, iob, payptr);
}
else
@ -454,7 +448,13 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_HC1)
{
FAR uint8_t *payptr;
ninfo("HC1 Dispatch\n");
/* Payload starts after the IEEE802.15.4 header(s) */
payptr = &iob->io_data[g_frame_hdrlen];
sixlowpan_uncompresshdr_hc1(ieee, fragsize, iob, payptr);
}
else
@ -467,16 +467,9 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
ninfo("IPv6 Dispatch\n");
g_frame_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
/* payptr was set up to begin just after the IPHC bytes. However,
* those bytes are not present for the case of IPv6 dispatch. Just
* reset back to the begnning of the buffer.
*/
payptr = iob->io_data;
/* Put uncompressed IP header in d_buf. */
memcpy(ipv6, payptr + g_frame_hdrlen, IPv6_HDRLEN);
memcpy(ipv6, iob->io_data + g_frame_hdrlen, IPv6_HDRLEN);
/* Update g_uncomp_hdrlen and g_frame_hdrlen. */
@ -492,6 +485,18 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
}
#ifdef CONFIG_NET_6LOWPAN_FRAG
/* Non-fragmented and FRAG1 frames pass through here. Remember the
* offset from the beginning of d_buf where be begin placing the data
* payload.
*/
if (isfirstfrag)
{
ieee->i_boffset = g_uncomp_hdrlen;
}
/* We branch to here on all good FRAGN frames */
copypayload:
#endif /* CONFIG_NET_6LOWPAN_FRAG */
@ -501,28 +506,28 @@ copypayload:
* and g_frame_hdrlen are non-zerio, fragoffset is.
*/
g_rime_payloadlen = iob->io_len - g_frame_hdrlen;
if (g_rime_payloadlen > CONFIG_NET_6LOWPAN_MTU)
paysize = iob->io_len - g_frame_hdrlen;
if (paysize > CONFIG_NET_6LOWPAN_MTU)
{
nwarn("WARNING: Packet dropped due to payload (%u) > packet buffer (%u)\n",
g_rime_payloadlen, CONFIG_NET_6LOWPAN_MTU);
paysize, CONFIG_NET_6LOWPAN_MTU);
return OK;
}
/* Sanity-check size of incoming packet to avoid buffer overflow */
reqsize = g_uncomp_hdrlen + (uint16_t) (fragoffset << 3) + g_rime_payloadlen;
reqsize = g_uncomp_hdrlen + (fragoffset << 3) + paysize;
if (reqsize > CONFIG_NET_6LOWPAN_MTU)
{
ninfo("Required buffer size: %d+%d+%d=%d Available: %d\n",
g_uncomp_hdrlen, (int)(fragoffset << 3), g_rime_payloadlen,
ninfo("Required buffer size: %u+%u+%u=%u Available=%u\n",
g_uncomp_hdrlen, (fragoffset << 3), paysize,
reqsize, CONFIG_NET_6LOWPAN_MTU);
return -ENOMEM;
}
memcpy((FAR uint8_t *)ieee->i_dev.d_buf + g_uncomp_hdrlen +
(int)(fragoffset << 3), payptr + g_frame_hdrlen,
g_rime_payloadlen);
memcpy(ieee->i_dev.d_buf + g_uncomp_hdrlen + (fragoffset << 3),
iob->io_data + g_frame_hdrlen,
paysize);
#ifdef CONFIG_NET_6LOWPAN_FRAG
/* Update ieee->i_accumlen if the frame is a fragment, ieee->i_pktlen
@ -531,42 +536,27 @@ copypayload:
if (isfrag)
{
/* Add the size of the header only for the first fragment. */
if (isfirstfrag)
{
ieee->i_accumlen += g_uncomp_hdrlen;
}
/* For the last fragment, we are OK if there is extraneous bytes at the
* end of the packet.
/* Check if it is the last fragment to be processed.
*
* If this is the last fragment, we may shave off any extrenous
* bytes at the end. We must be liberal in what we accept.
*/
if (islastfrag)
{
ieee->i_accumlen = fragsize;
}
else
{
ieee->i_accumlen += g_rime_payloadlen;
}
ninfo("i_accumlen %d, g_rime_payloadlen %d\n",
ieee->i_accumlen, g_rime_payloadlen);
ieee->i_accumlen = g_uncomp_hdrlen + (fragoffset << 3) + paysize;
}
else
{
ieee->i_pktlen = g_rime_payloadlen + g_uncomp_hdrlen;
ieee->i_pktlen = paysize + g_uncomp_hdrlen;
}
/* If we have a full IP packet in sixlowpan_buf, deliver it to
* the IP stack
*/
ninfo("sixlowpan_init i_accumlen %d, ieee->i_pktlen %d\n",
ieee->i_accumlen, ieee->i_pktlen);
ninfo("i_accumlen=%d i_pktlen=%d paysize=%d\n",
ieee->i_accumlen, ieee->i_pktlen, paysize);
if (ieee->i_accumlen == 0 || ieee->i_accumlen == ieee->i_pktlen)
if (ieee->i_accumlen == 0 || ieee->i_accumlen >= ieee->i_pktlen)
{
ninfo("IP packet ready (length %d)\n", ieee->i_pktlen);
@ -580,7 +570,7 @@ copypayload:
#else
/* Deliver the packet to the IP stack */
ieee->i_dev.d_len = g_rime_payloadlen + g_uncomp_hdrlen;
ieee->i_dev.d_len = paysize + g_uncomp_hdrlen;
return INPUT_COMPLETE;
#endif /* CONFIG_NET_6LOWPAN_FRAG */
}
@ -706,6 +696,10 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
ret = sixlowpan_frame_process(ieee, iob);
/* Free the IOB the held the consumed frame */
iob_free(iob);
/* Was the frame successfully processed? Is the packet in d_buf fully
* reassembled?
*/

View file

@ -409,15 +409,6 @@ struct frame802154_s
extern FAR uint8_t *g_rimeptr;
/* The length of the payload in the Rime buffer.
*
* The payload is what comes after the compressed or uncompressed headers
* (can be the IP payload if the IP header only is compressed or the UDP
* payload if the UDP header is also compressed)
*/
extern uint8_t g_rime_payloadlen;
/* g_uncomp_hdrlen is the length of the headers before compression (if HC2
* is used this includes the UDP header in addition to the IP header).
*/

View file

@ -403,6 +403,8 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
else
{
struct rimeaddr_s destmac;
FAR uint8_t *buf;
size_t buflen;
/* Get the Rime MAC address of the destination. This assumes an
* encoding of the MAC address in the IPv6 address.
@ -412,9 +414,12 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
/* Convert the outgoing packet into a frame list. */
buf = dev->d_buf + sizeof(struct ipv6_hdr_s);
buflen = dev->d_len - sizeof(struct ipv6_hdr_s);
(void)sixlowpan_queue_frames(
(FAR struct ieee802154_driver_s *)dev, ipv6hdr,
dev->d_buf, dev->d_len, &destmac);
buf, buflen, &destmac);
}
}

View file

@ -185,23 +185,25 @@ static int lo_txpoll(FAR struct net_driver_s *dev)
/* Find the tail of the IOB queue */
for (tail = NULL, iob = head;
iob != NULL;
tail = iob, iob = iob->io_flink);
iob != NULL;
tail = iob, iob = iob->io_flink);
/* Loop while there frames to be sent, i.e., while the IOB list is not
* emtpy. Sending, of course, just means relaying back through the network
* for this driver.
*/
while (!FRAME_IOB_EMPTY(&priv->lo_ieee))
while (head != NULL)
{
/* Remove the IOB from the queue */
FRAME_IOB_REMOVE(&priv->lo_ieee, iob);
iob = head;
head = iob->io_flink;
iob->io_flink = NULL;
/* Is the queue now empty? */
if (FRAME_IOB_EMPTY(&priv->lo_ieee))
if (head == NULL)
{
tail = NULL;
}
@ -239,8 +241,8 @@ static int lo_txpoll(FAR struct net_driver_s *dev)
/* Find the new tail of the IOB queue */
for (tail = iob, iob = iob->io_flink;
iob != NULL;
tail = iob, iob = iob->io_flink);
iob != NULL;
tail = iob, iob = iob->io_flink);
}
priv->lo_txdone = true;