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) {
322 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
323 if(frag_buf[i].len == 0) {
326 frag_buf[i].offset = offset;
327 frag_buf[i].len = len;
328 frag_buf[i].index = index;
340add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
348 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
350 if(frag_info[i].len > 0 &&
timer_expired(&frag_info[i].reass_timer)) {
355 if(found < 0 && frag_info[i].len == 0) {
363 LOG_WARN(
"reassembly: failed to store new fragment session - tag: %d\n", tag);
368 frag_info[found].len = frag_size;
369 frag_info[found].tag = tag;
371 packetbuf_addr(PACKETBUF_ADDR_SENDER));
379 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
380 if(frag_info[i].tag == tag && frag_info[i].len > 0 &&
381 linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
390 LOG_WARN(
"reassembly: failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
395 len = store_fragment(i, offset);
396 if(len < 0 && timeout_fragments(i) > 0) {
397 len = store_fragment(i, offset);
400 frag_info[i].reassembled_len += len;
405 LOG_WARN(
"reassembly: failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
413copy_frags2uip(
int context)
418 if(frag_info[context].len < frag_info[context].first_frag_len ||
419 frag_info[context].len >
sizeof(
uip_buf)) {
420 LOG_WARN(
"input: invalid total size of fragments\n");
421 clear_fragments(context);
426 memcpy((uint8_t *)
UIP_IP_BUF, (uint8_t *)frag_info[context].first_frag,
427 frag_info[context].first_frag_len);
430 memset((uint8_t *)
UIP_IP_BUF + frag_info[context].first_frag_len, 0,
431 frag_info[context].len - frag_info[context].first_frag_len);
433 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
435 if(frag_buf[i].len > 0 && frag_buf[i].index == context) {
436 if(((
size_t)frag_buf[i].offset << 3) + frag_buf[i].len >
sizeof(
uip_buf)) {
437 LOG_WARN(
"input: invalid fragment offset\n");
438 clear_fragments(context);
441 memcpy((uint8_t *)
UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3),
442 (uint8_t *)frag_buf[i].data, frag_buf[i].len);
446 clear_fragments(context);
457static struct netstack_sniffer *callback = NULL;
460netstack_sniffer_add(
struct netstack_sniffer *s)
466netstack_sniffer_remove(
struct netstack_sniffer *s)
472set_packet_attrs(
void)
476 packetbuf_set_attr(PACKETBUF_ATTR_NETWORK_ID,
UIP_IP_BUF->proto);
480 c = UIP_UDP_BUF_POS(0)->srcport;
481 if(UIP_UDP_BUF_POS(0)->destport < c) {
482 c = UIP_UDP_BUF_POS(0)->destport;
484 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_TCP) {
485 c = UIP_TCP_BUF->srcport;
486 if(UIP_TCP_BUF->destport < c) {
487 c = UIP_TCP_BUF->destport;
489 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
493 packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, c);
503#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
509#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
524const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
531const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
538const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};
541const uint8_t llprefix[] = {0xfe, 0x80};
544static const uint8_t ttl_values[] = {0, 1, 64, 255};
556#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
559 if((addr_contexts[i].used == 1) &&
560 uip_ipaddr_prefixcmp(&addr_contexts[i].prefix,
ipaddr, 64)) {
561 return &addr_contexts[i];
573#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
576 if((addr_contexts[i].used == 1) &&
577 addr_contexts[i].number == number) {
578 return &addr_contexts[i];
586compress_addr_64(uint8_t bitpos, uip_ipaddr_t *
ipaddr,
587 const uip_lladdr_t *lladdr)
612uncompress_addr(uip_ipaddr_t *
ipaddr, uint8_t
const prefix[],
613 uint8_t pref_post_count, uip_lladdr_t *lladdr)
615 uint8_t prefcount = pref_post_count >> 4;
616 uint8_t postcount = pref_post_count & 0x0f;
618 prefcount = prefcount == 15 ? 16 : prefcount;
619 postcount = postcount == 15 ? 16 : postcount;
621 LOG_DBG(
"uncompression: address %d %d ", prefcount, postcount);
624 memcpy(
ipaddr, prefix, prefcount);
626 if(prefcount + postcount < 16) {
627 memset(&
ipaddr->u8[prefcount], 0, 16 - (prefcount + postcount));
631 LOG_WARN(
"Insufficient packet data to decompress IP address\n");
636 if(postcount == 2 && prefcount < 11) {
642 }
else if (prefcount > 0) {
689 uint8_t tmp, iphc0, iphc1, *next_hdr, *next_nhc;
691 struct uip_udp_hdr *udp_buf;
693 if(LOG_DBG_ENABLED) {
695 LOG_DBG(
"compression: before (%d): ",
UIP_IP_BUF->len[1]);
696 for(ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
697 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
698 LOG_DBG_(
"%02x", data);
705#define CHECK_BUFFER_SPACE(writelen) do { \
706 if(iphc_ptr + (writelen) >= PACKETBUF_PAYLOAD_END) { \
707 LOG_WARN("Not enough packetbuf space to compress header (%u bytes, %u left). Aborting.\n", \
708 (unsigned)(writelen), (unsigned)(PACKETBUF_PAYLOAD_END - iphc_ptr)); \
718 CHECK_BUFFER_SPACE(38);
727 iphc0 = SICSLOWPAN_DISPATCH_IPHC;
729 PACKETBUF_IPHC_BUF[2] = 0;
743 if(source_context || destination_context) {
745 LOG_DBG(
"compression: dest or src ipaddr - setting CID\n");
746 iphc1 |= SICSLOWPAN_IPHC_CID;
760 tmp = ((tmp & 0x03) << 6) | (tmp >> 2);
765 iphc0 |= SICSLOWPAN_IPHC_FL_C;
769 iphc0 |= SICSLOWPAN_IPHC_TC_C;
780 iphc0 |= SICSLOWPAN_IPHC_TC_C;
797 if(IS_COMPRESSABLE_PROTO(
UIP_IP_BUF->proto)) {
798 iphc0 |= SICSLOWPAN_IPHC_NH_C;
802 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
816 iphc0 |= SICSLOWPAN_IPHC_TTL_1;
819 iphc0 |= SICSLOWPAN_IPHC_TTL_64;
822 iphc0 |= SICSLOWPAN_IPHC_TTL_255;
832 LOG_DBG(
"compression: addr unspecified - setting SAC\n");
833 iphc1 |= SICSLOWPAN_IPHC_SAC;
834 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
835 }
else if(source_context) {
837 LOG_DBG(
"compression: src with context - setting CID & SAC ctx: %d\n",
838 source_context->number);
839 iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
840 PACKETBUF_IPHC_BUF[2] |= source_context->number << 4;
843 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
850 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
854 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
862 iphc1 |= SICSLOWPAN_IPHC_M;
863 if(sicslowpan_is_mcast_addr_compressable8(&
UIP_IP_BUF->destipaddr)) {
864 iphc1 |= SICSLOWPAN_IPHC_DAM_11;
868 }
else if(sicslowpan_is_mcast_addr_compressable32(&
UIP_IP_BUF->destipaddr)) {
869 iphc1 |= SICSLOWPAN_IPHC_DAM_10;
874 }
else if(sicslowpan_is_mcast_addr_compressable48(&
UIP_IP_BUF->destipaddr)) {
875 iphc1 |= SICSLOWPAN_IPHC_DAM_01;
881 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
888 if(destination_context) {
890 iphc1 |= SICSLOWPAN_IPHC_DAC;
891 PACKETBUF_IPHC_BUF[2] |= destination_context->number;
894 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
896 (
const uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
902 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
904 (
const uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
907 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 *)
iphc_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(
iphc_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(
iphc_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(
iphc_ptr, &udp_buf->srcport, 4);
1019 CHECK_BUFFER_SPACE(2);
1020 memcpy(
iphc_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) {
1044 LOG_DBG_(
"%02x", data);
1076 uint8_t tmp, iphc0, iphc1, nhc;
1077 struct uip_ext_hdr *exthdr;
1078 uint8_t* last_nextheader;
1079 uint8_t* ip_payload;
1080 uint8_t ext_hdr_len = 0;
1085#define CHECK_READ_SPACE(readlen) \
1086 if((iphc_ptr - packetbuf_ptr) + (readlen) > cmpr_len) { \
1087 LOG_WARN("Not enough packetbuf space to decompress header (%u bytes, %u left). Aborting.\n", \
1088 (unsigned)(readlen), (unsigned)(cmpr_len - (iphc_ptr - packetbuf_ptr))); \
1099 iphc0 = PACKETBUF_IPHC_BUF[0];
1100 iphc1 = PACKETBUF_IPHC_BUF[1];
1103 if(iphc1 & SICSLOWPAN_IPHC_CID) {
1104 LOG_DBG(
"uncompression: CID flag set - increase header with one\n");
1109 if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) {
1111 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1113 CHECK_READ_SPACE(4);
1114 memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow,
iphc_ptr + 1, 3);
1119 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f);
1121 SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) |
1122 (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f);
1125 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1127 CHECK_READ_SPACE(3);
1128 SICSLOWPAN_IP_BUF(buf)->tcflow = (*
iphc_ptr & 0x0F) |
1130 memcpy(&SICSLOWPAN_IP_BUF(buf)->flow,
iphc_ptr + 1, 2);
1136 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1138 CHECK_READ_SPACE(1);
1139 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*
iphc_ptr >> 2) & 0x0f);
1140 SICSLOWPAN_IP_BUF(buf)->tcflow = ((*
iphc_ptr << 6) & 0xC0) | ((*
iphc_ptr >> 2) & 0x30);
1141 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1145 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1146 SICSLOWPAN_IP_BUF(buf)->tcflow = 0;
1147 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1152 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
1154 CHECK_READ_SPACE(1);
1155 SICSLOWPAN_IP_BUF(buf)->proto = *
iphc_ptr;
1156 LOG_DBG(
"uncompression: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
1161 if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) {
1162 SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03];
1164 CHECK_READ_SPACE(1);
1165 SICSLOWPAN_IP_BUF(buf)->ttl = *
iphc_ptr;
1170 tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03;
1173 if(iphc1 & SICSLOWPAN_IPHC_SAC) {
1174 uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
1175 PACKETBUF_IPHC_BUF[2] >> 4 : 0;
1181 if(!source_context) {
1182 LOG_ERR(
"uncompression: error source context not found\n");
1186 source_context = NULL;
1189 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr,
1190 source_context ? source_context->prefix : NULL,
1192 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
1197 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix,
1199 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
1206 tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03;
1209 if(iphc1 & SICSLOWPAN_IPHC_M) {
1211 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1219 uint8_t prefix[] = {0xff, 0x02};
1220 if(tmp > 0 && tmp < 3) {
1221 CHECK_READ_SPACE(1);
1226 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix,
1227 unc_mxconf[tmp], NULL)) {
1234 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1235 uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? PACKETBUF_IPHC_BUF[2] & 0x0f : 0;
1240 if(!destination_context) {
1241 LOG_ERR(
"uncompression: error destination context not found\n");
1244 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr,
1245 destination_context->prefix,
1247 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
1252 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix,
1254 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
1262 nhc = iphc0 & SICSLOWPAN_IPHC_NH_C;
1264 last_nextheader = &SICSLOWPAN_IP_BUF(buf)->proto;
1265 ip_payload = SICSLOWPAN_IPPAYLOAD_BUF(buf);
1267 CHECK_READ_SPACE(1);
1268 while(nhc && (*
iphc_ptr & SICSLOWPAN_NHC_MASK) == SICSLOWPAN_NHC_EXT_HDR) {
1269 uint8_t eid = (*
iphc_ptr & 0x0e) >> 1;
1279 CHECK_READ_SPACE(1);
1283 LOG_DBG(
"uncompression: next header is inlined. Next: %d\n", next);
1285 CHECK_READ_SPACE(1);
1289 LOG_DBG(
"uncompression: found ext header id: %d next: %d len: %d\n", eid, next, len);
1291 case SICSLOWPAN_NHC_ETX_HDR_HBHO:
1294 case SICSLOWPAN_NHC_ETX_HDR_ROUTING:
1295 proto = UIP_PROTO_ROUTING;
1297 case SICSLOWPAN_NHC_ETX_HDR_FRAG:
1298 proto = UIP_PROTO_FRAG;
1300 case SICSLOWPAN_NHC_ETX_HDR_DESTO:
1301 proto = UIP_PROTO_DESTO;
1304 LOG_DBG(
"uncompression: error unsupported ext header\n");
1307 *last_nextheader = proto;
1310 if((ip_payload - buf) + UIP_EXT_HDR_LEN + len > buf_size) {
1311 LOG_WARN(
"uncompression: cannot write ext header beyond target buffer\n");
1316 exthdr = (
struct uip_ext_hdr *)ip_payload;
1317 exthdr->len = (UIP_EXT_HDR_LEN + len) / 8;
1318 if(exthdr->len == 0) {
1319 LOG_WARN(
"Extension header length is below 8\n");
1323 exthdr->next = next;
1324 last_nextheader = &exthdr->next;
1327 CHECK_READ_SPACE(len + 1);
1328 memcpy((uint8_t *)exthdr + UIP_EXT_HDR_LEN,
iphc_ptr, len);
1332 ip_payload += (exthdr->len + 1) * 8;
1333 ext_hdr_len += (exthdr->len + 1) * 8;
1335 LOG_DBG(
"uncompression: %d len: %d exthdr len: %d (calc: %d)\n",
1336 proto, len, exthdr->len, (exthdr->len + 1) * 8);
1340 CHECK_READ_SPACE(1);
1341 if(nhc && (*
iphc_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
1342 struct uip_udp_hdr *udp_buf;
1344 uint8_t checksum_compressed;
1347 if((ip_payload - buf) + UIP_UDPH_LEN > buf_size) {
1348 LOG_WARN(
"uncompression: cannot write UDP header beyond target buffer\n");
1352 udp_buf = (
struct uip_udp_hdr *)ip_payload;
1353 *last_nextheader = UIP_PROTO_UDP;
1354 checksum_compressed = *
iphc_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
1355 LOG_DBG(
"uncompression: incoming header value: %i\n", *
iphc_ptr);
1356 switch(*
iphc_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
1357 case SICSLOWPAN_NHC_UDP_CS_P_00:
1359 CHECK_READ_SPACE(5);
1360 memcpy(&udp_buf->srcport,
iphc_ptr + 1, 2);
1361 memcpy(&udp_buf->destport,
iphc_ptr + 3, 2);
1362 LOG_DBG(
"uncompression: UDP ports (ptr+5): %x, %x\n",
1368 case SICSLOWPAN_NHC_UDP_CS_P_01:
1370 LOG_DBG(
"uncompression: destination address\n");
1371 CHECK_READ_SPACE(4);
1372 memcpy(&udp_buf->srcport,
iphc_ptr + 1, 2);
1373 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(
iphc_ptr + 3)));
1374 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1379 case SICSLOWPAN_NHC_UDP_CS_P_10:
1381 LOG_DBG(
"uncompression: source address\n");
1382 CHECK_READ_SPACE(4);
1383 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
1385 memcpy(&udp_buf->destport,
iphc_ptr + 2, 2);
1386 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1391 case SICSLOWPAN_NHC_UDP_CS_P_11:
1393 CHECK_READ_SPACE(2);
1394 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1396 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1398 LOG_DBG(
"uncompression: UDP ports (ptr+2): %x, %x\n",
1404 LOG_DBG(
"uncompression: error unsupported UDP compression\n");
1407 if(!checksum_compressed) {
1408 CHECK_READ_SPACE(2);
1409 memcpy(&udp_buf->udpchksum,
iphc_ptr, 2);
1411 LOG_DBG(
"uncompression: checksum included\n");
1413 LOG_DBG(
"uncompression: checksum *NOT* included\n");
1418 udp_buf->udplen =
UIP_HTONS(ip_len == 0 ? udp_len :
1419 ip_len - UIP_IPH_LEN - ext_hdr_len);
1420 LOG_DBG(
"uncompression: UDP length: %u (ext: %u) ip_len: %d udp_len: %d\n",
1421 UIP_HTONS(udp_buf->udplen), ext_hdr_len, ip_len, udp_len);
1431 LOG_DBG(
"uncompression: IP payload length: %d. %u - %u + %u - %u\n", len,
1435 SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8;
1436 SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF;
1439 SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
1440 SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
1448#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1457 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] = SICSLOWPAN_DISPATCH_PAGING | (page & 0x0f);
1479 if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_PAGING_MASK) == SICSLOWPAN_DISPATCH_PAGING) {
1481 curr_page = PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & 0x0f;
1510#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1512compress_hdr_ipv6(
void)
1532 const linkaddr_t *dest;
1534 if(callback != NULL) {
1535 callback->output_callback(status);
1540 dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
1546 link_stats_packet_sent(dest, status, transmissions);
1549 NETSTACK_ROUTING.
link_callback(dest, status, transmissions);
1570#if SICSLOWPAN_CONF_FRAG
1580fragment_copy_payload_and_send(uint16_t uip_offset)
1590 q = queuebuf_new_from_packetbuf();
1592 LOG_WARN(
"output: could not allocate queuebuf, dropping fragment\n");
1600 queuebuf_to_packetbuf(q);
1606 LOG_ERR(
"output: error in fragment tx, dropping subsequent fragments.\n");
1641 LOG_INFO(
"output: sending IPv6 packet with len %d\n",
uip_len);
1644 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
1645 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
1648 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER,
1651#if LLSEC802154_USES_AUX_HEADER
1653 packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
1654 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
1655#if LLSEC802154_USES_EXPLICIT_KEYS
1656 packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
1657 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_KEY_ID));
1666 LOG_WARN(
"output: failed to calculate payload size - dropping packet\n");
1671#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1672 compress_hdr_ipv6();
1674#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1682#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
1694 LOG_INFO(
"output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
1700#if SICSLOWPAN_CONF_FRAG
1702 uint16_t processed_ip_out_len;
1719 int fragn_max_payload = (
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
1721 int last_fragn_max_payload =
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
1723 int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
1725 unsigned fragment_count = 2;
1726 if(middle_fragn_total_payload > 0) {
1727 fragment_count += 1 + (middle_fragn_total_payload - 1) / fragn_max_payload;
1730 size_t free_bufs = queuebuf_numfree();
1731 LOG_INFO(
"output: fragmentation needed. fragments: %u, free queuebufs: %zu\n",
1732 fragment_count, free_bufs);
1736 size_t needed_bufs = fragment_count + 1;
1737 if(free_bufs < needed_bufs) {
1738 LOG_WARN(
"output: dropping packet, not enough free bufs (needed: %zu, free: %zu)\n",
1739 needed_bufs, free_bufs);
1743 if(frag1_payload < 0) {
1747 LOG_WARN(
"output: compressed header does not fit first fragment\n");
1754 frag_tag = my_tag++;
1761 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1762 ((SICSLOWPAN_DISPATCH_FRAG1 << 8) |
uip_len));
1763 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
1770 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d)\n",
1771 curr_frag + 1, fragment_count,
1781 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1782 ((SICSLOWPAN_DISPATCH_FRAGN << 8) |
uip_len));
1788 while(processed_ip_out_len <
uip_len) {
1791 PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
1794 if(
uip_len - processed_ip_out_len > last_fragn_max_payload) {
1804 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d, offset %d)\n",
1805 curr_frag + 1, fragment_count,
1807 if(fragment_copy_payload_and_send(processed_ip_out_len) == 0) {
1814 LOG_ERR(
"output: Packet too large to be sent without fragmentation support; dropping packet\n");
1824 LOG_ERR(
"output: uip_len is smaller than uncomp_hdr_len (%d < %d)",
1853 uint16_t frag_size = 0;
1855 uint8_t frag_offset = 0;
1857 uint16_t buffer_size;
1859#if SICSLOWPAN_CONF_FRAG
1860 uint8_t is_fragment = 0;
1861 int8_t frag_context = 0;
1864 uint16_t frag_tag = 0;
1865 uint8_t first_fragment = 0, last_fragment = 0;
1869 link_stats_input_callback(packetbuf_addr(PACKETBUF_ADDR_SENDER));
1879 LOG_WARN(
"input: empty packet\n");
1892 uipbuf_set_attr(UIPBUF_ATTR_RSSI, packetbuf_attr(PACKETBUF_ATTR_RSSI));
1893 uipbuf_set_attr(UIPBUF_ATTR_LINK_QUALITY, packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));
1896#if SICSLOWPAN_CONF_FRAG
1902 switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
1903 case SICSLOWPAN_DISPATCH_FRAG1:
1905 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1906 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1911 LOG_INFO(
"input: received first element of a fragmented packet (tag %d, len %d)\n",
1912 frag_tag, frag_size);
1915 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1917 if(frag_context == -1) {
1918 LOG_ERR(
"input: failed to allocate new reassembly context\n");
1922 buffer = frag_info[frag_context].first_frag;
1923 buffer_size = SICSLOWPAN_FIRST_FRAGMENT_SIZE;
1925 case SICSLOWPAN_DISPATCH_FRAGN:
1930 frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
1931 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1932 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1937 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1939 if(frag_context == -1) {
1940 LOG_ERR(
"input: reassembly context not found (tag %d)\n", frag_tag);
1948 if(frag_info[frag_context].reassembled_len >= frag_size) {
1957 if(is_fragment && !first_fragment) {
1967 LOG_INFO(
"input: page 1, 6LoRH\n");
1970 LOG_ERR(
"input: page %u not supported\n",
curr_page);
1976 (PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
1977 LOG_DBG(
"uncompression: IPHC dispatch\n");
1979 LOG_ERR(
"input: failed to decompress IPHC packet\n");
1982 }
else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
1983 LOG_DBG(
"uncompression: IPV6 dispatch\n");
1993 LOG_ERR(
"uncompression: unknown dispatch: 0x%02x, or IPHC disabled\n",
1994 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK);
1998#if SICSLOWPAN_CONF_FRAG
2009 LOG_ERR(
"input: packet dropped due to header > total packet\n");
2014#if SICSLOWPAN_CONF_FRAG
2016 LOG_INFO(
"input: fragment (tag %d, payload %d, offset %d) -- %u %u\n",
2023 unsigned int req_size =
uncomp_hdr_len + (uint16_t)(frag_offset << 3)
2025 if(req_size >
sizeof(
uip_buf)) {
2026#if SICSLOWPAN_CONF_FRAG
2028 "input: packet and fragment context %u dropped, minimum required IP_BUF size: %d+%d+%d=%u (current size: %u)\n",
2034 clear_fragments(frag_context);
2042 if(buffer != NULL) {
2044 LOG_ERR(
"input: cannot copy the payload into the buffer\n");
2052#if SICSLOWPAN_CONF_FRAG
2055 if(first_fragment != 0) {
2061 if(last_fragment != 0) {
2062 frag_info[frag_context].reassembled_len = frag_size;
2064 if(!copy_frags2uip(frag_context)) {
2074 if(!is_fragment || last_fragment) {
2076 if(is_fragment != 0 && last_fragment != 0) {
2084 LOG_INFO(
"input: received IPv6 packet with len %d\n",
2087 if(LOG_DBG_ENABLED) {
2089 LOG_DBG(
"uncompression: after (%u):",
UIP_IP_BUF->len[1]);
2090 for (ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
2091 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
2092 LOG_DBG_(
"%02x", data);
2100 callback->input_callback();
2103#if LLSEC802154_USES_AUX_HEADER
2108 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_LEVEL,
2109 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
2110#if LLSEC802154_USES_EXPLICIT_KEYS
2111 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_KEY_ID,
2112 packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX));
2117#if SICSLOWPAN_CONF_FRAG
2127sicslowpan_init(
void)
2130#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC
2136#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
2137 addr_contexts[0].used = 1;
2138 addr_contexts[0].number = 0;
2139#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0
2140 SICSLOWPAN_CONF_ADDR_CONTEXT_0;
2142 addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0;
2143 addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1;
2147#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1
2151#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1
2153 addr_contexts[1].used = 1;
2154 addr_contexts[1].number = 1;
2155 SICSLOWPAN_CONF_ADDR_CONTEXT_1;
2156#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2
2158 addr_contexts[2].used = 1;
2159 addr_contexts[2].number = 2;
2160 SICSLOWPAN_CONF_ADDR_CONTEXT_2;
2163 addr_contexts[i].used = 0;
2166 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.
static uint8_t * iphc_ptr
Addresses contexts for IPHC.
#define sicslowpan_is_iid_16_bit_compressable(a)
check whether we can compress the IID in address 'a' to 16 bits.
static struct sicslowpan_addr_context * addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr)
find the context corresponding to prefix ipaddr
static uint8_t uncomp_hdr_len
uncomp_hdr_len is the length of the headers before compression (if HC2 is used this includes the UDP ...
static int last_tx_status
the result of the last transmitted fragment
static uint8_t output(const linkaddr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
static int compress_hdr_iphc(void)
Compress IP/UDP header.
static bool uncompress_hdr_iphc(uint8_t *buf, uint16_t buf_size, uint16_t ip_len)
Uncompress IPHC (i.e., IPHC and LOWPAN_UDP) headers and put them in sicslowpan_buf.
static void add_paging_dispatch(uint8_t page)
Adds Paging dispatch byte.
static void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
static struct sicslowpan_addr_context * addr_context_lookup_by_number(uint8_t number)
find the context with the given number
static uint8_t packetbuf_hdr_len
packetbuf_hdr_len is the total length of (the processed) 6lowpan headers (fragment headers,...
static void add_6lorh_hdr(void)
Adds 6lorh headers before IPHC.
static void input(void)
Process a received 6lowpan packet.
static int packetbuf_payload_len
The length of the payload in the Packetbuf buffer.
static void digest_paging_dispatch(void)
Digest 6lorh headers before IPHC.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
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)
int(* max_payload)(void)
Read out estimated max payload size based on payload in packetbuf.
void(* send)(mac_callback_t sent_callback, void *ptr)
Send a packet from the packetbuf
The structure of a network driver in Contiki.
uint8_t(* output)(const linkaddr_t *localdest)
Output funtion, sends from uipbuf.
void(* link_callback)(const linkaddr_t *addr, int status, int numtx)
Called by lower layers after every packet transmission.
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.