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 120 #define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf) 121 #define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN]) 122 #define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_IPH_LEN]) 124 #define UIP_IPPAYLOAD_BUF_POS(pos) (&uip_buf[UIP_IPH_LEN + (pos)]) 125 #define UIP_UDP_BUF_POS(pos) ((struct uip_udp_hdr *)UIP_IPPAYLOAD_BUF_POS(pos)) 126 #define UIP_EXT_HDR_LEN 2 131 #ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR 132 #define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR 135 #define COMPRESS_EXT_HDR 1 139 #define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP \ 140 || x == UIP_PROTO_HBHO \ 141 || x == UIP_PROTO_DESTO \ 142 || x == UIP_PROTO_ROUTING \ 143 || x == UIP_PROTO_FRAG) 145 #define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP) 197 static int last_rssi;
203 #if SICSLOWPAN_CONF_FRAG 204 static uint16_t my_tag;
210 #ifdef SICSLOWPAN_CONF_FRAGMENT_BUFFERS 211 #define SICSLOWPAN_FRAGMENT_BUFFERS SICSLOWPAN_CONF_FRAGMENT_BUFFERS 213 #define SICSLOWPAN_FRAGMENT_BUFFERS 12 221 #ifdef SICSLOWPAN_CONF_REASS_CONTEXTS 222 #define SICSLOWPAN_REASS_CONTEXTS SICSLOWPAN_CONF_REASS_CONTEXTS 224 #define SICSLOWPAN_REASS_CONTEXTS 2 228 #ifdef SICSLOWPAN_CONF_FRAGMENT_SIZE 229 #define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE 232 #define SICSLOWPAN_FRAGMENT_SIZE (127 - 2 - 15) 236 #if SICSLOWPAN_FRAGMENT_SIZE > 255 237 #error Too large SICSLOWPAN_FRAGMENT_SIZE set. 241 #define SICSLOWPAN_FIRST_FRAGMENT_SIZE (SICSLOWPAN_FRAGMENT_SIZE + 38) 244 struct sicslowpan_frag_info {
254 uint16_t reassembled_len;
256 struct timer reass_timer;
259 uint16_t first_frag_len;
262 uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE];
265 static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS];
267 struct sicslowpan_frag_buf {
274 uint8_t data[SICSLOWPAN_FRAGMENT_SIZE];
277 static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS];
281 clear_fragments(uint8_t frag_info_index)
285 frag_info[frag_info_index].len = 0;
286 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
287 if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) {
297 timeout_fragments(
int not_context)
301 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
302 if(frag_info[i].len > 0 && i != not_context &&
305 count += clear_fragments(i);
312 store_fragment(uint8_t index, uint8_t offset)
319 if(len <= 0 || len > SICSLOWPAN_FRAGMENT_SIZE) {
324 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
325 if(frag_buf[i].len == 0) {
328 frag_buf[i].offset = offset;
329 frag_buf[i].len = len;
330 frag_buf[i].index = index;
342 add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
350 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
352 if(frag_info[i].len > 0 &&
timer_expired(&frag_info[i].reass_timer)) {
357 if(found < 0 && frag_info[i].len == 0) {
365 LOG_WARN(
"reassembly: failed to store new fragment session - tag: %d\n", tag);
370 frag_info[found].len = frag_size;
371 frag_info[found].tag = tag;
373 packetbuf_addr(PACKETBUF_ADDR_SENDER));
381 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
382 if(frag_info[i].tag == tag && frag_info[i].len > 0 &&
383 linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
392 LOG_WARN(
"reassembly: failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
397 len = store_fragment(i, offset);
398 if(len < 0 && timeout_fragments(i) > 0) {
399 len = store_fragment(i, offset);
402 frag_info[i].reassembled_len += len;
407 LOG_WARN(
"reassembly: failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
420 if(frag_info[context].len < frag_info[context].first_frag_len ||
421 frag_info[context].len >
sizeof(
uip_buf)) {
422 LOG_WARN(
"input: invalid total size of fragments\n");
423 clear_fragments(context);
428 memcpy((uint8_t *)
UIP_IP_BUF, (uint8_t *)frag_info[context].first_frag,
429 frag_info[context].first_frag_len);
432 memset((uint8_t *)UIP_IP_BUF + frag_info[context].first_frag_len, 0,
433 frag_info[context].len - frag_info[context].first_frag_len);
435 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
437 if(frag_buf[i].len > 0 && frag_buf[i].index == context) {
438 if((frag_buf[i].offset << 3) + frag_buf[i].len >
sizeof(
uip_buf)) {
439 LOG_WARN(
"input: invalid fragment offset\n");
440 clear_fragments(context);
443 memcpy((uint8_t *)UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3),
444 (uint8_t *)frag_buf[i].data, frag_buf[i].len);
448 clear_fragments(context);
459 static struct netstack_sniffer *callback = NULL;
462 netstack_sniffer_add(
struct netstack_sniffer *s)
468 netstack_sniffer_remove(
struct netstack_sniffer *s)
474 set_packet_attrs(
void)
478 packetbuf_set_attr(PACKETBUF_ATTR_NETWORK_ID,
UIP_IP_BUF->proto);
482 c = UIP_UDP_BUF_POS(0)->srcport;
483 if(UIP_UDP_BUF_POS(0)->destport < c) {
484 c = UIP_UDP_BUF_POS(0)->destport;
486 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_TCP) {
487 c = UIP_TCP_BUF->srcport;
488 if(UIP_TCP_BUF->destport < c) {
489 c = UIP_TCP_BUF->destport;
491 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
495 packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, c);
505 #if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC 511 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 513 addr_contexts[SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS];
529 const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
536 const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
543 const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};
546 const uint8_t llprefix[] = {0xfe, 0x80};
549 static const uint8_t ttl_values[] = {0, 1, 64, 255};
560 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 563 if((addr_contexts[i].used == 1) &&
564 uip_ipaddr_prefixcmp(&addr_contexts[i].prefix, ipaddr, 64)) {
565 return &addr_contexts[i];
577 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 580 if((addr_contexts[i].used == 1) &&
581 addr_contexts[i].number == number) {
582 return &addr_contexts[i];
590 compress_addr_64(uint8_t bitpos, uip_ipaddr_t *
ipaddr, uip_lladdr_t *lladdr)
615 uncompress_addr(uip_ipaddr_t *
ipaddr, uint8_t
const prefix[],
616 uint8_t pref_post_count, uip_lladdr_t *lladdr)
618 uint8_t prefcount = pref_post_count >> 4;
619 uint8_t postcount = pref_post_count & 0x0f;
621 prefcount = prefcount == 15 ? 16 : prefcount;
622 postcount = postcount == 15 ? 16 : postcount;
624 LOG_DBG(
"uncompression: address %d %d ", prefcount, postcount);
627 memcpy(
ipaddr, prefix, prefcount);
629 if(prefcount + postcount < 16) {
630 memset(&
ipaddr->u8[prefcount], 0, 16 - (prefcount + postcount));
634 if(postcount == 2 && prefcount < 11) {
640 }
else if (prefcount > 0) {
688 uint8_t tmp, iphc0, iphc1, *next_hdr, *next_nhc;
690 struct uip_udp_hdr *udp_buf;
692 if(LOG_DBG_ENABLED) {
694 LOG_DBG(
"compression: before (%d): ",
UIP_IP_BUF->len[1]);
695 for(ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
696 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
697 LOG_DBG_(
"%02x", data);
704 #define CHECK_BUFFER_SPACE(writelen) do { \ 705 if(hc06_ptr + (writelen) >= PACKETBUF_PAYLOAD_END) { \ 706 LOG_WARN("Not enough packetbuf space to compress header (%u bytes, %u left). Aborting.\n", \ 707 (unsigned)(writelen), (unsigned)(PACKETBUF_PAYLOAD_END - hc06_ptr)); \ 717 CHECK_BUFFER_SPACE(38);
726 iphc0 = SICSLOWPAN_DISPATCH_IPHC;
728 PACKETBUF_IPHC_BUF[2] = 0;
743 LOG_DBG(
"compression: dest or src ipaddr - setting CID\n");
744 iphc1 |= SICSLOWPAN_IPHC_CID;
758 tmp = ((tmp & 0x03) << 6) | (tmp >> 2);
763 iphc0 |= SICSLOWPAN_IPHC_FL_C;
767 iphc0 |= SICSLOWPAN_IPHC_TC_C;
778 iphc0 |= SICSLOWPAN_IPHC_TC_C;
795 if(IS_COMPRESSABLE_PROTO(
UIP_IP_BUF->proto)) {
796 iphc0 |= SICSLOWPAN_IPHC_NH_C;
800 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
814 iphc0 |= SICSLOWPAN_IPHC_TTL_1;
817 iphc0 |= SICSLOWPAN_IPHC_TTL_64;
820 iphc0 |= SICSLOWPAN_IPHC_TTL_255;
830 LOG_DBG(
"compression: addr unspecified - setting SAC\n");
831 iphc1 |= SICSLOWPAN_IPHC_SAC;
832 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
836 LOG_DBG(
"compression: src with context - setting CID & SAC ctx: %d\n",
838 iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
839 PACKETBUF_IPHC_BUF[2] |= context->number << 4;
842 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
849 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
853 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
861 iphc1 |= SICSLOWPAN_IPHC_M;
862 if(sicslowpan_is_mcast_addr_compressable8(&
UIP_IP_BUF->destipaddr)) {
863 iphc1 |= SICSLOWPAN_IPHC_DAM_11;
867 }
else if(sicslowpan_is_mcast_addr_compressable32(&
UIP_IP_BUF->destipaddr)) {
868 iphc1 |= SICSLOWPAN_IPHC_DAM_10;
873 }
else if(sicslowpan_is_mcast_addr_compressable48(&
UIP_IP_BUF->destipaddr)) {
874 iphc1 |= SICSLOWPAN_IPHC_DAM_01;
880 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
889 iphc1 |= SICSLOWPAN_IPHC_DAC;
890 PACKETBUF_IPHC_BUF[2] |= context->number;
893 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
895 (uip_lladdr_t *)link_destaddr);
901 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
902 &
UIP_IP_BUF->destipaddr, (uip_lladdr_t *)link_destaddr);
905 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
919 LOG_DBG(
"compression: first header: %d\n", *next_hdr);
920 while(next_hdr != NULL && IS_COMPRESSABLE_PROTO(*next_hdr)) {
921 LOG_DBG(
"compression: next header: %d\n", *next_hdr);
926 proto = SICSLOWPAN_NHC_ETX_HDR_HBHO;
927 case UIP_PROTO_ROUTING:
928 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_ROUTING : proto;
930 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_FRAG : proto;
931 case UIP_PROTO_DESTO:
934 struct uip_ext_hdr *ext_hdr =
935 (
struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF_POS(ext_hdr_len);
937 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
939 len = (ext_hdr->len << 3) + 8;
940 LOG_DBG(
"compression: next header %d (len:%d)\n", *next_hdr, len);
942 next_hdr = &ext_hdr->next;
946 if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
947 CHECK_BUFFER_SPACE(1);
949 LOG_DBG(
"compression: keeping the next header in this ext hdr: %d\n",
953 CHECK_BUFFER_SPACE(len);
956 ext_hdr = (
struct uip_ext_hdr *)
hc06_ptr;
957 ext_hdr->len = len - 2;
964 *next_nhc = SICSLOWPAN_NHC_EXT_HDR |
965 (IS_COMPRESSABLE_PROTO(*next_hdr) ? SICSLOWPAN_NHC_BIT : 0) |
974 udp_buf = UIP_UDP_BUF_POS(ext_hdr_len);
975 LOG_DBG(
"compression: inlined UDP ports on send side: %x, %x\n",
978 if(((
UIP_HTONS(udp_buf->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
979 ((
UIP_HTONS(udp_buf->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
981 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
982 LOG_DBG(
"IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
983 CHECK_BUFFER_SPACE(1);
986 SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
987 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
988 SICSLOWPAN_UDP_4_BIT_PORT_MIN));
990 }
else if((
UIP_HTONS(udp_buf->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
992 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
993 LOG_DBG(
"IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
994 CHECK_BUFFER_SPACE(3);
995 memcpy(
hc06_ptr, &udp_buf->srcport, 2);
997 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
998 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
1000 }
else if((
UIP_HTONS(udp_buf->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
1002 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_10;
1003 LOG_DBG(
"IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
1004 CHECK_BUFFER_SPACE(3);
1006 (uint8_t)((
UIP_HTONS(udp_buf->srcport) -
1007 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
1008 memcpy(
hc06_ptr + 1, &udp_buf->destport, 2);
1012 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
1013 LOG_DBG(
"IPHC: cannot compress UDP headers\n");
1014 CHECK_BUFFER_SPACE(4);
1015 memcpy(
hc06_ptr, &udp_buf->srcport, 4);
1019 CHECK_BUFFER_SPACE(2);
1020 memcpy(
hc06_ptr, &udp_buf->udpchksum, 2);
1027 LOG_ERR(
"compression: could not handle compression of header");
1030 if(next_hdr != NULL) {
1033 LOG_DBG(
"compression: last header could is not compressed: %d\n", *next_hdr);
1036 PACKETBUF_IPHC_BUF[0] = iphc0;
1037 PACKETBUF_IPHC_BUF[1] = iphc1;
1039 if(LOG_DBG_ENABLED) {
1043 uint8_t data = ((uint8_t *) packetbuf_ptr)[ndx];
1044 LOG_DBG_(
"%02x", data);
1075 uint8_t tmp, iphc0, iphc1, nhc;
1076 struct uip_ext_hdr *exthdr;
1077 uint8_t* last_nextheader;
1078 uint8_t* ip_payload;
1079 uint8_t ext_hdr_len = 0;
1084 iphc0 = PACKETBUF_IPHC_BUF[0];
1085 iphc1 = PACKETBUF_IPHC_BUF[1];
1088 if(iphc1 & SICSLOWPAN_IPHC_CID) {
1089 LOG_DBG(
"uncompression: CID flag set - increase header with one\n");
1094 if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) {
1096 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1098 memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow,
hc06_ptr + 1, 3);
1103 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f);
1105 SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) |
1106 (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f);
1109 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1111 SICSLOWPAN_IP_BUF(buf)->tcflow = (*
hc06_ptr & 0x0F) |
1113 memcpy(&SICSLOWPAN_IP_BUF(buf)->flow,
hc06_ptr + 1, 2);
1119 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1121 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*
hc06_ptr >> 2) & 0x0f);
1122 SICSLOWPAN_IP_BUF(buf)->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30);
1123 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1127 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1128 SICSLOWPAN_IP_BUF(buf)->tcflow = 0;
1129 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1134 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
1136 SICSLOWPAN_IP_BUF(buf)->proto = *
hc06_ptr;
1137 LOG_DBG(
"uncompression: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
1142 if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) {
1143 SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03];
1145 SICSLOWPAN_IP_BUF(buf)->ttl = *
hc06_ptr;
1150 tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03;
1153 if(iphc1 & SICSLOWPAN_IPHC_SAC) {
1154 uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
1155 PACKETBUF_IPHC_BUF[2] >> 4 : 0;
1160 if(context == NULL) {
1161 LOG_ERR(
"uncompression: error context not found\n");
1166 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr,
1167 tmp != 0 ? context->prefix : NULL, unc_ctxconf[tmp],
1168 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1171 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix, unc_llconf[tmp],
1172 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1177 tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03;
1180 if(iphc1 & SICSLOWPAN_IPHC_M) {
1182 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1190 uint8_t prefix[] = {0xff, 0x02};
1191 if(tmp > 0 && tmp < 3) {
1196 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix,
1197 unc_mxconf[tmp], NULL);
1202 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1203 uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? PACKETBUF_IPHC_BUF[2] & 0x0f : 0;
1207 if(context == NULL) {
1208 LOG_ERR(
"uncompression: error context not found\n");
1211 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, context->prefix,
1213 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1216 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix,
1218 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1224 nhc = iphc0 & SICSLOWPAN_IPHC_NH_C;
1226 last_nextheader = &SICSLOWPAN_IP_BUF(buf)->proto;
1227 ip_payload = SICSLOWPAN_IPPAYLOAD_BUF(buf);
1229 while(nhc && (*
hc06_ptr & SICSLOWPAN_NHC_MASK) == SICSLOWPAN_NHC_EXT_HDR) {
1230 uint8_t eid = (*
hc06_ptr & 0x0e) >> 1;
1243 LOG_DBG(
"uncompression: next header is inlined. Next: %d\n", next);
1248 LOG_DBG(
"uncompression: found ext header id: %d next: %d len: %d\n", eid, next, len);
1250 case SICSLOWPAN_NHC_ETX_HDR_HBHO:
1253 case SICSLOWPAN_NHC_ETX_HDR_ROUTING:
1254 proto = UIP_PROTO_ROUTING;
1256 case SICSLOWPAN_NHC_ETX_HDR_FRAG:
1257 proto = UIP_PROTO_FRAG;
1259 case SICSLOWPAN_NHC_ETX_HDR_DESTO:
1260 proto = UIP_PROTO_DESTO;
1263 LOG_DBG(
"uncompression: error unsupported ext header\n");
1266 *last_nextheader = proto;
1269 if((ip_payload - buf) + UIP_EXT_HDR_LEN + len > buf_size) {
1270 LOG_WARN(
"uncompression: cannot write ext header beyond target buffer\n");
1275 exthdr = (
struct uip_ext_hdr *)ip_payload;
1276 exthdr->len = (UIP_EXT_HDR_LEN + len) / 8;
1277 if(exthdr->len == 0) {
1278 LOG_WARN(
"Extension header length is below 8\n");
1282 exthdr->next = next;
1283 last_nextheader = &exthdr->next;
1284 memcpy((uint8_t *)exthdr + UIP_EXT_HDR_LEN,
hc06_ptr, len);
1288 ip_payload += (exthdr->len + 1) * 8;
1289 ext_hdr_len += (exthdr->len + 1) * 8;
1291 LOG_DBG(
"uncompression: %d len: %d exthdr len: %d (calc: %d)\n",
1292 proto, len, exthdr->len, (exthdr->len + 1) * 8);
1296 if(nhc && (*
hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
1297 struct uip_udp_hdr *udp_buf = (
struct uip_udp_hdr *)ip_payload;
1299 uint8_t checksum_compressed;
1300 *last_nextheader = UIP_PROTO_UDP;
1301 checksum_compressed = *
hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
1302 LOG_DBG(
"uncompression: incoming header value: %i\n", *
hc06_ptr);
1303 switch(*
hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
1304 case SICSLOWPAN_NHC_UDP_CS_P_00:
1306 memcpy(&udp_buf->srcport,
hc06_ptr + 1, 2);
1307 memcpy(&udp_buf->destport,
hc06_ptr + 3, 2);
1308 LOG_DBG(
"uncompression: UDP ports (ptr+5): %x, %x\n",
1314 case SICSLOWPAN_NHC_UDP_CS_P_01:
1316 LOG_DBG(
"uncompression: destination address\n");
1317 memcpy(&udp_buf->srcport,
hc06_ptr + 1, 2);
1318 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(
hc06_ptr + 3)));
1319 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1324 case SICSLOWPAN_NHC_UDP_CS_P_10:
1326 LOG_DBG(
"uncompression: source address\n");
1327 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
1329 memcpy(&udp_buf->destport,
hc06_ptr + 2, 2);
1330 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1335 case SICSLOWPAN_NHC_UDP_CS_P_11:
1337 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1339 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1341 LOG_DBG(
"uncompression: UDP ports (ptr+2): %x, %x\n",
1346 LOG_DBG(
"uncompression: error unsupported UDP compression\n");
1349 if(!checksum_compressed) {
1350 memcpy(&udp_buf->udpchksum,
hc06_ptr, 2);
1352 LOG_DBG(
"uncompression: checksum included\n");
1354 LOG_DBG(
"uncompression: checksum *NOT* included\n");
1359 udp_buf->udplen =
UIP_HTONS(ip_len == 0 ? udp_len :
1360 ip_len - UIP_IPH_LEN - ext_hdr_len);
1361 LOG_DBG(
"uncompression: UDP length: %u (ext: %u) ip_len: %d udp_len: %d\n",
1362 UIP_HTONS(udp_buf->udplen), ext_hdr_len, ip_len, udp_len);
1372 LOG_DBG(
"uncompression: IP payload length: %d. %u - %u + %u - %u\n", len,
1376 SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8;
1377 SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF;
1380 SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
1381 SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
1387 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH 1396 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] = SICSLOWPAN_DISPATCH_PAGING | (page & 0x0f);
1418 if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_PAGING_MASK) == SICSLOWPAN_DISPATCH_PAGING) {
1420 curr_page = PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & 0x0f;
1449 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 1451 compress_hdr_ipv6(linkaddr_t *link_destaddr)
1473 const linkaddr_t *dest;
1475 if(callback != NULL) {
1476 callback->output_callback(status);
1481 dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
1487 link_stats_packet_sent(dest, status, transmissions);
1490 NETSTACK_ROUTING.
link_callback(dest, status, transmissions);
1508 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, dest);
1510 #if NETSTACK_CONF_BRIDGE_MODE 1512 packetbuf_set_addr(PACKETBUF_ADDR_SENDER,(
void*)&
uip_lladdr);
1523 #if SICSLOWPAN_CONF_FRAG 1533 fragment_copy_payload_and_send(uint16_t uip_offset, linkaddr_t *dest) {
1542 q = queuebuf_new_from_packetbuf();
1544 LOG_WARN(
"output: could not allocate queuebuf, dropping fragment\n");
1552 queuebuf_to_packetbuf(q);
1559 LOG_ERR(
"output: error in fragment tx, dropping subsequent fragments.\n");
1602 if(localdest == NULL) {
1608 LOG_INFO(
"output: sending IPv6 packet with len %d\n",
uip_len);
1611 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
1612 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
1615 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
1616 #if LLSEC802154_USES_AUX_HEADER 1618 packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
1619 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
1620 #if LLSEC802154_USES_EXPLICIT_KEYS 1621 packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
1622 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_KEY_ID));
1630 LOG_WARN(
"output: failed to calculate payload size - dropping packet\n");
1635 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 1636 compress_hdr_ipv6(&dest);
1638 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH 1646 #if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC 1657 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
1660 LOG_INFO(
"output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
1666 #if SICSLOWPAN_CONF_FRAG 1668 uint16_t processed_ip_out_len;
1685 int fragn_max_payload = (
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
1687 int last_fragn_max_payload =
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
1689 int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
1691 int fragment_count = 2;
1692 if(middle_fragn_total_payload > 0) {
1693 fragment_count += 1 + (middle_fragn_total_payload - 1) / fragn_max_payload;
1696 int freebuf = queuebuf_numfree() - 1;
1697 LOG_INFO(
"output: fragmentation needed, fragments: %u, free queuebufs: %u\n",
1698 fragment_count, freebuf);
1700 if(freebuf < fragment_count) {
1701 LOG_WARN(
"output: dropping packet, not enough free bufs (needed: %u, free: %u)\n",
1702 fragment_count, freebuf);
1706 if(frag1_payload < 0) {
1710 LOG_WARN(
"output: compressed header does not fit first fragment\n");
1717 frag_tag = my_tag++;
1724 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1725 ((SICSLOWPAN_DISPATCH_FRAG1 << 8) |
uip_len));
1726 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
1733 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d)\n",
1734 curr_frag + 1, fragment_count,
1744 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1745 ((SICSLOWPAN_DISPATCH_FRAGN << 8) |
uip_len));
1751 while(processed_ip_out_len <
uip_len) {
1754 PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
1757 if(
uip_len - processed_ip_out_len > last_fragn_max_payload) {
1759 packetbuf_payload_len = fragn_max_payload;
1762 packetbuf_payload_len =
uip_len - processed_ip_out_len;
1767 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d, offset %d)\n",
1768 curr_frag + 1, fragment_count,
1769 frag_tag, packetbuf_payload_len, processed_ip_out_len);
1770 if(fragment_copy_payload_and_send(processed_ip_out_len, &dest) == 0) {
1777 LOG_ERR(
"output: Packet too large to be sent without fragmentation support; dropping packet\n");
1787 LOG_ERR(
"output: uip_len is smaller than uncomp_hdr_len (%d < %d)",
1816 uint16_t frag_size = 0;
1818 uint8_t frag_offset = 0;
1820 uint16_t buffer_size;
1822 #if SICSLOWPAN_CONF_FRAG 1823 uint8_t is_fragment = 0;
1824 int8_t frag_context = 0;
1827 uint16_t frag_tag = 0;
1828 uint8_t first_fragment = 0, last_fragment = 0;
1832 link_stats_input_callback(packetbuf_addr(PACKETBUF_ADDR_SENDER));
1842 LOG_WARN(
"input: empty packet\n");
1855 last_rssi = (
signed short)packetbuf_attr(PACKETBUF_ATTR_RSSI);
1857 #if SICSLOWPAN_CONF_FRAG 1863 switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
1864 case SICSLOWPAN_DISPATCH_FRAG1:
1866 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1867 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1872 LOG_INFO(
"input: received first element of a fragmented packet (tag %d, len %d)\n",
1873 frag_tag, frag_size);
1876 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1878 if(frag_context == -1) {
1879 LOG_ERR(
"input: failed to allocate new reassembly context\n");
1883 buffer = frag_info[frag_context].first_frag;
1884 buffer_size = SICSLOWPAN_FIRST_FRAGMENT_SIZE;
1886 case SICSLOWPAN_DISPATCH_FRAGN:
1891 frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
1892 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1893 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1898 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1900 if(frag_context == -1) {
1901 LOG_ERR(
"input: reassembly context not found (tag %d)\n", frag_tag);
1909 if(frag_info[frag_context].reassembled_len >= frag_size) {
1918 if(is_fragment && !first_fragment) {
1928 LOG_INFO(
"input: page 1, 6LoRH\n");
1931 LOG_ERR(
"input: page %u not supported\n",
curr_page);
1937 (PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
1938 LOG_DBG(
"uncompression: IPHC dispatch\n");
1940 }
else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
1941 LOG_DBG(
"uncompression: IPV6 dispatch\n");
1951 LOG_ERR(
"uncompression: unknown dispatch: 0x%02x, or IPHC disabled\n",
1952 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK);
1956 #if SICSLOWPAN_CONF_FRAG 1967 LOG_ERR(
"input: packet dropped due to header > total packet\n");
1972 #if SICSLOWPAN_CONF_FRAG 1974 LOG_INFO(
"input: fragment (tag %d, payload %d, offset %d) -- %u %u\n",
1983 if(req_size >
sizeof(
uip_buf)) {
1984 #if SICSLOWPAN_CONF_FRAG 1986 "input: packet and fragment context %u dropped, minimum required IP_BUF size: %d+%d+%d=%d (current size: %u)\n",
1992 clear_fragments(frag_context);
2000 if(buffer != NULL) {
2006 #if SICSLOWPAN_CONF_FRAG 2009 if(first_fragment != 0) {
2015 if(last_fragment != 0) {
2016 frag_info[frag_context].reassembled_len = frag_size;
2018 if(!copy_frags2uip(frag_context)) {
2028 if(!is_fragment || last_fragment) {
2030 if(is_fragment != 0 && last_fragment != 0) {
2038 LOG_INFO(
"input: received IPv6 packet with len %d\n",
2041 if(LOG_DBG_ENABLED) {
2043 LOG_DBG(
"uncompression: after (%u):",
UIP_IP_BUF->len[1]);
2044 for (ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
2045 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
2046 LOG_DBG_(
"%02x", data);
2054 callback->input_callback();
2057 #if LLSEC802154_USES_AUX_HEADER 2062 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_LEVEL,
2063 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
2064 #if LLSEC802154_USES_EXPLICIT_KEYS 2065 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_KEY_ID,
2066 packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX));
2071 #if SICSLOWPAN_CONF_FRAG 2081 sicslowpan_init(
void)
2084 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC 2090 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 2091 addr_contexts[0].used = 1;
2092 addr_contexts[0].number = 0;
2093 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0 2094 SICSLOWPAN_CONF_ADDR_CONTEXT_0;
2096 addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0;
2097 addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1;
2101 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1 2105 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1 2107 addr_contexts[1].used = 1;
2108 addr_contexts[1].number = 1;
2109 SICSLOWPAN_CONF_ADDR_CONTEXT_1;
2110 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2 2112 addr_contexts[2].used = 1;
2113 addr_contexts[2].number = 2;
2114 SICSLOWPAN_CONF_ADDR_CONTEXT_2;
2117 addr_contexts[i].used = 0;
2120 addr_contexts[i].used = 0;
2130 sicslowpan_get_last_rssi(
void)
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
#define UIP_IP_BUF
Direct access to IPv6 header.
static uint8_t packetbuf_hdr_len
packetbuf_hdr_len is the total length of (the processed) 6lowpan headers (fragment headers...
uip_lladdr_t uip_lladdr
Host L2 address.
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
Header for the Contiki/uIP interface.
static void digest_paging_dispatch(void)
Digest 6lorh headers before IPHC.
The MAC layer transmission could not be performed because of a fatal error.
void packetbuf_clear(void)
Clear and reset the packetbuf.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
static int packetbuf_payload_len
The length of the payload in the Packetbuf buffer.
#define UIP_ICMP_BUF
Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_...
void(* link_callback)(const linkaddr_t *addr, int status, int numtx)
Called by lower layers after every packet transmission.
static void send_packet(linkaddr_t *dest)
This function is called by the 6lowpan code to send out a packet.
#define UIP_PROTO_HBHO
extension headers types
#define UIP_BUFSIZE
The size of the uIP packet buffer.
static void digest_6lorh_hdr(void)
Digest 6lorh headers before IPHC.
static void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
void uip_ds6_link_callback(int status, int numtx)
The callback function to update link-layer stats in a neighbor cache.
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
const linkaddr_t linkaddr_null
The null link-layer address.
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 void 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.
Header file for IPv6-related data structures.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Configuration options for uIP.
#define sicslowpan_is_iid_16_bit_compressable(a)
check whether we can compress the IID in address 'a' to 16 bits.
static int mac_max_payload
mac_max_payload is the maimum payload space on the MAC frame.
#define CLOCK_SECOND
A second, measured in system clock time.
#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 ...
static void add_paging_dispatch(uint8_t page)
Adds Paging dispatch byte.
Header file for the Packet queue buffer management
The MAC layer did not get an acknowledgement for the packet.
#define SICSLOWPAN_COMPRESSION
Do we compress the IP header or not.
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 ...
The MAC layer transmission was OK.
static int last_tx_status
the result of the last transmitted fragment
The structure of a network driver in Contiki.
static uint8_t curr_page
The current page (RFC 4944)
#define SICSLOWPAN_REASS_MAXAGE
Timeout for packet reassembly at the 6lowpan layer (should be < 60s)
static uint8_t * hc06_ptr
pointer to the byte where to write next inline field.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
Routing driver header file
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
int timer_expired(struct timer *t)
Check if a timer has expired.
The header for fragments.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS
If we use IPHC compression, how many address contexts do we support.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
void(* send)(mac_callback_t sent_callback, void *ptr)
Send a packet from the packetbuf.
Header file for the uIP TCP/IP stack.
static int compress_hdr_iphc(linkaddr_t *link_destaddr)
Compress IP/UDP header.
static void add_6lorh_hdr(void)
Adds 6lorh headers before IPHC.
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
int(* max_payload)(void)
Read out estimated max payload size based on payload in packetbuf.
void watchdog_periodic(void)
Writes the WDT clear sequence.
Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01) ...
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
Header file for the logging system
static void input(void)
Process a received 6lowpan packet.
static struct sicslowpan_addr_context * addr_context_lookup_by_number(uint8_t number)
find the context with the given number
static struct sicslowpan_addr_context * addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr)
find the context corresponding to prefix ipaddr
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
static uint8_t * packetbuf_ptr
A pointer to the packetbuf buffer.
static struct sicslowpan_addr_context * context
Addresses contexts for IPHC.