/*--------------------------------------------------------------------*/ static uint8_t compress_addr_64(uint8_t bitpos, uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr) { if(uip_is_addr_mac_addr_based(ipaddr, lladdr)) { return 3 << bitpos; /* 0-bits */ } else if(sicslowpan_is_iid_16_bit_compressable(ipaddr)) { /* compress IID to 16 bits xxxx::0000:00ff:fe00:XXXX */ memcpy(iphc_ptr, &ipaddr->u16[7], 2); iphc_ptr += 2; return 2 << bitpos; /* 16-bits */ } else { /* do not compress IID => xxxx::IID */ memcpy(iphc_ptr, &ipaddr->u16[4], 8); iphc_ptr += 8; return 1 << bitpos; /* 64-bits */ } }
/* *hc1 compression */ void LoWPANCmd::compress_hdr_hc1() { /* * Check if all the assumptions for full compression * are valid : */ if(UIP_IP_BUF->vtc != 0x60 || UIP_IP_BUF->tcflow != 0 || UIP_IP_BUF->flow != 0 || !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) || !uip_is_addr_mac_addr_based(&UIP_IP_BUF->srcipaddr, &src_mac) || (UIP_IP_BUF->proto != UIP_PROTO_ICMP6 && UIP_IP_BUF->proto != UIP_PROTO_UDP && UIP_IP_BUF->proto != UIP_PROTO_TCP)) { /* * IPV6 DISPATCH * Something cannot be compressed, use IPV6 DISPATCH, * compress nothing, copy IPv6 header in rime buffer */ *rime_ptr = LOWPAN_DISPATCH_IPV6; rime_hdr_len += LOWPAN_IPV6_HDR_LEN; memcpy(rime_ptr + rime_hdr_len,UIP_IP_BUF,UIP_IPH_LEN); rime_hdr_len += UIP_IPH_LEN; uncomp_hdr_len = UIP_IPH_LEN; } else { /* * HC1 DISPATCH * maximum compresssion: * All fields in the IP header but Hop Limit are elided * If next header is UDP, we compress UDP header using HC2 */ RIME_HC1_PTR[RIME_HC1_DISPATCH] = LOWPAN_DISPATCH_HC1; uncomp_hdr_len += UIP_IPH_LEN; switch(UIP_IP_BUF->proto) { case UIP_PROTO_ICMP6: /* HC1 encoding and ttl */ RIME_HC1_PTR[RIME_HC1_ENCODING] = 0xFC; RIME_HC1_PTR[RIME_HC1_TTL] = UIP_IP_BUF->ttl; if (!uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) || !uip_is_addr_mac_addr_based(&UIP_IP_BUF->destipaddr,&dest_mac)) { RIME_HC1_PTR[RIME_HC1_ENCODING] = RIME_HC1_PTR[RIME_HC1_ENCODING]&0xCF; memcpy(rime_ptr + rime_hdr_len+LOWPAN_HC1_HDR_LEN,(char*)UIP_IP_BUF+24,16); rime_hdr_len += 16; } rime_hdr_len += LOWPAN_HC1_HDR_LEN; break; case UIP_PROTO_TCP: /* HC1 encoding and ttl */ RIME_HC1_PTR[RIME_HC1_ENCODING] = 0xFE; RIME_HC1_PTR[RIME_HC1_TTL] = UIP_IP_BUF->ttl; rime_hdr_len += LOWPAN_HC1_HDR_LEN; break; case UIP_PROTO_UDP: /* * try to compress UDP header (we do only full compression). * This is feasible if both src and dest ports are between * SICSLOWPAN_UDP_PORT_MIN and SICSLOWPAN_UDP_PORT_MIN + 15 */ if(HTONS(UIP_UDP_BUF->srcport) >= LOWPAN_UDP_PORT_MIN && HTONS(UIP_UDP_BUF->srcport) < LOWPAN_UDP_PORT_MAX && HTONS(UIP_UDP_BUF->destport) >= LOWPAN_UDP_PORT_MIN && HTONS(UIP_UDP_BUF->destport) < LOWPAN_UDP_PORT_MAX) { /* HC1 encoding */ RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_HC1_ENCODING] = 0xFB; /* HC_UDP encoding, ttl, src and dest ports, checksum */ RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_UDP_ENCODING] = 0xE0; RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_TTL] = UIP_IP_BUF->ttl; RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_PORTS] = (u8_t)((HTONS(UIP_UDP_BUF->srcport)-LOWPAN_UDP_PORT_MIN) << 4) + (u8_t)((HTONS(UIP_UDP_BUF->destport)-LOWPAN_UDP_PORT_MIN)); /*RIME_HC1_HC_UDP_BUF->udpchksum = UIP_UDP_BUF->udpchksum; */ memcpy(&RIME_HC1_HC_UDP_PTR[RIME_HC1_HC_UDP_CHKSUM], &UIP_UDP_BUF->udpchksum, 2); rime_hdr_len += LOWPAN_HC1_HC_UDP_HDR_LEN; uncomp_hdr_len += UIP_UDPH_LEN; } else { /* HC1 encoding and ttl */ RIME_HC1_PTR[RIME_HC1_ENCODING] = 0xFA; RIME_HC1_PTR[RIME_HC1_TTL] = UIP_IP_BUF->ttl; rime_hdr_len += LOWPAN_HC1_HDR_LEN; } break; } } }