65#include "dev/watchdog.h"
66#include "net/link-stats.h"
71#include "net/ipv6/uipbuf.h"
81#define LOG_MODULE "6LoWPAN"
82#define LOG_LEVEL LOG_LEVEL_6LOWPAN
84#define GET16(ptr,index) (((uint16_t)((ptr)[(index)] << 8)) | ((ptr)[(index) + 1]))
85#define SET16(ptr,index,value) do { \
86 (ptr)[(index)] = ((value) >> 8) & 0xff; \
87 (ptr)[(index) + 1] = (value) & 0xff; \
93#define PACKETBUF_FRAG_PTR (packetbuf_ptr)
94#define PACKETBUF_FRAG_DISPATCH_SIZE 0
95#define PACKETBUF_FRAG_TAG 2
96#define PACKETBUF_FRAG_OFFSET 4
99#define PACKETBUF_IPHC_BUF ((uint8_t *)(packetbuf_ptr + packetbuf_hdr_len))
100#define PACKETBUF_PAYLOAD_END ((uint8_t *)(packetbuf_ptr + mac_max_payload))
102#define PACKETBUF_6LO_PTR (packetbuf_ptr + packetbuf_hdr_len)
103#define PACKETBUF_6LO_DISPATCH 0
104#define PACKETBUF_6LO_ENCODING 1
105#define PACKETBUF_6LO_TTL 2
107#define PACKETBUF_6LO_HC_UDP_PTR (packetbuf_ptr + packetbuf_hdr_len)
108#define PACKETBUF_6LO_HC_UDP_DISPATCH 0
109#define PACKETBUF_6LO_HC_UDP_HC1_ENCODING 1
110#define PACKETBUF_6LO_HC_UDP_UDP_ENCODING 2
111#define PACKETBUF_6LO_HC_UDP_TTL 3
112#define PACKETBUF_6LO_HC_UDP_PORTS 4
113#define PACKETBUF_6LO_HC_UDP_CHKSUM 5
122#define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf)
123#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN])
124#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_IPH_LEN])
126#define UIP_IPPAYLOAD_BUF_POS(pos) (&uip_buf[UIP_IPH_LEN + (pos)])
127#define UIP_UDP_BUF_POS(pos) ((struct uip_udp_hdr *)UIP_IPPAYLOAD_BUF_POS(pos))
128#define UIP_EXT_HDR_LEN 2
133#ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR
134#define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR
137#define COMPRESS_EXT_HDR 1
141#define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP \
142 || x == UIP_PROTO_HBHO \
143 || x == UIP_PROTO_DESTO \
144 || x == UIP_PROTO_ROUTING \
145 || x == UIP_PROTO_FRAG)
147#define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP)
202#if SICSLOWPAN_CONF_FRAG
203static uint16_t my_tag;
209#ifdef SICSLOWPAN_CONF_FRAGMENT_BUFFERS
210#define SICSLOWPAN_FRAGMENT_BUFFERS SICSLOWPAN_CONF_FRAGMENT_BUFFERS
212#define SICSLOWPAN_FRAGMENT_BUFFERS 12
220#ifdef SICSLOWPAN_CONF_REASS_CONTEXTS
221#define SICSLOWPAN_REASS_CONTEXTS SICSLOWPAN_CONF_REASS_CONTEXTS
223#define SICSLOWPAN_REASS_CONTEXTS 2
227#ifdef SICSLOWPAN_CONF_FRAGMENT_SIZE
228#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE
231#define SICSLOWPAN_FRAGMENT_SIZE (127 - 2 - 15)
235#if SICSLOWPAN_FRAGMENT_SIZE > 255
236#error Too large SICSLOWPAN_FRAGMENT_SIZE set.
240#define SICSLOWPAN_FIRST_FRAGMENT_SIZE (SICSLOWPAN_FRAGMENT_SIZE + 38)
243struct sicslowpan_frag_info {
251 uint16_t reassembled_len;
253 struct timer reass_timer;
256 uint16_t first_frag_len;
259 uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE];
262static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS];
264struct sicslowpan_frag_buf {
271 uint8_t data[SICSLOWPAN_FRAGMENT_SIZE];
274static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS];
278clear_fragments(uint8_t frag_info_index)
282 frag_info[frag_info_index].len = 0;
283 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
284 if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) {
294timeout_fragments(
int not_context)
298 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
299 if(frag_info[i].len > 0 && i != not_context &&
302 count += clear_fragments(i);
309store_fragment(uint8_t index, uint8_t offset)
316 if(len <= 0 || len > SICSLOWPAN_FRAGMENT_SIZE) {
321 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
322 if(frag_buf[i].len == 0) {
325 frag_buf[i].offset = offset;
326 frag_buf[i].len = len;
327 frag_buf[i].index = index;
339add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
347 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
349 if(frag_info[i].len > 0 &&
timer_expired(&frag_info[i].reass_timer)) {
354 if(found < 0 && frag_info[i].len == 0) {
362 LOG_WARN(
"reassembly: failed to store new fragment session - tag: %d\n", tag);
367 frag_info[found].len = frag_size;
368 frag_info[found].tag = tag;
370 packetbuf_addr(PACKETBUF_ADDR_SENDER));
378 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
379 if(frag_info[i].tag == tag && frag_info[i].len > 0 &&
380 linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
389 LOG_WARN(
"reassembly: failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
394 len = store_fragment(i, offset);
395 if(len < 0 && timeout_fragments(i) > 0) {
396 len = store_fragment(i, offset);
399 frag_info[i].reassembled_len += len;
404 LOG_WARN(
"reassembly: failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
419 LOG_WARN(
"input: invalid total size of fragments\n");
426 frag_info[
context].first_frag_len);
432 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
434 if(frag_buf[i].len > 0 && frag_buf[i].index ==
context) {
435 if(((
size_t)frag_buf[i].offset << 3) + frag_buf[i].len >
sizeof(
uip_buf)) {
436 LOG_WARN(
"input: invalid fragment offset\n");
440 memcpy((uint8_t *)
UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3),
441 (uint8_t *)frag_buf[i].data, frag_buf[i].len);
456static struct netstack_sniffer *callback = NULL;
459netstack_sniffer_add(
struct netstack_sniffer *s)
465netstack_sniffer_remove(
struct netstack_sniffer *s)
471set_packet_attrs(
void)
475 packetbuf_set_attr(PACKETBUF_ATTR_NETWORK_ID,
UIP_IP_BUF->proto);
479 c = UIP_UDP_BUF_POS(0)->srcport;
480 if(UIP_UDP_BUF_POS(0)->destport < c) {
481 c = UIP_UDP_BUF_POS(0)->destport;
483 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_TCP) {
484 c = UIP_TCP_BUF->srcport;
485 if(UIP_TCP_BUF->destport < c) {
486 c = UIP_TCP_BUF->destport;
488 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
492 packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, c);
502#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
508#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
526const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
533const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
540const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};
543const uint8_t llprefix[] = {0xfe, 0x80};
546static const uint8_t ttl_values[] = {0, 1, 64, 255};
558#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
561 if((addr_contexts[i].used == 1) &&
562 uip_ipaddr_prefixcmp(&addr_contexts[i].prefix,
ipaddr, 64)) {
563 return &addr_contexts[i];
575#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
578 if((addr_contexts[i].used == 1) &&
579 addr_contexts[i].number == number) {
580 return &addr_contexts[i];
588compress_addr_64(uint8_t bitpos, uip_ipaddr_t *
ipaddr,
589 const uip_lladdr_t *lladdr)
614uncompress_addr(uip_ipaddr_t *
ipaddr, uint8_t
const prefix[],
615 uint8_t pref_post_count, uip_lladdr_t *lladdr)
617 uint8_t prefcount = pref_post_count >> 4;
618 uint8_t postcount = pref_post_count & 0x0f;
620 prefcount = prefcount == 15 ? 16 : prefcount;
621 postcount = postcount == 15 ? 16 : postcount;
623 LOG_DBG(
"uncompression: address %d %d ", prefcount, postcount);
626 memcpy(
ipaddr, prefix, prefcount);
628 if(prefcount + postcount < 16) {
629 memset(&
ipaddr->u8[prefcount], 0, 16 - (prefcount + postcount));
633 if(postcount == 2 && prefcount < 11) {
639 }
else if (prefcount > 0) {
685 uint8_t tmp, iphc0, iphc1, *next_hdr, *next_nhc;
687 struct uip_udp_hdr *udp_buf;
689 if(LOG_DBG_ENABLED) {
691 LOG_DBG(
"compression: before (%d): ",
UIP_IP_BUF->len[1]);
692 for(ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
693 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
694 LOG_DBG_(
"%02x", data);
701#define CHECK_BUFFER_SPACE(writelen) do { \
702 if(iphc_ptr + (writelen) >= PACKETBUF_PAYLOAD_END) { \
703 LOG_WARN("Not enough packetbuf space to compress header (%u bytes, %u left). Aborting.\n", \
704 (unsigned)(writelen), (unsigned)(PACKETBUF_PAYLOAD_END - iphc_ptr)); \
714 CHECK_BUFFER_SPACE(38);
723 iphc0 = SICSLOWPAN_DISPATCH_IPHC;
725 PACKETBUF_IPHC_BUF[2] = 0;
740 LOG_DBG(
"compression: dest or src ipaddr - setting CID\n");
741 iphc1 |= SICSLOWPAN_IPHC_CID;
755 tmp = ((tmp & 0x03) << 6) | (tmp >> 2);
760 iphc0 |= SICSLOWPAN_IPHC_FL_C;
764 iphc0 |= SICSLOWPAN_IPHC_TC_C;
775 iphc0 |= SICSLOWPAN_IPHC_TC_C;
792 if(IS_COMPRESSABLE_PROTO(
UIP_IP_BUF->proto)) {
793 iphc0 |= SICSLOWPAN_IPHC_NH_C;
797 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
811 iphc0 |= SICSLOWPAN_IPHC_TTL_1;
814 iphc0 |= SICSLOWPAN_IPHC_TTL_64;
817 iphc0 |= SICSLOWPAN_IPHC_TTL_255;
827 LOG_DBG(
"compression: addr unspecified - setting SAC\n");
828 iphc1 |= SICSLOWPAN_IPHC_SAC;
829 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
833 LOG_DBG(
"compression: src with context - setting CID & SAC ctx: %d\n",
835 iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
836 PACKETBUF_IPHC_BUF[2] |=
context->number << 4;
839 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
846 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
850 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
858 iphc1 |= SICSLOWPAN_IPHC_M;
859 if(sicslowpan_is_mcast_addr_compressable8(&
UIP_IP_BUF->destipaddr)) {
860 iphc1 |= SICSLOWPAN_IPHC_DAM_11;
864 }
else if(sicslowpan_is_mcast_addr_compressable32(&
UIP_IP_BUF->destipaddr)) {
865 iphc1 |= SICSLOWPAN_IPHC_DAM_10;
870 }
else if(sicslowpan_is_mcast_addr_compressable48(&
UIP_IP_BUF->destipaddr)) {
871 iphc1 |= SICSLOWPAN_IPHC_DAM_01;
877 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
886 iphc1 |= SICSLOWPAN_IPHC_DAC;
887 PACKETBUF_IPHC_BUF[2] |=
context->number;
890 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
892 (
const uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
898 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
900 (
const uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
903 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
917 LOG_DBG(
"compression: first header: %d\n", *next_hdr);
918 while(next_hdr != NULL && IS_COMPRESSABLE_PROTO(*next_hdr)) {
919 LOG_DBG(
"compression: next header: %d\n", *next_hdr);
924 proto = SICSLOWPAN_NHC_ETX_HDR_HBHO;
925 case UIP_PROTO_ROUTING:
926 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_ROUTING : proto;
928 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_FRAG : proto;
929 case UIP_PROTO_DESTO:
932 struct uip_ext_hdr *ext_hdr =
933 (
struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF_POS(ext_hdr_len);
935 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
937 len = (ext_hdr->len << 3) + 8;
938 LOG_DBG(
"compression: next header %d (len:%d)\n", *next_hdr, len);
940 next_hdr = &ext_hdr->next;
944 if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
945 CHECK_BUFFER_SPACE(1);
947 LOG_DBG(
"compression: keeping the next header in this ext hdr: %d\n",
951 CHECK_BUFFER_SPACE(len);
954 ext_hdr = (
struct uip_ext_hdr *)
iphc_ptr;
955 ext_hdr->len = len - 2;
962 *next_nhc = SICSLOWPAN_NHC_EXT_HDR |
963 (IS_COMPRESSABLE_PROTO(*next_hdr) ? SICSLOWPAN_NHC_BIT : 0) |
972 udp_buf = UIP_UDP_BUF_POS(ext_hdr_len);
973 LOG_DBG(
"compression: inlined UDP ports on send side: %x, %x\n",
976 if(((
UIP_HTONS(udp_buf->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
977 ((
UIP_HTONS(udp_buf->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
979 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
980 LOG_DBG(
"IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
981 CHECK_BUFFER_SPACE(1);
984 SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
985 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
986 SICSLOWPAN_UDP_4_BIT_PORT_MIN));
988 }
else if((
UIP_HTONS(udp_buf->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
990 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
991 LOG_DBG(
"IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
992 CHECK_BUFFER_SPACE(3);
993 memcpy(
iphc_ptr, &udp_buf->srcport, 2);
995 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
996 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
998 }
else if((
UIP_HTONS(udp_buf->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
1000 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_10;
1001 LOG_DBG(
"IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
1002 CHECK_BUFFER_SPACE(3);
1004 (uint8_t)((
UIP_HTONS(udp_buf->srcport) -
1005 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
1006 memcpy(
iphc_ptr + 1, &udp_buf->destport, 2);
1010 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
1011 LOG_DBG(
"IPHC: cannot compress UDP headers\n");
1012 CHECK_BUFFER_SPACE(4);
1013 memcpy(
iphc_ptr, &udp_buf->srcport, 4);
1017 CHECK_BUFFER_SPACE(2);
1018 memcpy(
iphc_ptr, &udp_buf->udpchksum, 2);
1025 LOG_ERR(
"compression: could not handle compression of header");
1028 if(next_hdr != NULL) {
1031 LOG_DBG(
"compression: last header could is not compressed: %d\n", *next_hdr);
1034 PACKETBUF_IPHC_BUF[0] = iphc0;
1035 PACKETBUF_IPHC_BUF[1] = iphc1;
1037 if(LOG_DBG_ENABLED) {
1042 LOG_DBG_(
"%02x", data);
1074 uint8_t tmp, iphc0, iphc1, nhc;
1075 struct uip_ext_hdr *exthdr;
1076 uint8_t* last_nextheader;
1077 uint8_t* ip_payload;
1078 uint8_t ext_hdr_len = 0;
1083#define CHECK_READ_SPACE(readlen) \
1084 if((iphc_ptr - packetbuf_ptr) + (readlen) > cmpr_len) { \
1085 LOG_WARN("Not enough packetbuf space to decompress header (%u bytes, %u left). Aborting.\n", \
1086 (unsigned)(readlen), (unsigned)(cmpr_len - (iphc_ptr - packetbuf_ptr))); \
1097 iphc0 = PACKETBUF_IPHC_BUF[0];
1098 iphc1 = PACKETBUF_IPHC_BUF[1];
1101 if(iphc1 & SICSLOWPAN_IPHC_CID) {
1102 LOG_DBG(
"uncompression: CID flag set - increase header with one\n");
1107 if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) {
1109 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1111 CHECK_READ_SPACE(4);
1112 memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow,
iphc_ptr + 1, 3);
1117 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f);
1119 SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) |
1120 (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f);
1123 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1125 CHECK_READ_SPACE(3);
1126 SICSLOWPAN_IP_BUF(buf)->tcflow = (*
iphc_ptr & 0x0F) |
1128 memcpy(&SICSLOWPAN_IP_BUF(buf)->flow,
iphc_ptr + 1, 2);
1134 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1136 CHECK_READ_SPACE(1);
1137 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*
iphc_ptr >> 2) & 0x0f);
1138 SICSLOWPAN_IP_BUF(buf)->tcflow = ((*
iphc_ptr << 6) & 0xC0) | ((*
iphc_ptr >> 2) & 0x30);
1139 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1143 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1144 SICSLOWPAN_IP_BUF(buf)->tcflow = 0;
1145 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1150 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
1152 CHECK_READ_SPACE(1);
1153 SICSLOWPAN_IP_BUF(buf)->proto = *
iphc_ptr;
1154 LOG_DBG(
"uncompression: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
1159 if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) {
1160 SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03];
1162 CHECK_READ_SPACE(1);
1163 SICSLOWPAN_IP_BUF(buf)->ttl = *
iphc_ptr;
1168 tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03;
1171 if(iphc1 & SICSLOWPAN_IPHC_SAC) {
1172 uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
1173 PACKETBUF_IPHC_BUF[2] >> 4 : 0;
1179 LOG_ERR(
"uncompression: error context not found\n");
1184 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr,
1185 tmp != 0 ?
context->prefix : NULL, unc_ctxconf[tmp],
1186 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1189 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix, unc_llconf[tmp],
1190 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1195 tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03;
1198 if(iphc1 & SICSLOWPAN_IPHC_M) {
1200 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1208 uint8_t prefix[] = {0xff, 0x02};
1209 if(tmp > 0 && tmp < 3) {
1210 CHECK_READ_SPACE(1);
1215 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix,
1216 unc_mxconf[tmp], NULL);
1221 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1222 uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? PACKETBUF_IPHC_BUF[2] & 0x0f : 0;
1227 LOG_ERR(
"uncompression: error context not found\n");
1230 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr,
context->prefix,
1232 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1235 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix,
1237 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1243 nhc = iphc0 & SICSLOWPAN_IPHC_NH_C;
1245 last_nextheader = &SICSLOWPAN_IP_BUF(buf)->proto;
1246 ip_payload = SICSLOWPAN_IPPAYLOAD_BUF(buf);
1248 CHECK_READ_SPACE(1);
1249 while(nhc && (*
iphc_ptr & SICSLOWPAN_NHC_MASK) == SICSLOWPAN_NHC_EXT_HDR) {
1250 uint8_t eid = (*
iphc_ptr & 0x0e) >> 1;
1260 CHECK_READ_SPACE(1);
1264 LOG_DBG(
"uncompression: next header is inlined. Next: %d\n", next);
1266 CHECK_READ_SPACE(1);
1270 LOG_DBG(
"uncompression: found ext header id: %d next: %d len: %d\n", eid, next, len);
1272 case SICSLOWPAN_NHC_ETX_HDR_HBHO:
1275 case SICSLOWPAN_NHC_ETX_HDR_ROUTING:
1276 proto = UIP_PROTO_ROUTING;
1278 case SICSLOWPAN_NHC_ETX_HDR_FRAG:
1279 proto = UIP_PROTO_FRAG;
1281 case SICSLOWPAN_NHC_ETX_HDR_DESTO:
1282 proto = UIP_PROTO_DESTO;
1285 LOG_DBG(
"uncompression: error unsupported ext header\n");
1288 *last_nextheader = proto;
1291 if((ip_payload - buf) + UIP_EXT_HDR_LEN + len > buf_size) {
1292 LOG_WARN(
"uncompression: cannot write ext header beyond target buffer\n");
1297 exthdr = (
struct uip_ext_hdr *)ip_payload;
1298 exthdr->len = (UIP_EXT_HDR_LEN + len) / 8;
1299 if(exthdr->len == 0) {
1300 LOG_WARN(
"Extension header length is below 8\n");
1304 exthdr->next = next;
1305 last_nextheader = &exthdr->next;
1308 CHECK_READ_SPACE(len + 1);
1309 memcpy((uint8_t *)exthdr + UIP_EXT_HDR_LEN,
iphc_ptr, len);
1313 ip_payload += (exthdr->len + 1) * 8;
1314 ext_hdr_len += (exthdr->len + 1) * 8;
1316 LOG_DBG(
"uncompression: %d len: %d exthdr len: %d (calc: %d)\n",
1317 proto, len, exthdr->len, (exthdr->len + 1) * 8);
1321 CHECK_READ_SPACE(1);
1322 if(nhc && (*
iphc_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
1323 struct uip_udp_hdr *udp_buf;
1325 uint8_t checksum_compressed;
1328 if((ip_payload - buf) + UIP_UDPH_LEN > buf_size) {
1329 LOG_WARN(
"uncompression: cannot write UDP header beyond target buffer\n");
1333 udp_buf = (
struct uip_udp_hdr *)ip_payload;
1334 *last_nextheader = UIP_PROTO_UDP;
1335 checksum_compressed = *
iphc_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
1336 LOG_DBG(
"uncompression: incoming header value: %i\n", *
iphc_ptr);
1337 switch(*
iphc_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
1338 case SICSLOWPAN_NHC_UDP_CS_P_00:
1340 CHECK_READ_SPACE(5);
1341 memcpy(&udp_buf->srcport,
iphc_ptr + 1, 2);
1342 memcpy(&udp_buf->destport,
iphc_ptr + 3, 2);
1343 LOG_DBG(
"uncompression: UDP ports (ptr+5): %x, %x\n",
1349 case SICSLOWPAN_NHC_UDP_CS_P_01:
1351 LOG_DBG(
"uncompression: destination address\n");
1352 CHECK_READ_SPACE(4);
1353 memcpy(&udp_buf->srcport,
iphc_ptr + 1, 2);
1354 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(
iphc_ptr + 3)));
1355 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1360 case SICSLOWPAN_NHC_UDP_CS_P_10:
1362 LOG_DBG(
"uncompression: source address\n");
1363 CHECK_READ_SPACE(4);
1364 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
1366 memcpy(&udp_buf->destport,
iphc_ptr + 2, 2);
1367 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1372 case SICSLOWPAN_NHC_UDP_CS_P_11:
1374 CHECK_READ_SPACE(2);
1375 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1377 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1379 LOG_DBG(
"uncompression: UDP ports (ptr+2): %x, %x\n",
1385 LOG_DBG(
"uncompression: error unsupported UDP compression\n");
1388 if(!checksum_compressed) {
1389 CHECK_READ_SPACE(2);
1390 memcpy(&udp_buf->udpchksum,
iphc_ptr, 2);
1392 LOG_DBG(
"uncompression: checksum included\n");
1394 LOG_DBG(
"uncompression: checksum *NOT* included\n");
1399 udp_buf->udplen =
UIP_HTONS(ip_len == 0 ? udp_len :
1400 ip_len - UIP_IPH_LEN - ext_hdr_len);
1401 LOG_DBG(
"uncompression: UDP length: %u (ext: %u) ip_len: %d udp_len: %d\n",
1402 UIP_HTONS(udp_buf->udplen), ext_hdr_len, ip_len, udp_len);
1412 LOG_DBG(
"uncompression: IP payload length: %d. %u - %u + %u - %u\n", len,
1416 SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8;
1417 SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF;
1420 SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
1421 SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
1429#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1438 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] = SICSLOWPAN_DISPATCH_PAGING | (page & 0x0f);
1460 if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_PAGING_MASK) == SICSLOWPAN_DISPATCH_PAGING) {
1462 curr_page = PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & 0x0f;
1491#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1493compress_hdr_ipv6(
void)
1515 const linkaddr_t *dest;
1517 if(callback != NULL) {
1518 callback->output_callback(status);
1523 dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
1529 link_stats_packet_sent(dest, status, transmissions);
1532 NETSTACK_ROUTING.
link_callback(dest, status, transmissions);
1553#if SICSLOWPAN_CONF_FRAG
1563fragment_copy_payload_and_send(uint16_t uip_offset)
1573 q = queuebuf_new_from_packetbuf();
1575 LOG_WARN(
"output: could not allocate queuebuf, dropping fragment\n");
1583 queuebuf_to_packetbuf(q);
1589 LOG_ERR(
"output: error in fragment tx, dropping subsequent fragments.\n");
1624 LOG_INFO(
"output: sending IPv6 packet with len %d\n",
uip_len);
1627 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
1628 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
1631 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER,
1634#if LLSEC802154_USES_AUX_HEADER
1636 packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
1637 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
1638#if LLSEC802154_USES_EXPLICIT_KEYS
1639 packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
1640 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_KEY_ID));
1649 LOG_WARN(
"output: failed to calculate payload size - dropping packet\n");
1654#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1655 compress_hdr_ipv6();
1657#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1665#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
1677 LOG_INFO(
"output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
1683#if SICSLOWPAN_CONF_FRAG
1685 uint16_t processed_ip_out_len;
1702 int fragn_max_payload = (
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
1704 int last_fragn_max_payload =
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
1706 int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
1708 unsigned fragment_count = 2;
1709 if(middle_fragn_total_payload > 0) {
1710 fragment_count += 1 + (middle_fragn_total_payload - 1) / fragn_max_payload;
1713 size_t free_bufs = queuebuf_numfree();
1714 LOG_INFO(
"output: fragmentation needed. fragments: %u, free queuebufs: %zu\n",
1715 fragment_count, free_bufs);
1719 size_t needed_bufs = fragment_count + 1;
1720 if(free_bufs < needed_bufs) {
1721 LOG_WARN(
"output: dropping packet, not enough free bufs (needed: %zu, free: %zu)\n",
1722 needed_bufs, free_bufs);
1726 if(frag1_payload < 0) {
1730 LOG_WARN(
"output: compressed header does not fit first fragment\n");
1737 frag_tag = my_tag++;
1744 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1745 ((SICSLOWPAN_DISPATCH_FRAG1 << 8) |
uip_len));
1746 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
1753 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d)\n",
1754 curr_frag + 1, fragment_count,
1764 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1765 ((SICSLOWPAN_DISPATCH_FRAGN << 8) |
uip_len));
1771 while(processed_ip_out_len <
uip_len) {
1774 PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
1777 if(
uip_len - processed_ip_out_len > last_fragn_max_payload) {
1787 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d, offset %d)\n",
1788 curr_frag + 1, fragment_count,
1790 if(fragment_copy_payload_and_send(processed_ip_out_len) == 0) {
1797 LOG_ERR(
"output: Packet too large to be sent without fragmentation support; dropping packet\n");
1807 LOG_ERR(
"output: uip_len is smaller than uncomp_hdr_len (%d < %d)",
1836 uint16_t frag_size = 0;
1838 uint8_t frag_offset = 0;
1840 uint16_t buffer_size;
1842#if SICSLOWPAN_CONF_FRAG
1843 uint8_t is_fragment = 0;
1844 int8_t frag_context = 0;
1847 uint16_t frag_tag = 0;
1848 uint8_t first_fragment = 0, last_fragment = 0;
1852 link_stats_input_callback(packetbuf_addr(PACKETBUF_ADDR_SENDER));
1862 LOG_WARN(
"input: empty packet\n");
1875 uipbuf_set_attr(UIPBUF_ATTR_RSSI, packetbuf_attr(PACKETBUF_ATTR_RSSI));
1876 uipbuf_set_attr(UIPBUF_ATTR_LINK_QUALITY, packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));
1879#if SICSLOWPAN_CONF_FRAG
1885 switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
1886 case SICSLOWPAN_DISPATCH_FRAG1:
1888 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1889 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1894 LOG_INFO(
"input: received first element of a fragmented packet (tag %d, len %d)\n",
1895 frag_tag, frag_size);
1898 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1900 if(frag_context == -1) {
1901 LOG_ERR(
"input: failed to allocate new reassembly context\n");
1905 buffer = frag_info[frag_context].first_frag;
1906 buffer_size = SICSLOWPAN_FIRST_FRAGMENT_SIZE;
1908 case SICSLOWPAN_DISPATCH_FRAGN:
1913 frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
1914 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1915 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1920 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1922 if(frag_context == -1) {
1923 LOG_ERR(
"input: reassembly context not found (tag %d)\n", frag_tag);
1931 if(frag_info[frag_context].reassembled_len >= frag_size) {
1940 if(is_fragment && !first_fragment) {
1950 LOG_INFO(
"input: page 1, 6LoRH\n");
1953 LOG_ERR(
"input: page %u not supported\n",
curr_page);
1959 (PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
1960 LOG_DBG(
"uncompression: IPHC dispatch\n");
1962 LOG_ERR(
"input: failed to decompress IPHC packet\n");
1965 }
else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
1966 LOG_DBG(
"uncompression: IPV6 dispatch\n");
1976 LOG_ERR(
"uncompression: unknown dispatch: 0x%02x, or IPHC disabled\n",
1977 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK);
1981#if SICSLOWPAN_CONF_FRAG
1992 LOG_ERR(
"input: packet dropped due to header > total packet\n");
1997#if SICSLOWPAN_CONF_FRAG
1999 LOG_INFO(
"input: fragment (tag %d, payload %d, offset %d) -- %u %u\n",
2006 unsigned int req_size =
uncomp_hdr_len + (uint16_t)(frag_offset << 3)
2008 if(req_size >
sizeof(
uip_buf)) {
2009#if SICSLOWPAN_CONF_FRAG
2011 "input: packet and fragment context %u dropped, minimum required IP_BUF size: %d+%d+%d=%u (current size: %u)\n",
2017 clear_fragments(frag_context);
2025 if(buffer != NULL) {
2027 LOG_ERR(
"input: cannot copy the payload into the buffer\n");
2035#if SICSLOWPAN_CONF_FRAG
2038 if(first_fragment != 0) {
2044 if(last_fragment != 0) {
2045 frag_info[frag_context].reassembled_len = frag_size;
2047 if(!copy_frags2uip(frag_context)) {
2057 if(!is_fragment || last_fragment) {
2059 if(is_fragment != 0 && last_fragment != 0) {
2067 LOG_INFO(
"input: received IPv6 packet with len %d\n",
2070 if(LOG_DBG_ENABLED) {
2072 LOG_DBG(
"uncompression: after (%u):",
UIP_IP_BUF->len[1]);
2073 for (ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
2074 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
2075 LOG_DBG_(
"%02x", data);
2083 callback->input_callback();
2086#if LLSEC802154_USES_AUX_HEADER
2091 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_LEVEL,
2092 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
2093#if LLSEC802154_USES_EXPLICIT_KEYS
2094 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_KEY_ID,
2095 packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX));
2100#if SICSLOWPAN_CONF_FRAG
2110sicslowpan_init(
void)
2113#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC
2119#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
2120 addr_contexts[0].used = 1;
2121 addr_contexts[0].number = 0;
2122#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0
2123 SICSLOWPAN_CONF_ADDR_CONTEXT_0;
2125 addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0;
2126 addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1;
2130#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1
2134#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1
2136 addr_contexts[1].used = 1;
2137 addr_contexts[1].number = 1;
2138 SICSLOWPAN_CONF_ADDR_CONTEXT_1;
2139#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2
2141 addr_contexts[2].used = 1;
2142 addr_contexts[2].number = 2;
2143 SICSLOWPAN_CONF_ADDR_CONTEXT_2;
2146 addr_contexts[i].used = 0;
2149 addr_contexts[i].used = 0;
void watchdog_periodic(void)
Writes the WDT clear sequence.
static volatile uint64_t count
Num.
#define CLOCK_SECOND
A second, measured in system clock time.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
bool linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
const linkaddr_t linkaddr_null
The null link-layer address.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
void packetbuf_clear(void)
Clear and reset the packetbuf.
static void digest_6lorh_hdr(void)
Digest 6lorh headers before IPHC.
static struct sicslowpan_addr_context * context
Addresses contexts for IPHC.
static void send_packet(void)
This function is called by the 6lowpan code to send out a packet.
static uint8_t curr_page
The current page (RFC 4944)
static uint8_t * packetbuf_ptr
A pointer to the packetbuf buffer.
static int mac_max_payload
mac_max_payload is the maimum payload space on the MAC frame.
static uint8_t * iphc_ptr
pointer to the byte where to write next inline field.
#define sicslowpan_is_iid_16_bit_compressable(a)
check whether we can compress the IID in address 'a' to 16 bits.
static struct sicslowpan_addr_context * addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr)
find the context corresponding to prefix ipaddr
static uint8_t uncomp_hdr_len
uncomp_hdr_len is the length of the headers before compression (if HC2 is used this includes the UDP ...
static int last_tx_status
the result of the last transmitted fragment
static uint8_t output(const linkaddr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
static int compress_hdr_iphc(void)
Compress IP/UDP header.
static bool uncompress_hdr_iphc(uint8_t *buf, uint16_t buf_size, uint16_t ip_len)
Uncompress IPHC (i.e., IPHC and LOWPAN_UDP) headers and put them in sicslowpan_buf.
static void add_paging_dispatch(uint8_t page)
Adds Paging dispatch byte.
static void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
static struct sicslowpan_addr_context * addr_context_lookup_by_number(uint8_t number)
find the context with the given number
static uint8_t packetbuf_hdr_len
packetbuf_hdr_len is the total length of (the processed) 6lowpan headers (fragment headers,...
static void add_6lorh_hdr(void)
Adds 6lorh headers before IPHC.
static void input(void)
Process a received 6lowpan packet.
static int packetbuf_payload_len
The length of the payload in the Packetbuf buffer.
static void digest_paging_dispatch(void)
Digest 6lorh headers before IPHC.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
int timer_expired(struct timer *t)
Check if a timer has expired.
#define uip_is_addr_mac_addr_based(a, m)
was addr (a) forged based on the mac address m a type is uip_ipaddr_t m type is uiplladdr_t
uip_lladdr_t uip_lladdr
Host L2 address.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
#define UIP_ICMP_BUF
Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_...
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
void uip_ds6_link_callback(int status, int numtx)
The callback function to update link-layer stats in a neighbor cache.
#define UIP_PROTO_HBHO
extension headers types
#define UIP_IP_BUF
Direct access to IPv6 header.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
#define UIP_BUFSIZE
The size of the uIP packet buffer.
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS
If we use IPHC compression, how many address contexts do we support.
#define SICSLOWPAN_REASS_MAXAGE
Timeout for packet reassembly at the 6lowpan layer (should be < 60s)
#define SICSLOWPAN_COMPRESSION
Do we compress the IP header or not.
Header file for the logging system.
@ MAC_TX_COLLISION
The MAC layer did not get an acknowledgement for the packet.
@ MAC_TX_OK
The MAC layer transmission was OK.
@ MAC_TX_ERR
The MAC layer transmission could not be performed because of a fatal error.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.
Header file for the Packet queue buffer management.
Routing driver header file.
Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01)
int(* max_payload)(void)
Read out estimated max payload size based on payload in packetbuf.
void(* send)(mac_callback_t sent_callback, void *ptr)
Send a packet from the packetbuf
The structure of a network driver in Contiki.
void(* link_callback)(const linkaddr_t *addr, int status, int numtx)
Called by lower layers after every packet transmission.
The header for fragments.
Header for the Contiki/uIP interface.
Header file for IPv6-related data structures.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Header file for the uIP TCP/IP stack.
Configuration options for uIP.