65#include "dev/watchdog.h"
66#include "net/link-stats.h"
71#include "net/ipv6/uipbuf.h"
82#define LOG_MODULE "6LoWPAN"
83#define LOG_LEVEL LOG_LEVEL_6LOWPAN
85#define GET16(ptr,index) (((uint16_t)((ptr)[(index)] << 8)) | ((ptr)[(index) + 1]))
86#define SET16(ptr,index,value) do { \
87 (ptr)[(index)] = ((value) >> 8) & 0xff; \
88 (ptr)[(index) + 1] = (value) & 0xff; \
94#define PACKETBUF_FRAG_PTR (packetbuf_ptr)
95#define PACKETBUF_FRAG_DISPATCH_SIZE 0
96#define PACKETBUF_FRAG_TAG 2
97#define PACKETBUF_FRAG_OFFSET 4
100#define PACKETBUF_IPHC_BUF ((uint8_t *)(packetbuf_ptr + packetbuf_hdr_len))
101#define PACKETBUF_PAYLOAD_END ((uint8_t *)(packetbuf_ptr + mac_max_payload))
103#define PACKETBUF_6LO_PTR (packetbuf_ptr + packetbuf_hdr_len)
104#define PACKETBUF_6LO_DISPATCH 0
105#define PACKETBUF_6LO_ENCODING 1
106#define PACKETBUF_6LO_TTL 2
108#define PACKETBUF_6LO_HC_UDP_PTR (packetbuf_ptr + packetbuf_hdr_len)
109#define PACKETBUF_6LO_HC_UDP_DISPATCH 0
110#define PACKETBUF_6LO_HC_UDP_HC1_ENCODING 1
111#define PACKETBUF_6LO_HC_UDP_UDP_ENCODING 2
112#define PACKETBUF_6LO_HC_UDP_TTL 3
113#define PACKETBUF_6LO_HC_UDP_PORTS 4
114#define PACKETBUF_6LO_HC_UDP_CHKSUM 5
123#define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf)
124#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN])
125#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_IPH_LEN])
127#define UIP_IPPAYLOAD_BUF_POS(pos) (&uip_buf[UIP_IPH_LEN + (pos)])
128#define UIP_UDP_BUF_POS(pos) ((struct uip_udp_hdr *)UIP_IPPAYLOAD_BUF_POS(pos))
129#define UIP_EXT_HDR_LEN 2
134#ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR
135#define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR
138#define COMPRESS_EXT_HDR 1
142#define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP \
143 || x == UIP_PROTO_HBHO \
144 || x == UIP_PROTO_DESTO \
145 || x == UIP_PROTO_ROUTING \
146 || x == UIP_PROTO_FRAG)
148#define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP)
203#if SICSLOWPAN_CONF_FRAG
204static 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)
244struct sicslowpan_frag_info {
252 uint16_t reassembled_len;
254 struct timer reass_timer;
257 uint16_t first_frag_len;
260 uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE];
263static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS];
265struct sicslowpan_frag_buf {
272 uint8_t data[SICSLOWPAN_FRAGMENT_SIZE];
275static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS];
279clear_fragments(uint8_t frag_info_index)
283 frag_info[frag_info_index].len = 0;
284 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
285 if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) {
295timeout_fragments(
int not_context)
299 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
300 if(frag_info[i].len > 0 && i != not_context &&
303 count += clear_fragments(i);
310store_fragment(uint8_t index, uint8_t offset)
317 if(len <= 0 || len > SICSLOWPAN_FRAGMENT_SIZE) {
325 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
326 if(frag_buf[i].len > 0 && frag_buf[i].index == index &&
327 frag_buf[i].offset == offset) {
332 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
333 if(frag_buf[i].len == 0) {
336 frag_buf[i].offset = offset;
337 frag_buf[i].len = len;
338 frag_buf[i].index = index;
350add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
358 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
360 if(frag_info[i].len > 0 &&
timer_expired(&frag_info[i].reass_timer)) {
366 if(frag_info[i].len > 0 && frag_info[i].tag == tag &&
368 packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
375 if(found < 0 && frag_info[i].len == 0) {
383 LOG_WARN(
"reassembly: failed to store new fragment session - tag: %d\n", tag);
391 frag_info[found].len = frag_size;
392 frag_info[found].reassembled_len = 0;
393 frag_info[found].first_frag_len = 0;
394 frag_info[found].tag = tag;
396 packetbuf_addr(PACKETBUF_ADDR_SENDER));
404 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
405 if(frag_info[i].tag == tag && frag_info[i].len > 0 &&
406 linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
415 LOG_WARN(
"reassembly: failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
420 len = store_fragment(i, offset);
421 if(len < 0 && timeout_fragments(i) > 0) {
422 len = store_fragment(i, offset);
425 frag_info[i].reassembled_len += len;
427 }
else if(len == 0) {
433 LOG_WARN(
"reassembly: failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
441copy_frags2uip(
int context)
446 if(frag_info[context].len < frag_info[context].first_frag_len ||
447 frag_info[context].len >
sizeof(
uip_buf)) {
448 LOG_WARN(
"input: invalid total size of fragments\n");
449 clear_fragments(context);
454 memcpy((uint8_t *)
UIP_IP_BUF, (uint8_t *)frag_info[context].first_frag,
455 frag_info[context].first_frag_len);
458 memset((uint8_t *)
UIP_IP_BUF + frag_info[context].first_frag_len, 0,
459 frag_info[context].len - frag_info[context].first_frag_len);
461 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
463 if(frag_buf[i].len > 0 && frag_buf[i].index == context) {
464 if(((
size_t)frag_buf[i].offset << 3) + frag_buf[i].len >
sizeof(
uip_buf)) {
465 LOG_WARN(
"input: invalid fragment offset\n");
466 clear_fragments(context);
469 memcpy((uint8_t *)
UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3),
470 (uint8_t *)frag_buf[i].data, frag_buf[i].len);
474 clear_fragments(context);
485static struct netstack_sniffer *callback = NULL;
488netstack_sniffer_add(
struct netstack_sniffer *s)
494netstack_sniffer_remove(
struct netstack_sniffer *s)
500set_packet_attrs(
void)
504 packetbuf_set_attr(PACKETBUF_ATTR_NETWORK_ID,
UIP_IP_BUF->proto);
508 c = UIP_UDP_BUF_POS(0)->srcport;
509 if(UIP_UDP_BUF_POS(0)->destport < c) {
510 c = UIP_UDP_BUF_POS(0)->destport;
512 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_TCP) {
513 c = UIP_TCP_BUF->srcport;
514 if(UIP_TCP_BUF->destport < c) {
515 c = UIP_TCP_BUF->destport;
517 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
521 packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, c);
531#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
537#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
543static uint8_t *iphc_ptr;
552const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
559const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
566const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};
569const uint8_t llprefix[] = {0xfe, 0x80};
572static const uint8_t ttl_values[] = {0, 1, 64, 255};
581addr_context_lookup_by_prefix(uip_ipaddr_t *
ipaddr)
584#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
587 if((addr_contexts[i].used == 1) &&
588 uip_ipaddr_prefixcmp(&addr_contexts[i].prefix,
ipaddr, 64)) {
589 return &addr_contexts[i];
598addr_context_lookup_by_number(uint8_t number)
601#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
604 if((addr_contexts[i].used == 1) &&
605 addr_contexts[i].number == number) {
606 return &addr_contexts[i];
614compress_addr_64(uint8_t bitpos, uip_ipaddr_t *
ipaddr,
615 const uip_lladdr_t *lladdr)
621 memcpy(iphc_ptr, &
ipaddr->u16[7], 2);
626 memcpy(iphc_ptr, &
ipaddr->u16[4], 8);
640uncompress_addr(uip_ipaddr_t *
ipaddr, uint8_t
const prefix[],
641 uint8_t pref_post_count, uip_lladdr_t *lladdr)
643 uint8_t prefcount = pref_post_count >> 4;
644 uint8_t postcount = pref_post_count & 0x0f;
646 prefcount = prefcount == 15 ? 16 : prefcount;
647 postcount = postcount == 15 ? 16 : postcount;
649 LOG_DBG(
"uncompression: address %d %d ", prefcount, postcount);
652 memcpy(
ipaddr, prefix, prefcount);
654 if(prefcount + postcount < 16) {
655 memset(&
ipaddr->u8[prefcount], 0, 16 - (prefcount + postcount));
659 LOG_WARN(
"Insufficient packet data to decompress IP address\n");
663 memcpy(&
ipaddr->u8[16 - postcount], iphc_ptr, postcount);
664 if(postcount == 2 && prefcount < 11) {
669 iphc_ptr += postcount;
670 }
else if (prefcount > 0) {
715compress_hdr_iphc(
void)
717 uint8_t tmp, iphc0, iphc1, *next_hdr, *next_nhc;
719 struct uip_udp_hdr *udp_buf;
721 if(LOG_DBG_ENABLED) {
723 LOG_DBG(
"compression: before (%d): ",
UIP_IP_BUF->len[1]);
724 for(ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
725 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
726 LOG_DBG_(
"%02x", data);
733#define CHECK_BUFFER_SPACE(writelen) do { \
734 if(iphc_ptr + (writelen) >= PACKETBUF_PAYLOAD_END) { \
735 LOG_WARN("Not enough packetbuf space to compress header (%u bytes, %u left). Aborting.\n", \
736 (unsigned)(writelen), (unsigned)(PACKETBUF_PAYLOAD_END - iphc_ptr)); \
741 iphc_ptr = PACKETBUF_IPHC_BUF + 2;
746 CHECK_BUFFER_SPACE(38);
755 iphc0 = SICSLOWPAN_DISPATCH_IPHC;
757 PACKETBUF_IPHC_BUF[2] = 0;
768 addr_context_lookup_by_prefix(&
UIP_IP_BUF->srcipaddr);
770 addr_context_lookup_by_prefix(&
UIP_IP_BUF->destipaddr);
771 if(source_context || destination_context) {
773 LOG_DBG(
"compression: dest or src ipaddr - setting CID\n");
774 iphc1 |= SICSLOWPAN_IPHC_CID;
788 tmp = ((tmp & 0x03) << 6) | (tmp >> 2);
793 iphc0 |= SICSLOWPAN_IPHC_FL_C;
797 iphc0 |= SICSLOWPAN_IPHC_TC_C;
808 iphc0 |= SICSLOWPAN_IPHC_TC_C;
809 *iphc_ptr = (tmp & 0xc0) |
825 if(IS_COMPRESSABLE_PROTO(
UIP_IP_BUF->proto)) {
826 iphc0 |= SICSLOWPAN_IPHC_NH_C;
830 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
844 iphc0 |= SICSLOWPAN_IPHC_TTL_1;
847 iphc0 |= SICSLOWPAN_IPHC_TTL_64;
850 iphc0 |= SICSLOWPAN_IPHC_TTL_255;
860 LOG_DBG(
"compression: addr unspecified - setting SAC\n");
861 iphc1 |= SICSLOWPAN_IPHC_SAC;
862 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
863 }
else if(source_context) {
865 LOG_DBG(
"compression: src with context - setting CID & SAC ctx: %d\n",
866 source_context->number);
867 iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
868 PACKETBUF_IPHC_BUF[2] |= source_context->number << 4;
871 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
878 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
882 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
883 memcpy(iphc_ptr, &
UIP_IP_BUF->srcipaddr.u16[0], 16);
890 iphc1 |= SICSLOWPAN_IPHC_M;
891 if(sicslowpan_is_mcast_addr_compressable8(&
UIP_IP_BUF->destipaddr)) {
892 iphc1 |= SICSLOWPAN_IPHC_DAM_11;
896 }
else if(sicslowpan_is_mcast_addr_compressable32(&
UIP_IP_BUF->destipaddr)) {
897 iphc1 |= SICSLOWPAN_IPHC_DAM_10;
900 memcpy(iphc_ptr + 1, &
UIP_IP_BUF->destipaddr.u8[13], 3);
902 }
else if(sicslowpan_is_mcast_addr_compressable48(&
UIP_IP_BUF->destipaddr)) {
903 iphc1 |= SICSLOWPAN_IPHC_DAM_01;
906 memcpy(iphc_ptr + 1, &
UIP_IP_BUF->destipaddr.u8[11], 5);
909 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
911 memcpy(iphc_ptr, &
UIP_IP_BUF->destipaddr.u8[0], 16);
916 if(destination_context) {
918 iphc1 |= SICSLOWPAN_IPHC_DAC;
919 PACKETBUF_IPHC_BUF[2] |= destination_context->number;
922 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
924 (
const uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
930 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
932 (
const uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
935 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
936 memcpy(iphc_ptr, &
UIP_IP_BUF->destipaddr.u16[0], 16);
947 LOG_DBG(
"compression: first header: %d\n", *next_hdr);
948 while(next_hdr != NULL && IS_COMPRESSABLE_PROTO(*next_hdr)) {
949 LOG_DBG(
"compression: next header: %d\n", *next_hdr);
954 proto = SICSLOWPAN_NHC_ETX_HDR_HBHO;
955 case UIP_PROTO_ROUTING:
956 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_ROUTING : proto;
958 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_FRAG : proto;
959 case UIP_PROTO_DESTO:
962 struct uip_ext_hdr *ext_hdr =
963 (
struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF_POS(ext_hdr_len);
965 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
967 len = (ext_hdr->len << 3) + 8;
968 LOG_DBG(
"compression: next header %d (len:%d)\n", *next_hdr, len);
970 next_hdr = &ext_hdr->next;
974 if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
975 CHECK_BUFFER_SPACE(1);
977 LOG_DBG(
"compression: keeping the next header in this ext hdr: %d\n",
981 CHECK_BUFFER_SPACE(len);
982 memcpy(iphc_ptr, ext_hdr, len);
984 ext_hdr = (
struct uip_ext_hdr *) iphc_ptr;
985 ext_hdr->len = len - 2;
992 *next_nhc = SICSLOWPAN_NHC_EXT_HDR |
993 (IS_COMPRESSABLE_PROTO(*next_hdr) ? SICSLOWPAN_NHC_BIT : 0) |
1002 udp_buf = UIP_UDP_BUF_POS(ext_hdr_len);
1003 LOG_DBG(
"compression: inlined UDP ports on send side: %x, %x\n",
1006 if(((
UIP_HTONS(udp_buf->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
1007 ((
UIP_HTONS(udp_buf->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
1009 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
1010 LOG_DBG(
"IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
1011 CHECK_BUFFER_SPACE(1);
1013 (uint8_t)((
UIP_HTONS(udp_buf->srcport) -
1014 SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
1015 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
1016 SICSLOWPAN_UDP_4_BIT_PORT_MIN));
1018 }
else if((
UIP_HTONS(udp_buf->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
1020 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
1021 LOG_DBG(
"IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
1022 CHECK_BUFFER_SPACE(3);
1023 memcpy(iphc_ptr, &udp_buf->srcport, 2);
1025 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
1026 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
1028 }
else if((
UIP_HTONS(udp_buf->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
1030 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_10;
1031 LOG_DBG(
"IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
1032 CHECK_BUFFER_SPACE(3);
1034 (uint8_t)((
UIP_HTONS(udp_buf->srcport) -
1035 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
1036 memcpy(iphc_ptr + 1, &udp_buf->destport, 2);
1040 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
1041 LOG_DBG(
"IPHC: cannot compress UDP headers\n");
1042 CHECK_BUFFER_SPACE(4);
1043 memcpy(iphc_ptr, &udp_buf->srcport, 4);
1047 CHECK_BUFFER_SPACE(2);
1048 memcpy(iphc_ptr, &udp_buf->udpchksum, 2);
1055 LOG_ERR(
"compression: could not handle compression of header");
1058 if(next_hdr != NULL) {
1061 LOG_DBG(
"compression: last header could is not compressed: %d\n", *next_hdr);
1064 PACKETBUF_IPHC_BUF[0] = iphc0;
1065 PACKETBUF_IPHC_BUF[1] = iphc1;
1067 if(LOG_DBG_ENABLED) {
1069 LOG_DBG(
"compression: after (%d): ", (
int)(iphc_ptr -
packetbuf_ptr));
1072 LOG_DBG_(
"%02x", data);
1102uncompress_hdr_iphc(uint8_t *buf, uint16_t buf_size, uint16_t ip_len)
1104 uint8_t tmp, iphc0, iphc1, nhc;
1105 struct uip_ext_hdr *exthdr;
1106 uint8_t* last_nextheader;
1107 uint8_t* ip_payload;
1108 uint8_t ext_hdr_len = 0;
1113#define CHECK_READ_SPACE(readlen) \
1114 if((iphc_ptr - packetbuf_ptr) + (readlen) > cmpr_len) { \
1115 LOG_WARN("Not enough packetbuf space to decompress header (%u bytes, %u left). Aborting.\n", \
1116 (unsigned)(readlen), (unsigned)(cmpr_len - (iphc_ptr - packetbuf_ptr))); \
1127 iphc0 = PACKETBUF_IPHC_BUF[0];
1128 iphc1 = PACKETBUF_IPHC_BUF[1];
1131 if(iphc1 & SICSLOWPAN_IPHC_CID) {
1135 LOG_DBG(
"uncompression: CID flag set - increase header with one\n");
1140 if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) {
1142 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1144 CHECK_READ_SPACE(4);
1145 memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow, iphc_ptr + 1, 3);
1150 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f);
1152 SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) |
1153 (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f);
1156 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1158 CHECK_READ_SPACE(3);
1159 SICSLOWPAN_IP_BUF(buf)->tcflow = (*iphc_ptr & 0x0F) |
1160 ((*iphc_ptr >> 2) & 0x30);
1161 memcpy(&SICSLOWPAN_IP_BUF(buf)->flow, iphc_ptr + 1, 2);
1167 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1169 CHECK_READ_SPACE(1);
1170 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*iphc_ptr >> 2) & 0x0f);
1171 SICSLOWPAN_IP_BUF(buf)->tcflow = ((*iphc_ptr << 6) & 0xC0) | ((*iphc_ptr >> 2) & 0x30);
1172 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1176 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1177 SICSLOWPAN_IP_BUF(buf)->tcflow = 0;
1178 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1183 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
1185 CHECK_READ_SPACE(1);
1186 SICSLOWPAN_IP_BUF(buf)->proto = *iphc_ptr;
1187 LOG_DBG(
"uncompression: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
1192 if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) {
1193 SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03];
1195 CHECK_READ_SPACE(1);
1196 SICSLOWPAN_IP_BUF(buf)->ttl = *iphc_ptr;
1201 tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03;
1204 if(iphc1 & SICSLOWPAN_IPHC_SAC) {
1205 uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
1206 PACKETBUF_IPHC_BUF[2] >> 4 : 0;
1211 source_context = addr_context_lookup_by_number(sci);
1212 if(!source_context) {
1213 LOG_ERR(
"uncompression: error source context not found\n");
1217 source_context = NULL;
1220 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr,
1221 source_context ? source_context->prefix : NULL,
1223 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
1228 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix,
1230 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
1237 tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03;
1240 if(iphc1 & SICSLOWPAN_IPHC_M) {
1242 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1250 uint8_t prefix[] = {0xff, 0x02};
1251 if(tmp > 0 && tmp < 3) {
1252 CHECK_READ_SPACE(1);
1253 prefix[1] = *iphc_ptr;
1257 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix,
1258 unc_mxconf[tmp], NULL)) {
1265 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1266 uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? PACKETBUF_IPHC_BUF[2] & 0x0f : 0;
1268 addr_context_lookup_by_number(dci);
1271 if(!destination_context) {
1272 LOG_ERR(
"uncompression: error destination context not found\n");
1275 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr,
1276 destination_context->prefix,
1278 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
1283 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix,
1285 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
1293 nhc = iphc0 & SICSLOWPAN_IPHC_NH_C;
1295 last_nextheader = &SICSLOWPAN_IP_BUF(buf)->proto;
1296 ip_payload = SICSLOWPAN_IPPAYLOAD_BUF(buf);
1298 CHECK_READ_SPACE(1);
1299 while(nhc && (*iphc_ptr & SICSLOWPAN_NHC_MASK) == SICSLOWPAN_NHC_EXT_HDR) {
1300 uint8_t eid = (*iphc_ptr & 0x0e) >> 1;
1302 uint8_t nh = (*iphc_ptr & 0x01);
1310 CHECK_READ_SPACE(1);
1314 LOG_DBG(
"uncompression: next header is inlined. Next: %d\n", next);
1316 CHECK_READ_SPACE(1);
1320 LOG_DBG(
"uncompression: found ext header id: %d next: %d len: %d\n", eid, next, len);
1322 case SICSLOWPAN_NHC_ETX_HDR_HBHO:
1325 case SICSLOWPAN_NHC_ETX_HDR_ROUTING:
1326 proto = UIP_PROTO_ROUTING;
1328 case SICSLOWPAN_NHC_ETX_HDR_FRAG:
1329 proto = UIP_PROTO_FRAG;
1331 case SICSLOWPAN_NHC_ETX_HDR_DESTO:
1332 proto = UIP_PROTO_DESTO;
1335 LOG_DBG(
"uncompression: error unsupported ext header\n");
1338 *last_nextheader = proto;
1341 if((ip_payload - buf) + UIP_EXT_HDR_LEN + len > buf_size) {
1342 LOG_WARN(
"uncompression: cannot write ext header beyond target buffer\n");
1347 exthdr = (
struct uip_ext_hdr *)ip_payload;
1348 if((UIP_EXT_HDR_LEN + len) < 8 || (UIP_EXT_HDR_LEN + len) % 8 != 0) {
1349 LOG_WARN(
"Extension header length %u is not a valid multiple of 8\n",
1350 (
unsigned)(UIP_EXT_HDR_LEN + len));
1353 exthdr->len = (UIP_EXT_HDR_LEN + len) / 8 - 1;
1354 exthdr->next = next;
1355 last_nextheader = &exthdr->next;
1358 CHECK_READ_SPACE(len + 1);
1359 memcpy((uint8_t *)exthdr + UIP_EXT_HDR_LEN, iphc_ptr, len);
1363 ip_payload += (exthdr->len + 1) * 8;
1364 ext_hdr_len += (exthdr->len + 1) * 8;
1366 LOG_DBG(
"uncompression: %d len: %d exthdr len: %d (calc: %d)\n",
1367 proto, len, exthdr->len, (exthdr->len + 1) * 8);
1371 CHECK_READ_SPACE(1);
1372 if(nhc && (*iphc_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
1373 struct uip_udp_hdr *udp_buf;
1375 uint8_t checksum_compressed;
1378 if((ip_payload - buf) + UIP_UDPH_LEN > buf_size) {
1379 LOG_WARN(
"uncompression: cannot write UDP header beyond target buffer\n");
1383 udp_buf = (
struct uip_udp_hdr *)ip_payload;
1384 *last_nextheader = UIP_PROTO_UDP;
1385 checksum_compressed = *iphc_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
1386 LOG_DBG(
"uncompression: incoming header value: %i\n", *iphc_ptr);
1387 switch(*iphc_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
1388 case SICSLOWPAN_NHC_UDP_CS_P_00:
1390 CHECK_READ_SPACE(5);
1391 memcpy(&udp_buf->srcport, iphc_ptr + 1, 2);
1392 memcpy(&udp_buf->destport, iphc_ptr + 3, 2);
1393 LOG_DBG(
"uncompression: UDP ports (ptr+5): %x, %x\n",
1399 case SICSLOWPAN_NHC_UDP_CS_P_01:
1401 LOG_DBG(
"uncompression: destination address\n");
1402 CHECK_READ_SPACE(4);
1403 memcpy(&udp_buf->srcport, iphc_ptr + 1, 2);
1404 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(iphc_ptr + 3)));
1405 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1410 case SICSLOWPAN_NHC_UDP_CS_P_10:
1412 LOG_DBG(
"uncompression: source address\n");
1413 CHECK_READ_SPACE(4);
1414 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
1416 memcpy(&udp_buf->destport, iphc_ptr + 2, 2);
1417 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1422 case SICSLOWPAN_NHC_UDP_CS_P_11:
1424 CHECK_READ_SPACE(2);
1425 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1426 (*(iphc_ptr + 1) >> 4));
1427 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1428 ((*(iphc_ptr + 1)) & 0x0F));
1429 LOG_DBG(
"uncompression: UDP ports (ptr+2): %x, %x\n",
1435 LOG_DBG(
"uncompression: error unsupported UDP compression\n");
1438 if(!checksum_compressed) {
1439 CHECK_READ_SPACE(2);
1440 memcpy(&udp_buf->udpchksum, iphc_ptr, 2);
1442 LOG_DBG(
"uncompression: checksum included\n");
1444 LOG_DBG(
"uncompression: checksum *NOT* included\n");
1449 udp_buf->udplen =
UIP_HTONS(ip_len == 0 ? udp_len :
1450 ip_len - UIP_IPH_LEN - ext_hdr_len);
1451 LOG_DBG(
"uncompression: UDP length: %u (ext: %u) ip_len: %d udp_len: %d\n",
1452 UIP_HTONS(udp_buf->udplen), ext_hdr_len, ip_len, udp_len);
1462 LOG_DBG(
"uncompression: IP payload length: %d. %u - %u + %u - %u\n", len,
1466 SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8;
1467 SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF;
1470 SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
1471 SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
1479#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1485add_paging_dispatch(uint8_t page)
1488 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] = SICSLOWPAN_DISPATCH_PAGING | (page & 0x0f);
1510 if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_PAGING_MASK) == SICSLOWPAN_DISPATCH_PAGING) {
1512 curr_page = PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & 0x0f;
1541#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1543compress_hdr_ipv6(
void)
1563 const linkaddr_t *dest;
1565 if(callback != NULL) {
1566 callback->output_callback(status);
1571 dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
1577 link_stats_packet_sent(dest, status, transmissions);
1580 NETSTACK_ROUTING.link_callback(dest, status, transmissions);
1601#if SICSLOWPAN_CONF_FRAG
1611fragment_copy_payload_and_send(uint16_t uip_offset)
1621 q = queuebuf_new_from_packetbuf();
1623 LOG_WARN(
"output: could not allocate queuebuf, dropping fragment\n");
1631 queuebuf_to_packetbuf(q);
1637 LOG_ERR(
"output: error in fragment tx, dropping subsequent fragments.\n");
1672 LOG_INFO(
"output: sending IPv6 packet with len %d\n",
uip_len);
1675 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
1676 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
1679 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER,
1682#if LLSEC802154_USES_AUX_HEADER
1684 packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
1685 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
1686#if LLSEC802154_USES_EXPLICIT_KEYS
1687 packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
1688 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_KEY_ID));
1697 LOG_WARN(
"output: failed to calculate payload size - dropping packet\n");
1702#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1703 compress_hdr_ipv6();
1705#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1709 add_paging_dispatch(1);
1713#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
1714 if(compress_hdr_iphc() == 0) {
1725 LOG_INFO(
"output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
1731#if SICSLOWPAN_CONF_FRAG
1733 uint16_t processed_ip_out_len;
1750 int fragn_max_payload = (
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
1752 int last_fragn_max_payload =
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
1754 int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
1756 unsigned fragment_count = 2;
1757 if(middle_fragn_total_payload > 0) {
1758 fragment_count += 1 + (middle_fragn_total_payload - 1) / fragn_max_payload;
1761 size_t free_bufs = queuebuf_numfree();
1762 LOG_INFO(
"output: fragmentation needed. fragments: %u, free queuebufs: %zu\n",
1763 fragment_count, free_bufs);
1767 size_t needed_bufs = fragment_count + 1;
1768 if(free_bufs < needed_bufs) {
1769 LOG_WARN(
"output: dropping packet, not enough free bufs (needed: %zu, free: %zu)\n",
1770 needed_bufs, free_bufs);
1774 if(frag1_payload < 0) {
1778 LOG_WARN(
"output: compressed header does not fit first fragment\n");
1785 frag_tag = my_tag++;
1792 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1793 ((SICSLOWPAN_DISPATCH_FRAG1 << 8) |
uip_len));
1794 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
1801 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d)\n",
1802 curr_frag + 1, fragment_count,
1812 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1813 ((SICSLOWPAN_DISPATCH_FRAGN << 8) |
uip_len));
1819 while(processed_ip_out_len <
uip_len) {
1822 PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
1825 if(
uip_len - processed_ip_out_len > last_fragn_max_payload) {
1835 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d, offset %d)\n",
1836 curr_frag + 1, fragment_count,
1838 if(fragment_copy_payload_and_send(processed_ip_out_len) == 0) {
1845 LOG_ERR(
"output: Packet too large to be sent without fragmentation support; dropping packet\n");
1855 LOG_ERR(
"output: uip_len is smaller than uncomp_hdr_len (%d < %d)",
1884 uint16_t frag_size = 0;
1886 uint8_t frag_offset = 0;
1888 uint16_t buffer_size;
1890#if SICSLOWPAN_CONF_FRAG
1891 uint8_t is_fragment = 0;
1892 int8_t frag_context = 0;
1895 uint16_t frag_tag = 0;
1896 uint8_t first_fragment = 0, last_fragment = 0;
1900 link_stats_input_callback(packetbuf_addr(PACKETBUF_ADDR_SENDER));
1910 LOG_WARN(
"input: empty packet\n");
1923 uipbuf_set_attr(UIPBUF_ATTR_RSSI, packetbuf_attr(PACKETBUF_ATTR_RSSI));
1924 uipbuf_set_attr(UIPBUF_ATTR_LINK_QUALITY, packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));
1927#if SICSLOWPAN_CONF_FRAG
1933 switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
1934 case SICSLOWPAN_DISPATCH_FRAG1:
1936 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1937 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1942 LOG_INFO(
"input: received first element of a fragmented packet (tag %d, len %d)\n",
1943 frag_tag, frag_size);
1946 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1948 if(frag_context == -1) {
1949 LOG_ERR(
"input: failed to allocate new reassembly context\n");
1953 buffer = frag_info[frag_context].first_frag;
1954 buffer_size = SICSLOWPAN_FIRST_FRAGMENT_SIZE;
1956 case SICSLOWPAN_DISPATCH_FRAGN:
1961 frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
1962 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1963 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1968 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1970 if(frag_context == -1) {
1971 LOG_ERR(
"input: reassembly context not found (tag %d)\n", frag_tag);
1979 if(frag_info[frag_context].reassembled_len >= frag_size) {
1988 if(is_fragment && !first_fragment) {
1998 LOG_INFO(
"input: page 1, 6LoRH\n");
2001 LOG_ERR(
"input: page %u not supported\n",
curr_page);
2007 (PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
2008 LOG_DBG(
"uncompression: IPHC dispatch\n");
2009 if(uncompress_hdr_iphc(buffer, buffer_size, frag_size) ==
false) {
2010 LOG_ERR(
"input: failed to decompress IPHC packet\n");
2013 }
else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
2014 LOG_DBG(
"uncompression: IPV6 dispatch\n");
2024 LOG_ERR(
"uncompression: unknown dispatch: 0x%02x, or IPHC disabled\n",
2025 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK);
2029#if SICSLOWPAN_CONF_FRAG
2040 LOG_ERR(
"input: packet dropped due to header > total packet\n");
2045#if SICSLOWPAN_CONF_FRAG
2047 LOG_INFO(
"input: fragment (tag %d, payload %d, offset %d) -- %u %u\n",
2054 unsigned int req_size =
uncomp_hdr_len + (uint16_t)(frag_offset << 3)
2056 if(req_size >
sizeof(
uip_buf)) {
2057#if SICSLOWPAN_CONF_FRAG
2059 "input: packet and fragment context %u dropped, minimum required IP_BUF size: %d+%d+%d=%u (current size: %u)\n",
2065 clear_fragments(frag_context);
2073 if(buffer != NULL) {
2075 LOG_ERR(
"input: cannot copy the payload into the buffer\n");
2083#if SICSLOWPAN_CONF_FRAG
2086 if(first_fragment != 0) {
2092 if(last_fragment != 0) {
2093 frag_info[frag_context].reassembled_len = frag_size;
2095 if(!copy_frags2uip(frag_context)) {
2105 if(!is_fragment || last_fragment) {
2107 if(is_fragment != 0 && last_fragment != 0) {
2115 LOG_INFO(
"input: received IPv6 packet with len %d\n",
2118 if(LOG_DBG_ENABLED) {
2120 LOG_DBG(
"uncompression: after (%u):",
UIP_IP_BUF->len[1]);
2121 for (ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
2122 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
2123 LOG_DBG_(
"%02x", data);
2131 callback->input_callback();
2134#if LLSEC802154_USES_AUX_HEADER
2139 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_LEVEL,
2140 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
2141#if LLSEC802154_USES_EXPLICIT_KEYS
2142 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_KEY_ID,
2143 packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX));
2148#if SICSLOWPAN_CONF_FRAG
2158sicslowpan_init(
void)
2161#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC
2167#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
2168 addr_contexts[0].used = 1;
2169 addr_contexts[0].number = 0;
2170#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0
2171 SICSLOWPAN_CONF_ADDR_CONTEXT_0;
2173 addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0;
2174 addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1;
2178#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1
2182#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1
2184 addr_contexts[1].used = 1;
2185 addr_contexts[1].number = 1;
2186 SICSLOWPAN_CONF_ADDR_CONTEXT_1;
2187#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2
2189 addr_contexts[2].used = 1;
2190 addr_contexts[2].number = 2;
2191 SICSLOWPAN_CONF_ADDR_CONTEXT_2;
2194 addr_contexts[i].used = 0;
2197 addr_contexts[i].used = 0;
802.15.4 frame creation and parsing functions
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 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.
#define sicslowpan_is_iid_16_bit_compressable(a)
check whether we can compress the IID in address 'a' to 16 bits.
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 void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
static uint8_t packetbuf_hdr_len
packetbuf_hdr_len is the total length of (the processed) 6lowpan headers (fragment headers,...
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.
bool 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
Determines whether the 6LoWPAN layer uses IP header compression.
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).
The structure of a network driver in Contiki.
An address context for IPHC address compression each context can have upto 8 bytes.
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.