added support for all UDP port compressions in hc06

This commit is contained in:
joxe 2010-03-26 10:28:51 +00:00
parent e6a8ba41fd
commit bec1ccc57d
2 changed files with 107 additions and 41 deletions

View File

@ -32,7 +32,7 @@
* *
* This file is part of the Contiki operating system. * 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 * \file
@ -44,6 +44,7 @@
* \author Mathilde Durvy <mdurvy@cisco.com> * \author Mathilde Durvy <mdurvy@cisco.com>
* \author Julien Abeille <jabeille@cisco.com> * \author Julien Abeille <jabeille@cisco.com>
* \author Joakim Eriksson <joakime@sics.se> * \author Joakim Eriksson <joakime@sics.se>
* \author Joel Hoglund <joel@sics.se>
*/ */
/** /**
@ -607,31 +608,54 @@ compress_hdr_hc06(rimeaddr_t *rime_destaddr)
} }
} }
uncomp_hdr_len = UIP_IPH_LEN; uncomp_hdr_len = UIP_IPH_LEN;
#if UIP_CONF_UDP #if UIP_CONF_UDP
/* UDP header compression */ /* UDP header compression */
if(UIP_IP_BUF->proto == UIP_PROTO_UDP) { if(UIP_IP_BUF->proto == UIP_PROTO_UDP) {
if(HTONS(UIP_UDP_BUF->srcport) >= SICSLOWPAN_UDP_PORT_MIN && PRINTF("IPHC: Uncompressed UDP ports on send side: %x, %x\n",
HTONS(UIP_UDP_BUF->srcport) < SICSLOWPAN_UDP_PORT_MAX && HTONS(UIP_UDP_BUF->srcport), HTONS(UIP_UDP_BUF->destport));
HTONS(UIP_UDP_BUF->destport) >= SICSLOWPAN_UDP_PORT_MIN && /* Mask out the last 4 bits can be used as a mask */
HTONS(UIP_UDP_BUF->destport) < SICSLOWPAN_UDP_PORT_MAX) { if(((HTONS(UIP_UDP_BUF->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
/* we can compress. Copy compressed ports, full chcksum */ ((HTONS(UIP_UDP_BUF->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
*hc06_ptr = SICSLOWPAN_NHC_UDP_C; /* 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) = *(hc06_ptr + 1) =
(u8_t)((HTONS(UIP_UDP_BUF->srcport) - (u8_t)((HTONS(UIP_UDP_BUF->srcport) -
SICSLOWPAN_UDP_PORT_MIN) << 4) + SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
(u8_t)((HTONS(UIP_UDP_BUF->destport) - (u8_t)((HTONS(UIP_UDP_BUF->destport) -
SICSLOWPAN_UDP_PORT_MIN)); SICSLOWPAN_UDP_4_BIT_PORT_MIN));
memcpy(hc06_ptr + 2, &UIP_UDP_BUF->udpchksum, 2); 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; hc06_ptr += 4;
} else { } else {
/* we cannot compress. Copy uncompressed ports, full chcksum */ /* we cannot compress. Copy uncompressed ports, full checksum */
*hc06_ptr = SICSLOWPAN_NHC_UDP_I; *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 + 1, &UIP_UDP_BUF->srcport, 4);
memcpy(hc06_ptr + 5, &UIP_UDP_BUF->udpchksum, 2); hc06_ptr += 5;
hc06_ptr += 7; }
/* always inline the checksum */
if(1) {
memcpy(hc06_ptr, &UIP_UDP_BUF->udpchksum, 2);
hc06_ptr += 2;
} }
uncomp_hdr_len += UIP_UDPH_LEN; 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)) { if((RIME_IPHC_BUF[0] & SICSLOWPAN_IPHC_NH_C)) {
/* The next header is compressed, NHC is following */ /* The next header is compressed, NHC is following */
if((*hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) { if((*hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
uint8_t checksum_compressed;
SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP; SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP;
switch(*hc06_ptr) { checksum_compressed = *hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
case SICSLOWPAN_NHC_UDP_C: PRINTF("IPHC: Incoming header value: %i\n", *hc06_ptr);
/* 1 byte for NHC, 1 byte for ports, 2 bytes chksum */ switch(*hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
SICSLOWPAN_UDP_BUF->srcport = HTONS(SICSLOWPAN_UDP_PORT_MIN + case SICSLOWPAN_NHC_UDP_CS_P_00:
(*(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:
/* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */
memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2); memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2);
memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 3, 2); memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 3, 2);
memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr + 5, 2); PRINTF("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n",
PRINTF("IPHC: Uncompressed UDP ports (7): %x, %x\n", HTONS(SICSLOWPAN_UDP_BUF->srcport), HTONS(SICSLOWPAN_UDP_BUF->destport));
SICSLOWPAN_UDP_BUF->srcport, SICSLOWPAN_UDP_BUF->destport); hc06_ptr += 5;
hc06_ptr += 7;
break; 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: default:
PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n"); PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n");
return; 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; uncomp_hdr_len += UIP_UDPH_LEN;
} }
#ifdef SICSLOWPAN_NH_COMPRESSOR #ifdef SICSLOWPAN_NH_COMPRESSOR

View File

@ -33,7 +33,7 @@
* *
* This file is part of the Contiki operating system. * 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 * \file
@ -55,9 +55,12 @@
* \name General sicslowpan defines * \name General sicslowpan defines
* @{ * @{
*/ */
/* Min and Max compressible UDP ports */ /* Min and Max compressible UDP ports - HC06 */
#define SICSLOWPAN_UDP_PORT_MIN 0xF0B0 #define SICSLOWPAN_UDP_4_BIT_PORT_MIN 0xF0B0
#define SICSLOWPAN_UDP_PORT_MAX 0xF0BF /* F0B0 + 15 */ #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_MASK 0xF0
#define SICSLOWPAN_NHC_EXT_HDR 0xE0 #define SICSLOWPAN_NHC_EXT_HDR 0xE0
/**
* \name LOWPAN_UDP encoding (works together with IPHC)
* @{
*/
/** /**
* \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_MASK 0xF8
#define SICSLOWPAN_NHC_UDP_ID 0xF0 #define SICSLOWPAN_NHC_UDP_ID 0xF0
#define SICSLOWPAN_NHC_UDP_C 0xF3 #define SICSLOWPAN_NHC_UDP_CHECKSUMC 0x04
#define SICSLOWPAN_NHC_UDP_I 0xF0 #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 */
/** @} */ /** @} */