6loWPAN: Fix an error in how reassembly timeouts work.

This commit is contained in:
Gregory Nutt 2017-04-04 09:08:48 -06:00
parent 9a29b9a327
commit a6ae7d4ae3
4 changed files with 55 additions and 61 deletions

View File

@ -134,10 +134,10 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
*
* Description:
* Process an outgoing UDP or TCP packet. This function is called from
* send interrupt logic when a TX poll is received. It formates the
* send interrupt logic when a TX poll is received. It formats the
* list of frames to be sent by the IEEE802.15.4 MAC driver.
*
* The payload data is in the caller 's_buf' and is of length 's_len'.
* The payload data is in the caller 'buf' and is of length 'buflen'.
* Compressed headers will be added and if necessary the packet is
* fragmented. The resulting packet/fragments are put in ieee->i_framelist
* and the entire list of frames will be delivered to the 802.15.4 MAC via
@ -146,8 +146,9 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
* Input Parameters:
* ieee - The IEEE802.15.4 MAC driver instance
* ipv6hdr - IPv6 header followed by TCP or UDP header.
* buf - Data to send
* len - Length of data to send
* buf - Beginning of the packet packet to send (with IPv6 + protocol
* headers)
* buflen - Length of data to send (include IPv6 and protocol headers)
* destmac - The IEEE802.15.4 MAC address of the destination
*
* Returned Value:
@ -163,7 +164,7 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *destip,
FAR const void *buf, size_t len,
FAR const void *buf, size_t buflen,
FAR const struct rimeaddr_s *destmac)
{
FAR struct iob_s *iob;
@ -231,10 +232,10 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
iob->io_pktlen = 0;
fptr = iob->io_data;
ninfo("Sending packet len %d\n", len);
ninfo("Sending packet length %d\n", buflen);
#ifndef CONFIG_NET_6LOWPAN_COMPRESSION_IPv6
if (len >= CONFIG_NET_6LOWPAN_COMPRESSION_THRESHOLD)
if (buflen >= CONFIG_NET_6LOWPAN_COMPRESSION_THRESHOLD)
{
/* Try to compress the headers */
@ -254,7 +255,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
sixlowpan_compress_ipv6hdr(ieee, destip, fptr);
}
ninfo("Header of len %d\n", g_frame_hdrlen);
ninfo("Header of length %d\n", g_frame_hdrlen);
rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER], destmac);
@ -271,7 +272,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Check if we need to fragment the packet into several frames */
if ((int)len - (int)g_uncomp_hdrlen >
if ((int)buflen - (int)g_uncomp_hdrlen >
(int)CONFIG_NET_6LOWPAN_MAXPAYLOAD - framer_hdrlen -
(int)g_frame_hdrlen)
{
@ -290,7 +291,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
* The following fragments contain only the fragn dispatch.
*/
ninfo("Fragmentation sending packet len %d\n", len);
ninfo("Fragmentation sending packet length %d\n", buflen);
/* Create 1st Fragment */
/* Add the frame header using the pre-allocated IOB. */
@ -319,7 +320,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
*/
PUTINT16(fptr, RIME_FRAG_DISPATCH_SIZE,
((SIXLOWPAN_DISPATCH_FRAG1 << 8) | len));
((SIXLOWPAN_DISPATCH_FRAG1 << 8) | buflen));
PUTINT16(fptr, RIME_FRAG_TAG, ieee->i_dgramtag);
ieee->i_dgramtag++;
@ -337,7 +338,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
outlen = g_rime_payloadlen + g_uncomp_hdrlen;
ninfo("First fragment: len %d, tag %d\n",
ninfo("First fragment: length %d, tag %d\n",
g_rime_payloadlen, ieee->i_dgramtag);
/* Add the first frame to the IOB queue */
@ -353,7 +354,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
g_frame_hdrlen = SIXLOWPAN_FRAGN_HDR_LEN;
while (outlen < len)
while (outlen < buflen)
{
/* Allocate an IOB to hold the next fragment, waiting if
* necessary.
@ -383,17 +384,17 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Setup up the fragment header */
PUTINT16(fptr, RIME_FRAG_DISPATCH_SIZE,
((SIXLOWPAN_DISPATCH_FRAGN << 8) | len));
((SIXLOWPAN_DISPATCH_FRAGN << 8) | buflen));
PUTINT16(fptr, RIME_FRAG_TAG, ieee->i_dgramtag);
fptr[RIME_FRAG_OFFSET] = outlen >> 3;
/* Copy payload and enqueue */
if (len - outlen < g_rime_payloadlen)
if (buflen - outlen < g_rime_payloadlen)
{
/* Last fragment */
g_rime_payloadlen = len - outlen;
g_rime_payloadlen = buflen - outlen;
}
else
{
@ -409,7 +410,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
outlen += (g_rime_payloadlen + g_uncomp_hdrlen);
ninfo("sixlowpan output: fragment offset %d, len %d, tag %d\n",
ninfo("sixlowpan output: fragment offset %d, length %d, tag %d\n",
outlen >> 3, g_rime_payloadlen, ieee->i_dgramtag);
/* Add the next frame to the tail of the IOB queue */
@ -421,7 +422,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
ieee->i_framelist->io_pktlen += iob->io_len;
}
#else
nerr("ERROR: Packet too large: %d\n", len);
nerr("ERROR: Packet too large: %d\n", buflen);
nerr(" Cannot to be sent without fragmentation support\n");
nerr(" dropping packet\n");
@ -436,7 +437,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
* and send in one frame.
*/
/* Add the frame header to the prealloated IOB. */
/* Add the frame header to the preallocated IOB. */
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
DEBUGASSERT(verify == framer_hdrlen);
@ -445,8 +446,8 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Copy the payload and queue */
memcpy(fptr + g_frame_hdrlen, (FAR uint8_t *)destip + g_uncomp_hdrlen,
len - g_uncomp_hdrlen);
iob->io_len = len - g_uncomp_hdrlen + g_frame_hdrlen;
buflen - g_uncomp_hdrlen);
iob->io_len = buflen - g_uncomp_hdrlen + g_frame_hdrlen;
/* Add the first frame to the IOB queue */

View File

@ -148,16 +148,6 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
payptr = &iob->io_data[PACKETBUF_HDR_SIZE];
#if CONFIG_NET_6LOWPAN_FRAG
/* If reassembly timed out, cancel it */
elapsed = clock_systimer() - ieee->i_time;
if (elapsed > NET_6LOWPAN_TIMEOUT)
{
nwarn("WARNING: Reassembly timed out\n");
ieee->i_pktlen = 0;
ieee->i_accumlen = 0;
}
/* Since we don't support the mesh and broadcast header, the first header
* we look for is the fragmentation header
*/
@ -229,6 +219,16 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
if (ieee->i_accumlen > 0)
{
/* If reassembly timed out, cancel it */
elapsed = clock_systimer() - ieee->i_time;
if (elapsed > NET_6LOWPAN_TIMEOUT)
{
nwarn("WARNING: Reassembly timed out\n");
ieee->i_pktlen = 0;
ieee->i_accumlen = 0;
}
/* In this case what we expect is that the next frame will hold the
* next FRAGN of the sequence. We have to handle a few exeptional
* cases that we need to handle:
@ -246,7 +246,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
*
*/
if (!isfrag)
else if (!isfrag)
{
/* Discard the partially assembled packet */
@ -287,13 +287,15 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
"the packet currently being reassembled\n");
return OK;
}
else
{
/* Looks good. We are currently processing a reassembling sequence
* and we recieved a valid FRAGN fragment. Skip the header
* compression dispatch logic.
*/
/* Looks good. We are currently processing a reassembling sequence and
* we recieved a valid FRAGN fragment. Skip the header compression
* dispatch logic.
*/
goto copypayload;
goto copypayload;
}
}
/* There is no reassembly in progress. Check if we received a fragment */
@ -359,6 +361,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
}
else
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */
if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_IPV6)
{
ninfo("IPV6 Dispatch\n");

View File

@ -543,7 +543,7 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
* send interrupt logic when a TX poll is received. It formates the
* list of frames to be sent by the IEEE802.15.4 MAC driver.
*
* The payload data is in the caller 's_buf' and is of length 's_len'.
* The payload data is in the caller 'buf' and is of length 'buflen'.
* Compressed headers will be added and if necessary the packet is
* fragmented. The resulting packet/fragments are put in ieee->i_framelist
* and the entire list of frames will be delivered to the 802.15.4 MAC via
@ -552,8 +552,9 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
* Input Parameters:
* ieee - The IEEE802.15.4 MAC driver instance
* ipv6hdr - IPv6 header followed by TCP or UDP header.
* buf - Data to send
* buflen - Length of data to send
* buf - Beginning of the packet packet to send (with IPv6 + protocol
* headers)
* buflen - Length of data to send (include IPv6 and protocol headers)
* destmac - The IEEE802.15.4 MAC address of the destination
*
* Returned Value:

View File

@ -390,30 +390,19 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
}
else
{
size_t hdrlen;
struct rimeaddr_s destmac;
hdrlen = IPv6_HDRLEN + TCP_HDRLEN;
if (hdrlen > dev->d_len)
{
nwarn("WARNING: Packet to small: Have %u need >%u\n",
dev->d_len, hdrlen);
}
else
{
struct rimeaddr_s destmac;
/* Get the Rime MAC address of the destination. This assumes an
* encoding of the MAC address in the IPv6 address.
*/
/* Get the Rime MAC address of the destination. This assumes
* an encoding of the MAC address in the IPv6 address.
*/
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
/* Convert the outgoing packet into a frame list. */
/* Convert the outgoing packet into a frame list. */
(void)sixlowpan_queue_frames(
(FAR struct ieee802154_driver_s *)dev, ipv6hdr,
dev->d_buf + hdrlen, dev->d_len - hdrlen, &destmac);
}
(void)sixlowpan_queue_frames(
(FAR struct ieee802154_driver_s *)dev, ipv6hdr,
dev->d_buf, dev->d_len, &destmac);
}
}