diff --git a/core/net/sicslowpan.c b/core/net/sicslowpan.c index 120b2e218..3fd8c3234 100644 --- a/core/net/sicslowpan.c +++ b/core/net/sicslowpan.c @@ -32,7 +32,7 @@ * * This file is part of the Contiki operating system. * - * $Id: sicslowpan.c,v 1.32 2010/03/19 12:54:38 nifi Exp $ + * $Id: sicslowpan.c,v 1.33 2010/03/26 10:28:52 joxe Exp $ */ /** * \file @@ -44,6 +44,7 @@ * \author Mathilde Durvy * \author Julien Abeille * \author Joakim Eriksson + * \author Joel Hoglund */ /** @@ -607,31 +608,54 @@ compress_hdr_hc06(rimeaddr_t *rime_destaddr) } } - uncomp_hdr_len = UIP_IPH_LEN; #if UIP_CONF_UDP /* UDP header compression */ if(UIP_IP_BUF->proto == UIP_PROTO_UDP) { - if(HTONS(UIP_UDP_BUF->srcport) >= SICSLOWPAN_UDP_PORT_MIN && - HTONS(UIP_UDP_BUF->srcport) < SICSLOWPAN_UDP_PORT_MAX && - HTONS(UIP_UDP_BUF->destport) >= SICSLOWPAN_UDP_PORT_MIN && - HTONS(UIP_UDP_BUF->destport) < SICSLOWPAN_UDP_PORT_MAX) { - /* we can compress. Copy compressed ports, full chcksum */ - *hc06_ptr = SICSLOWPAN_NHC_UDP_C; + PRINTF("IPHC: Uncompressed UDP ports on send side: %x, %x\n", + HTONS(UIP_UDP_BUF->srcport), HTONS(UIP_UDP_BUF->destport)); + /* Mask out the last 4 bits can be used as a mask */ + if(((HTONS(UIP_UDP_BUF->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) && + ((HTONS(UIP_UDP_BUF->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) { + /* we can compress 12 bits of both source and dest */ + *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_11; + PRINTF("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n"); *(hc06_ptr + 1) = - (u8_t)((HTONS(UIP_UDP_BUF->srcport) - - SICSLOWPAN_UDP_PORT_MIN) << 4) + - (u8_t)((HTONS(UIP_UDP_BUF->destport) - - SICSLOWPAN_UDP_PORT_MIN)); - memcpy(hc06_ptr + 2, &UIP_UDP_BUF->udpchksum, 2); + (u8_t)((HTONS(UIP_UDP_BUF->srcport) - + SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) + + (u8_t)((HTONS(UIP_UDP_BUF->destport) - + SICSLOWPAN_UDP_4_BIT_PORT_MIN)); + hc06_ptr += 2; + } else if((HTONS(UIP_UDP_BUF->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) { + /* we can compress 8 bits of dest, leave source. */ + *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_01; + PRINTF("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n"); + memcpy(hc06_ptr + 1, &UIP_UDP_BUF->srcport, 2); + *(hc06_ptr + 3) = + (u8_t)((HTONS(UIP_UDP_BUF->destport) - + SICSLOWPAN_UDP_8_BIT_PORT_MIN)); + hc06_ptr += 4; + } else if((HTONS(UIP_UDP_BUF->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) { + /* we can compress 8 bits of src, leave dest. Copy compressed port */ + *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_10; + PRINTF("IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *hc06_ptr); + *(hc06_ptr + 1) = + (u8_t)((HTONS(UIP_UDP_BUF->srcport) - + SICSLOWPAN_UDP_8_BIT_PORT_MIN)); + memcpy(hc06_ptr + 2, &UIP_UDP_BUF->destport, 2); hc06_ptr += 4; } else { - /* we cannot compress. Copy uncompressed ports, full chcksum */ - *hc06_ptr = SICSLOWPAN_NHC_UDP_I; + /* we cannot compress. Copy uncompressed ports, full checksum */ + *hc06_ptr = SICSLOWPAN_NHC_UDP_CS_P_00; + PRINTF("IPHC: cannot compress headers\n"); memcpy(hc06_ptr + 1, &UIP_UDP_BUF->srcport, 4); - memcpy(hc06_ptr + 5, &UIP_UDP_BUF->udpchksum, 2); - hc06_ptr += 7; + hc06_ptr += 5; + } + /* always inline the checksum */ + if(1) { + memcpy(hc06_ptr, &UIP_UDP_BUF->udpchksum, 2); + hc06_ptr += 2; } uncomp_hdr_len += UIP_UDPH_LEN; } @@ -877,33 +901,63 @@ uncompress_hdr_hc06(u16_t ip_len) { if((RIME_IPHC_BUF[0] & SICSLOWPAN_IPHC_NH_C)) { /* The next header is compressed, NHC is following */ if((*hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) { + uint8_t checksum_compressed; SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP; - switch(*hc06_ptr) { - case SICSLOWPAN_NHC_UDP_C: - /* 1 byte for NHC, 1 byte for ports, 2 bytes chksum */ - SICSLOWPAN_UDP_BUF->srcport = HTONS(SICSLOWPAN_UDP_PORT_MIN + - (*(hc06_ptr + 1) >> 4)); - SICSLOWPAN_UDP_BUF->destport = HTONS(SICSLOWPAN_UDP_PORT_MIN + - ((*(hc06_ptr + 1)) & 0x0F)); - memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr + 2, 2); - PRINTF("IPHC: Uncompressed UDP ports (4): %x, %x\n", - SICSLOWPAN_UDP_BUF->srcport, SICSLOWPAN_UDP_BUF->destport); - hc06_ptr += 4; - break; - case SICSLOWPAN_NHC_UDP_I: + checksum_compressed = *hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC; + PRINTF("IPHC: Incoming header value: %i\n", *hc06_ptr); + switch(*hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) { + case SICSLOWPAN_NHC_UDP_CS_P_00: /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2); memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 3, 2); - memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr + 5, 2); - PRINTF("IPHC: Uncompressed UDP ports (7): %x, %x\n", - SICSLOWPAN_UDP_BUF->srcport, SICSLOWPAN_UDP_BUF->destport); - - hc06_ptr += 7; + PRINTF("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n", + HTONS(SICSLOWPAN_UDP_BUF->srcport), HTONS(SICSLOWPAN_UDP_BUF->destport)); + hc06_ptr += 5; break; + + case SICSLOWPAN_NHC_UDP_CS_P_01: + //1 byte for NHC + source 16bit inline, dest = 0xF0 + 8 bit inline + PRINTF("IPHC: Decompressing destination\n"); + memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2); + SICSLOWPAN_UDP_BUF->destport = HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3))); + PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", + HTONS(SICSLOWPAN_UDP_BUF->srcport), HTONS(SICSLOWPAN_UDP_BUF->destport)); + hc06_ptr += 4; + break; + + case SICSLOWPAN_NHC_UDP_CS_P_10: + //1 byte for NHC + source = 0xF0 + 8bit inline, dest = 16 bit inline + PRINTF("IPHC: Decompressing source\n"); + SICSLOWPAN_UDP_BUF->srcport = HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + + (*(hc06_ptr + 1))); + memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 2, 2); + PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", + HTONS(SICSLOWPAN_UDP_BUF->srcport), HTONS(SICSLOWPAN_UDP_BUF->destport)); + hc06_ptr += 4; + break; + + case SICSLOWPAN_NHC_UDP_CS_P_11: + /* 1 byte for NHC, 1 byte for ports */ + SICSLOWPAN_UDP_BUF->srcport = HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + + (*(hc06_ptr + 1) >> 4)); + SICSLOWPAN_UDP_BUF->destport = HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + + ((*(hc06_ptr + 1)) & 0x0F)); + PRINTF("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n", + HTONS(SICSLOWPAN_UDP_BUF->srcport), HTONS(SICSLOWPAN_UDP_BUF->destport)); + hc06_ptr += 2; + break; + default: PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n"); return; } + if(!checksum_compressed) { /* has_checksum, default */ + memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr, 2); + hc06_ptr += 2; + PRINTF("IPHC: sicslowpan uncompress_hdr: checksum included\n"); + } else { + PRINTF("IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n"); + } uncomp_hdr_len += UIP_UDPH_LEN; } #ifdef SICSLOWPAN_NH_COMPRESSOR diff --git a/core/net/sicslowpan.h b/core/net/sicslowpan.h index 77ccaa240..49488bcc2 100644 --- a/core/net/sicslowpan.h +++ b/core/net/sicslowpan.h @@ -33,7 +33,7 @@ * * This file is part of the Contiki operating system. * - * $Id: sicslowpan.h,v 1.12 2010/03/17 20:57:25 joxe Exp $ + * $Id: sicslowpan.h,v 1.13 2010/03/26 10:28:51 joxe Exp $ */ /** * \file @@ -55,9 +55,12 @@ * \name General sicslowpan defines * @{ */ -/* Min and Max compressible UDP ports */ -#define SICSLOWPAN_UDP_PORT_MIN 0xF0B0 -#define SICSLOWPAN_UDP_PORT_MAX 0xF0BF /* F0B0 + 15 */ +/* Min and Max compressible UDP ports - HC06 */ +#define SICSLOWPAN_UDP_4_BIT_PORT_MIN 0xF0B0 +#define SICSLOWPAN_UDP_4_BIT_PORT_MAX 0xF0BF /* F0B0 + 15 */ +#define SICSLOWPAN_UDP_8_BIT_PORT_MIN 0xF000 +#define SICSLOWPAN_UDP_8_BIT_PORT_MAX 0xF0FF /* F000 + 255 */ + /** @} */ /** @@ -141,14 +144,23 @@ #define SICSLOWPAN_NHC_MASK 0xF0 #define SICSLOWPAN_NHC_EXT_HDR 0xE0 +/** + * \name LOWPAN_UDP encoding (works together with IPHC) + * @{ + */ /** * \name LOWPAN_UDP encoding (works together with IPHC) * @{ */ #define SICSLOWPAN_NHC_UDP_MASK 0xF8 #define SICSLOWPAN_NHC_UDP_ID 0xF0 -#define SICSLOWPAN_NHC_UDP_C 0xF3 -#define SICSLOWPAN_NHC_UDP_I 0xF0 +#define SICSLOWPAN_NHC_UDP_CHECKSUMC 0x04 +#define SICSLOWPAN_NHC_UDP_CHECKSUMI 0x00 +/* values for port compression, _with checksum_ ie bit 5 set to 0 */ +#define SICSLOWPAN_NHC_UDP_CS_P_00 0xF0 /* all inline */ +#define SICSLOWPAN_NHC_UDP_CS_P_01 0xF1 /* source 16bit inline, dest = 0xF0 + 8 bit inline */ +#define SICSLOWPAN_NHC_UDP_CS_P_10 0xF2 /* source = 0xF0 + 8bit inline, dest = 16 bit inline */ +#define SICSLOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ /** @} */