Exemplo n.º 1
0
/*--------------------------------------------------------------------*/
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 */
  }
}
Exemplo n.º 2
0
/*
 *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;
        }


    }
}