65#include "dev/watchdog.h"
66#include "net/link-stats.h"
71#include "net/ipv6/uipbuf.h"
81#define LOG_MODULE "6LoWPAN"
82#define LOG_LEVEL LOG_LEVEL_6LOWPAN
84#define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1]))
85#define SET16(ptr,index,value) do { \
86 (ptr)[index] = ((value) >> 8) & 0xff; \
87 (ptr)[index + 1] = (value) & 0xff; \
93#define PACKETBUF_FRAG_PTR (packetbuf_ptr)
94#define PACKETBUF_FRAG_DISPATCH_SIZE 0
95#define PACKETBUF_FRAG_TAG 2
96#define PACKETBUF_FRAG_OFFSET 4
99#define PACKETBUF_IPHC_BUF ((uint8_t *)(packetbuf_ptr + packetbuf_hdr_len))
100#define PACKETBUF_PAYLOAD_END ((uint8_t *)(packetbuf_ptr + mac_max_payload))
102#define PACKETBUF_6LO_PTR (packetbuf_ptr + packetbuf_hdr_len)
103#define PACKETBUF_6LO_DISPATCH 0
104#define PACKETBUF_6LO_ENCODING 1
105#define PACKETBUF_6LO_TTL 2
107#define PACKETBUF_6LO_HC_UDP_PTR (packetbuf_ptr + packetbuf_hdr_len)
108#define PACKETBUF_6LO_HC_UDP_DISPATCH 0
109#define PACKETBUF_6LO_HC_UDP_HC1_ENCODING 1
110#define PACKETBUF_6LO_HC_UDP_UDP_ENCODING 2
111#define PACKETBUF_6LO_HC_UDP_TTL 3
112#define PACKETBUF_6LO_HC_UDP_PORTS 4
113#define PACKETBUF_6LO_HC_UDP_CHKSUM 5
122#define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf)
123#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN])
124#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_IPH_LEN])
126#define UIP_IPPAYLOAD_BUF_POS(pos) (&uip_buf[UIP_IPH_LEN + (pos)])
127#define UIP_UDP_BUF_POS(pos) ((struct uip_udp_hdr *)UIP_IPPAYLOAD_BUF_POS(pos))
128#define UIP_EXT_HDR_LEN 2
133#ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR
134#define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR
137#define COMPRESS_EXT_HDR 1
141#define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP \
142 || x == UIP_PROTO_HBHO \
143 || x == UIP_PROTO_DESTO \
144 || x == UIP_PROTO_ROUTING \
145 || x == UIP_PROTO_FRAG)
147#define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP)
204#if SICSLOWPAN_CONF_FRAG
205static uint16_t my_tag;
211#ifdef SICSLOWPAN_CONF_FRAGMENT_BUFFERS
212#define SICSLOWPAN_FRAGMENT_BUFFERS SICSLOWPAN_CONF_FRAGMENT_BUFFERS
214#define SICSLOWPAN_FRAGMENT_BUFFERS 12
222#ifdef SICSLOWPAN_CONF_REASS_CONTEXTS
223#define SICSLOWPAN_REASS_CONTEXTS SICSLOWPAN_CONF_REASS_CONTEXTS
225#define SICSLOWPAN_REASS_CONTEXTS 2
229#ifdef SICSLOWPAN_CONF_FRAGMENT_SIZE
230#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE
233#define SICSLOWPAN_FRAGMENT_SIZE (127 - 2 - 15)
237#if SICSLOWPAN_FRAGMENT_SIZE > 255
238#error Too large SICSLOWPAN_FRAGMENT_SIZE set.
242#define SICSLOWPAN_FIRST_FRAGMENT_SIZE (SICSLOWPAN_FRAGMENT_SIZE + 38)
245struct sicslowpan_frag_info {
255 uint16_t reassembled_len;
257 struct timer reass_timer;
260 uint16_t first_frag_len;
263 uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE];
266static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS];
268struct sicslowpan_frag_buf {
275 uint8_t data[SICSLOWPAN_FRAGMENT_SIZE];
278static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS];
282clear_fragments(uint8_t frag_info_index)
286 frag_info[frag_info_index].len = 0;
287 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
288 if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) {
298timeout_fragments(
int not_context)
302 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
303 if(frag_info[i].len > 0 && i != not_context &&
306 count += clear_fragments(i);
313store_fragment(uint8_t index, uint8_t offset)
320 if(len <= 0 || len > SICSLOWPAN_FRAGMENT_SIZE) {
325 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
326 if(frag_buf[i].len == 0) {
329 frag_buf[i].offset = offset;
330 frag_buf[i].len = len;
331 frag_buf[i].index = index;
343add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
351 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
353 if(frag_info[i].len > 0 &&
timer_expired(&frag_info[i].reass_timer)) {
358 if(found < 0 && frag_info[i].len == 0) {
366 LOG_WARN(
"reassembly: failed to store new fragment session - tag: %d\n", tag);
371 frag_info[found].len = frag_size;
372 frag_info[found].tag = tag;
374 packetbuf_addr(PACKETBUF_ADDR_SENDER));
382 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
383 if(frag_info[i].tag == tag && frag_info[i].len > 0 &&
384 linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
393 LOG_WARN(
"reassembly: failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
398 len = store_fragment(i, offset);
399 if(len < 0 && timeout_fragments(i) > 0) {
400 len = store_fragment(i, offset);
403 frag_info[i].reassembled_len += len;
408 LOG_WARN(
"reassembly: failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
423 LOG_WARN(
"input: invalid total size of fragments\n");
430 frag_info[
context].first_frag_len);
436 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
438 if(frag_buf[i].len > 0 && frag_buf[i].index ==
context) {
439 if(((
size_t)frag_buf[i].offset << 3) + frag_buf[i].len >
sizeof(
uip_buf)) {
440 LOG_WARN(
"input: invalid fragment offset\n");
444 memcpy((uint8_t *)
UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3),
445 (uint8_t *)frag_buf[i].data, frag_buf[i].len);
460static struct netstack_sniffer *callback = NULL;
463netstack_sniffer_add(
struct netstack_sniffer *s)
469netstack_sniffer_remove(
struct netstack_sniffer *s)
475set_packet_attrs(
void)
479 packetbuf_set_attr(PACKETBUF_ATTR_NETWORK_ID,
UIP_IP_BUF->proto);
483 c = UIP_UDP_BUF_POS(0)->srcport;
484 if(UIP_UDP_BUF_POS(0)->destport < c) {
485 c = UIP_UDP_BUF_POS(0)->destport;
487 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_TCP) {
488 c = UIP_TCP_BUF->srcport;
489 if(UIP_TCP_BUF->destport < c) {
490 c = UIP_TCP_BUF->destport;
492 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
496 packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, c);
506#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
512#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
530const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
537const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
544const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};
547const uint8_t llprefix[] = {0xfe, 0x80};
550static const uint8_t ttl_values[] = {0, 1, 64, 255};
562#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
565 if((addr_contexts[i].used == 1) &&
566 uip_ipaddr_prefixcmp(&addr_contexts[i].prefix,
ipaddr, 64)) {
567 return &addr_contexts[i];
579#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
582 if((addr_contexts[i].used == 1) &&
583 addr_contexts[i].number == number) {
584 return &addr_contexts[i];
592compress_addr_64(uint8_t bitpos, uip_ipaddr_t *
ipaddr, uip_lladdr_t *lladdr)
617uncompress_addr(uip_ipaddr_t *
ipaddr, uint8_t
const prefix[],
618 uint8_t pref_post_count, uip_lladdr_t *lladdr)
620 uint8_t prefcount = pref_post_count >> 4;
621 uint8_t postcount = pref_post_count & 0x0f;
623 prefcount = prefcount == 15 ? 16 : prefcount;
624 postcount = postcount == 15 ? 16 : postcount;
626 LOG_DBG(
"uncompression: address %d %d ", prefcount, postcount);
629 memcpy(
ipaddr, prefix, prefcount);
631 if(prefcount + postcount < 16) {
632 memset(&
ipaddr->u8[prefcount], 0, 16 - (prefcount + postcount));
636 if(postcount == 2 && prefcount < 11) {
642 }
else if (prefcount > 0) {
690 uint8_t tmp, iphc0, iphc1, *next_hdr, *next_nhc;
692 struct uip_udp_hdr *udp_buf;
694 if(LOG_DBG_ENABLED) {
696 LOG_DBG(
"compression: before (%d): ",
UIP_IP_BUF->len[1]);
697 for(ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
698 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
699 LOG_DBG_(
"%02x", data);
706#define CHECK_BUFFER_SPACE(writelen) do { \
707 if(iphc_ptr + (writelen) >= PACKETBUF_PAYLOAD_END) { \
708 LOG_WARN("Not enough packetbuf space to compress header (%u bytes, %u left). Aborting.\n", \
709 (unsigned)(writelen), (unsigned)(PACKETBUF_PAYLOAD_END - iphc_ptr)); \
719 CHECK_BUFFER_SPACE(38);
728 iphc0 = SICSLOWPAN_DISPATCH_IPHC;
730 PACKETBUF_IPHC_BUF[2] = 0;
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;
838 LOG_DBG(
"compression: src with context - setting CID & SAC ctx: %d\n",
840 iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
841 PACKETBUF_IPHC_BUF[2] |=
context->number << 4;
844 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
851 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
855 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
863 iphc1 |= SICSLOWPAN_IPHC_M;
864 if(sicslowpan_is_mcast_addr_compressable8(&
UIP_IP_BUF->destipaddr)) {
865 iphc1 |= SICSLOWPAN_IPHC_DAM_11;
869 }
else if(sicslowpan_is_mcast_addr_compressable32(&
UIP_IP_BUF->destipaddr)) {
870 iphc1 |= SICSLOWPAN_IPHC_DAM_10;
875 }
else if(sicslowpan_is_mcast_addr_compressable48(&
UIP_IP_BUF->destipaddr)) {
876 iphc1 |= SICSLOWPAN_IPHC_DAM_01;
882 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
891 iphc1 |= SICSLOWPAN_IPHC_DAC;
892 PACKETBUF_IPHC_BUF[2] |=
context->number;
895 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
897 (uip_lladdr_t *)link_destaddr);
903 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
904 &
UIP_IP_BUF->destipaddr, (uip_lladdr_t *)link_destaddr);
907 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
921 LOG_DBG(
"compression: first header: %d\n", *next_hdr);
922 while(next_hdr != NULL && IS_COMPRESSABLE_PROTO(*next_hdr)) {
923 LOG_DBG(
"compression: next header: %d\n", *next_hdr);
928 proto = SICSLOWPAN_NHC_ETX_HDR_HBHO;
929 case UIP_PROTO_ROUTING:
930 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_ROUTING : proto;
932 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_FRAG : proto;
933 case UIP_PROTO_DESTO:
936 struct uip_ext_hdr *ext_hdr =
937 (
struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF_POS(ext_hdr_len);
939 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
941 len = (ext_hdr->len << 3) + 8;
942 LOG_DBG(
"compression: next header %d (len:%d)\n", *next_hdr, len);
944 next_hdr = &ext_hdr->next;
948 if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
949 CHECK_BUFFER_SPACE(1);
951 LOG_DBG(
"compression: keeping the next header in this ext hdr: %d\n",
955 CHECK_BUFFER_SPACE(len);
958 ext_hdr = (
struct uip_ext_hdr *)
iphc_ptr;
959 ext_hdr->len = len - 2;
966 *next_nhc = SICSLOWPAN_NHC_EXT_HDR |
967 (IS_COMPRESSABLE_PROTO(*next_hdr) ? SICSLOWPAN_NHC_BIT : 0) |
976 udp_buf = UIP_UDP_BUF_POS(ext_hdr_len);
977 LOG_DBG(
"compression: inlined UDP ports on send side: %x, %x\n",
980 if(((
UIP_HTONS(udp_buf->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
981 ((
UIP_HTONS(udp_buf->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
983 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
984 LOG_DBG(
"IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
985 CHECK_BUFFER_SPACE(1);
988 SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
989 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
990 SICSLOWPAN_UDP_4_BIT_PORT_MIN));
992 }
else if((
UIP_HTONS(udp_buf->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
994 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
995 LOG_DBG(
"IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
996 CHECK_BUFFER_SPACE(3);
997 memcpy(
iphc_ptr, &udp_buf->srcport, 2);
999 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
1000 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
1002 }
else if((
UIP_HTONS(udp_buf->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
1004 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_10;
1005 LOG_DBG(
"IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
1006 CHECK_BUFFER_SPACE(3);
1008 (uint8_t)((
UIP_HTONS(udp_buf->srcport) -
1009 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
1010 memcpy(
iphc_ptr + 1, &udp_buf->destport, 2);
1014 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
1015 LOG_DBG(
"IPHC: cannot compress UDP headers\n");
1016 CHECK_BUFFER_SPACE(4);
1017 memcpy(
iphc_ptr, &udp_buf->srcport, 4);
1021 CHECK_BUFFER_SPACE(2);
1022 memcpy(
iphc_ptr, &udp_buf->udpchksum, 2);
1029 LOG_ERR(
"compression: could not handle compression of header");
1032 if(next_hdr != NULL) {
1035 LOG_DBG(
"compression: last header could is not compressed: %d\n", *next_hdr);
1038 PACKETBUF_IPHC_BUF[0] = iphc0;
1039 PACKETBUF_IPHC_BUF[1] = iphc1;
1041 if(LOG_DBG_ENABLED) {
1046 LOG_DBG_(
"%02x", data);
1078 uint8_t tmp, iphc0, iphc1, nhc;
1079 struct uip_ext_hdr *exthdr;
1080 uint8_t* last_nextheader;
1081 uint8_t* ip_payload;
1082 uint8_t ext_hdr_len = 0;
1087#define CHECK_READ_SPACE(readlen) \
1088 if((iphc_ptr - packetbuf_ptr) + (readlen) > cmpr_len) { \
1089 LOG_WARN("Not enough packetbuf space to decompress header (%u bytes, %u left). Aborting.\n", \
1090 (unsigned)(readlen), (unsigned)(cmpr_len - (iphc_ptr - packetbuf_ptr))); \
1101 iphc0 = PACKETBUF_IPHC_BUF[0];
1102 iphc1 = PACKETBUF_IPHC_BUF[1];
1105 if(iphc1 & SICSLOWPAN_IPHC_CID) {
1106 LOG_DBG(
"uncompression: CID flag set - increase header with one\n");
1111 if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) {
1113 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1115 CHECK_READ_SPACE(4);
1116 memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow,
iphc_ptr + 1, 3);
1121 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f);
1123 SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) |
1124 (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f);
1127 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1129 CHECK_READ_SPACE(3);
1130 SICSLOWPAN_IP_BUF(buf)->tcflow = (*
iphc_ptr & 0x0F) |
1132 memcpy(&SICSLOWPAN_IP_BUF(buf)->flow,
iphc_ptr + 1, 2);
1138 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1140 CHECK_READ_SPACE(1);
1141 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*
iphc_ptr >> 2) & 0x0f);
1142 SICSLOWPAN_IP_BUF(buf)->tcflow = ((*
iphc_ptr << 6) & 0xC0) | ((*
iphc_ptr >> 2) & 0x30);
1143 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1147 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1148 SICSLOWPAN_IP_BUF(buf)->tcflow = 0;
1149 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1154 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
1156 CHECK_READ_SPACE(1);
1157 SICSLOWPAN_IP_BUF(buf)->proto = *
iphc_ptr;
1158 LOG_DBG(
"uncompression: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
1163 if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) {
1164 SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03];
1166 CHECK_READ_SPACE(1);
1167 SICSLOWPAN_IP_BUF(buf)->ttl = *
iphc_ptr;
1172 tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03;
1175 if(iphc1 & SICSLOWPAN_IPHC_SAC) {
1176 uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
1177 PACKETBUF_IPHC_BUF[2] >> 4 : 0;
1183 LOG_ERR(
"uncompression: error context not found\n");
1188 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr,
1189 tmp != 0 ?
context->prefix : NULL, unc_ctxconf[tmp],
1190 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1193 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix, unc_llconf[tmp],
1194 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1199 tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03;
1202 if(iphc1 & SICSLOWPAN_IPHC_M) {
1204 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1212 uint8_t prefix[] = {0xff, 0x02};
1213 if(tmp > 0 && tmp < 3) {
1214 CHECK_READ_SPACE(1);
1219 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix,
1220 unc_mxconf[tmp], NULL);
1225 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1226 uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? PACKETBUF_IPHC_BUF[2] & 0x0f : 0;
1231 LOG_ERR(
"uncompression: error context not found\n");
1234 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr,
context->prefix,
1236 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1239 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix,
1241 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1247 nhc = iphc0 & SICSLOWPAN_IPHC_NH_C;
1249 last_nextheader = &SICSLOWPAN_IP_BUF(buf)->proto;
1250 ip_payload = SICSLOWPAN_IPPAYLOAD_BUF(buf);
1252 CHECK_READ_SPACE(1);
1253 while(nhc && (*
iphc_ptr & SICSLOWPAN_NHC_MASK) == SICSLOWPAN_NHC_EXT_HDR) {
1254 uint8_t eid = (*
iphc_ptr & 0x0e) >> 1;
1264 CHECK_READ_SPACE(1);
1268 LOG_DBG(
"uncompression: next header is inlined. Next: %d\n", next);
1270 CHECK_READ_SPACE(1);
1274 LOG_DBG(
"uncompression: found ext header id: %d next: %d len: %d\n", eid, next, len);
1276 case SICSLOWPAN_NHC_ETX_HDR_HBHO:
1279 case SICSLOWPAN_NHC_ETX_HDR_ROUTING:
1280 proto = UIP_PROTO_ROUTING;
1282 case SICSLOWPAN_NHC_ETX_HDR_FRAG:
1283 proto = UIP_PROTO_FRAG;
1285 case SICSLOWPAN_NHC_ETX_HDR_DESTO:
1286 proto = UIP_PROTO_DESTO;
1289 LOG_DBG(
"uncompression: error unsupported ext header\n");
1292 *last_nextheader = proto;
1295 if((ip_payload - buf) + UIP_EXT_HDR_LEN + len > buf_size) {
1296 LOG_WARN(
"uncompression: cannot write ext header beyond target buffer\n");
1301 exthdr = (
struct uip_ext_hdr *)ip_payload;
1302 exthdr->len = (UIP_EXT_HDR_LEN + len) / 8;
1303 if(exthdr->len == 0) {
1304 LOG_WARN(
"Extension header length is below 8\n");
1308 exthdr->next = next;
1309 last_nextheader = &exthdr->next;
1312 CHECK_READ_SPACE(len + 1);
1313 memcpy((uint8_t *)exthdr + UIP_EXT_HDR_LEN,
iphc_ptr, len);
1317 ip_payload += (exthdr->len + 1) * 8;
1318 ext_hdr_len += (exthdr->len + 1) * 8;
1320 LOG_DBG(
"uncompression: %d len: %d exthdr len: %d (calc: %d)\n",
1321 proto, len, exthdr->len, (exthdr->len + 1) * 8);
1325 CHECK_READ_SPACE(1);
1326 if(nhc && (*
iphc_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
1327 struct uip_udp_hdr *udp_buf;
1329 uint8_t checksum_compressed;
1332 if((ip_payload - buf) + UIP_UDPH_LEN > buf_size) {
1333 LOG_WARN(
"uncompression: cannot write UDP header beyond target buffer\n");
1337 udp_buf = (
struct uip_udp_hdr *)ip_payload;
1338 *last_nextheader = UIP_PROTO_UDP;
1339 checksum_compressed = *
iphc_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
1340 LOG_DBG(
"uncompression: incoming header value: %i\n", *
iphc_ptr);
1341 switch(*
iphc_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
1342 case SICSLOWPAN_NHC_UDP_CS_P_00:
1344 CHECK_READ_SPACE(5);
1345 memcpy(&udp_buf->srcport,
iphc_ptr + 1, 2);
1346 memcpy(&udp_buf->destport,
iphc_ptr + 3, 2);
1347 LOG_DBG(
"uncompression: UDP ports (ptr+5): %x, %x\n",
1353 case SICSLOWPAN_NHC_UDP_CS_P_01:
1355 LOG_DBG(
"uncompression: destination address\n");
1356 CHECK_READ_SPACE(4);
1357 memcpy(&udp_buf->srcport,
iphc_ptr + 1, 2);
1358 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(
iphc_ptr + 3)));
1359 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1364 case SICSLOWPAN_NHC_UDP_CS_P_10:
1366 LOG_DBG(
"uncompression: source address\n");
1367 CHECK_READ_SPACE(4);
1368 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
1370 memcpy(&udp_buf->destport,
iphc_ptr + 2, 2);
1371 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1376 case SICSLOWPAN_NHC_UDP_CS_P_11:
1378 CHECK_READ_SPACE(2);
1379 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1381 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1383 LOG_DBG(
"uncompression: UDP ports (ptr+2): %x, %x\n",
1389 LOG_DBG(
"uncompression: error unsupported UDP compression\n");
1392 if(!checksum_compressed) {
1393 CHECK_READ_SPACE(2);
1394 memcpy(&udp_buf->udpchksum,
iphc_ptr, 2);
1396 LOG_DBG(
"uncompression: checksum included\n");
1398 LOG_DBG(
"uncompression: checksum *NOT* included\n");
1403 udp_buf->udplen =
UIP_HTONS(ip_len == 0 ? udp_len :
1404 ip_len - UIP_IPH_LEN - ext_hdr_len);
1405 LOG_DBG(
"uncompression: UDP length: %u (ext: %u) ip_len: %d udp_len: %d\n",
1406 UIP_HTONS(udp_buf->udplen), ext_hdr_len, ip_len, udp_len);
1416 LOG_DBG(
"uncompression: IP payload length: %d. %u - %u + %u - %u\n", len,
1420 SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8;
1421 SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF;
1424 SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
1425 SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
1433#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1442 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] = SICSLOWPAN_DISPATCH_PAGING | (page & 0x0f);
1464 if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_PAGING_MASK) == SICSLOWPAN_DISPATCH_PAGING) {
1466 curr_page = PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & 0x0f;
1495#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1497compress_hdr_ipv6(linkaddr_t *link_destaddr)
1519 const linkaddr_t *dest;
1521 if(callback != NULL) {
1522 callback->output_callback(status);
1527 dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
1533 link_stats_packet_sent(dest, status, transmissions);
1536 NETSTACK_ROUTING.
link_callback(dest, status, transmissions);
1554 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, dest);
1556#if NETSTACK_CONF_BRIDGE_MODE
1558 packetbuf_set_addr(PACKETBUF_ADDR_SENDER,(
void*)&
uip_lladdr);
1569#if SICSLOWPAN_CONF_FRAG
1579fragment_copy_payload_and_send(uint16_t uip_offset, linkaddr_t *dest) {
1588 q = queuebuf_new_from_packetbuf();
1590 LOG_WARN(
"output: could not allocate queuebuf, dropping fragment\n");
1598 queuebuf_to_packetbuf(q);
1604 LOG_ERR(
"output: error in fragment tx, dropping subsequent fragments.\n");
1647 if(localdest == NULL) {
1653 LOG_INFO(
"output: sending IPv6 packet with len %d\n",
uip_len);
1656 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
1657 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
1660 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
1661#if LLSEC802154_USES_AUX_HEADER
1663 packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
1664 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
1665#if LLSEC802154_USES_EXPLICIT_KEYS
1666 packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
1667 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_KEY_ID));
1675 LOG_WARN(
"output: failed to calculate payload size - dropping packet\n");
1680#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1681 compress_hdr_ipv6(&dest);
1683#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1691#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
1702 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
1705 LOG_INFO(
"output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
1711#if SICSLOWPAN_CONF_FRAG
1713 uint16_t processed_ip_out_len;
1730 int fragn_max_payload = (
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
1732 int last_fragn_max_payload =
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
1734 int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
1736 int fragment_count = 2;
1737 if(middle_fragn_total_payload > 0) {
1738 fragment_count += 1 + (middle_fragn_total_payload - 1) / fragn_max_payload;
1741 int freebuf = queuebuf_numfree() - 1;
1742 LOG_INFO(
"output: fragmentation needed, fragments: %u, free queuebufs: %u\n",
1743 fragment_count, freebuf);
1745 if(freebuf < fragment_count) {
1746 LOG_WARN(
"output: dropping packet, not enough free bufs (needed: %u, free: %u)\n",
1747 fragment_count, freebuf);
1751 if(frag1_payload < 0) {
1755 LOG_WARN(
"output: compressed header does not fit first fragment\n");
1762 frag_tag = my_tag++;
1769 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1770 ((SICSLOWPAN_DISPATCH_FRAG1 << 8) |
uip_len));
1771 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
1778 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d)\n",
1779 curr_frag + 1, fragment_count,
1789 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1790 ((SICSLOWPAN_DISPATCH_FRAGN << 8) |
uip_len));
1796 while(processed_ip_out_len <
uip_len) {
1799 PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
1802 if(
uip_len - processed_ip_out_len > last_fragn_max_payload) {
1812 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d, offset %d)\n",
1813 curr_frag + 1, fragment_count,
1815 if(fragment_copy_payload_and_send(processed_ip_out_len, &dest) == 0) {
1822 LOG_ERR(
"output: Packet too large to be sent without fragmentation support; dropping packet\n");
1832 LOG_ERR(
"output: uip_len is smaller than uncomp_hdr_len (%d < %d)",
1861 uint16_t frag_size = 0;
1863 uint8_t frag_offset = 0;
1865 uint16_t buffer_size;
1867#if SICSLOWPAN_CONF_FRAG
1868 uint8_t is_fragment = 0;
1869 int8_t frag_context = 0;
1872 uint16_t frag_tag = 0;
1873 uint8_t first_fragment = 0, last_fragment = 0;
1877 link_stats_input_callback(packetbuf_addr(PACKETBUF_ADDR_SENDER));
1887 LOG_WARN(
"input: empty packet\n");
1900 last_rssi = (
signed short)packetbuf_attr(PACKETBUF_ATTR_RSSI);
1901 uipbuf_set_attr(UIPBUF_ATTR_RSSI, packetbuf_attr(PACKETBUF_ATTR_RSSI));
1902 uipbuf_set_attr(UIPBUF_ATTR_LINK_QUALITY, packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));
1905#if SICSLOWPAN_CONF_FRAG
1911 switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
1912 case SICSLOWPAN_DISPATCH_FRAG1:
1914 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1915 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1920 LOG_INFO(
"input: received first element of a fragmented packet (tag %d, len %d)\n",
1921 frag_tag, frag_size);
1924 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1926 if(frag_context == -1) {
1927 LOG_ERR(
"input: failed to allocate new reassembly context\n");
1931 buffer = frag_info[frag_context].first_frag;
1932 buffer_size = SICSLOWPAN_FIRST_FRAGMENT_SIZE;
1934 case SICSLOWPAN_DISPATCH_FRAGN:
1939 frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
1940 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1941 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1946 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1948 if(frag_context == -1) {
1949 LOG_ERR(
"input: reassembly context not found (tag %d)\n", frag_tag);
1957 if(frag_info[frag_context].reassembled_len >= frag_size) {
1966 if(is_fragment && !first_fragment) {
1976 LOG_INFO(
"input: page 1, 6LoRH\n");
1979 LOG_ERR(
"input: page %u not supported\n",
curr_page);
1985 (PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
1986 LOG_DBG(
"uncompression: IPHC dispatch\n");
1988 LOG_ERR(
"input: failed to decompress IPHC packet\n");
1991 }
else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
1992 LOG_DBG(
"uncompression: IPV6 dispatch\n");
2002 LOG_ERR(
"uncompression: unknown dispatch: 0x%02x, or IPHC disabled\n",
2003 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK);
2007#if SICSLOWPAN_CONF_FRAG
2018 LOG_ERR(
"input: packet dropped due to header > total packet\n");
2023#if SICSLOWPAN_CONF_FRAG
2025 LOG_INFO(
"input: fragment (tag %d, payload %d, offset %d) -- %u %u\n",
2032 unsigned int req_size =
uncomp_hdr_len + (uint16_t)(frag_offset << 3)
2034 if(req_size >
sizeof(
uip_buf)) {
2035#if SICSLOWPAN_CONF_FRAG
2037 "input: packet and fragment context %u dropped, minimum required IP_BUF size: %d+%d+%d=%u (current size: %u)\n",
2043 clear_fragments(frag_context);
2051 if(buffer != NULL) {
2053 LOG_ERR(
"input: cannot copy the payload into the buffer\n");
2061#if SICSLOWPAN_CONF_FRAG
2064 if(first_fragment != 0) {
2070 if(last_fragment != 0) {
2071 frag_info[frag_context].reassembled_len = frag_size;
2073 if(!copy_frags2uip(frag_context)) {
2083 if(!is_fragment || last_fragment) {
2085 if(is_fragment != 0 && last_fragment != 0) {
2093 LOG_INFO(
"input: received IPv6 packet with len %d\n",
2096 if(LOG_DBG_ENABLED) {
2098 LOG_DBG(
"uncompression: after (%u):",
UIP_IP_BUF->len[1]);
2099 for (ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
2100 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
2101 LOG_DBG_(
"%02x", data);
2109 callback->input_callback();
2112#if LLSEC802154_USES_AUX_HEADER
2117 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_LEVEL,
2118 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
2119#if LLSEC802154_USES_EXPLICIT_KEYS
2120 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_KEY_ID,
2121 packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX));
2126#if SICSLOWPAN_CONF_FRAG
2136sicslowpan_init(
void)
2139#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC
2145#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
2146 addr_contexts[0].used = 1;
2147 addr_contexts[0].number = 0;
2148#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0
2149 SICSLOWPAN_CONF_ADDR_CONTEXT_0;
2151 addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0;
2152 addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1;
2156#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1
2160#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1
2162 addr_contexts[1].used = 1;
2163 addr_contexts[1].number = 1;
2164 SICSLOWPAN_CONF_ADDR_CONTEXT_1;
2165#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2
2167 addr_contexts[2].used = 1;
2168 addr_contexts[2].number = 2;
2169 SICSLOWPAN_CONF_ADDR_CONTEXT_2;
2172 addr_contexts[i].used = 0;
2175 addr_contexts[i].used = 0;
2185sicslowpan_get_last_rssi(
void)
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.
const linkaddr_t linkaddr_null
The null link-layer address.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
void packetbuf_clear(void)
Clear and reset the packetbuf.
static void digest_6lorh_hdr(void)
Digest 6lorh headers before IPHC.
static struct sicslowpan_addr_context * context
Addresses contexts for IPHC.
static uint8_t curr_page
The current page (RFC 4944)
static int compress_hdr_iphc(linkaddr_t *link_destaddr)
Compress IP/UDP header.
static uint8_t * packetbuf_ptr
A pointer to the packetbuf buffer.
static int mac_max_payload
mac_max_payload is the maimum payload space on the MAC frame.
static uint8_t * iphc_ptr
pointer to the byte where to write next inline field.
#define sicslowpan_is_iid_16_bit_compressable(a)
check whether we can compress the IID in address 'a' to 16 bits.
static struct sicslowpan_addr_context * addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr)
find the context corresponding to prefix ipaddr
static uint8_t uncomp_hdr_len
uncomp_hdr_len is the length of the headers before compression (if HC2 is used this includes the UDP ...
static int last_tx_status
the result of the last transmitted fragment
static uint8_t output(const linkaddr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
static 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 send_packet(linkaddr_t *dest)
This function is called by the 6lowpan code to send out a packet.
static void add_6lorh_hdr(void)
Adds 6lorh headers before IPHC.
static void input(void)
Process a received 6lowpan packet.
static int packetbuf_payload_len
The length of the payload in the Packetbuf buffer.
static void digest_paging_dispatch(void)
Digest 6lorh headers before IPHC.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
int timer_expired(struct timer *t)
Check if a timer has expired.
#define uip_is_addr_mac_addr_based(a, m)
was addr (a) forged based on the mac address m a type is uip_ipaddr_t m type is uiplladdr_t
uip_lladdr_t uip_lladdr
Host L2 address.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
#define UIP_ICMP_BUF
Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_...
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
void uip_ds6_link_callback(int status, int numtx)
The callback function to update link-layer stats in a neighbor cache.
#define UIP_PROTO_HBHO
extension headers types
#define UIP_IP_BUF
Direct access to IPv6 header.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
#define UIP_BUFSIZE
The size of the uIP packet buffer.
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS
If we use IPHC compression, how many address contexts do we support.
#define SICSLOWPAN_REASS_MAXAGE
Timeout for packet reassembly at the 6lowpan layer (should be < 60s)
#define SICSLOWPAN_COMPRESSION
Do we compress the IP header or not.
Header file for the logging system.
@ MAC_TX_COLLISION
The MAC layer did not get an acknowledgement for the packet.
@ MAC_TX_OK
The MAC layer transmission was OK.
@ MAC_TX_ERR
The MAC layer transmission could not be performed because of a fatal error.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.
Header file for the Packet queue buffer management.
Routing driver header file.
Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01)
int(* max_payload)(void)
Read out estimated max payload size based on payload in packetbuf.
void(* send)(mac_callback_t sent_callback, void *ptr)
Send a packet from the packetbuf
The structure of a network driver in Contiki.
void(* link_callback)(const linkaddr_t *addr, int status, int numtx)
Called by lower layers after every packet transmission.
The header for fragments.
Header for the Contiki/uIP interface.
Header file for IPv6-related data structures.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Header file for the uIP TCP/IP stack.
Configuration options for uIP.