mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +00:00
lowpan6_common.c: add comments from ble version
This commit is contained in:
parent
a4b9beef04
commit
ac03107036
@ -90,4 +90,17 @@
|
||||
#define LWIP_LOWPAN6_802154_DEBUG LWIP_DBG_OFF
|
||||
#endif
|
||||
|
||||
/** LWIP_LOWPAN6_IP_COMPRESSED_DEBUG: enable compressed IP frame
|
||||
* output debugging
|
||||
*/
|
||||
#ifndef LWIP_LOWPAN6_IP_COMPRESSED_DEBUG
|
||||
#define LWIP_LOWPAN6_IP_COMPRESSED_DEBUG LWIP_DBG_OFF
|
||||
#endif
|
||||
|
||||
/** LWIP_LOWPAN6_DECOMPRESSION_DEBUG: enable decompression debug output
|
||||
*/
|
||||
#ifndef LWIP_LOWPAN6_DECOMPRESSION_DEBUG
|
||||
#define LWIP_LOWPAN6_DECOMPRESSION_DEBUG LWIP_DBG_OFF
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_HDR_LOWPAN6_OPTS_H */
|
||||
|
@ -398,6 +398,7 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
u16_t lowpan6_offset;
|
||||
struct ip6_hdr *ip6hdr;
|
||||
s8_t i;
|
||||
u32_t header_temp;
|
||||
u16_t ip6_offset = IP6_HLEN;
|
||||
|
||||
LWIP_ASSERT("lowpan6_buffer != NULL", lowpan6_buffer != NULL);
|
||||
@ -412,84 +413,143 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
/* output the full compressed packet, if set in @see lowpan6_opts.h */
|
||||
#if LWIP_LOWPAN6_IP_COMPRESSED_DEBUG
|
||||
{
|
||||
u16_t j;
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("lowpan6_decompress_hdr: IP6 payload (compressed): \n"));
|
||||
for (j = 0; j < lowpan6_bufsize; j++) {
|
||||
if ((j % 4) == 0) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("\n"));
|
||||
}
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("%2X ", lowpan6_buffer[j]));
|
||||
}
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("\np->len: %d", lowpan6_bufsize));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* offset for inline IP headers (RFC 6282 ch3)*/
|
||||
lowpan6_offset = 2;
|
||||
/* if CID is set (context identifier), the context byte
|
||||
* follows immediately after the header, so other IPHC fields are @+3 */
|
||||
if (lowpan6_buffer[1] & 0x80) {
|
||||
lowpan6_offset++;
|
||||
}
|
||||
|
||||
/* Set IPv6 version, traffic class and flow label. */
|
||||
/* Set IPv6 version, traffic class and flow label. (RFC6282, ch 3.1.1.)*/
|
||||
if ((lowpan6_buffer[0] & 0x18) == 0x00) {
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset], ((lowpan6_buffer[lowpan6_offset + 1] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset + 3]);
|
||||
header_temp = ((lowpan6_buffer[lowpan6_offset+1] & 0x0f) << 16) | \
|
||||
(lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset+3];
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 00, ECN: 0x%2x, Flowlabel+DSCP: 0x%8X\n", \
|
||||
lowpan6_buffer[lowpan6_offset],header_temp));
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset], header_temp);
|
||||
/* increase offset, processed 4 bytes here:
|
||||
* TF=00: ECN + DSCP + 4-bit Pad + Flow Label (4 bytes)*/
|
||||
lowpan6_offset += 4;
|
||||
} else if ((lowpan6_buffer[0] & 0x18) == 0x08) {
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset] & 0xc0, ((lowpan6_buffer[lowpan6_offset] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset + 2]);
|
||||
header_temp = ((lowpan6_buffer[lowpan6_offset] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset+2];
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 01, ECN: 0x%2x, Flowlabel: 0x%2X, DSCP ignored\n", \
|
||||
lowpan6_buffer[lowpan6_offset] & 0xc0,header_temp));
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset] & 0xc0, header_temp);
|
||||
/* increase offset, processed 3 bytes here:
|
||||
* TF=01: ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided.*/
|
||||
lowpan6_offset += 3;
|
||||
} else if ((lowpan6_buffer[0] & 0x18) == 0x10) {
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset], 0);
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 10, DCSP+ECN: 0x%2x, Flowlabel ignored\n", lowpan6_buffer[lowpan6_offset]));
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset],0);
|
||||
/* increase offset, processed 1 byte here:
|
||||
* ECN + DSCP (1 byte), Flow Label is elided.*/
|
||||
lowpan6_offset += 1;
|
||||
} else if ((lowpan6_buffer[0] & 0x18) == 0x18) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 11, DCSP/ECN & Flowlabel ignored\n"));
|
||||
/* don't increase offset, no bytes processed here */
|
||||
IP6H_VTCFL_SET(ip6hdr, 6, 0, 0);
|
||||
}
|
||||
|
||||
/* Set Next Header */
|
||||
/* Set Next Header (NH) */
|
||||
if ((lowpan6_buffer[0] & 0x04) == 0x00) {
|
||||
/* 0: full next header byte carried inline (increase offset)*/
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NH: 0x%2X\n", lowpan6_buffer[lowpan6_offset+1]));
|
||||
IP6H_NEXTH_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]);
|
||||
} else {
|
||||
/* 1: NH compression, LOWPAN_NHC (RFC6282, ch 4.1) */
|
||||
/* We should fill this later with NHC decoding */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NH: skipped, later done with NHC\n"));
|
||||
IP6H_NEXTH_SET(ip6hdr, 0);
|
||||
}
|
||||
|
||||
/* Set Hop Limit */
|
||||
/* Set Hop Limit, either carried inline or 3 different hops (1,64,255) */
|
||||
if ((lowpan6_buffer[0] & 0x03) == 0x00) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: full value: %d\n", lowpan6_buffer[lowpan6_offset+1]));
|
||||
IP6H_HOPLIM_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]);
|
||||
} else if ((lowpan6_buffer[0] & 0x03) == 0x01) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: compressed: 1\n"));
|
||||
IP6H_HOPLIM_SET(ip6hdr, 1);
|
||||
} else if ((lowpan6_buffer[0] & 0x03) == 0x02) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: compressed: 64\n"));
|
||||
IP6H_HOPLIM_SET(ip6hdr, 64);
|
||||
} else if ((lowpan6_buffer[0] & 0x03) == 0x03) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: compressed: 255\n"));
|
||||
IP6H_HOPLIM_SET(ip6hdr, 255);
|
||||
}
|
||||
|
||||
/* Source address decoding. */
|
||||
if ((lowpan6_buffer[1] & 0x40) == 0x00) {
|
||||
/* Source address compression (SAC) = 0 -> stateless compression */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAC == 0, no context byte\n"));
|
||||
/* Stateless compression */
|
||||
if ((lowpan6_buffer[1] & 0x30) == 0x00) {
|
||||
/* copy full address */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 00, no src compression, fetching 128bits inline\n"));
|
||||
/* copy full address, increase offset by 16 Bytes */
|
||||
MEMCPY(&ip6hdr->src.addr[0], lowpan6_buffer + lowpan6_offset, 16);
|
||||
lowpan6_offset += 16;
|
||||
} else if ((lowpan6_buffer[1] & 0x30) == 0x10) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 01, src compression, 64bits inline\n"));
|
||||
/* set 64 bits to link local */
|
||||
ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL);
|
||||
ip6hdr->src.addr[1] = 0;
|
||||
/* copy 8 Bytes, increase offset */
|
||||
MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8);
|
||||
lowpan6_offset += 8;
|
||||
} else if ((lowpan6_buffer[1] & 0x30) == 0x20) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 10, src compression, 16bits inline\n"));
|
||||
/* set 96 bits to link local */
|
||||
ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL);
|
||||
ip6hdr->src.addr[1] = 0;
|
||||
ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
|
||||
/* extract remaining 16bits from inline bytes, increase offset */
|
||||
ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) |
|
||||
lowpan6_buffer[lowpan6_offset + 1]);
|
||||
lowpan6_offset += 2;
|
||||
} else if ((lowpan6_buffer[1] & 0x30) == 0x30) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 11, src compression, 0bits inline, using other headers\n"));
|
||||
/* no information avalaible, using other layers, see RFC6282 ch 3.2.2 */
|
||||
ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL);
|
||||
ip6hdr->src.addr[1] = 0;
|
||||
if (src->addr_len == 2) {
|
||||
ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
|
||||
ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]);
|
||||
} else {
|
||||
} else if (src->addr_len == 8) {
|
||||
ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) |
|
||||
(src->addr[2] << 8) | src->addr[3]);
|
||||
ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) |
|
||||
(src->addr[6] << 8) | src->addr[7]);
|
||||
} else {
|
||||
/* invalid source address length */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Invalid source address length\n"));
|
||||
return ERR_VAL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Stateful compression */
|
||||
/* Source address compression (SAC) = 1 -> stateful/context-based compression */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAC == 1, additional context byte\n"));
|
||||
if ((lowpan6_buffer[1] & 0x30) == 0x00) {
|
||||
/* ANY address */
|
||||
/* SAM=00, address=> :: (ANY) */
|
||||
ip6hdr->src.addr[0] = 0;
|
||||
ip6hdr->src.addr[1] = 0;
|
||||
ip6hdr->src.addr[2] = 0;
|
||||
ip6hdr->src.addr[3] = 0;
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 00, context compression, ANY (::)\n"));
|
||||
} else {
|
||||
/* Set prefix from context info */
|
||||
if (lowpan6_buffer[1] & 0x80) {
|
||||
@ -504,54 +564,75 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
|
||||
ip6hdr->src.addr[0] = lowpan6_contexts[i].addr[0];
|
||||
ip6hdr->src.addr[1] = lowpan6_contexts[i].addr[1];
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == xx, context compression found @%d: %8X, %8X\n", (int)i, ip6hdr->src.addr[0], ip6hdr->src.addr[1]));
|
||||
#else
|
||||
LWIP_UNUSED_ARG(lowpan6_contexts);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* determine further address bits */
|
||||
if ((lowpan6_buffer[1] & 0x30) == 0x10) {
|
||||
/* SAM=01, load additional 64bits */
|
||||
MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8);
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 01, context compression, 64bits inline\n"));
|
||||
lowpan6_offset += 8;
|
||||
} else if ((lowpan6_buffer[1] & 0x30) == 0x20) {
|
||||
/* SAM=01, load additional 16bits */
|
||||
ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
|
||||
ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset + 1]);
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 10, context compression, 16bits inline\n"));
|
||||
lowpan6_offset += 2;
|
||||
} else if ((lowpan6_buffer[1] & 0x30) == 0x30) {
|
||||
/* SAM=11, address is fully elided, load from other layers */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 11, context compression, 0bits inline, using other headers\n"));
|
||||
if (src->addr_len == 2) {
|
||||
ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
|
||||
ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]);
|
||||
} else {
|
||||
} else if (src->addr_len == 8) {
|
||||
ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) | (src->addr[2] << 8) | src->addr[3]);
|
||||
ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) | (src->addr[6] << 8) | src->addr[7]);
|
||||
} else {
|
||||
/* invalid source address length */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Invalid source address length\n"));
|
||||
return ERR_VAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Destination address decoding. */
|
||||
if (lowpan6_buffer[1] & 0x08) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("M=1: multicast\n"));
|
||||
/* Multicast destination */
|
||||
if (lowpan6_buffer[1] & 0x04) {
|
||||
LWIP_DEBUGF(LWIP_DBG_ON,("DAC == 1, context multicast: unsupported!!!\n"));
|
||||
/* @todo support stateful multicast addressing */
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
if ((lowpan6_buffer[1] & 0x03) == 0x00) {
|
||||
/* copy full address */
|
||||
/* DAM = 00, copy full address (128bits) */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 00, no dst compression, fetching 128bits inline\n"));
|
||||
MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16);
|
||||
lowpan6_offset += 16;
|
||||
} else if ((lowpan6_buffer[1] & 0x03) == 0x01) {
|
||||
/* DAM = 01, copy 4 bytes (32bits) */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 01, dst address form (48bits): ffXX::00XX:XXXX:XXXX\n"));
|
||||
ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | (lowpan6_buffer[lowpan6_offset++] << 16));
|
||||
ip6hdr->dest.addr[1] = 0;
|
||||
ip6hdr->dest.addr[2] = lwip_htonl(lowpan6_buffer[lowpan6_offset++]);
|
||||
ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 24) | (lowpan6_buffer[lowpan6_offset + 1] << 16) | (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset + 3]);
|
||||
lowpan6_offset += 4;
|
||||
} else if ((lowpan6_buffer[1] & 0x03) == 0x02) {
|
||||
/* DAM = 10, copy 3 bytes (24bits) */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 10, dst address form (32bits): ffXX::00XX:XXXX\n"));
|
||||
ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | (lowpan6_buffer[lowpan6_offset++] << 16));
|
||||
ip6hdr->dest.addr[1] = 0;
|
||||
ip6hdr->dest.addr[2] = 0;
|
||||
ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset + 2]);
|
||||
lowpan6_offset += 3;
|
||||
} else if ((lowpan6_buffer[1] & 0x03) == 0x03) {
|
||||
/* DAM = 11, copy 1 byte (8bits) */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 11, dst address form (8bits): ff02::00XX\n"));
|
||||
ip6hdr->dest.addr[0] = PP_HTONL(0xff020000UL);
|
||||
ip6hdr->dest.addr[1] = 0;
|
||||
ip6hdr->dest.addr[2] = 0;
|
||||
@ -559,7 +640,9 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
}
|
||||
|
||||
} else {
|
||||
/* no Multicast (M=0) */
|
||||
if (lowpan6_buffer[1] & 0x04) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAC == 1, stateful compression\n"));
|
||||
/* Stateful destination compression */
|
||||
/* Set prefix from context info */
|
||||
if (lowpan6_buffer[1] & 0x80) {
|
||||
@ -576,29 +659,42 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
ip6hdr->dest.addr[1] = lowpan6_contexts[i].addr[1];
|
||||
#endif
|
||||
} else {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAC == 0, stateless compression, setting link local prefix\n"));
|
||||
/* Link local address compression */
|
||||
ip6hdr->dest.addr[0] = PP_HTONL(0xfe800000UL);
|
||||
ip6hdr->dest.addr[1] = 0;
|
||||
}
|
||||
|
||||
/* M=0, DAC=0, determining destination address length via DAM=xx */
|
||||
if ((lowpan6_buffer[1] & 0x03) == 0x00) {
|
||||
/* copy full address */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 00, no dst compression, fetching 128bits inline"));
|
||||
/* DAM=00, copy full address */
|
||||
MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16);
|
||||
lowpan6_offset += 16;
|
||||
} else if ((lowpan6_buffer[1] & 0x03) == 0x01) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 01, dst compression, 64bits inline\n"));
|
||||
/* DAM=01, copy 64 inline bits, increase offset */
|
||||
MEMCPY(&ip6hdr->dest.addr[2], lowpan6_buffer + lowpan6_offset, 8);
|
||||
lowpan6_offset += 8;
|
||||
} else if ((lowpan6_buffer[1] & 0x03) == 0x02) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 01, dst compression, 16bits inline\n"));
|
||||
/* DAM=10, copy 16 inline bits, increase offset */
|
||||
ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL);
|
||||
ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset + 1]);
|
||||
lowpan6_offset += 2;
|
||||
} else if ((lowpan6_buffer[1] & 0x03) == 0x03) {
|
||||
/* DAM=11, no bits available, use other headers (not done here) */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG,("DAM == 01, dst compression, 0bits inline, using other headers\n"));
|
||||
if (dest->addr_len == 2) {
|
||||
ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL);
|
||||
ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (dest->addr[0] << 8) | dest->addr[1]);
|
||||
} else {
|
||||
} else if (dest->addr_len == 8) {
|
||||
ip6hdr->dest.addr[2] = lwip_htonl(((dest->addr[0] ^ 2) << 24) | (dest->addr[1] << 16) | dest->addr[2] << 8 | dest->addr[3]);
|
||||
ip6hdr->dest.addr[3] = lwip_htonl((dest->addr[4] << 24) | (dest->addr[5] << 16) | dest->addr[6] << 8 | dest->addr[7]);
|
||||
} else {
|
||||
/* invalid destination address length */
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Invalid destination address length\n"));
|
||||
return ERR_VAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -606,9 +702,12 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
|
||||
/* Next Header Compression (NHC) decoding? */
|
||||
if (lowpan6_buffer[0] & 0x04) {
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NHC decoding\n"));
|
||||
#if LWIP_UDP
|
||||
if ((lowpan6_buffer[lowpan6_offset] & 0xf8) == 0xf0) {
|
||||
/* NHC: UDP */
|
||||
struct udp_hdr *udphdr;
|
||||
LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NHC: UDP\n"));
|
||||
|
||||
/* UDP compression */
|
||||
IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_UDP);
|
||||
@ -617,12 +716,14 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
/* Checksum decompression */
|
||||
if (lowpan6_buffer[lowpan6_offset] & 0x04) {
|
||||
/* @todo support checksum decompress */
|
||||
LWIP_DEBUGF(LWIP_DBG_ON, ("NHC: UDP chechsum decompression UNSUPPORTED\n"));
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
||||
/* Decompress ports */
|
||||
/* Decompress ports, according to RFC4944 */
|
||||
i = lowpan6_buffer[lowpan6_offset++] & 0x03;
|
||||
if (i == 0) {
|
||||
udphdr->src = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]);
|
||||
@ -653,6 +754,7 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
|
||||
} else
|
||||
#endif /* LWIP_UDP */
|
||||
{
|
||||
LWIP_DEBUGF(LWIP_DBG_ON,("NHC: unsupported protocol!\n"));
|
||||
/* @todo support NHC other than UDP */
|
||||
return ERR_VAL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user