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)) 130 #ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR 131 #define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR 134 #define COMPRESS_EXT_HDR 1 138 #define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP \ 139 || x == UIP_PROTO_HBHO \ 140 || x == UIP_PROTO_DESTO \ 141 || x == UIP_PROTO_ROUTING \ 142 || x == UIP_PROTO_FRAG) 144 #define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP) 196 static int last_rssi;
202 #if SICSLOWPAN_CONF_FRAG 203 static 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) 243 struct sicslowpan_frag_info {
253 uint16_t reassembled_len;
255 struct timer reass_timer;
258 uint16_t first_frag_len;
261 uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE];
264 static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS];
266 struct sicslowpan_frag_buf {
273 uint8_t data[SICSLOWPAN_FRAGMENT_SIZE];
276 static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS];
280 clear_fragments(uint8_t frag_info_index)
284 frag_info[frag_info_index].len = 0;
285 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
286 if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) {
296 timeout_fragments(
int not_context)
300 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
301 if(frag_info[i].len > 0 && i != not_context &&
304 count += clear_fragments(i);
311 store_fragment(uint8_t index, uint8_t offset)
318 if(len < 0 || len > SICSLOWPAN_FRAGMENT_SIZE) {
323 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
324 if(frag_buf[i].len == 0) {
327 frag_buf[i].offset = offset;
328 frag_buf[i].len = len;
329 frag_buf[i].index = index;
341 add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
349 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
351 if(frag_info[i].len > 0 &&
timer_expired(&frag_info[i].reass_timer)) {
356 if(found < 0 && frag_info[i].len == 0) {
364 LOG_WARN(
"reassembly: failed to store new fragment session - tag: %d\n", tag);
369 frag_info[found].len = frag_size;
370 frag_info[found].tag = tag;
372 packetbuf_addr(PACKETBUF_ADDR_SENDER));
380 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
381 if(frag_info[i].tag == tag && frag_info[i].len > 0 &&
382 linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
391 LOG_WARN(
"reassembly: failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
396 len = store_fragment(i, offset);
397 if(len < 0 && timeout_fragments(i) > 0) {
398 len = store_fragment(i, offset);
401 frag_info[i].reassembled_len += len;
406 LOG_WARN(
"reassembly: failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
419 if(frag_info[context].len < frag_info[context].first_frag_len ||
420 frag_info[context].len >
sizeof(
uip_buf)) {
421 LOG_WARN(
"input: invalid total size of fragments\n");
422 clear_fragments(context);
427 memcpy((uint8_t *)
UIP_IP_BUF, (uint8_t *)frag_info[context].first_frag,
428 frag_info[context].first_frag_len);
431 memset((uint8_t *)UIP_IP_BUF + frag_info[context].first_frag_len, 0,
432 frag_info[context].len - frag_info[context].first_frag_len);
434 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
436 if(frag_buf[i].len > 0 && frag_buf[i].index == context) {
437 if((frag_buf[i].offset << 3) + frag_buf[i].len >
sizeof(
uip_buf)) {
438 LOG_WARN(
"input: invalid fragment offset\n");
439 clear_fragments(context);
442 memcpy((uint8_t *)UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3),
443 (uint8_t *)frag_buf[i].data, frag_buf[i].len);
447 clear_fragments(context);
458 static struct netstack_sniffer *callback = NULL;
461 netstack_sniffer_add(
struct netstack_sniffer *s)
467 netstack_sniffer_remove(
struct netstack_sniffer *s)
473 set_packet_attrs(
void)
477 packetbuf_set_attr(PACKETBUF_ATTR_NETWORK_ID,
UIP_IP_BUF->proto);
481 c = UIP_UDP_BUF_POS(0)->srcport;
482 if(UIP_UDP_BUF_POS(0)->destport < c) {
483 c = UIP_UDP_BUF_POS(0)->destport;
485 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_TCP) {
486 c = UIP_TCP_BUF->srcport;
487 if(UIP_TCP_BUF->destport < c) {
488 c = UIP_TCP_BUF->destport;
490 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
494 packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, c);
504 #if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC 510 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 512 addr_contexts[SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS];
528 const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
535 const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
542 const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};
545 const uint8_t llprefix[] = {0xfe, 0x80};
548 static const uint8_t ttl_values[] = {0, 1, 64, 255};
559 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 562 if((addr_contexts[i].used == 1) &&
563 uip_ipaddr_prefixcmp(&addr_contexts[i].prefix, ipaddr, 64)) {
564 return &addr_contexts[i];
576 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 579 if((addr_contexts[i].used == 1) &&
580 addr_contexts[i].number == number) {
581 return &addr_contexts[i];
589 compress_addr_64(uint8_t bitpos, uip_ipaddr_t *
ipaddr, uip_lladdr_t *lladdr)
614 uncompress_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) {
687 uint8_t tmp, iphc0, iphc1, *next_hdr, *next_nhc;
689 struct uip_udp_hdr *udp_buf;
691 if(LOG_DBG_ENABLED) {
693 LOG_DBG(
"compression: before (%d): ",
UIP_IP_BUF->len[1]);
694 for(ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
695 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
696 LOG_DBG_(
"%02x", data);
703 #define CHECK_BUFFER_SPACE(writelen) do { \ 704 if(hc06_ptr + (writelen) >= PACKETBUF_PAYLOAD_END) { \ 705 LOG_WARN("Not enough packetbuf space to compress header (%u bytes, %u left). Aborting.\n", \ 706 (unsigned)(writelen), (unsigned)(PACKETBUF_PAYLOAD_END - hc06_ptr)); \ 716 CHECK_BUFFER_SPACE(38);
725 iphc0 = SICSLOWPAN_DISPATCH_IPHC;
727 PACKETBUF_IPHC_BUF[2] = 0;
742 LOG_DBG(
"compression: dest or src ipaddr - setting CID\n");
743 iphc1 |= SICSLOWPAN_IPHC_CID;
757 tmp = ((tmp & 0x03) << 6) | (tmp >> 2);
762 iphc0 |= SICSLOWPAN_IPHC_FL_C;
766 iphc0 |= SICSLOWPAN_IPHC_TC_C;
777 iphc0 |= SICSLOWPAN_IPHC_TC_C;
794 if(IS_COMPRESSABLE_PROTO(
UIP_IP_BUF->proto)) {
795 iphc0 |= SICSLOWPAN_IPHC_NH_C;
799 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
813 iphc0 |= SICSLOWPAN_IPHC_TTL_1;
816 iphc0 |= SICSLOWPAN_IPHC_TTL_64;
819 iphc0 |= SICSLOWPAN_IPHC_TTL_255;
829 LOG_DBG(
"compression: addr unspecified - setting SAC\n");
830 iphc1 |= SICSLOWPAN_IPHC_SAC;
831 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
835 LOG_DBG(
"compression: src with context - setting CID & SAC ctx: %d\n",
837 iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
838 PACKETBUF_IPHC_BUF[2] |= context->number << 4;
841 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
848 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
852 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
860 iphc1 |= SICSLOWPAN_IPHC_M;
861 if(sicslowpan_is_mcast_addr_compressable8(&
UIP_IP_BUF->destipaddr)) {
862 iphc1 |= SICSLOWPAN_IPHC_DAM_11;
866 }
else if(sicslowpan_is_mcast_addr_compressable32(&
UIP_IP_BUF->destipaddr)) {
867 iphc1 |= SICSLOWPAN_IPHC_DAM_10;
872 }
else if(sicslowpan_is_mcast_addr_compressable48(&
UIP_IP_BUF->destipaddr)) {
873 iphc1 |= SICSLOWPAN_IPHC_DAM_01;
879 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
888 iphc1 |= SICSLOWPAN_IPHC_DAC;
889 PACKETBUF_IPHC_BUF[2] |= context->number;
892 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
894 (uip_lladdr_t *)link_destaddr);
900 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
901 &
UIP_IP_BUF->destipaddr, (uip_lladdr_t *)link_destaddr);
904 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
918 LOG_DBG(
"compression: first header: %d\n", *next_hdr);
919 while(next_hdr != NULL && IS_COMPRESSABLE_PROTO(*next_hdr)) {
920 LOG_DBG(
"compression: next header: %d\n", *next_hdr);
925 proto = SICSLOWPAN_NHC_ETX_HDR_HBHO;
926 case UIP_PROTO_ROUTING:
927 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_ROUTING : proto;
929 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_FRAG : proto;
930 case UIP_PROTO_DESTO:
933 struct uip_ext_hdr *ext_hdr =
934 (
struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF_POS(ext_hdr_len);
936 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
938 len = (ext_hdr->len << 3) + 8;
939 LOG_DBG(
"compression: next header %d (len:%d)\n", *next_hdr, len);
941 next_hdr = &ext_hdr->next;
945 if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
946 CHECK_BUFFER_SPACE(1);
948 LOG_DBG(
"compression: keeping the next header in this ext hdr: %d\n",
952 CHECK_BUFFER_SPACE(len);
955 ext_hdr = (
struct uip_ext_hdr *)
hc06_ptr;
956 ext_hdr->len = len - 2;
963 *next_nhc = SICSLOWPAN_NHC_EXT_HDR |
964 (IS_COMPRESSABLE_PROTO(*next_hdr) ? SICSLOWPAN_NHC_BIT : 0) |
973 udp_buf = UIP_UDP_BUF_POS(ext_hdr_len);
974 LOG_DBG(
"compression: inlined UDP ports on send side: %x, %x\n",
977 if(((
UIP_HTONS(udp_buf->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
978 ((
UIP_HTONS(udp_buf->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
980 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
981 LOG_DBG(
"IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
982 CHECK_BUFFER_SPACE(1);
985 SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
986 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
987 SICSLOWPAN_UDP_4_BIT_PORT_MIN));
989 }
else if((
UIP_HTONS(udp_buf->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
991 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
992 LOG_DBG(
"IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
993 CHECK_BUFFER_SPACE(3);
994 memcpy(
hc06_ptr, &udp_buf->srcport, 2);
996 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
997 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
999 }
else if((
UIP_HTONS(udp_buf->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
1001 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_10;
1002 LOG_DBG(
"IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
1003 CHECK_BUFFER_SPACE(3);
1005 (uint8_t)((
UIP_HTONS(udp_buf->srcport) -
1006 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
1007 memcpy(
hc06_ptr + 1, &udp_buf->destport, 2);
1011 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
1012 LOG_DBG(
"IPHC: cannot compress UDP headers\n");
1013 CHECK_BUFFER_SPACE(4);
1014 memcpy(
hc06_ptr, &udp_buf->srcport, 4);
1018 CHECK_BUFFER_SPACE(2);
1019 memcpy(
hc06_ptr, &udp_buf->udpchksum, 2);
1026 LOG_ERR(
"compression: could not handle compression of header");
1029 if(next_hdr != NULL) {
1032 LOG_DBG(
"compression: last header could is not compressed: %d\n", *next_hdr);
1035 PACKETBUF_IPHC_BUF[0] = iphc0;
1036 PACKETBUF_IPHC_BUF[1] = iphc1;
1038 if(LOG_DBG_ENABLED) {
1042 uint8_t data = ((uint8_t *) packetbuf_ptr)[ndx];
1043 LOG_DBG_(
"%02x", data);
1073 uint8_t tmp, iphc0, iphc1, nhc;
1074 struct uip_ext_hdr *exthdr;
1075 uint8_t* last_nextheader;
1076 uint8_t* ip_payload;
1077 uint8_t ext_hdr_len = 0;
1082 iphc0 = PACKETBUF_IPHC_BUF[0];
1083 iphc1 = PACKETBUF_IPHC_BUF[1];
1086 if(iphc1 & SICSLOWPAN_IPHC_CID) {
1087 LOG_DBG(
"uncompression: CID flag set - increase header with one\n");
1092 if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) {
1094 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1096 memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow,
hc06_ptr + 1, 3);
1101 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f);
1103 SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) |
1104 (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f);
1107 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1109 SICSLOWPAN_IP_BUF(buf)->tcflow = (*
hc06_ptr & 0x0F) |
1111 memcpy(&SICSLOWPAN_IP_BUF(buf)->flow,
hc06_ptr + 1, 2);
1117 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1119 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*
hc06_ptr >> 2) & 0x0f);
1120 SICSLOWPAN_IP_BUF(buf)->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30);
1121 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1125 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1126 SICSLOWPAN_IP_BUF(buf)->tcflow = 0;
1127 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1132 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
1134 SICSLOWPAN_IP_BUF(buf)->proto = *
hc06_ptr;
1135 LOG_DBG(
"uncompression: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
1140 if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) {
1141 SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03];
1143 SICSLOWPAN_IP_BUF(buf)->ttl = *
hc06_ptr;
1148 tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03;
1151 if(iphc1 & SICSLOWPAN_IPHC_SAC) {
1152 uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
1153 PACKETBUF_IPHC_BUF[2] >> 4 : 0;
1158 if(context == NULL) {
1159 LOG_ERR(
"uncompression: error context not found\n");
1164 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr,
1165 tmp != 0 ? context->prefix : NULL, unc_ctxconf[tmp],
1166 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1169 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix, unc_llconf[tmp],
1170 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1175 tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03;
1178 if(iphc1 & SICSLOWPAN_IPHC_M) {
1180 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1188 uint8_t prefix[] = {0xff, 0x02};
1189 if(tmp > 0 && tmp < 3) {
1194 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix,
1195 unc_mxconf[tmp], NULL);
1200 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1201 uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? PACKETBUF_IPHC_BUF[2] & 0x0f : 0;
1205 if(context == NULL) {
1206 LOG_ERR(
"uncompression: error context not found\n");
1209 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, context->prefix,
1211 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1214 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix,
1216 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1222 nhc = iphc0 & SICSLOWPAN_IPHC_NH_C;
1224 last_nextheader = &SICSLOWPAN_IP_BUF(buf)->proto;
1225 ip_payload = SICSLOWPAN_IPPAYLOAD_BUF(buf);
1227 while(nhc && (*
hc06_ptr & SICSLOWPAN_NHC_MASK) == SICSLOWPAN_NHC_EXT_HDR) {
1228 uint8_t eid = (*
hc06_ptr & 0x0e) >> 1;
1241 LOG_DBG(
"uncompression: next header is inlined. Next: %d\n", next);
1246 LOG_DBG(
"uncompression: found ext header id: %d next: %d len: %d\n", eid, next, len);
1248 case SICSLOWPAN_NHC_ETX_HDR_HBHO:
1251 case SICSLOWPAN_NHC_ETX_HDR_ROUTING:
1252 proto = UIP_PROTO_ROUTING;
1254 case SICSLOWPAN_NHC_ETX_HDR_FRAG:
1255 proto = UIP_PROTO_FRAG;
1257 case SICSLOWPAN_NHC_ETX_HDR_DESTO:
1258 proto = UIP_PROTO_DESTO;
1261 LOG_DBG(
"uncompression: error unsupported ext header\n");
1264 *last_nextheader = proto;
1266 exthdr = (
struct uip_ext_hdr *)ip_payload;
1267 exthdr->len = (2 + len) / 8 - 1;
1268 exthdr->next = next;
1269 last_nextheader = &exthdr->next;
1270 if(ip_len == 0 && (uint8_t *)exthdr -
uip_buf + 2 + len >
sizeof(
uip_buf)) {
1271 LOG_DBG(
"uncompression: ext header points beyond uip buffer boundary\n");
1274 memcpy((uint8_t*)exthdr + 2,
hc06_ptr, len);
1277 ip_payload += (exthdr->len + 1) * 8;
1278 ext_hdr_len += (exthdr->len + 1) * 8;
1280 LOG_DBG(
"uncompression: %d len: %d exhdrlen: %d (calc: %d)\n",
1281 proto, len, exthdr->len, (exthdr->len + 1) * 8);
1285 if(nhc && (*
hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
1286 struct uip_udp_hdr *udp_buf = (
struct uip_udp_hdr *)ip_payload;
1288 uint8_t checksum_compressed;
1289 *last_nextheader = UIP_PROTO_UDP;
1290 checksum_compressed = *
hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
1291 LOG_DBG(
"uncompression: incoming header value: %i\n", *
hc06_ptr);
1292 switch(*
hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
1293 case SICSLOWPAN_NHC_UDP_CS_P_00:
1295 memcpy(&udp_buf->srcport,
hc06_ptr + 1, 2);
1296 memcpy(&udp_buf->destport,
hc06_ptr + 3, 2);
1297 LOG_DBG(
"uncompression: UDP ports (ptr+5): %x, %x\n",
1303 case SICSLOWPAN_NHC_UDP_CS_P_01:
1305 LOG_DBG(
"uncompression: destination address\n");
1306 memcpy(&udp_buf->srcport,
hc06_ptr + 1, 2);
1307 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(
hc06_ptr + 3)));
1308 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1313 case SICSLOWPAN_NHC_UDP_CS_P_10:
1315 LOG_DBG(
"uncompression: source address\n");
1316 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
1318 memcpy(&udp_buf->destport,
hc06_ptr + 2, 2);
1319 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1324 case SICSLOWPAN_NHC_UDP_CS_P_11:
1326 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1328 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1330 LOG_DBG(
"uncompression: UDP ports (ptr+2): %x, %x\n",
1335 LOG_DBG(
"uncompression: error unsupported UDP compression\n");
1338 if(!checksum_compressed) {
1339 memcpy(&udp_buf->udpchksum,
hc06_ptr, 2);
1341 LOG_DBG(
"uncompression: checksum included\n");
1343 LOG_DBG(
"uncompression: checksum *NOT* included\n");
1348 udp_buf->udplen =
UIP_HTONS(ip_len == 0 ? udp_len :
1349 ip_len - UIP_IPH_LEN - ext_hdr_len);
1350 LOG_DBG(
"uncompression: UDP length: %u (ext: %u) ip_len: %d udp_len: %d\n",
1351 UIP_HTONS(udp_buf->udplen), ext_hdr_len, ip_len, udp_len);
1361 LOG_DBG(
"uncompression: IP payload length: %d. %u - %u + %u - %u\n", len,
1365 SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8;
1366 SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF;
1369 SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
1370 SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
1376 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH 1385 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] = SICSLOWPAN_DISPATCH_PAGING | (page & 0x0f);
1407 if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_PAGING_MASK) == SICSLOWPAN_DISPATCH_PAGING) {
1409 curr_page = PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & 0x0f;
1438 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 1440 compress_hdr_ipv6(linkaddr_t *link_destaddr)
1462 const linkaddr_t *dest;
1464 if(callback != NULL) {
1465 callback->output_callback(status);
1470 dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
1476 link_stats_packet_sent(dest, status, transmissions);
1479 NETSTACK_ROUTING.
link_callback(dest, status, transmissions);
1497 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, dest);
1499 #if NETSTACK_CONF_BRIDGE_MODE 1501 packetbuf_set_addr(PACKETBUF_ADDR_SENDER,(
void*)&
uip_lladdr);
1512 #if SICSLOWPAN_CONF_FRAG 1522 fragment_copy_payload_and_send(uint16_t uip_offset, linkaddr_t *dest) {
1531 q = queuebuf_new_from_packetbuf();
1533 LOG_WARN(
"output: could not allocate queuebuf, dropping fragment\n");
1541 queuebuf_to_packetbuf(q);
1548 LOG_ERR(
"output: error in fragment tx, dropping subsequent fragments.\n");
1591 if(localdest == NULL) {
1597 LOG_INFO(
"output: sending IPv6 packet with len %d\n",
uip_len);
1600 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
1601 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
1604 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
1605 #if LLSEC802154_USES_AUX_HEADER 1607 packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
1608 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
1609 #if LLSEC802154_USES_EXPLICIT_KEYS 1610 packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
1611 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_KEY_ID));
1619 LOG_WARN(
"output: failed to calculate payload size - dropping packet\n");
1624 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 1625 compress_hdr_ipv6(&dest);
1627 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH 1635 #if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC 1646 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
1649 LOG_INFO(
"output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
1655 #if SICSLOWPAN_CONF_FRAG 1657 uint16_t processed_ip_out_len;
1674 int fragn_max_payload = (
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
1676 int last_fragn_max_payload =
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
1678 int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
1680 int fragment_count = 2;
1681 if(middle_fragn_total_payload > 0) {
1682 fragment_count += 1 + (middle_fragn_total_payload - 1) / fragn_max_payload;
1685 int freebuf = queuebuf_numfree() - 1;
1686 LOG_INFO(
"output: fragmentation needed, fragments: %u, free queuebufs: %u\n",
1687 fragment_count, freebuf);
1689 if(freebuf < fragment_count) {
1690 LOG_WARN(
"output: dropping packet, not enough free bufs (needed: %u, free: %u)\n",
1691 fragment_count, freebuf);
1695 if(frag1_payload < 0) {
1699 LOG_WARN(
"output: compressed header does not fit first fragment\n");
1706 frag_tag = my_tag++;
1713 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1714 ((SICSLOWPAN_DISPATCH_FRAG1 << 8) |
uip_len));
1715 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
1722 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d)\n",
1723 curr_frag + 1, fragment_count,
1733 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1734 ((SICSLOWPAN_DISPATCH_FRAGN << 8) |
uip_len));
1740 while(processed_ip_out_len <
uip_len) {
1743 PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
1746 if(
uip_len - processed_ip_out_len > last_fragn_max_payload) {
1748 packetbuf_payload_len = fragn_max_payload;
1751 packetbuf_payload_len =
uip_len - processed_ip_out_len;
1756 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d, offset %d)\n",
1757 curr_frag + 1, fragment_count,
1758 frag_tag, packetbuf_payload_len, processed_ip_out_len);
1759 if(fragment_copy_payload_and_send(processed_ip_out_len, &dest) == 0) {
1766 LOG_ERR(
"output: Packet too large to be sent without fragmentation support; dropping packet\n");
1776 LOG_ERR(
"output: uip_len is smaller than uncomp_hdr_len (%d < %d)",
1805 uint16_t frag_size = 0;
1807 uint8_t frag_offset = 0;
1810 #if SICSLOWPAN_CONF_FRAG 1811 uint8_t is_fragment = 0;
1812 int8_t frag_context = 0;
1815 uint16_t frag_tag = 0;
1816 uint8_t first_fragment = 0, last_fragment = 0;
1820 link_stats_input_callback(packetbuf_addr(PACKETBUF_ADDR_SENDER));
1830 LOG_WARN(
"input: empty packet\n");
1842 last_rssi = (
signed short)packetbuf_attr(PACKETBUF_ATTR_RSSI);
1844 #if SICSLOWPAN_CONF_FRAG 1850 switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
1851 case SICSLOWPAN_DISPATCH_FRAG1:
1853 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1854 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1859 LOG_INFO(
"input: received first element of a fragmented packet (tag %d, len %d)\n",
1860 frag_tag, frag_size);
1863 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1865 if(frag_context == -1) {
1866 LOG_ERR(
"input: failed to allocate new reassembly context\n");
1870 buffer = frag_info[frag_context].first_frag;
1872 case SICSLOWPAN_DISPATCH_FRAGN:
1877 frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
1878 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1879 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1884 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1886 if(frag_context == -1) {
1887 LOG_ERR(
"input: reassembly context not found (tag %d)\n", frag_tag);
1895 if(frag_info[frag_context].reassembled_len >= frag_size) {
1904 if(is_fragment && !first_fragment) {
1914 LOG_INFO(
"input: page 1, 6LoRH\n");
1917 LOG_ERR(
"input: page %u not supported\n",
curr_page);
1923 (PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
1924 LOG_DBG(
"uncompression: IPHC dispatch\n");
1926 }
else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
1927 LOG_DBG(
"uncompression: IPV6 dispatch\n");
1937 LOG_ERR(
"uncompression: unknown dispatch: 0x%02x, or IPHC disabled\n",
1938 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK);
1942 #if SICSLOWPAN_CONF_FRAG 1953 LOG_ERR(
"input: packet dropped due to header > total packet\n");
1958 #if SICSLOWPAN_CONF_FRAG 1960 LOG_INFO(
"input: fragment (tag %d, payload %d, offset %d) -- %u %u\n",
1969 if(req_size >
sizeof(
uip_buf)) {
1970 #if SICSLOWPAN_CONF_FRAG 1972 "input: packet and fragment context %u dropped, minimum required IP_BUF size: %d+%d+%d=%d (current size: %u)\n",
1978 clear_fragments(frag_context);
1986 if(buffer != NULL) {
1992 #if SICSLOWPAN_CONF_FRAG 1995 if(first_fragment != 0) {
2001 if(last_fragment != 0) {
2002 frag_info[frag_context].reassembled_len = frag_size;
2004 if(!copy_frags2uip(frag_context)) {
2014 if(!is_fragment || last_fragment) {
2016 if(is_fragment != 0 && last_fragment != 0) {
2024 LOG_INFO(
"input: received IPv6 packet with len %d\n",
2027 if(LOG_DBG_ENABLED) {
2029 LOG_DBG(
"uncompression: after (%u):",
UIP_IP_BUF->len[1]);
2030 for (ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
2031 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
2032 LOG_DBG_(
"%02x", data);
2040 callback->input_callback();
2043 #if LLSEC802154_USES_AUX_HEADER 2048 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_LEVEL,
2049 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
2050 #if LLSEC802154_USES_EXPLICIT_KEYS 2051 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_KEY_ID,
2052 packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX));
2057 #if SICSLOWPAN_CONF_FRAG 2067 sicslowpan_init(
void)
2070 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC 2076 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 2077 addr_contexts[0].used = 1;
2078 addr_contexts[0].number = 0;
2079 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0 2080 SICSLOWPAN_CONF_ADDR_CONTEXT_0;
2082 addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0;
2083 addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1;
2087 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1 2091 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1 2093 addr_contexts[1].used = 1;
2094 addr_contexts[1].number = 1;
2095 SICSLOWPAN_CONF_ADDR_CONTEXT_1;
2096 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2 2098 addr_contexts[2].used = 1;
2099 addr_contexts[2].number = 2;
2100 SICSLOWPAN_CONF_ADDR_CONTEXT_2;
2103 addr_contexts[i].used = 0;
2106 addr_contexts[i].used = 0;
2116 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.
The MAC layer did not get an acknowledgement for the packet.
static void digest_paging_dispatch(void)
Digest 6lorh headers before IPHC.
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
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.
The MAC layer transmission was OK.
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
static void uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
Uncompress IPHC (i.e., IPHC and LOWPAN_UDP) headers and put them in sicslowpan_buf.
#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 ...
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.
The MAC layer transmission could not be performed because of a fatal error.
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.