00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #include <string.h>
00061
00062 #include "contiki.h"
00063 #include "dev/watchdog.h"
00064 #include "net/tcpip.h"
00065 #include "net/uip.h"
00066 #include "net/uip-ds6.h"
00067 #include "net/rime.h"
00068 #include "net/sicslowpan.h"
00069 #include "net/neighbor-info.h"
00070 #include "net/netstack.h"
00071
00072 #define DEBUG 0
00073 #if DEBUG
00074
00075 u8_t p;
00076 #include <stdio.h>
00077 #define PRINTF(...) printf(__VA_ARGS__)
00078 #define PRINTFI(...) printf(__VA_ARGS__)
00079 #define PRINTFO(...) printf(__VA_ARGS__)
00080 #define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15])
00081 #define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",lladdr->addr[0], lladdr->addr[1], lladdr->addr[2], lladdr->addr[3],lladdr->addr[4], lladdr->addr[5],lladdr->addr[6], lladdr->addr[7])
00082 #define PRINTPACKETBUF() PRINTF("RIME buffer: "); for(p = 0; p < packetbuf_datalen(); p++){PRINTF("%.2X", *(rime_ptr + p));} PRINTF("\n")
00083 #define PRINTUIPBUF() PRINTF("UIP buffer: "); for(p = 0; p < uip_len; p++){PRINTF("%.2X", uip_buf[p]);}PRINTF("\n")
00084 #define PRINTSICSLOWPANBUF() PRINTF("SICSLOWPAN buffer: "); for(p = 0; p < sicslowpan_len; p++){PRINTF("%.2X", sicslowpan_buf[p]);}PRINTF("\n")
00085 #else
00086 #define PRINTF(...)
00087 #define PRINTFI(...)
00088 #define PRINTFO(...)
00089 #define PRINT6ADDR(addr)
00090 #define PRINTLLADDR(lladdr)
00091 #define PRINTPACKETBUF()
00092 #define PRINTUIPBUF()
00093 #define PRINTSICSLOWPANBUF()
00094 #endif
00095
00096 #if UIP_LOGGING
00097 #include <stdio.h>
00098 void uip_log(char *msg);
00099 #define UIP_LOG(m) uip_log(m)
00100 #else
00101 #define UIP_LOG(m)
00102 #endif
00103
00104 #ifdef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS
00105 #define SICSLOWPAN_MAX_MAC_TRANSMISSIONS SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS
00106 #else
00107 #define SICSLOWPAN_MAX_MAC_TRANSMISSIONS 4
00108 #endif
00109
00110 #ifndef SICSLOWPAN_COMPRESSION
00111 #ifdef SICSLOWPAN_CONF_COMPRESSION
00112 #define SICSLOWPAN_COMPRESSION SICSLOWPAN_CONF_COMPRESSION
00113 #else
00114 #define SICSLOWPAN_COMPRESSION SICSLOWPAN_COMPRESSION_IPV6
00115 #endif
00116 #endif
00117
00118 #ifndef SICSLOWPAN_CONF_NEIGHBOR_INFO
00119
00120 #define SICSLOWPAN_CONF_NEIGHBOR_INFO UIP_CONF_IPV6_RPL
00121 #endif
00122
00123 #define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1]))
00124 #define SET16(ptr,index,value) do { \
00125 (ptr)[index] = ((value) >> 8) & 0xff; \
00126 (ptr)[index + 1] = (value) & 0xff; \
00127 } while(0)
00128
00129
00130
00131
00132 #define RIME_FRAG_PTR (rime_ptr)
00133 #define RIME_FRAG_DISPATCH_SIZE 0
00134 #define RIME_FRAG_TAG 2
00135 #define RIME_FRAG_OFFSET 4
00136
00137
00138 #define RIME_IPHC_BUF ((uint8_t *)(rime_ptr + rime_hdr_len))
00139
00140 #define RIME_HC1_PTR (rime_ptr + rime_hdr_len)
00141 #define RIME_HC1_DISPATCH 0
00142 #define RIME_HC1_ENCODING 1
00143 #define RIME_HC1_TTL 2
00144
00145 #define RIME_HC1_HC_UDP_PTR (rime_ptr + rime_hdr_len)
00146 #define RIME_HC1_HC_UDP_DISPATCH 0
00147 #define RIME_HC1_HC_UDP_HC1_ENCODING 1
00148 #define RIME_HC1_HC_UDP_UDP_ENCODING 2
00149 #define RIME_HC1_HC_UDP_TTL 3
00150 #define RIME_HC1_HC_UDP_PORTS 4
00151 #define RIME_HC1_HC_UDP_CHKSUM 5
00152
00153
00154
00155
00156 #define SICSLOWPAN_IP_BUF ((struct uip_ip_hdr *)&sicslowpan_buf[UIP_LLH_LEN])
00157 #define SICSLOWPAN_UDP_BUF ((struct uip_udp_hdr *)&sicslowpan_buf[UIP_LLIPH_LEN])
00158
00159 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
00160 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])
00161 #define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLIPH_LEN])
00162
00163
00164
00165
00166 #define MAC_MAX_PAYLOAD 102
00167
00168
00169
00170
00171
00172 const struct mac_driver *sicslowpan_mac;
00173
00174 #ifdef SICSLOWPAN_NH_COMPRESSOR
00175
00176 extern struct sicslowpan_nh_compressor SICSLOWPAN_NH_COMPRESSOR;
00177 #endif
00178
00179
00180
00181
00182
00183
00184 static u8_t *rime_ptr;
00185
00186
00187
00188
00189
00190
00191 static u8_t rime_hdr_len;
00192
00193
00194
00195
00196
00197
00198
00199 static u8_t rime_payload_len;
00200
00201
00202
00203
00204
00205 static u8_t uncomp_hdr_len;
00206
00207
00208 #if SICSLOWPAN_CONF_FRAG
00209
00210
00211
00212
00213 static uint16_t sicslowpan_len;
00214
00215
00216
00217
00218
00219
00220 static uip_buf_t sicslowpan_aligned_buf;
00221 #define sicslowpan_buf (sicslowpan_aligned_buf.u8)
00222
00223
00224
00225
00226
00227
00228
00229 static uint16_t processed_ip_len;
00230
00231
00232 static uint16_t my_tag;
00233
00234
00235 static uint16_t reass_tag;
00236
00237
00238 rimeaddr_t frag_sender;
00239
00240
00241 static struct timer reass_timer;
00242
00243
00244 #else
00245
00246
00247 #define sicslowpan_buf uip_buf
00248 #define sicslowpan_len uip_len
00249 #endif
00250
00251 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06
00252
00253
00254
00255
00256
00257 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
00258 static struct sicslowpan_addr_context
00259 addr_contexts[SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS];
00260 #endif
00261
00262
00263 static struct sicslowpan_addr_context *context;
00264
00265
00266 static uint8_t *hc06_ptr;
00267
00268
00269
00270
00271
00272
00273
00274
00275 const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
00276
00277
00278
00279
00280
00281
00282 const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
00283
00284
00285
00286
00287
00288
00289 const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};
00290
00291
00292 const uint8_t llprefix[] = {0xfe, 0x80};
00293
00294
00295 static const uint8_t ttl_values[] = {0, 1, 64, 255};
00296
00297
00298
00299
00300
00301
00302 static struct sicslowpan_addr_context*
00303 addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr)
00304 {
00305
00306 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
00307 int i;
00308 for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) {
00309 if((addr_contexts[i].used == 1) &&
00310 uip_ipaddr_prefixcmp(&addr_contexts[i].prefix, ipaddr, 64)) {
00311 return &addr_contexts[i];
00312 }
00313 }
00314 #endif
00315 return NULL;
00316 }
00317
00318
00319 static struct sicslowpan_addr_context*
00320 addr_context_lookup_by_number(u8_t number)
00321 {
00322
00323 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
00324 int i;
00325 for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) {
00326 if((addr_contexts[i].used == 1) &&
00327 addr_contexts[i].number == number) {
00328 return &addr_contexts[i];
00329 }
00330 }
00331 #endif
00332 return NULL;
00333 }
00334
00335 static uint8_t
00336 compress_addr_64(uint8_t bitpos, uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
00337 {
00338 if(uip_is_addr_mac_addr_based(ipaddr, lladdr)) {
00339 return 3 << bitpos;
00340 } else if(sicslowpan_is_iid_16_bit_compressable(ipaddr)) {
00341
00342 memcpy(hc06_ptr, &ipaddr->u16[7], 2);
00343 hc06_ptr += 2;
00344 return 2 << bitpos;
00345 } else {
00346
00347 memcpy(hc06_ptr, &ipaddr->u16[4], 8);
00348 hc06_ptr += 8;
00349 return 1 << bitpos;
00350 }
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360 static void
00361 uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[],
00362 uint8_t pref_post_count, uip_lladdr_t *lladdr)
00363 {
00364 uint8_t prefcount = pref_post_count >> 4;
00365 uint8_t postcount = pref_post_count & 0x0f;
00366
00367 prefcount = prefcount == 15 ? 16 : prefcount;
00368 postcount = postcount == 15 ? 16 : postcount;
00369
00370 PRINTF("Uncompressing %d + %d => ", prefcount, postcount);
00371
00372 if(prefcount > 0) {
00373 memcpy(ipaddr, prefix, prefcount);
00374 }
00375 if(prefcount + postcount < 16) {
00376 memset(&ipaddr->u8[prefcount], 0, 16 - (prefcount + postcount));
00377 }
00378 if(postcount > 0) {
00379 memcpy(&ipaddr->u8[16 - postcount], hc06_ptr, postcount);
00380 if(postcount == 2 && prefcount < 11) {
00381
00382 ipaddr->u8[11] = 0xff;
00383 ipaddr->u8[12] = 0xfe;
00384 }
00385 hc06_ptr += postcount;
00386 } else if (prefcount > 0) {
00387
00388 uip_ds6_set_addr_iid(ipaddr, lladdr);
00389 }
00390
00391 PRINT6ADDR(ipaddr);
00392 PRINTF("\n");
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 static void
00431 compress_hdr_hc06(rimeaddr_t *rime_destaddr)
00432 {
00433 uint8_t tmp, iphc0, iphc1;
00434 #if DEBUG
00435 PRINTF("before compression: ");
00436 for (tmp = 0; tmp < UIP_IP_BUF->len[1] + 40; tmp++) {
00437 uint8_t data = ((uint8_t *) (UIP_IP_BUF))[tmp];
00438 PRINTF("%02x", data);
00439 }
00440 PRINTF("\n");
00441 #endif
00442
00443 hc06_ptr = rime_ptr + 2;
00444
00445
00446
00447
00448
00449
00450
00451 iphc0 = SICSLOWPAN_DISPATCH_IPHC;
00452 iphc1 = 0;
00453 RIME_IPHC_BUF[2] = 0;
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 if(addr_context_lookup_by_prefix(&UIP_IP_BUF->destipaddr) != NULL ||
00466 addr_context_lookup_by_prefix(&UIP_IP_BUF->srcipaddr) != NULL) {
00467
00468 PRINTF("IPHC: compressing dest or src ipaddr - setting CID\n");
00469 iphc1 |= SICSLOWPAN_IPHC_CID;
00470 hc06_ptr++;
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 tmp = (UIP_IP_BUF->vtc << 4) | (UIP_IP_BUF->tcflow >> 4);
00482 tmp = ((tmp & 0x03) << 6) | (tmp >> 2);
00483
00484 if(((UIP_IP_BUF->tcflow & 0x0F) == 0) &&
00485 (UIP_IP_BUF->flow == 0)) {
00486
00487 iphc0 |= SICSLOWPAN_IPHC_FL_C;
00488 if(((UIP_IP_BUF->vtc & 0x0F) == 0) &&
00489 ((UIP_IP_BUF->tcflow & 0xF0) == 0)) {
00490
00491 iphc0 |= SICSLOWPAN_IPHC_TC_C;
00492 } else {
00493
00494 *hc06_ptr = tmp;
00495 hc06_ptr += 1;
00496 }
00497 } else {
00498
00499 if(((UIP_IP_BUF->vtc & 0x0F) == 0) &&
00500 ((UIP_IP_BUF->tcflow & 0xF0) == 0)) {
00501
00502 iphc0 |= SICSLOWPAN_IPHC_TC_C;
00503 *hc06_ptr = (tmp & 0xc0) |
00504 (UIP_IP_BUF->tcflow & 0x0F);
00505 memcpy(hc06_ptr + 1, &UIP_IP_BUF->flow, 2);
00506 hc06_ptr += 3;
00507 } else {
00508
00509 memcpy(hc06_ptr, &UIP_IP_BUF->vtc, 4);
00510
00511 *hc06_ptr = tmp;
00512 hc06_ptr += 4;
00513 }
00514 }
00515
00516
00517
00518
00519 #if UIP_CONF_UDP
00520 if(UIP_IP_BUF->proto == UIP_PROTO_UDP) {
00521 iphc0 |= SICSLOWPAN_IPHC_NH_C;
00522 }
00523 #endif
00524 #ifdef SICSLOWPAN_NH_COMPRESSOR
00525 if(SICSLOWPAN_NH_COMPRESSOR.is_compressable(UIP_IP_BUF->proto)) {
00526 iphc0 |= SICSLOWPAN_IPHC_NH_C;
00527 }
00528 #endif
00529 if ((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
00530 *hc06_ptr = UIP_IP_BUF->proto;
00531 hc06_ptr += 1;
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541 switch(UIP_IP_BUF->ttl) {
00542 case 1:
00543 iphc0 |= SICSLOWPAN_IPHC_TTL_1;
00544 break;
00545 case 64:
00546 iphc0 |= SICSLOWPAN_IPHC_TTL_64;
00547 break;
00548 case 255:
00549 iphc0 |= SICSLOWPAN_IPHC_TTL_255;
00550 break;
00551 default:
00552 *hc06_ptr = UIP_IP_BUF->ttl;
00553 hc06_ptr += 1;
00554 break;
00555 }
00556
00557
00558 if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
00559 PRINTF("IPHC: compressing unspecified - setting SAC\n");
00560 iphc1 |= SICSLOWPAN_IPHC_SAC;
00561 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
00562 } else if((context = addr_context_lookup_by_prefix(&UIP_IP_BUF->srcipaddr))
00563 != NULL) {
00564
00565 PRINTF("IPHC: compressing src with context - setting CID & SAC ctx: %d\n",
00566 context->number);
00567 iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
00568 RIME_IPHC_BUF[2] |= context->number << 4;
00569
00570
00571 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
00572 &UIP_IP_BUF->srcipaddr, &uip_lladdr);
00573
00574 } else if(uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) &&
00575 UIP_IP_BUF->destipaddr.u16[1] == 0 &&
00576 UIP_IP_BUF->destipaddr.u16[2] == 0 &&
00577 UIP_IP_BUF->destipaddr.u16[3] == 0) {
00578 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
00579 &UIP_IP_BUF->srcipaddr, &uip_lladdr);
00580 } else {
00581
00582 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
00583 memcpy(hc06_ptr, &UIP_IP_BUF->srcipaddr.u16[0], 16);
00584 hc06_ptr += 16;
00585 }
00586
00587
00588 if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
00589
00590 iphc1 |= SICSLOWPAN_IPHC_M;
00591 if(sicslowpan_is_mcast_addr_compressable8(&UIP_IP_BUF->destipaddr)) {
00592 iphc1 |= SICSLOWPAN_IPHC_DAM_11;
00593
00594 *hc06_ptr = UIP_IP_BUF->destipaddr.u8[15];
00595 hc06_ptr += 1;
00596 } else if(sicslowpan_is_mcast_addr_compressable32(&UIP_IP_BUF->destipaddr)) {
00597 iphc1 |= SICSLOWPAN_IPHC_DAM_10;
00598
00599 *hc06_ptr = UIP_IP_BUF->destipaddr.u8[1];
00600 memcpy(hc06_ptr + 1, &UIP_IP_BUF->destipaddr.u8[13], 3);
00601 hc06_ptr += 4;
00602 } else if(sicslowpan_is_mcast_addr_compressable48(&UIP_IP_BUF->destipaddr)) {
00603 iphc1 |= SICSLOWPAN_IPHC_DAM_01;
00604
00605 *hc06_ptr = UIP_IP_BUF->destipaddr.u8[1];
00606 memcpy(hc06_ptr + 1, &UIP_IP_BUF->destipaddr.u8[11], 5);
00607 hc06_ptr += 6;
00608 } else {
00609 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
00610
00611 memcpy(hc06_ptr, &UIP_IP_BUF->destipaddr.u8[0], 16);
00612 hc06_ptr += 16;
00613 }
00614 } else {
00615
00616 if((context = addr_context_lookup_by_prefix(&UIP_IP_BUF->destipaddr)) != NULL) {
00617
00618 iphc1 |= SICSLOWPAN_IPHC_DAC;
00619 RIME_IPHC_BUF[2] |= context->number;
00620
00621
00622 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
00623 &UIP_IP_BUF->destipaddr, (uip_lladdr_t *)rime_destaddr);
00624
00625 } else if(uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) &&
00626 UIP_IP_BUF->destipaddr.u16[1] == 0 &&
00627 UIP_IP_BUF->destipaddr.u16[2] == 0 &&
00628 UIP_IP_BUF->destipaddr.u16[3] == 0) {
00629 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
00630 &UIP_IP_BUF->destipaddr, (uip_lladdr_t *)rime_destaddr);
00631 } else {
00632
00633 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
00634 memcpy(hc06_ptr, &UIP_IP_BUF->destipaddr.u16[0], 16);
00635 hc06_ptr += 16;
00636 }
00637 }
00638
00639 uncomp_hdr_len = UIP_IPH_LEN;
00640
00641 #if UIP_CONF_UDP
00642
00643 if(UIP_IP_BUF->proto == UIP_PROTO_UDP) {
00644 PRINTF("IPHC: Uncompressed UDP ports on send side: %x, %x\n",
00645 UIP_HTONS(UIP_UDP_BUF->srcport), UIP_HTONS(UIP_UDP_BUF->destport));
00646
00647 if(((UIP_HTONS(UIP_UDP_BUF->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
00648 ((UIP_HTONS(UIP_UDP_BUF->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
00649
00650 *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_11;
00651 PRINTF("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
00652 *(hc06_ptr + 1) =
00653 (u8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) -
00654 SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
00655 (u8_t)((UIP_HTONS(UIP_UDP_BUF->destport) -
00656 SICSLOWPAN_UDP_4_BIT_PORT_MIN));
00657 hc06_ptr += 2;
00658 } else if((UIP_HTONS(UIP_UDP_BUF->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
00659
00660 *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_01;
00661 PRINTF("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
00662 memcpy(hc06_ptr + 1, &UIP_UDP_BUF->srcport, 2);
00663 *(hc06_ptr + 3) =
00664 (u8_t)((UIP_HTONS(UIP_UDP_BUF->destport) -
00665 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
00666 hc06_ptr += 4;
00667 } else if((UIP_HTONS(UIP_UDP_BUF->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
00668
00669 *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_10;
00670 PRINTF("IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *hc06_ptr);
00671 *(hc06_ptr + 1) =
00672 (u8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) -
00673 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
00674 memcpy(hc06_ptr + 2, &UIP_UDP_BUF->destport, 2);
00675 hc06_ptr += 4;
00676 } else {
00677
00678 *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_00;
00679 PRINTF("IPHC: cannot compress headers\n");
00680 memcpy(hc06_ptr + 1, &UIP_UDP_BUF->srcport, 4);
00681 hc06_ptr += 5;
00682 }
00683
00684 if(1) {
00685 memcpy(hc06_ptr, &UIP_UDP_BUF->udpchksum, 2);
00686 hc06_ptr += 2;
00687 }
00688 uncomp_hdr_len += UIP_UDPH_LEN;
00689 }
00690 #endif
00691
00692 #ifdef SICSLOWPAN_NH_COMPRESSOR
00693
00694 hc06_ptr += SICSLOWPAN_NH_COMPRESSOR.compress(hc06_ptr, &uncomp_hdr_len);
00695 #endif
00696
00697
00698 RIME_IPHC_BUF[0] = iphc0;
00699 RIME_IPHC_BUF[1] = iphc1;
00700
00701 rime_hdr_len = hc06_ptr - rime_ptr;
00702 return;
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 static void
00722 uncompress_hdr_hc06(uint16_t ip_len)
00723 {
00724 uint8_t tmp, iphc0, iphc1;
00725
00726 hc06_ptr = rime_ptr + rime_hdr_len + 2;
00727
00728 iphc0 = RIME_IPHC_BUF[0];
00729 iphc1 = RIME_IPHC_BUF[1];
00730
00731
00732 if(iphc1 & SICSLOWPAN_IPHC_CID) {
00733 PRINTF("IPHC: CID flag set - increase header with one\n");
00734 hc06_ptr++;
00735 }
00736
00737
00738 if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) {
00739
00740 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
00741
00742 memcpy(&SICSLOWPAN_IP_BUF->tcflow, hc06_ptr + 1, 3);
00743 tmp = *hc06_ptr;
00744 hc06_ptr += 4;
00745
00746
00747 SICSLOWPAN_IP_BUF->vtc = 0x60 | ((tmp >> 2) & 0x0f);
00748
00749 SICSLOWPAN_IP_BUF->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) |
00750 (SICSLOWPAN_IP_BUF->tcflow & 0x0f);
00751 } else {
00752
00753 SICSLOWPAN_IP_BUF->vtc = 0x60;
00754
00755 SICSLOWPAN_IP_BUF->tcflow = (*hc06_ptr & 0x0F) |
00756 ((*hc06_ptr >> 2) & 0x30);
00757 memcpy(&SICSLOWPAN_IP_BUF->flow, hc06_ptr + 1, 2);
00758 hc06_ptr += 3;
00759 }
00760 } else {
00761
00762
00763 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
00764
00765 SICSLOWPAN_IP_BUF->vtc = 0x60 | ((*hc06_ptr >> 2) & 0x0f);
00766 SICSLOWPAN_IP_BUF->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30);
00767 SICSLOWPAN_IP_BUF->flow = 0;
00768 hc06_ptr += 3;
00769 } else {
00770
00771 SICSLOWPAN_IP_BUF->vtc = 0x60;
00772 SICSLOWPAN_IP_BUF->tcflow = 0;
00773 SICSLOWPAN_IP_BUF->flow = 0;
00774 }
00775 }
00776
00777
00778 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
00779
00780 SICSLOWPAN_IP_BUF->proto = *hc06_ptr;
00781 PRINTF("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF->proto);
00782 hc06_ptr += 1;
00783 }
00784
00785
00786 if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) {
00787 SICSLOWPAN_IP_BUF->ttl = ttl_values[iphc0 & 0x03];
00788 } else {
00789 SICSLOWPAN_IP_BUF->ttl = *hc06_ptr;
00790 hc06_ptr += 1;
00791 }
00792
00793
00794 tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03;
00795
00796
00797 if(iphc1 & SICSLOWPAN_IPHC_SAC) {
00798 uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
00799 RIME_IPHC_BUF[2] >> 4 : 0;
00800
00801
00802 if (tmp != 0) {
00803 context = addr_context_lookup_by_number(sci);
00804 if(context == NULL) {
00805 PRINTF("sicslowpan uncompress_hdr: error context not found\n");
00806 return;
00807 }
00808 }
00809
00810 uncompress_addr(&SICSLOWPAN_IP_BUF->srcipaddr,
00811 tmp != 0 ? context->prefix : NULL, unc_ctxconf[tmp],
00812 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
00813 } else {
00814
00815 uncompress_addr(&SICSLOWPAN_IP_BUF->srcipaddr, llprefix, unc_llconf[tmp],
00816 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
00817 }
00818
00819
00820
00821 tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03;
00822
00823
00824 if(iphc1 & SICSLOWPAN_IPHC_M) {
00825
00826 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
00827
00828 } else {
00829
00830
00831
00832
00833
00834 uint8_t prefix[] = {0xff, 0x02};
00835 if(tmp > 0 && tmp < 3) {
00836 prefix[1] = *hc06_ptr;
00837 hc06_ptr++;
00838 }
00839
00840 uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, prefix,
00841 unc_mxconf[tmp], NULL);
00842 }
00843 } else {
00844
00845
00846 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
00847 uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
00848 RIME_IPHC_BUF[2] & 0x0f : 0;
00849 context = addr_context_lookup_by_number(dci);
00850
00851
00852 if(context == NULL) {
00853 PRINTF("sicslowpan uncompress_hdr: error context not found\n");
00854 return;
00855 }
00856 uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, context->prefix,
00857 unc_ctxconf[tmp],
00858 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
00859 } else {
00860
00861 uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, llprefix,
00862 unc_llconf[tmp],
00863 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
00864 }
00865 }
00866 uncomp_hdr_len += UIP_IPH_LEN;
00867
00868
00869 if((iphc0 & SICSLOWPAN_IPHC_NH_C)) {
00870
00871 if((*hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
00872 uint8_t checksum_compressed;
00873 SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP;
00874 checksum_compressed = *hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
00875 PRINTF("IPHC: Incoming header value: %i\n", *hc06_ptr);
00876 switch(*hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
00877 case SICSLOWPAN_NHC_UDP_CS_P_00:
00878
00879 memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2);
00880 memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 3, 2);
00881 PRINTF("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n",
00882 UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport));
00883 hc06_ptr += 5;
00884 break;
00885
00886 case SICSLOWPAN_NHC_UDP_CS_P_01:
00887
00888 PRINTF("IPHC: Decompressing destination\n");
00889 memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2);
00890 SICSLOWPAN_UDP_BUF->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3)));
00891 PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
00892 UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport));
00893 hc06_ptr += 4;
00894 break;
00895
00896 case SICSLOWPAN_NHC_UDP_CS_P_10:
00897
00898 PRINTF("IPHC: Decompressing source\n");
00899 SICSLOWPAN_UDP_BUF->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
00900 (*(hc06_ptr + 1)));
00901 memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 2, 2);
00902 PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
00903 UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport));
00904 hc06_ptr += 4;
00905 break;
00906
00907 case SICSLOWPAN_NHC_UDP_CS_P_11:
00908
00909 SICSLOWPAN_UDP_BUF->srcport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
00910 (*(hc06_ptr + 1) >> 4));
00911 SICSLOWPAN_UDP_BUF->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
00912 ((*(hc06_ptr + 1)) & 0x0F));
00913 PRINTF("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n",
00914 UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport));
00915 hc06_ptr += 2;
00916 break;
00917
00918 default:
00919 PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n");
00920 return;
00921 }
00922 if(!checksum_compressed) {
00923 memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr, 2);
00924 hc06_ptr += 2;
00925 PRINTF("IPHC: sicslowpan uncompress_hdr: checksum included\n");
00926 } else {
00927 PRINTF("IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n");
00928 }
00929 uncomp_hdr_len += UIP_UDPH_LEN;
00930 }
00931 #ifdef SICSLOWPAN_NH_COMPRESSOR
00932 else {
00933 hc06_ptr += SICSLOWPAN_NH_COMPRESSOR.uncompress(hc06_ptr, sicslowpan_buf, &uncomp_hdr_len);
00934 }
00935 #endif
00936 }
00937
00938 rime_hdr_len = hc06_ptr - rime_ptr;
00939
00940
00941 if(ip_len == 0) {
00942
00943 SICSLOWPAN_IP_BUF->len[0] = 0;
00944 SICSLOWPAN_IP_BUF->len[1] = packetbuf_datalen() - rime_hdr_len + uncomp_hdr_len - UIP_IPH_LEN;
00945 } else {
00946
00947 SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
00948 SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
00949 }
00950
00951
00952 if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) {
00953 memcpy(&SICSLOWPAN_UDP_BUF->udplen, &SICSLOWPAN_IP_BUF->len[0], 2);
00954 }
00955
00956 return;
00957 }
00958
00959 #endif
00960
00961
00962 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015 static void
01016 compress_hdr_hc1(rimeaddr_t *rime_destaddr)
01017 {
01018
01019
01020
01021
01022 if(UIP_IP_BUF->vtc != 0x60 ||
01023 UIP_IP_BUF->tcflow != 0 ||
01024 UIP_IP_BUF->flow != 0 ||
01025 !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) ||
01026 !uip_is_addr_mac_addr_based(&UIP_IP_BUF->srcipaddr, &uip_lladdr) ||
01027 !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) ||
01028 !uip_is_addr_mac_addr_based(&UIP_IP_BUF->destipaddr,
01029 (uip_lladdr_t *)rime_destaddr) ||
01030 (UIP_IP_BUF->proto != UIP_PROTO_ICMP6 &&
01031 UIP_IP_BUF->proto != UIP_PROTO_UDP &&
01032 UIP_IP_BUF->proto != UIP_PROTO_TCP))
01033 {
01034
01035
01036
01037
01038
01039 *rime_ptr = SICSLOWPAN_DISPATCH_IPV6;
01040 rime_hdr_len += SICSLOWPAN_IPV6_HDR_LEN;
01041 memcpy(rime_ptr + rime_hdr_len, UIP_IP_BUF, UIP_IPH_LEN);
01042 rime_hdr_len += UIP_IPH_LEN;
01043 uncomp_hdr_len += UIP_IPH_LEN;
01044 } else {
01045
01046
01047
01048
01049
01050
01051 RIME_HC1_PTR[RIME_HC1_DISPATCH] = SICSLOWPAN_DISPATCH_HC1;
01052 uncomp_hdr_len += UIP_IPH_LEN;
01053 switch(UIP_IP_BUF->proto) {
01054 case UIP_PROTO_ICMP6:
01055
01056 RIME_HC1_PTR[RIME_HC1_ENCODING] = 0xFC;
01057 RIME_HC1_PTR[RIME_HC1_TTL] = UIP_IP_BUF->ttl;
01058 rime_hdr_len += SICSLOWPAN_HC1_HDR_LEN;
01059 break;
01060 #if UIP_CONF_TCP
01061 case UIP_PROTO_TCP:
01062
01063 RIME_HC1_PTR[RIME_HC1_ENCODING] = 0xFE;
01064 RIME_HC1_PTR[RIME_HC1_TTL] = UIP_IP_BUF->ttl;
01065 rime_hdr_len += SICSLOWPAN_HC1_HDR_LEN;
01066 break;
01067 #endif
01068 #if UIP_CONF_UDP
01069 case UIP_PROTO_UDP:
01070
01071
01072
01073
01074
01075 PRINTF("local/remote port %u/%u\n",UIP_UDP_BUF->srcport,UIP_UDP_BUF->destport);
01076 if(UIP_HTONS(UIP_UDP_BUF->srcport) >= SICSLOWPAN_UDP_PORT_MIN &&
01077 UIP_HTONS(UIP_UDP_BUF->srcport) < SICSLOWPAN_UDP_PORT_MAX &&
01078 UIP_HTONS(UIP_UDP_BUF->destport) >= SICSLOWPAN_UDP_PORT_MIN &&
01079 UIP_HTONS(UIP_UDP_BUF->destport) < SICSLOWPAN_UDP_PORT_MAX) {
01080
01081 RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_HC1_ENCODING] = 0xFB;
01082
01083
01084 RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_UDP_ENCODING] = 0xE0;
01085 RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_TTL] = UIP_IP_BUF->ttl;
01086
01087 RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_PORTS] =
01088 (u8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) -
01089 SICSLOWPAN_UDP_PORT_MIN) << 4) +
01090 (u8_t)((UIP_HTONS(UIP_UDP_BUF->destport) - SICSLOWPAN_UDP_PORT_MIN));
01091 memcpy(&RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_CHKSUM], &UIP_UDP_BUF->udpchksum, 2);
01092 rime_hdr_len += SICSLOWPAN_HC1_HC_UDP_HDR_LEN;
01093 uncomp_hdr_len += UIP_UDPH_LEN;
01094 } else {
01095
01096 RIME_HC1_PTR[RIME_HC1_ENCODING] = 0xFA;
01097 RIME_HC1_PTR[RIME_HC1_TTL] = UIP_IP_BUF->ttl;
01098 rime_hdr_len += SICSLOWPAN_HC1_HDR_LEN;
01099 }
01100 break;
01101 #endif
01102 }
01103 }
01104 return;
01105 }
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123 static void
01124 uncompress_hdr_hc1(uint16_t ip_len)
01125 {
01126
01127 SICSLOWPAN_IP_BUF->vtc = 0x60;
01128 SICSLOWPAN_IP_BUF->tcflow = 0;
01129 SICSLOWPAN_IP_BUF->flow = 0;
01130
01131
01132 uip_ip6addr(&SICSLOWPAN_IP_BUF->srcipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
01133 uip_sd6_set_addr_iid(&SICSLOWPAN_IP_BUF->srcipaddr,
01134 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
01135 uip_ip6addr(&SICSLOWPAN_IP_BUF->destipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
01136 uip_sd6_set_addr_iid(&SICSLOWPAN_IP_BUF->destipaddr,
01137 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
01138
01139 uncomp_hdr_len += UIP_IPH_LEN;
01140
01141
01142 switch(RIME_HC1_PTR[RIME_HC1_ENCODING] & 0x06) {
01143 case SICSLOWPAN_HC1_NH_ICMP6:
01144 SICSLOWPAN_IP_BUF->proto = UIP_PROTO_ICMP6;
01145 SICSLOWPAN_IP_BUF->ttl = RIME_HC1_PTR[RIME_HC1_TTL];
01146 rime_hdr_len += SICSLOWPAN_HC1_HDR_LEN;
01147 break;
01148 #if UIP_CONF_TCP
01149 case SICSLOWPAN_HC1_NH_TCP:
01150 SICSLOWPAN_IP_BUF->proto = UIP_PROTO_TCP;
01151 SICSLOWPAN_IP_BUF->ttl = RIME_HC1_PTR[RIME_HC1_TTL];
01152 rime_hdr_len += SICSLOWPAN_HC1_HDR_LEN;
01153 break;
01154 #endif
01155 #if UIP_CONF_UDP
01156 case SICSLOWPAN_HC1_NH_UDP:
01157 SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP;
01158 if(RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_HC1_ENCODING] & 0x01) {
01159
01160 if(RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_UDP_ENCODING] !=
01161 SICSLOWPAN_HC_UDP_ALL_C) {
01162 PRINTF("sicslowpan (uncompress_hdr), packet not supported");
01163 return;
01164 }
01165
01166 SICSLOWPAN_IP_BUF->ttl = RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_TTL];
01167
01168 SICSLOWPAN_UDP_BUF->srcport =
01169 UIP_HTONS(SICSLOWPAN_UDP_PORT_MIN +
01170 (RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_PORTS] >> 4));
01171 SICSLOWPAN_UDP_BUF->destport =
01172 UIP_HTONS(SICSLOWPAN_UDP_PORT_MIN +
01173 (RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_PORTS] & 0x0F));
01174 memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, &RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_CHKSUM], 2);
01175 uncomp_hdr_len += UIP_UDPH_LEN;
01176 rime_hdr_len += SICSLOWPAN_HC1_HC_UDP_HDR_LEN;
01177 } else {
01178 rime_hdr_len += SICSLOWPAN_HC1_HDR_LEN;
01179 }
01180 break;
01181 #endif
01182 default:
01183
01184 return;
01185 }
01186
01187
01188 if(ip_len == 0) {
01189
01190 SICSLOWPAN_IP_BUF->len[0] = 0;
01191 SICSLOWPAN_IP_BUF->len[1] = packetbuf_datalen() - rime_hdr_len + uncomp_hdr_len - UIP_IPH_LEN;
01192 } else {
01193
01194 SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
01195 SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
01196 }
01197
01198 if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) {
01199 memcpy(&SICSLOWPAN_UDP_BUF->udplen, &SICSLOWPAN_IP_BUF->len[0], 2);
01200 }
01201 return;
01202 }
01203
01204 #endif
01205
01206
01207 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224 static void
01225 compress_hdr_ipv6(rimeaddr_t *rime_destaddr)
01226 {
01227 *rime_ptr = SICSLOWPAN_DISPATCH_IPV6;
01228 rime_hdr_len += SICSLOWPAN_IPV6_HDR_LEN;
01229 memcpy(rime_ptr + rime_hdr_len, UIP_IP_BUF, UIP_IPH_LEN);
01230 rime_hdr_len += UIP_IPH_LEN;
01231 uncomp_hdr_len += UIP_IPH_LEN;
01232 return;
01233 }
01234
01235 #endif
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246 static void
01247 packet_sent(void *ptr, int status, int transmissions)
01248 {
01249 #if SICSLOWPAN_CONF_NEIGHBOR_INFO
01250 neighbor_info_packet_sent(status, transmissions);
01251 #endif
01252 }
01253
01254
01255
01256
01257
01258
01259 static void
01260 send_packet(rimeaddr_t *dest)
01261 {
01262
01263
01264
01265
01266
01267 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, dest);
01268
01269
01270 #if SICSLOWPAN_CONF_ACK_ALL
01271 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
01272 #endif
01273
01274
01275
01276 NETSTACK_MAC.send(&packet_sent, NULL);
01277
01278
01279
01280 watchdog_periodic();
01281 }
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292 static uint8_t
01293 output(uip_lladdr_t *localdest)
01294 {
01295
01296 rimeaddr_t dest;
01297
01298
01299
01300 uncomp_hdr_len = 0;
01301 rime_hdr_len = 0;
01302
01303
01304 packetbuf_clear();
01305 rime_ptr = packetbuf_dataptr();
01306
01307 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
01308 SICSLOWPAN_MAX_MAC_TRANSMISSIONS);
01309
01310 #define TCP_FIN 0x01
01311 #define TCP_ACK 0x10
01312 #define TCP_CTL 0x3f
01313
01314 if(UIP_IP_BUF->proto == UIP_PROTO_TCP &&
01315 (UIP_TCP_BUF->flags & TCP_FIN) == 0 &&
01316 (UIP_TCP_BUF->flags & TCP_CTL) != TCP_ACK) {
01317 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE,
01318 PACKETBUF_ATTR_PACKET_TYPE_STREAM);
01319 } else if(UIP_IP_BUF->proto == UIP_PROTO_TCP &&
01320 (UIP_TCP_BUF->flags & TCP_FIN) == TCP_FIN) {
01321 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE,
01322 PACKETBUF_ATTR_PACKET_TYPE_STREAM_END);
01323 }
01324
01325
01326
01327
01328
01329
01330 if(localdest == NULL) {
01331 rimeaddr_copy(&dest, &rimeaddr_null);
01332 } else {
01333 rimeaddr_copy(&dest, (const rimeaddr_t *)localdest);
01334 }
01335
01336 PRINTFO("sicslowpan output: sending packet len %d\n", uip_len);
01337
01338
01339 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1
01340 compress_hdr_hc1(&dest);
01341 #endif
01342 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
01343 compress_hdr_ipv6(&dest);
01344 #endif
01345 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06
01346 compress_hdr_hc06(&dest);
01347 #endif
01348 PRINTFO("sicslowpan output: header of len %d\n", rime_hdr_len);
01349
01350 if(uip_len - uncomp_hdr_len > MAC_MAX_PAYLOAD - rime_hdr_len) {
01351 #if SICSLOWPAN_CONF_FRAG
01352 struct queuebuf *q;
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362 PRINTFO("Fragmentation sending packet len %d\n", uip_len);
01363
01364
01365 PRINTFO("sicslowpan output: 1rst fragment ");
01366
01367
01368 memmove(rime_ptr + SICSLOWPAN_FRAG1_HDR_LEN, rime_ptr, rime_hdr_len);
01369
01370
01371
01372
01373
01374
01375
01376 SET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE,
01377 ((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len));
01378
01379 SET16(RIME_FRAG_PTR, RIME_FRAG_TAG, my_tag);
01380
01381
01382 rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
01383 rime_payload_len = (MAC_MAX_PAYLOAD - rime_hdr_len) & 0xf8;
01384 PRINTFO("(len %d, tag %d)\n", rime_payload_len, my_tag);
01385 memcpy(rime_ptr + rime_hdr_len,
01386 (uint8_t *)UIP_IP_BUF + uncomp_hdr_len, rime_payload_len);
01387 packetbuf_set_datalen(rime_payload_len + rime_hdr_len);
01388 q = queuebuf_new_from_packetbuf();
01389 if(q == NULL) {
01390 PRINTFO("could not allocate queuebuf for first fragment, dropping packet\n");
01391 return 0;
01392 }
01393 send_packet(&dest);
01394 queuebuf_to_packetbuf(q);
01395 queuebuf_free(q);
01396 q = NULL;
01397
01398
01399 processed_ip_len = rime_payload_len + uncomp_hdr_len;
01400
01401
01402
01403
01404
01405
01406 rime_hdr_len = SICSLOWPAN_FRAGN_HDR_LEN;
01407
01408
01409 SET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE,
01410 ((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len));
01411 rime_payload_len = (MAC_MAX_PAYLOAD - rime_hdr_len) & 0xf8;
01412 while(processed_ip_len < uip_len) {
01413 PRINTFO("sicslowpan output: fragment ");
01414 RIME_FRAG_PTR[RIME_FRAG_OFFSET] = processed_ip_len >> 3;
01415
01416
01417 if(uip_len - processed_ip_len < rime_payload_len) {
01418
01419 rime_payload_len = uip_len - processed_ip_len;
01420 }
01421 PRINTFO("(offset %d, len %d, tag %d)\n",
01422 processed_ip_len >> 3, rime_payload_len, my_tag);
01423 memcpy(rime_ptr + rime_hdr_len,
01424 (uint8_t *)UIP_IP_BUF + processed_ip_len, rime_payload_len);
01425 packetbuf_set_datalen(rime_payload_len + rime_hdr_len);
01426 q = queuebuf_new_from_packetbuf();
01427 if(q == NULL) {
01428 PRINTFO("could not allocate queuebuf, dropping fragment\n");
01429 return 0;
01430 }
01431 send_packet(&dest);
01432 queuebuf_to_packetbuf(q);
01433 queuebuf_free(q);
01434 q = NULL;
01435 processed_ip_len += rime_payload_len;
01436 }
01437
01438
01439 my_tag++;
01440 processed_ip_len = 0;
01441 #else
01442 PRINTFO("sicslowpan output: Packet too large to be sent without fragmentation support; dropping packet\n");
01443 return 0;
01444 #endif
01445 } else {
01446
01447
01448
01449
01450 memcpy(rime_ptr + rime_hdr_len, (uint8_t *)UIP_IP_BUF + uncomp_hdr_len,
01451 uip_len - uncomp_hdr_len);
01452 packetbuf_set_datalen(uip_len - uncomp_hdr_len + rime_hdr_len);
01453 send_packet(&dest);
01454 }
01455 return 1;
01456 }
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471 static void
01472 input(void)
01473 {
01474
01475 uint16_t frag_size = 0;
01476
01477 uint8_t frag_offset = 0;
01478 #if SICSLOWPAN_CONF_FRAG
01479
01480 uint16_t frag_tag = 0;
01481 uint8_t first_fragment = 0;
01482 #endif
01483
01484
01485 uncomp_hdr_len = 0;
01486 rime_hdr_len = 0;
01487
01488
01489 rime_ptr = packetbuf_dataptr();
01490
01491 #if SICSLOWPAN_CONF_FRAG
01492
01493 if(timer_expired(&reass_timer)) {
01494 sicslowpan_len = 0;
01495 processed_ip_len = 0;
01496 }
01497
01498
01499
01500
01501 switch((GET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE) & 0xf800) >> 8) {
01502 case SICSLOWPAN_DISPATCH_FRAG1:
01503 PRINTFI("sicslowpan input: FRAG1 ");
01504 frag_offset = 0;
01505
01506 frag_size = GET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
01507
01508 frag_tag = GET16(RIME_FRAG_PTR, RIME_FRAG_TAG);
01509 PRINTFI("size %d, tag %d, offset %d)\n",
01510 frag_size, frag_tag, frag_offset);
01511 rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
01512
01513 first_fragment = 1;
01514 break;
01515 case SICSLOWPAN_DISPATCH_FRAGN:
01516
01517
01518
01519
01520 PRINTFI("sicslowpan input: FRAGN ");
01521 frag_offset = RIME_FRAG_PTR[RIME_FRAG_OFFSET];
01522 frag_tag = GET16(RIME_FRAG_PTR, RIME_FRAG_TAG);
01523 frag_size = GET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
01524 PRINTFI("size %d, tag %d, offset %d)\n",
01525 frag_size, frag_tag, frag_offset);
01526 rime_hdr_len += SICSLOWPAN_FRAGN_HDR_LEN;
01527 break;
01528 default:
01529 break;
01530 }
01531
01532 if(processed_ip_len > 0) {
01533
01534
01535 if((frag_size > 0 &&
01536 (frag_size != sicslowpan_len ||
01537 reass_tag != frag_tag ||
01538 !rimeaddr_cmp(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)))) ||
01539 frag_size == 0) {
01540
01541
01542
01543
01544 PRINTFI("sicslowpan input: Dropping 6lowpan packet that is not a fragment of the packet currently being reassembled\n");
01545 return;
01546 }
01547 } else {
01548
01549
01550
01551
01552 if(frag_size > 0) {
01553 sicslowpan_len = frag_size;
01554 reass_tag = frag_tag;
01555 timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE*CLOCK_SECOND);
01556 PRINTFI("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n",
01557 sicslowpan_len, reass_tag);
01558 rimeaddr_copy(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER));
01559 }
01560 }
01561
01562 if(rime_hdr_len == SICSLOWPAN_FRAGN_HDR_LEN) {
01563
01564 goto copypayload;
01565 }
01566 #endif
01567
01568
01569 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06
01570 if((RIME_HC1_PTR[RIME_HC1_DISPATCH] & 0xe0) == SICSLOWPAN_DISPATCH_IPHC) {
01571 PRINTFI("sicslowpan input: IPHC\n");
01572 uncompress_hdr_hc06(frag_size);
01573 } else
01574 #endif
01575 switch(RIME_HC1_PTR[RIME_HC1_DISPATCH]) {
01576 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1
01577 case SICSLOWPAN_DISPATCH_HC1:
01578 PRINTFI("sicslowpan input: HC1\n");
01579 uncompress_hdr_hc1(frag_size);
01580 break;
01581 #endif
01582 case SICSLOWPAN_DISPATCH_IPV6:
01583 PRINTFI("sicslowpan input: IPV6\n");
01584 rime_hdr_len += SICSLOWPAN_IPV6_HDR_LEN;
01585
01586
01587 memcpy(SICSLOWPAN_IP_BUF, rime_ptr + rime_hdr_len, UIP_IPH_LEN);
01588
01589
01590 rime_hdr_len += UIP_IPH_LEN;
01591 uncomp_hdr_len += UIP_IPH_LEN;
01592 break;
01593 default:
01594
01595 PRINTFI("sicslowpan input: unknown dispatch: %u\n",
01596 RIME_HC1_PTR[RIME_HC1_DISPATCH]);
01597 return;
01598 }
01599
01600
01601 #if SICSLOWPAN_CONF_FRAG
01602 copypayload:
01603 #endif
01604
01605
01606
01607
01608
01609
01610
01611 if(packetbuf_datalen() < rime_hdr_len) {
01612 PRINTF("SICSLOWPAN: packet dropped due to header > total packet\n");
01613 return;
01614 }
01615 rime_payload_len = packetbuf_datalen() - rime_hdr_len;
01616 memcpy((uint8_t *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (uint16_t)(frag_offset << 3), rime_ptr + rime_hdr_len, rime_payload_len);
01617
01618
01619
01620 #if SICSLOWPAN_CONF_FRAG
01621 if(frag_size > 0) {
01622
01623 if(first_fragment != 0) {
01624 processed_ip_len += uncomp_hdr_len;
01625 }
01626 processed_ip_len += rime_payload_len;
01627 } else {
01628 #endif
01629 sicslowpan_len = rime_payload_len + uncomp_hdr_len;
01630 #if SICSLOWPAN_CONF_FRAG
01631 }
01632
01633
01634
01635
01636
01637 if(processed_ip_len == 0 || (processed_ip_len == sicslowpan_len)) {
01638 PRINTFI("sicslowpan input: IP packet ready (length %d)\n",
01639 sicslowpan_len);
01640 memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)SICSLOWPAN_IP_BUF, sicslowpan_len);
01641 uip_len = sicslowpan_len;
01642 sicslowpan_len = 0;
01643 processed_ip_len = 0;
01644 #endif
01645
01646 #if DEBUG
01647 {
01648 uint8_t tmp;
01649 PRINTF("after decompression: ");
01650 for (tmp = 0; tmp < SICSLOWPAN_IP_BUF->len[1] + 40; tmp++) {
01651 uint8_t data = ((uint8_t *) (SICSLOWPAN_IP_BUF))[tmp];
01652 PRINTF("%02x", data);
01653 }
01654 PRINTF("\n");
01655 }
01656 #endif
01657
01658 #if SICSLOWPAN_CONF_NEIGHBOR_INFO
01659 neighbor_info_packet_received();
01660 #endif
01661
01662 tcpip_input();
01663 #if SICSLOWPAN_CONF_FRAG
01664 }
01665 #endif
01666 }
01667
01668
01669
01670
01671
01672 void
01673 sicslowpan_init(void)
01674 {
01675
01676 sicslowpan_mac = &NETSTACK_MAC;
01677
01678
01679
01680
01681
01682 tcpip_set_outputfunc(output);
01683
01684 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06
01685
01686
01687
01688
01689
01690 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
01691 addr_contexts[0].used = 1;
01692 addr_contexts[0].number = 0;
01693 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0
01694 SICSLOWPAN_CONF_ADDR_CONTEXT_0;
01695 #else
01696 addr_contexts[0].prefix[0] = 0xaa;
01697 addr_contexts[0].prefix[1] = 0xaa;
01698 #endif
01699 #endif
01700
01701 #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1
01702 {
01703 int i;
01704 for(i = 1; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) {
01705 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1
01706 if (i==1) {
01707 addr_contexts[1].used = 1;
01708 addr_contexts[1].number = 1;
01709 SICSLOWPAN_CONF_ADDR_CONTEXT_1;
01710 #ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2
01711 } else if (i==2) {
01712 addr_contexts[2].used = 1;
01713 addr_contexts[2].number = 2;
01714 SICSLOWPAN_CONF_ADDR_CONTEXT_2;
01715 #endif
01716 } else {
01717 addr_contexts[i].used = 0;
01718 }
01719 #else
01720 addr_contexts[i].used = 0;
01721 #endif
01722
01723 }
01724 }
01725 #endif
01726
01727 #endif
01728 }
01729
01730 const struct network_driver sicslowpan_driver = {
01731 "sicslowpan",
01732 sicslowpan_init,
01733 input
01734 };
01735
01736