net: 6lowpan: Fix 6lowpan fragmentation
IP packet passing through 6lowpan compression and 802.15.4 fragmentation has an issue. (RFC 6282 and 4944) RFC4944, 5.3 says "fragment header's datagram_size and datagram_offset values as the size and offset of the IPv6 datagram before compression". At the moment datagram size and offset values are after compression. Due to multiple bearer (15.4 and bluetooth) support and multiple incoming buffers support functionality is divided to compression and fragmentation parts. And datagram size and offset values for BT are after compression. Small packet (which doesn't need fragmentation) doesn't go through this. So cacheing compressed and uncompressed header lengths and with hdr difference preparing fragments as per original buffer (total buf size and offset). Change-Id: I9d3b0433e64964c68519d7c007cc06ec6035b573 Jira: ZEP-208 Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
This commit is contained in:
parent
592acc09fd
commit
5e99b14ad4
6 changed files with 105 additions and 34 deletions
|
@ -122,6 +122,12 @@ struct ip_buf {
|
||||||
uint8_t *nd6_opt_llao;
|
uint8_t *nd6_opt_llao;
|
||||||
uip_ipaddr_t ipaddr;
|
uip_ipaddr_t ipaddr;
|
||||||
uint8_t nd6_opt_offset;
|
uint8_t nd6_opt_offset;
|
||||||
|
|
||||||
|
/* 6lowpan specific vars */
|
||||||
|
uint8_t compressed_hdr_len;
|
||||||
|
uint8_t uncompressed_hdr_len;
|
||||||
|
uint8_t first_frag_len;
|
||||||
|
uint8_t uncompressed;
|
||||||
/* @endcond */
|
/* @endcond */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,6 +200,14 @@ struct ip_buf {
|
||||||
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_llao)
|
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_llao)
|
||||||
#define uip_nd6_ipaddr(buf) \
|
#define uip_nd6_ipaddr(buf) \
|
||||||
(((struct ip_buf *)net_buf_user_data((buf)))->ipaddr)
|
(((struct ip_buf *)net_buf_user_data((buf)))->ipaddr)
|
||||||
|
#define uip_compressed_hdr_len(buf) \
|
||||||
|
(((struct ip_buf *)net_buf_user_data((buf)))->compressed_hdr_len)
|
||||||
|
#define uip_uncompressed_hdr_len(buf) \
|
||||||
|
(((struct ip_buf *)net_buf_user_data((buf)))->uncompressed_hdr_len)
|
||||||
|
#define uip_first_frag_len(buf) \
|
||||||
|
(((struct ip_buf *)net_buf_user_data((buf)))->first_frag_len)
|
||||||
|
#define uip_uncompressed(buf) \
|
||||||
|
(((struct ip_buf *)net_buf_user_data((buf)))->uncompressed)
|
||||||
|
|
||||||
/* These two return only the application data and length without
|
/* These two return only the application data and length without
|
||||||
* IP and UDP header length.
|
* IP and UDP header length.
|
||||||
|
|
|
@ -64,7 +64,7 @@ struct l2_buf {
|
||||||
/* 6LoWPAN pointers */
|
/* 6LoWPAN pointers */
|
||||||
uint8_t *packetbuf_ptr;
|
uint8_t *packetbuf_ptr;
|
||||||
uint8_t packetbuf_hdr_len;
|
uint8_t packetbuf_hdr_len;
|
||||||
int packetbuf_payload_len;
|
uint8_t packetbuf_payload_len;
|
||||||
uint8_t uncomp_hdr_len;
|
uint8_t uncomp_hdr_len;
|
||||||
int last_tx_status;
|
int last_tx_status;
|
||||||
#if defined(CONFIG_NETWORKING_WITH_15_4)
|
#if defined(CONFIG_NETWORKING_WITH_15_4)
|
||||||
|
|
|
@ -831,11 +831,15 @@ uncompress_hdr_iphc(struct net_buf *mbuf, struct net_buf *ibuf)
|
||||||
|
|
||||||
uip_packetbuf_hdr_len(mbuf) = iphc_ptr - uip_packetbuf_ptr(mbuf);
|
uip_packetbuf_hdr_len(mbuf) = iphc_ptr - uip_packetbuf_ptr(mbuf);
|
||||||
|
|
||||||
ip_len = uip_len(ibuf) + (uip_uncomp_hdr_len(mbuf) -
|
if(uip_first_frag_len(ibuf) > 0) {
|
||||||
uip_packetbuf_hdr_len(mbuf)) - UIP_IPH_LEN;
|
ip_len = uip_len(ibuf) - UIP_IPH_LEN;
|
||||||
/* This is not a fragmented packet */
|
} else {
|
||||||
SICSLOWPAN_IP_BUF(buf)->len[0] = ip_len >> 8;
|
ip_len = uip_len(ibuf) + uip_uncomp_hdr_len(mbuf) -
|
||||||
SICSLOWPAN_IP_BUF(buf)->len[1] = ip_len & 0x00FF;
|
uip_packetbuf_hdr_len(mbuf) - UIP_IPH_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
SICSLOWPAN_IP_BUF(buf)->len[0] = ip_len >> 8;
|
||||||
|
SICSLOWPAN_IP_BUF(buf)->len[1] = ip_len & 0x00FF;
|
||||||
|
|
||||||
/* length field in UDP header */
|
/* length field in UDP header */
|
||||||
if(SICSLOWPAN_IP_BUF(buf)->proto == UIP_PROTO_UDP) {
|
if(SICSLOWPAN_IP_BUF(buf)->proto == UIP_PROTO_UDP) {
|
||||||
|
@ -871,7 +875,9 @@ compress_hdr_ipv6(struct net_buf *buf)
|
||||||
memmove(uip_buf(buf) + SICSLOWPAN_IPV6_HDR_LEN, uip_buf(buf), uip_len(buf));
|
memmove(uip_buf(buf) + SICSLOWPAN_IPV6_HDR_LEN, uip_buf(buf), uip_len(buf));
|
||||||
*uip_buf(buf) = SICSLOWPAN_DISPATCH_IPV6;
|
*uip_buf(buf) = SICSLOWPAN_DISPATCH_IPV6;
|
||||||
uip_len(buf)++;
|
uip_len(buf)++;
|
||||||
buf->len++;
|
ip_buf_len(buf)++;
|
||||||
|
uip_compressed_hdr_len(buf) = UIP_IPH_LEN + SICSLOWPAN_IPV6_HDR_LEN;
|
||||||
|
uip_uncompressed_hdr_len(buf) = UIP_IPH_LEN;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -881,7 +887,7 @@ static int
|
||||||
uncompress_hdr_ipv6(struct net_buf *buf)
|
uncompress_hdr_ipv6(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
uip_len(buf)--;
|
uip_len(buf)--;
|
||||||
buf->len--;
|
ip_buf_len(buf)--;
|
||||||
memmove(uip_buf(buf), uip_buf(buf) + SICSLOWPAN_IPV6_HDR_LEN, uip_len(buf));
|
memmove(uip_buf(buf), uip_buf(buf) + SICSLOWPAN_IPV6_HDR_LEN, uip_len(buf));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -946,7 +952,9 @@ static int compress(struct net_buf *buf)
|
||||||
memmove(uip_buf(buf) + uip_packetbuf_hdr_len(mbuf),
|
memmove(uip_buf(buf) + uip_packetbuf_hdr_len(mbuf),
|
||||||
uip_buf(buf) + uip_uncomp_hdr_len(mbuf), uip_len(buf) - uip_uncomp_hdr_len(mbuf));
|
uip_buf(buf) + uip_uncomp_hdr_len(mbuf), uip_len(buf) - uip_uncomp_hdr_len(mbuf));
|
||||||
uip_len(buf) -= hdr_diff;
|
uip_len(buf) -= hdr_diff;
|
||||||
buf->len -= hdr_diff;
|
ip_buf_len(buf) -= hdr_diff;
|
||||||
|
uip_compressed_hdr_len(buf) = uip_packetbuf_hdr_len(mbuf);
|
||||||
|
uip_uncompressed_hdr_len(buf) = uip_uncomp_hdr_len(mbuf);
|
||||||
packetbuf_clear(mbuf);
|
packetbuf_clear(mbuf);
|
||||||
l2_buf_unref(mbuf);
|
l2_buf_unref(mbuf);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1004,12 +1012,30 @@ static int uncompress(struct net_buf *buf)
|
||||||
uip_len(buf), uip_packetbuf_hdr_len(mbuf));
|
uip_len(buf), uip_packetbuf_hdr_len(mbuf));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
memmove(uip_buf(buf) + uip_uncomp_hdr_len(mbuf),
|
|
||||||
|
#if defined(CONFIG_NETWORKING_WITH_15_4)
|
||||||
|
if (uip_first_frag_len(buf) > 0) {
|
||||||
|
memmove(uip_buf(buf) + uip_uncomp_hdr_len(mbuf),
|
||||||
|
uip_buf(buf) + uip_packetbuf_hdr_len(mbuf),
|
||||||
|
uip_first_frag_len(buf) - uip_packetbuf_hdr_len(mbuf));
|
||||||
|
memcpy(uip_buf(buf), uip_packetbuf_ptr(mbuf), uip_uncomp_hdr_len(mbuf));
|
||||||
|
ip_buf_len(buf) = uip_len(buf);
|
||||||
|
} else {
|
||||||
|
memmove(uip_buf(buf) + uip_uncomp_hdr_len(mbuf),
|
||||||
uip_buf(buf) + uip_packetbuf_hdr_len(mbuf),
|
uip_buf(buf) + uip_packetbuf_hdr_len(mbuf),
|
||||||
uip_len(buf) - uip_packetbuf_hdr_len(mbuf));
|
uip_len(buf) - uip_packetbuf_hdr_len(mbuf));
|
||||||
memcpy(uip_buf(buf), uip_packetbuf_ptr(mbuf), uip_uncomp_hdr_len(mbuf));
|
memcpy(uip_buf(buf), uip_packetbuf_ptr(mbuf), uip_uncomp_hdr_len(mbuf));
|
||||||
uip_len(buf) += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf));
|
uip_len(buf) += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf));
|
||||||
buf->len += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf));
|
ip_buf_len(buf) += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf));
|
||||||
|
}
|
||||||
|
#elif defined(CONFIG_NETWORKING_WITH_BT)
|
||||||
|
memmove(uip_buf(buf) + uip_uncomp_hdr_len(mbuf),
|
||||||
|
uip_buf(buf) + uip_packetbuf_hdr_len(mbuf),
|
||||||
|
uip_len(buf) - uip_packetbuf_hdr_len(mbuf));
|
||||||
|
memcpy(uip_buf(buf), uip_packetbuf_ptr(mbuf), uip_uncomp_hdr_len(mbuf));
|
||||||
|
uip_len(buf) += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf));
|
||||||
|
ip_buf_len(buf) += (uip_uncomp_hdr_len(mbuf) - uip_packetbuf_hdr_len(mbuf));
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
l2_buf_unref(mbuf);
|
l2_buf_unref(mbuf);
|
||||||
|
|
|
@ -145,6 +145,8 @@ void uip_log(char *msg);
|
||||||
#define MAC_MAX_PAYLOAD (127 - 2)
|
#define MAC_MAX_PAYLOAD (127 - 2)
|
||||||
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
|
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
|
||||||
|
|
||||||
|
#define SICSLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */
|
||||||
|
|
||||||
static int last_rssi;
|
static int last_rssi;
|
||||||
|
|
||||||
/** Datagram tag to be put in the fragments I send. */
|
/** Datagram tag to be put in the fragments I send. */
|
||||||
|
@ -188,6 +190,8 @@ struct sicslowpan_frag_info {
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
/** Current length of reassembled fragments */
|
/** Current length of reassembled fragments */
|
||||||
uint16_t reassembled_len;
|
uint16_t reassembled_len;
|
||||||
|
/** Last fragment */
|
||||||
|
uint8_t last_fragment;
|
||||||
/** Reassembly %process %timer. */
|
/** Reassembly %process %timer. */
|
||||||
struct timer reass_timer;
|
struct timer reass_timer;
|
||||||
};
|
};
|
||||||
|
@ -237,7 +241,7 @@ store_fragment(struct net_buf *mbuf, uint8_t index, uint8_t offset)
|
||||||
memcpy(frag_buf[i].data, uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf),
|
memcpy(frag_buf[i].data, uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf),
|
||||||
packetbuf_datalen(mbuf) - uip_packetbuf_hdr_len(mbuf));
|
packetbuf_datalen(mbuf) - uip_packetbuf_hdr_len(mbuf));
|
||||||
|
|
||||||
PRINTF("Fragsize: %d\n", frag_buf[i].len);
|
PRINTF("Fragment payload length: %d\n", frag_buf[i].len);
|
||||||
/* return the length of the stored fragment */
|
/* return the length of the stored fragment */
|
||||||
return frag_buf[i].len;
|
return frag_buf[i].len;
|
||||||
}
|
}
|
||||||
|
@ -309,6 +313,11 @@ store:
|
||||||
len = store_fragment(mbuf, i, offset);
|
len = store_fragment(mbuf, i, offset);
|
||||||
if(len > 0) {
|
if(len > 0) {
|
||||||
frag_info[i].reassembled_len += len;
|
frag_info[i].reassembled_len += len;
|
||||||
|
if((offset << 3)+ len >= frag_size) {
|
||||||
|
frag_info[i].last_fragment = 1;
|
||||||
|
} else {
|
||||||
|
frag_info[i].last_fragment = 0;
|
||||||
|
}
|
||||||
return i;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
/* should we also clear all fragments since we failed to store this fragment? */
|
/* should we also clear all fragments since we failed to store this fragment? */
|
||||||
|
@ -334,6 +343,16 @@ static struct net_buf *copy_frags2uip(int context)
|
||||||
linkaddr_copy(&ip_buf_ll_src(buf), &frag_info[context].sender);
|
linkaddr_copy(&ip_buf_ll_src(buf), &frag_info[context].sender);
|
||||||
|
|
||||||
for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
|
for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
|
||||||
|
if(i == 0) {
|
||||||
|
uip_first_frag_len(buf) = frag_buf[i].len;
|
||||||
|
if(frag_buf[i].data[0] == SICSLOWPAN_DISPATCH_IPV6) {
|
||||||
|
memmove(frag_buf[i].data, frag_buf[i].data + 1, frag_buf[i].len - 1);
|
||||||
|
frag_buf[i].len -= 1;
|
||||||
|
uip_uncompressed(buf) = 1;
|
||||||
|
} else {
|
||||||
|
uip_uncompressed(buf) = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* And also copy all matching fragments */
|
/* And also copy all matching fragments */
|
||||||
if(frag_buf[i].len > 0 && frag_buf[i].index == context) {
|
if(frag_buf[i].len > 0 && frag_buf[i].index == context) {
|
||||||
memcpy(uip_buf(buf) + (uint16_t)(frag_buf[i].offset << 3),
|
memcpy(uip_buf(buf) + (uint16_t)(frag_buf[i].offset << 3),
|
||||||
|
@ -377,6 +396,8 @@ static struct net_buf *copy_buf(struct net_buf *mbuf)
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uip_first_frag_len(buf) = 0;
|
||||||
|
uip_uncompressed(buf) = 0;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,7 +450,8 @@ static int fragment(struct net_buf *buf, void *ptr)
|
||||||
int max_payload;
|
int max_payload;
|
||||||
int framer_hdrlen;
|
int framer_hdrlen;
|
||||||
uint16_t frag_tag;
|
uint16_t frag_tag;
|
||||||
|
uint16_t frag_offset;
|
||||||
|
int hdr_diff;
|
||||||
/* Number of bytes processed. */
|
/* Number of bytes processed. */
|
||||||
uint16_t processed_ip_out_len;
|
uint16_t processed_ip_out_len;
|
||||||
struct net_buf *mbuf;
|
struct net_buf *mbuf;
|
||||||
|
@ -486,7 +508,7 @@ static int fragment(struct net_buf *buf, void *ptr)
|
||||||
* IPv6/HC1/HC06/HC_UDP dispatchs/headers.
|
* IPv6/HC1/HC06/HC_UDP dispatchs/headers.
|
||||||
* The following fragments contain only the fragn dispatch.
|
* The following fragments contain only the fragn dispatch.
|
||||||
*/
|
*/
|
||||||
int estimated_fragments = ((int)uip_len(buf)) / ((int)MAC_MAX_PAYLOAD - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
|
int estimated_fragments = ((int)uip_len(buf)) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
|
||||||
int freebuf = queuebuf_numfree(mbuf) - 1;
|
int freebuf = queuebuf_numfree(mbuf) - 1;
|
||||||
PRINTF("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len(buf), estimated_fragments, freebuf);
|
PRINTF("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len(buf), estimated_fragments, freebuf);
|
||||||
if(freebuf < estimated_fragments) {
|
if(freebuf < estimated_fragments) {
|
||||||
|
@ -494,23 +516,28 @@ static int fragment(struct net_buf *buf, void *ptr)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdr_diff = uip_uncompressed_hdr_len(buf) - uip_compressed_hdr_len(buf);
|
||||||
|
PRINTF("fragment: hdr difference %d\n", hdr_diff);
|
||||||
/* Create 1st Fragment */
|
/* Create 1st Fragment */
|
||||||
SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE,
|
SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE,
|
||||||
((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len(buf)));
|
((SICSLOWPAN_DISPATCH_FRAG1 << 8) | (uip_len(buf) + hdr_diff)));
|
||||||
|
|
||||||
frag_tag = my_tag++;
|
frag_tag = my_tag++;
|
||||||
SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_TAG, frag_tag);
|
SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_TAG, frag_tag);
|
||||||
PRINTF("fragmentation: fragment %d \n", frag_tag);
|
PRINTF("fragment: tag %d \n", frag_tag);
|
||||||
|
|
||||||
/* Copy payload and send */
|
/* Copy payload and send */
|
||||||
|
uip_packetbuf_hdr_len(mbuf) = uip_compressed_hdr_len(buf);
|
||||||
uip_packetbuf_hdr_len(mbuf) += SICSLOWPAN_FRAG1_HDR_LEN;
|
uip_packetbuf_hdr_len(mbuf) += SICSLOWPAN_FRAG1_HDR_LEN;
|
||||||
uip_packetbuf_payload_len(mbuf) = (max_payload - uip_packetbuf_hdr_len(mbuf)) & 0xfffffff8;
|
uip_packetbuf_payload_len(mbuf) = (max_payload - uip_packetbuf_hdr_len(mbuf)) & 0xf8;
|
||||||
PRINTF("(payload len %d, hdr len %d, tag %d)\n",
|
PRINTF("fragment: payload len %d, hdr len %d, tag %d\n",
|
||||||
uip_packetbuf_payload_len(mbuf), uip_packetbuf_hdr_len(mbuf), frag_tag);
|
uip_packetbuf_payload_len(mbuf), uip_packetbuf_hdr_len(mbuf), frag_tag);
|
||||||
|
|
||||||
memcpy(uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf),
|
memcpy(uip_packetbuf_ptr(mbuf) + SICSLOWPAN_FRAG1_HDR_LEN,
|
||||||
uip_buf(buf), uip_packetbuf_payload_len(mbuf));
|
uip_buf(buf), uip_packetbuf_payload_len(mbuf) +
|
||||||
|
uip_packetbuf_hdr_len(mbuf));
|
||||||
packetbuf_set_datalen(mbuf, uip_packetbuf_payload_len(mbuf) + uip_packetbuf_hdr_len(mbuf));
|
packetbuf_set_datalen(mbuf, uip_packetbuf_payload_len(mbuf) + uip_packetbuf_hdr_len(mbuf));
|
||||||
|
PRINTF("fragment: packetbuf_datalen %d\n", packetbuf_datalen(mbuf));
|
||||||
q = queuebuf_new_from_packetbuf(mbuf);
|
q = queuebuf_new_from_packetbuf(mbuf);
|
||||||
if(q == NULL) {
|
if(q == NULL) {
|
||||||
PRINTF("could not allocate queuebuf for first fragment, dropping packet\n");
|
PRINTF("could not allocate queuebuf for first fragment, dropping packet\n");
|
||||||
|
@ -531,8 +558,7 @@ static int fragment(struct net_buf *buf, void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set processed_ip_out_len to what we already sent from the IP payload*/
|
/* set processed_ip_out_len to what we already sent from the IP payload*/
|
||||||
processed_ip_out_len = uip_packetbuf_payload_len(mbuf);
|
processed_ip_out_len = uip_packetbuf_payload_len(mbuf) + uip_compressed_hdr_len(buf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create following fragments
|
* Create following fragments
|
||||||
* Datagram tag is already in the buffer, we need to set the
|
* Datagram tag is already in the buffer, we need to set the
|
||||||
|
@ -540,24 +566,25 @@ static int fragment(struct net_buf *buf, void *ptr)
|
||||||
*/
|
*/
|
||||||
uip_packetbuf_hdr_len(mbuf) = SICSLOWPAN_FRAGN_HDR_LEN;
|
uip_packetbuf_hdr_len(mbuf) = SICSLOWPAN_FRAGN_HDR_LEN;
|
||||||
SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE,
|
SET16(uip_packetbuf_ptr(mbuf), PACKETBUF_FRAG_DISPATCH_SIZE,
|
||||||
((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len(buf)));
|
((SICSLOWPAN_DISPATCH_FRAGN << 8) | (uip_len(buf) + hdr_diff)));
|
||||||
uip_packetbuf_payload_len(mbuf) = (max_payload - uip_packetbuf_hdr_len(mbuf)) & 0xfffffff8;
|
uip_packetbuf_payload_len(mbuf) = (max_payload - uip_packetbuf_hdr_len(mbuf)) & 0xf8;
|
||||||
|
|
||||||
while(processed_ip_out_len < uip_len(buf)) {
|
while(processed_ip_out_len < uip_len(buf)) {
|
||||||
PRINTF("fragmentation: fragment:%d, processed_ip_out_len:%d \n", my_tag, processed_ip_out_len);
|
PRINTF("fragment: tag:%d, processed_ip_out_len:%d \n", frag_tag, processed_ip_out_len);
|
||||||
uip_packetbuf_ptr(mbuf)[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
|
frag_offset = processed_ip_out_len + hdr_diff;
|
||||||
|
uip_packetbuf_ptr(mbuf)[PACKETBUF_FRAG_OFFSET] = frag_offset >> 3;
|
||||||
/* Copy payload and send */
|
/* Copy payload and send */
|
||||||
if(uip_len(buf) - processed_ip_out_len < uip_packetbuf_payload_len(mbuf)) {
|
if(uip_len(buf) - processed_ip_out_len < uip_packetbuf_payload_len(mbuf)) {
|
||||||
/* last fragment */
|
/* last fragment */
|
||||||
last_fragment = true;
|
last_fragment = true;
|
||||||
uip_packetbuf_payload_len(mbuf) = uip_len(buf) - processed_ip_out_len;
|
uip_packetbuf_payload_len(mbuf) = uip_len(buf) - processed_ip_out_len;
|
||||||
}
|
}
|
||||||
PRINTF("(offset %d, len %d, tag %d)\n",
|
PRINTF("fragment: offset %d, len %d, tag %d\n",
|
||||||
processed_ip_out_len >> 3, uip_packetbuf_payload_len(mbuf), my_tag);
|
frag_offset, uip_packetbuf_payload_len(mbuf), frag_tag);
|
||||||
memcpy(uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf),
|
memcpy(uip_packetbuf_ptr(mbuf) + uip_packetbuf_hdr_len(mbuf),
|
||||||
(uint8_t *)UIP_IP_BUF(buf) + processed_ip_out_len, uip_packetbuf_payload_len(mbuf));
|
(uint8_t *)UIP_IP_BUF(buf) + processed_ip_out_len, uip_packetbuf_payload_len(mbuf));
|
||||||
packetbuf_set_datalen(mbuf, uip_packetbuf_payload_len(mbuf) + uip_packetbuf_hdr_len(mbuf));
|
packetbuf_set_datalen(mbuf, uip_packetbuf_payload_len(mbuf) + uip_packetbuf_hdr_len(mbuf));
|
||||||
|
PRINTF("fragment: packetbuf_datalen %d\n", packetbuf_datalen(mbuf));
|
||||||
q = queuebuf_new_from_packetbuf(mbuf);
|
q = queuebuf_new_from_packetbuf(mbuf);
|
||||||
if(q == NULL) {
|
if(q == NULL) {
|
||||||
PRINTF("could not allocate queuebuf, dropping fragment\n");
|
PRINTF("could not allocate queuebuf, dropping fragment\n");
|
||||||
|
@ -667,7 +694,8 @@ static int reassemble(struct net_buf *mbuf)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(frag_info[frag_context].reassembled_len >= frag_size) {
|
if(frag_info[frag_context].reassembled_len >= frag_size
|
||||||
|
|| frag_info[frag_context].last_fragment) {
|
||||||
last_fragment = 1;
|
last_fragment = 1;
|
||||||
}
|
}
|
||||||
is_fragment = 1;
|
is_fragment = 1;
|
||||||
|
|
|
@ -189,8 +189,10 @@ int net_driver_15_4_init(void)
|
||||||
|
|
||||||
int net_driver_15_4_recv(struct net_buf *buf)
|
int net_driver_15_4_recv(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
if (!NETSTACK_COMPRESS.uncompress(buf)) {
|
if (!uip_uncompressed(buf)) {
|
||||||
return -EINVAL;
|
if (!NETSTACK_COMPRESS.uncompress(buf)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (net_recv(buf) < 0) {
|
if (net_recv(buf) < 0) {
|
||||||
|
|
|
@ -101,6 +101,7 @@ static void ipsp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
|
||||||
|
|
||||||
/* Initialize uip_len */
|
/* Initialize uip_len */
|
||||||
uip_len(buf) = ip_buf_len(buf);
|
uip_len(buf) = ip_buf_len(buf);
|
||||||
|
uip_first_frag_len(buf) = 0;
|
||||||
|
|
||||||
/* Uncompress data */
|
/* Uncompress data */
|
||||||
if (!NETSTACK_COMPRESS.uncompress(buf)) {
|
if (!NETSTACK_COMPRESS.uncompress(buf)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue