64 #include "dev/watchdog.h"
65 #include "net/link-stats.h"
75 #define DEBUG DEBUG_NONE
81 #define PRINTFI(...) PRINTF(__VA_ARGS__)
82 #define PRINTFO(...) PRINTF(__VA_ARGS__)
91 #define UIP_LOG(m) uip_log(m)
96 #ifndef SICSLOWPAN_COMPRESSION
97 #ifdef SICSLOWPAN_CONF_COMPRESSION
98 #define SICSLOWPAN_COMPRESSION SICSLOWPAN_CONF_COMPRESSION
100 #define SICSLOWPAN_COMPRESSION SICSLOWPAN_COMPRESSION_IPV6
104 #define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1]))
105 #define SET16(ptr,index,value) do { \
106 (ptr)[index] = ((value) >> 8) & 0xff; \
107 (ptr)[index + 1] = (value) & 0xff; \
113 #define PACKETBUF_FRAG_PTR (packetbuf_ptr)
114 #define PACKETBUF_FRAG_DISPATCH_SIZE 0
115 #define PACKETBUF_FRAG_TAG 2
116 #define PACKETBUF_FRAG_OFFSET 4
119 #define PACKETBUF_IPHC_BUF ((uint8_t *)(packetbuf_ptr + packetbuf_hdr_len))
121 #define PACKETBUF_HC1_PTR (packetbuf_ptr + packetbuf_hdr_len)
122 #define PACKETBUF_HC1_DISPATCH 0
123 #define PACKETBUF_HC1_ENCODING 1
124 #define PACKETBUF_HC1_TTL 2
126 #define PACKETBUF_HC1_HC_UDP_PTR (packetbuf_ptr + packetbuf_hdr_len)
127 #define PACKETBUF_HC1_HC_UDP_DISPATCH 0
128 #define PACKETBUF_HC1_HC_UDP_HC1_ENCODING 1
129 #define PACKETBUF_HC1_HC_UDP_UDP_ENCODING 2
130 #define PACKETBUF_HC1_HC_UDP_TTL 3
131 #define PACKETBUF_HC1_HC_UDP_PORTS 4
132 #define PACKETBUF_HC1_HC_UDP_CHKSUM 5
139 #define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf)
140 #define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN])
142 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
143 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])
144 #define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLIPH_LEN])
145 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN])
152 #ifdef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
153 #define MAC_MAX_PAYLOAD SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
155 #define MAC_MAX_PAYLOAD (127 - 2)
161 #ifdef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD
162 #define COMPRESSION_THRESHOLD SICSLOWPAN_CONF_COMPRESSION_THRESHOLD
164 #define COMPRESSION_THRESHOLD 0
171 #ifndef SICSLOWPAN_FIXED_HDRLEN
172 #define SICSLOWPAN_FIXED_HDRLEN 21
214 static int last_rssi;
220 #if SICSLOWPAN_CONF_FRAG
221 static uint16_t my_tag;
227 #ifdef SICSLOWPAN_CONF_FRAGMENT_BUFFERS
228 #define SICSLOWPAN_FRAGMENT_BUFFERS SICSLOWPAN_CONF_FRAGMENT_BUFFERS
230 #define SICSLOWPAN_FRAGMENT_BUFFERS 12
238 #ifdef SICSLOWPAN_CONF_REASS_CONTEXTS
239 #define SICSLOWPAN_REASS_CONTEXTS SICSLOWPAN_CONF_REASS_CONTEXTS
241 #define SICSLOWPAN_REASS_CONTEXTS 2
245 #ifdef SICSLOWPAN_CONF_FRAGMENT_SIZE
246 #define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE
248 #define SICSLOWPAN_FRAGMENT_SIZE 110
252 #define SICSLOWPAN_FIRST_FRAGMENT_SIZE (SICSLOWPAN_FRAGMENT_SIZE + 38)
255 struct sicslowpan_frag_info {
265 uint16_t reassembled_len;
267 struct timer reass_timer;
270 uint16_t first_frag_len;
273 uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE];
276 static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS];
278 struct sicslowpan_frag_buf {
285 uint8_t data[SICSLOWPAN_FRAGMENT_SIZE];
288 static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS];
292 clear_fragments(uint8_t frag_info_index)
296 frag_info[frag_info_index].len = 0;
297 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
298 if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) {
308 timeout_fragments(
int not_context)
312 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
313 if(frag_info[i].len > 0 && i != not_context &&
316 count += clear_fragments(i);
323 store_fragment(uint8_t index, uint8_t offset)
326 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
327 if(frag_buf[i].len == 0) {
329 frag_buf[i].offset = offset;
331 frag_buf[i].index = index;
335 PRINTF(
"Fragsize: %d\n", frag_buf[i].len);
337 return frag_buf[i].len;
346 add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
354 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
356 if(frag_info[i].len > 0 &&
timer_expired(&frag_info[i].reass_timer)) {
361 if(found < 0 && frag_info[i].len == 0) {
369 PRINTF(
"*** Failed to store new fragment session - tag: %d\n", tag);
374 frag_info[found].len = frag_size;
375 frag_info[found].tag = tag;
377 packetbuf_addr(PACKETBUF_ADDR_SENDER));
385 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
386 if(frag_info[i].tag == tag && frag_info[i].len > 0 &&
387 linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
396 PRINTF(
"*** Failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
401 len = store_fragment(i, offset);
402 if(len < 0 && timeout_fragments(i) > 0) {
403 len = store_fragment(i, offset);
406 frag_info[i].reassembled_len += len;
411 PRINTF(
"*** Failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
424 memcpy((uint8_t *)
UIP_IP_BUF, (uint8_t *)frag_info[context].first_frag,
425 frag_info[context].first_frag_len);
426 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
428 if(frag_buf[i].len > 0 && frag_buf[i].index == context) {
429 memcpy((uint8_t *)
UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3),
430 (uint8_t *)frag_buf[i].data, frag_buf[i].len);
434 clear_fragments(context);
443 static struct rime_sniffer *callback =
NULL;
446 rime_sniffer_add(
struct rime_sniffer *s)
452 rime_sniffer_remove(
struct rime_sniffer *s)
458 set_packet_attrs(
void)
462 packetbuf_set_attr(PACKETBUF_ATTR_NETWORK_ID,
UIP_IP_BUF->proto);
466 c = UIP_UDP_BUF->srcport;
467 if(UIP_UDP_BUF->destport < c) {
468 c = UIP_UDP_BUF->destport;
470 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_TCP) {
471 c = UIP_TCP_BUF->srcport;
472 if(UIP_TCP_BUF->destport < c) {
473 c = UIP_TCP_BUF->destport;
475 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
479 packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, c);
489 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06
495 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
513 const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
520 const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
527 const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};
530 const uint8_t llprefix[] = {0xfe, 0x80};
533 static const uint8_t ttl_values[] = {0, 1, 64, 255};
544 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
547 if((addr_contexts[i].used == 1) &&
548 uip_ipaddr_prefixcmp(&addr_contexts[i].prefix, ipaddr, 64)) {
549 return &addr_contexts[i];
561 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
564 if((addr_contexts[i].used == 1) &&
565 addr_contexts[i].number == number) {
566 return &addr_contexts[i];
580 memcpy(hc06_ptr, &ipaddr->u16[7], 2);
585 memcpy(hc06_ptr, &ipaddr->u16[4], 8);
599 uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t
const prefix[],
602 uint8_t prefcount = pref_post_count >> 4;
603 uint8_t postcount = pref_post_count & 0x0f;
605 prefcount = prefcount == 15 ? 16 : prefcount;
606 postcount = postcount == 15 ? 16 : postcount;
608 PRINTF(
"Uncompressing %d + %d => ", prefcount, postcount);
611 memcpy(ipaddr, prefix, prefcount);
613 if(prefcount + postcount < 16) {
614 memset(&ipaddr->u8[prefcount], 0, 16 - (prefcount + postcount));
617 memcpy(&ipaddr->u8[16 - postcount], hc06_ptr, postcount);
618 if(postcount == 2 && prefcount < 11) {
620 ipaddr->u8[11] = 0xff;
621 ipaddr->u8[12] = 0xfe;
623 hc06_ptr += postcount;
624 }
else if (prefcount > 0) {
671 uint8_t tmp, iphc0, iphc1;
674 PRINTF(
"before compression (%d): ",
UIP_IP_BUF->len[1]);
675 for(ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
676 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
677 PRINTF(
"%02x", data);
691 iphc0 = SICSLOWPAN_DISPATCH_IPHC;
693 PACKETBUF_IPHC_BUF[2] = 0;
708 PRINTF(
"IPHC: compressing dest or src ipaddr - setting CID\n");
709 iphc1 |= SICSLOWPAN_IPHC_CID;
723 tmp = ((tmp & 0x03) << 6) | (tmp >> 2);
728 iphc0 |= SICSLOWPAN_IPHC_FL_C;
732 iphc0 |= SICSLOWPAN_IPHC_TC_C;
743 iphc0 |= SICSLOWPAN_IPHC_TC_C;
744 *hc06_ptr = (tmp & 0xc0) |
760 #if UIP_CONF_UDP || UIP_CONF_ROUTER
762 iphc0 |= SICSLOWPAN_IPHC_NH_C;
766 if ((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
780 iphc0 |= SICSLOWPAN_IPHC_TTL_1;
783 iphc0 |= SICSLOWPAN_IPHC_TTL_64;
786 iphc0 |= SICSLOWPAN_IPHC_TTL_255;
796 PRINTF(
"IPHC: compressing unspecified - setting SAC\n");
797 iphc1 |= SICSLOWPAN_IPHC_SAC;
798 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
802 PRINTF(
"IPHC: compressing src with context - setting CID & SAC ctx: %d\n",
804 iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
805 PACKETBUF_IPHC_BUF[2] |= context->number << 4;
808 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
815 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
819 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
820 memcpy(hc06_ptr, &
UIP_IP_BUF->srcipaddr.u16[0], 16);
827 iphc1 |= SICSLOWPAN_IPHC_M;
828 if(sicslowpan_is_mcast_addr_compressable8(&
UIP_IP_BUF->destipaddr)) {
829 iphc1 |= SICSLOWPAN_IPHC_DAM_11;
833 }
else if(sicslowpan_is_mcast_addr_compressable32(&
UIP_IP_BUF->destipaddr)) {
834 iphc1 |= SICSLOWPAN_IPHC_DAM_10;
837 memcpy(hc06_ptr + 1, &
UIP_IP_BUF->destipaddr.u8[13], 3);
839 }
else if(sicslowpan_is_mcast_addr_compressable48(&
UIP_IP_BUF->destipaddr)) {
840 iphc1 |= SICSLOWPAN_IPHC_DAM_01;
843 memcpy(hc06_ptr + 1, &
UIP_IP_BUF->destipaddr.u8[11], 5);
846 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
848 memcpy(hc06_ptr, &
UIP_IP_BUF->destipaddr.u8[0], 16);
855 iphc1 |= SICSLOWPAN_IPHC_DAC;
856 PACKETBUF_IPHC_BUF[2] |= context->number;
859 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
867 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
871 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
872 memcpy(hc06_ptr, &
UIP_IP_BUF->destipaddr.u16[0], 16);
879 #if UIP_CONF_UDP || UIP_CONF_ROUTER
882 PRINTF(
"IPHC: Uncompressed UDP ports on send side: %x, %x\n",
885 if(((
UIP_HTONS(UIP_UDP_BUF->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
886 ((
UIP_HTONS(UIP_UDP_BUF->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
888 *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_11;
889 PRINTF(
"IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
891 (uint8_t)((
UIP_HTONS(UIP_UDP_BUF->srcport) -
892 SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
893 (uint8_t)((
UIP_HTONS(UIP_UDP_BUF->destport) -
894 SICSLOWPAN_UDP_4_BIT_PORT_MIN));
896 }
else if((
UIP_HTONS(UIP_UDP_BUF->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
898 *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_01;
899 PRINTF(
"IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
900 memcpy(hc06_ptr + 1, &UIP_UDP_BUF->srcport, 2);
902 (uint8_t)((
UIP_HTONS(UIP_UDP_BUF->destport) -
903 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
905 }
else if((
UIP_HTONS(UIP_UDP_BUF->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
907 *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_10;
908 PRINTF(
"IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *hc06_ptr);
910 (uint8_t)((
UIP_HTONS(UIP_UDP_BUF->srcport) -
911 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
912 memcpy(hc06_ptr + 2, &UIP_UDP_BUF->destport, 2);
916 *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_00;
917 PRINTF(
"IPHC: cannot compress headers\n");
918 memcpy(hc06_ptr + 1, &UIP_UDP_BUF->srcport, 4);
923 memcpy(hc06_ptr, &UIP_UDP_BUF->udpchksum, 2);
931 PACKETBUF_IPHC_BUF[0] = iphc0;
932 PACKETBUF_IPHC_BUF[1] = iphc1;
958 uint8_t tmp, iphc0, iphc1;
962 iphc0 = PACKETBUF_IPHC_BUF[0];
963 iphc1 = PACKETBUF_IPHC_BUF[1];
966 if(iphc1 & SICSLOWPAN_IPHC_CID) {
967 PRINTF(
"IPHC: CID flag set - increase header with one\n");
972 if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) {
974 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
976 memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow, hc06_ptr + 1, 3);
981 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f);
983 SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) |
984 (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f);
987 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
989 SICSLOWPAN_IP_BUF(buf)->tcflow = (*hc06_ptr & 0x0F) |
990 ((*hc06_ptr >> 2) & 0x30);
991 memcpy(&SICSLOWPAN_IP_BUF(buf)->flow, hc06_ptr + 1, 2);
997 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
999 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*hc06_ptr >> 2) & 0x0f);
1000 SICSLOWPAN_IP_BUF(buf)->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30);
1001 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1005 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1006 SICSLOWPAN_IP_BUF(buf)->tcflow = 0;
1007 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1012 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
1014 SICSLOWPAN_IP_BUF(buf)->proto = *
hc06_ptr;
1015 PRINTF(
"IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
1020 if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) {
1021 SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03];
1023 SICSLOWPAN_IP_BUF(buf)->ttl = *
hc06_ptr;
1028 tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03;
1031 if(iphc1 & SICSLOWPAN_IPHC_SAC) {
1032 uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
1033 PACKETBUF_IPHC_BUF[2] >> 4 : 0;
1038 if(context ==
NULL) {
1039 PRINTF(
"sicslowpan uncompress_hdr: error context not found\n");
1044 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr,
1045 tmp != 0 ? context->prefix :
NULL, unc_ctxconf[tmp],
1046 (
uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1049 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix, unc_llconf[tmp],
1050 (
uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
1055 tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03;
1058 if(iphc1 & SICSLOWPAN_IPHC_M) {
1060 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1068 uint8_t prefix[] = {0xff, 0x02};
1069 if(tmp > 0 && tmp < 3) {
1074 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix,
1075 unc_mxconf[tmp],
NULL);
1080 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1081 uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? PACKETBUF_IPHC_BUF[2] & 0x0f : 0;
1085 if(context ==
NULL) {
1086 PRINTF(
"sicslowpan uncompress_hdr: error context not found\n");
1089 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, context->prefix,
1091 (
uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1094 uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix,
1096 (
uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
1102 if((iphc0 & SICSLOWPAN_IPHC_NH_C)) {
1104 if((*hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
1105 uint8_t checksum_compressed;
1106 SICSLOWPAN_IP_BUF(buf)->proto = UIP_PROTO_UDP;
1107 checksum_compressed = *hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
1108 PRINTF(
"IPHC: Incoming header value: %i\n", *hc06_ptr);
1109 switch(*hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
1110 case SICSLOWPAN_NHC_UDP_CS_P_00:
1112 memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, hc06_ptr + 1, 2);
1113 memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, hc06_ptr + 3, 2);
1114 PRINTF(
"IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n",
1115 UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport),
1116 UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport));
1120 case SICSLOWPAN_NHC_UDP_CS_P_01:
1122 PRINTF(
"IPHC: Decompressing destination\n");
1123 memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, hc06_ptr + 1, 2);
1124 SICSLOWPAN_UDP_BUF(buf)->destport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3)));
1125 PRINTF(
"IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
1126 UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport),
UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport));
1130 case SICSLOWPAN_NHC_UDP_CS_P_10:
1132 PRINTF(
"IPHC: Decompressing source\n");
1133 SICSLOWPAN_UDP_BUF(buf)->srcport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
1135 memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, hc06_ptr + 2, 2);
1136 PRINTF(
"IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
1137 UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport),
UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport));
1141 case SICSLOWPAN_NHC_UDP_CS_P_11:
1143 SICSLOWPAN_UDP_BUF(buf)->srcport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1144 (*(hc06_ptr + 1) >> 4));
1145 SICSLOWPAN_UDP_BUF(buf)->destport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1146 ((*(hc06_ptr + 1)) & 0x0F));
1147 PRINTF(
"IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n",
1148 UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport),
UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport));
1153 PRINTF(
"sicslowpan uncompress_hdr: error unsupported UDP compression\n");
1156 if(!checksum_compressed) {
1157 memcpy(&SICSLOWPAN_UDP_BUF(buf)->udpchksum, hc06_ptr, 2);
1159 PRINTF(
"IPHC: sicslowpan uncompress_hdr: checksum included\n");
1161 PRINTF(
"IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n");
1173 SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8;
1174 SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF;
1177 SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
1178 SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
1182 if(SICSLOWPAN_IP_BUF(buf)->proto == UIP_PROTO_UDP) {
1183 memcpy(&SICSLOWPAN_UDP_BUF(buf)->udplen, &SICSLOWPAN_IP_BUF(buf)->len[0], 2);
1208 compress_hdr_ipv6(linkaddr_t *link_destaddr)
1229 uip_ds6_link_neighbor_callback(status, transmissions);
1231 if(callback !=
NULL) {
1232 callback->output_callback(status);
1249 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, dest);
1251 #if NETSTACK_CONF_BRIDGE_MODE
1253 packetbuf_set_addr(PACKETBUF_ADDR_SENDER,(
void*)&
uip_lladdr);
1297 #if PACKETBUF_WITH_PACKET_TYPE
1298 #define TCP_FIN 0x01
1299 #define TCP_ACK 0x10
1300 #define TCP_CTL 0x3f
1303 (UIP_TCP_BUF->flags & TCP_FIN) == 0 &&
1304 (UIP_TCP_BUF->flags & TCP_CTL) != TCP_ACK) {
1305 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE,
1306 PACKETBUF_ATTR_PACKET_TYPE_STREAM);
1307 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_TCP &&
1308 (UIP_TCP_BUF->flags & TCP_FIN) == TCP_FIN) {
1309 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE,
1310 PACKETBUF_ATTR_PACKET_TYPE_STREAM_END);
1319 if(localdest ==
NULL) {
1325 PRINTFO(
"sicslowpan output: sending packet len %d\n",
uip_len);
1329 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1330 compress_hdr_ipv6(&dest);
1332 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06
1336 compress_hdr_ipv6(&dest);
1343 #ifndef SICSLOWPAN_USE_FIXED_HDRLEN
1344 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
1345 framer_hdrlen = NETSTACK_FRAMER.length();
1346 if(framer_hdrlen < 0) {
1356 #if SICSLOWPAN_CONF_FRAG
1358 uint16_t processed_ip_out_len;
1370 int estimated_fragments = ((int)
uip_len) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
1371 int freebuf = queuebuf_numfree() - 1;
1372 PRINTFO(
"uip_len: %d, fragments: %d, free bufs: %d\n",
uip_len, estimated_fragments, freebuf);
1373 if(freebuf < estimated_fragments) {
1374 PRINTFO(
"Dropping packet, not enough free bufs\n");
1378 PRINTFO(
"Fragmentation sending packet len %d\n",
uip_len);
1381 PRINTFO(
"sicslowpan output: 1rst fragment ");
1395 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1396 ((SICSLOWPAN_DISPATCH_FRAG1 << 8) |
uip_len));
1397 frag_tag = my_tag++;
1398 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
1401 packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
1407 q = queuebuf_new_from_packetbuf();
1409 PRINTFO(
"could not allocate queuebuf for first fragment, dropping packet\n");
1413 queuebuf_to_packetbuf(q);
1421 PRINTFO(
"error in fragment tx, dropping subsequent fragments.\n");
1433 packetbuf_hdr_len = SICSLOWPAN_FRAGN_HDR_LEN;
1436 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1437 ((SICSLOWPAN_DISPATCH_FRAGN << 8) |
uip_len));
1439 while(processed_ip_out_len <
uip_len) {
1440 PRINTFO(
"sicslowpan output: fragment ");
1441 PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
1448 PRINTFO(
"(offset %d, len %d, tag %d)\n",
1453 q = queuebuf_new_from_packetbuf();
1455 PRINTFO(
"could not allocate queuebuf, dropping fragment\n");
1459 queuebuf_to_packetbuf(q);
1468 PRINTFO(
"error in fragment tx, dropping subsequent fragments.\n");
1473 PRINTFO(
"sicslowpan output: Packet too large to be sent without fragmentation support; dropping packet\n");
1506 uint16_t frag_size = 0;
1508 uint8_t frag_offset = 0;
1511 #if SICSLOWPAN_CONF_FRAG
1512 uint8_t is_fragment = 0;
1513 int8_t frag_context = 0;
1516 uint16_t frag_tag = 0;
1517 uint8_t first_fragment = 0, last_fragment = 0;
1521 link_stats_input_callback(packetbuf_addr(PACKETBUF_ADDR_SENDER));
1535 last_rssi = (
signed short)packetbuf_attr(PACKETBUF_ATTR_RSSI);
1537 #if SICSLOWPAN_CONF_FRAG
1543 switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0xf800) >> 8) {
1544 case SICSLOWPAN_DISPATCH_FRAG1:
1545 PRINTFI(
"sicslowpan input: FRAG1 ");
1548 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1550 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1551 PRINTFI(
"size %d, tag %d, offset %d)\n",
1552 frag_size, frag_tag, frag_offset);
1559 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1561 if(frag_context == -1) {
1565 buffer = frag_info[frag_context].first_frag;
1568 case SICSLOWPAN_DISPATCH_FRAGN:
1573 PRINTFI(
"sicslowpan input: FRAGN ");
1574 frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
1575 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1576 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1577 PRINTFI(
"size %d, tag %d, offset %d)\n",
1578 frag_size, frag_tag, frag_offset);
1583 PRINTFI(
"last_fragment?: packetbuf_payload_len %d frag_size %d\n",
1588 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1590 if(frag_context == -1) {
1598 if(frag_info[frag_context].reassembled_len >= frag_size) {
1607 if(is_fragment && !first_fragment) {
1614 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06
1615 if((PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH] & 0xe0) == SICSLOWPAN_DISPATCH_IPHC) {
1616 PRINTFI(
"sicslowpan input: IPHC\n");
1620 switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]) {
1621 case SICSLOWPAN_DISPATCH_IPV6:
1622 PRINTFI(
"sicslowpan input: IPV6\n");
1634 PRINTFI(
"sicslowpan input: unknown dispatch: %u\n",
1635 PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]);
1640 #if SICSLOWPAN_CONF_FRAG
1651 PRINTF(
"SICSLOWPAN: packet dropped due to header > total packet\n");
1660 if(req_size >
sizeof(
uip_buf)) {
1662 "SICSLOWPAN: packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n",
1664 packetbuf_payload_len, req_size, (
unsigned)
sizeof(
uip_buf));
1671 if(buffer !=
NULL) {
1677 #if SICSLOWPAN_CONF_FRAG
1680 if(first_fragment != 0) {
1686 if(last_fragment != 0) {
1687 frag_info[frag_context].reassembled_len = frag_size;
1689 copy_frags2uip(frag_context);
1697 if(!is_fragment || last_fragment) {
1699 if(is_fragment != 0 && last_fragment != 0) {
1707 PRINTFI(
"sicslowpan input: IP packet ready (length %d)\n",
1713 PRINTF(
"after decompression %u:",
UIP_IP_BUF->len[1]);
1714 for (ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
1715 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
1716 PRINTF(
"%02x", data);
1725 callback->input_callback();
1729 #if SICSLOWPAN_CONF_FRAG
1739 sicslowpan_init(
void)
1746 tcpip_set_outputfunc(
output);
1748 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06
1754 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
1755 addr_contexts[0].used = 1;
1756 addr_contexts[0].number = 0;
1757 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0
1758 SICSLOWPAN_CONF_ADDR_CONTEXT_0;
1760 addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0;
1761 addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1;
1765 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1
1769 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1
1771 addr_contexts[1].used = 1;
1772 addr_contexts[1].number = 1;
1773 SICSLOWPAN_CONF_ADDR_CONTEXT_1;
1774 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2
1776 addr_contexts[2].used = 1;
1777 addr_contexts[2].number = 2;
1778 SICSLOWPAN_CONF_ADDR_CONTEXT_2;
1781 addr_contexts[i].used = 0;
1784 addr_contexts[i].used = 0;
1794 sicslowpan_get_last_rssi(
void)
void uip_log(char *msg)
Print out a uIP log message.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
uip_len
The length of the packet in the uip_buf buffer.
static uint8_t * hc06_ptr
pointer to the byte where to write next inline field.
static void send_packet(linkaddr_t *dest)
This function is called by the 6lowpan code to send out a packet.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
static uint8_t * packetbuf_ptr
A pointer to the packetbuf buffer.
The MAC layer did not get an acknowledgement for the packet.
Header file for IPv6-related data structures.
void packetbuf_clear(void)
Clear and reset the packetbuf.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
static void input(void)
Process a received 6lowpan packet.
#define UIP_LLH_LEN
The link level header length.
The header for fragments.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
const linkaddr_t linkaddr_null
The null Rime address.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
static void compress_hdr_iphc(linkaddr_t *link_destaddr)
Compress IP/UDP header.
#define UIP_IP_BUF
Pointer to IP header.
static uint8_t packetbuf_hdr_len
packetbuf_hdr_len is the total length of (the processed) 6lowpan headers (fragment headers...
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 3513 a is of type uip_ipaddr_t*
static void uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
Uncompress IPHC (i.e., IPHC and LOWPAN_UDP) headers and put them in sicslowpan_buf.
#define SICSLOWPAN_FIXED_HDRLEN
Fixed size of a frame header.
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS
If we use IPHC compression, how many address contexts do we support.
The MAC layer transmission could not be performed because of a fatal error.
static struct sicslowpan_addr_context * context
Addresses contexts for IPHC.
static void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
#define MAC_MAX_PAYLOAD
Maximum available size for frame headers, link layer security-related overhead, as well as 6LoWPAN pa...
Header for the Contiki/uIP interface.
Header file for the Rime stack
The MAC layer transmission was OK.
#define NULL
The null pointer.
static struct sicslowpan_addr_context * addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr)
find the context corresponding to prefix ipaddr
#define SICSLOWPAN_REASS_MAXAGE
Timeout for packet reassembly at the 6lowpan layer (should be < 60s)
void watchdog_periodic(void)
Writes the WDT clear sequence.
#define UIP_ICMP_BUF
Pointer to ICMP header.
#define CLOCK_SECOND
A second, measured in system clock time.
static volatile clock_time_t count
These routines define the AVR-specific calls declared in /core/sys/clock.h CLOCK_SECOND is the number...
Header file for the uIP TCP/IP stack.
static int last_tx_status
the result of the last transmitted fragment
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
A set of debugging macros for the IP stack
static uint8_t output(const uip_lladdr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
static int packetbuf_payload_len
The length of the payload in the Packetbuf buffer.
CCIF uip_lladdr_t uip_lladdr
Host L2 address.
#define sicslowpan_is_iid_16_bit_compressable(a)
check whether we can compress the IID in address 'a' to 16 bits.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
#define COMPRESSION_THRESHOLD
Some MAC layers need a minimum payload, which is configurable through the SICSLOWPAN_CONF_COMPRESSION...
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC3513 i.e.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a Rime address.
The structure of a network driver in Contiki.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
#define uip_is_addr_mac_addr_based(a, m)
was addr (a) forged based on the mac address m a type is uip_ipaddr_t m type is uiplladdr_t ...
static 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 struct sicslowpan_addr_context * addr_context_lookup_by_number(uint8_t number)
find the context with the given number
Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01) ...
Include file for the Contiki low-layer network stack (NETSTACK)
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
int timer_expired(struct timer *t)
Check if a timer has expired.