6loWPAN: Finishes port of Contiki HC06 compression logic

This commit is contained in:
Gregory Nutt
2017-04-02 10:06:31 -06:00
parent d16fc98c74
commit ec3c40d99d
5 changed files with 610 additions and 156 deletions
+71 -3
View File
@@ -483,7 +483,7 @@ EXTERN const net_ipv6addr_t g_ipv6_llnetmask; /* Netmask for local link addres
#endif
/****************************************************************************
* Function: net_ipv4addr_maskcmp and net_ipv6addr_maskcmp
* Name: net_ipv4addr_maskcmp and net_ipv6addr_maskcmp
*
* Description:
* Compare two IP addresses under a netmask. The mask is used to mask
@@ -527,7 +527,7 @@ bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1,
#endif
/****************************************************************************
* Function: net_ipv6addr_prefixcmp
* Name: net_ipv6addr_prefixcmp
*
* Description:
* Compare two IPv6 address prefixes.
@@ -538,7 +538,75 @@ bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1,
(memcmp(addr1, addr2, length >> 3) == 0)
/****************************************************************************
* Function: net_ipaddr_mask
* Name: net_is_addr_loopback
*
* Description:
* Is Ithe Pv6 address a the loopback address?
*
****************************************************************************/
#define net_is_addr_loopback(a) \
((a)[0] == 0 && (a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && (a)[7] == 0x0001)
/****************************************************************************
* Name: net_is_addr_unspecified
*
* Description:
* Is Ithe Pv6 address the unspecified address?
*
****************************************************************************/
#define net_is_addr_unspecified(a) \
((a)[0] == 0 && (a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && (a)[7] == 0)
/****************************************************************************
* Name: net_is_addr_mcast
*
* Description:
* s address a multicast address? see RFC 3513.
*
****************************************************************************/
#define net_is_addr_mcast(a) (((a)[0] & 0xff00) == 0xff00)
/****************************************************************************
* Name: net_is_addr_linklocal_allnodes_mcast
*
* Description:
* Is IPv6 address a the link local all-nodes multicast address?
*
****************************************************************************/
#define net_is_addr_linklocal_allnodes_mcast(a) \
((a)[0] == 0xff02 && (a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && (a)[7] == 0x0001)
/****************************************************************************
* Name: net_is_addr_linklocal_allrouters_mcast
*
* Description:
* Is IPv6 address a the link local all-routers multicast address?
*
****************************************************************************/
#define net_is_addr_linklocal_allrouters_mcast(a) \
((a)[0] == 0xff02 && (a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && (a)[7] == 0x0002)
/****************************************************************************
* Name: net_is_addr_linklocal
*
* Description:
* Checks whether the address a is link local.
*
****************************************************************************/
#define net_is_addr_linklocal(a) ((a)[0] == 0xfe80)
/****************************************************************************
* Name: net_ipaddr_mask
*
* Description:
* Mask out the network part of an IP address, given the address and
-71
View File
@@ -160,77 +160,6 @@
#define SIXLOWPAN_FRAG1_HDR_LEN 4
#define SIXLOWPAN_FRAGN_HDR_LEN 5
/* Address compressibility test macros */
/* Check whether we can compress the IID in address 'a' to 16 bits. This is
* used for unicast addresses only, and is true if the address is on the
* format <PREFIX>::0000:00ff:fe00:XXXX
*
* NOTE: we currently assume 64-bits prefixes
*/
#define SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(a) \
((((a)->u16[4]) == 0) && \
// (((a)->u8[10]) == 0)&& \
(((a)->u8[11]) == 0xff)&& \
(((a)->u8[12]) == 0xfe)&& \
(((a)->u8[13]) == 0))
/* Check whether the 9-bit group-id of the compressed multicast address is
* known. It is true if the 9-bit group is the all nodes or all routers
* group. Parameter 'a' is typed uint8_t *
*/
#define SIXLOWPAN_IS_MCASTADDR_DECOMPRESSABLE(a) \
(((*a & 0x01) == 0) && \
((*(a + 1) == 0x01) || (*(a + 1) == 0x02)))
/* Check whether the 112-bit group-id of the multicast address is mappable
* to a 9-bit group-id. It is true if the group is the all nodes or all
* routers group.
*/
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE(a) \
((((a)->u16[1]) == 0) && \
(((a)->u16[2]) == 0) && \
(((a)->u16[3]) == 0) && \
(((a)->u16[4]) == 0) && \
(((a)->u16[5]) == 0) && \
(((a)->u16[6]) == 0) && \
(((a)->u8[14]) == 0) && \
((((a)->u8[15]) == 1) || (((a)->u8[15]) == 2)))
/* FFXX::00XX:XXXX:XXXX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE48(a) \
((((a)->u16[1]) == 0) && \
(((a)->u16[2]) == 0) && \
(((a)->u16[3]) == 0) && \
(((a)->u16[4]) == 0) && \
(((a)->u8[10]) == 0))
/* FFXX::00XX:XXXX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE32(a) \
((((a)->u16[1]) == 0) && \
(((a)->u16[2]) == 0) && \
(((a)->u16[3]) == 0) && \
(((a)->u16[4]) == 0) && \
(((a)->u16[5]) == 0) && \
(((a)->u8[12]) == 0))
/* FF02::00XX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE8(a) \
((((a)->u8[1]) == 2) && \
(((a)->u16[1]) == 0) && \
(((a)->u16[2]) == 0) && \
(((a)->u16[3]) == 0) && \
(((a)->u16[4]) == 0) && \
(((a)->u16[5]) == 0) && \
(((a)->u16[6]) == 0) && \
(((a)->u8[14]) == 0))
/* This maximum size of an IEEE802.15.4 frame. Certain, non-standard
* devices may exceed this value, however.
*/
File diff suppressed because it is too large Load Diff
+38 -38
View File
@@ -113,11 +113,11 @@
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Input Parmeters:
* ieee - A reference to the IEE802.15.4 network device state
* destip - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* iob - The IOB into which the compressed header should be saved.
* ieee - A reference to the IEE802.15.4 network device state
* ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* iob - The IOB into which the compressed header should be saved.
*
* Returned Value:
* None
@@ -125,7 +125,7 @@
****************************************************************************/
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *destip,
FAR const struct ipv6_hdr_s *ipv6,
FAR const struct rimeaddr_s *destmac,
FAR struct iob_s *iob)
{
@@ -133,13 +133,13 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
/* Check if all the assumptions for full compression are valid */
if (destip->vtc != 0x60 || destip->tcflow != 0 || destip->flow != 0 ||
!sixlowpan_islinklocal(&destip->srcipaddr) ||
!sixlowpan_ismacbased(&destip->srcipaddr, &ieee->i_rimeaddr) ||
!sixlowpan_islinklocal(&destip->destipaddr) ||
!sixlowpan_ismacbased(&destip->destipaddr, destmac) ||
(destip->proto != IP_PROTO_ICMP6 && destip->proto != IP_PROTO_UDP &&
destip->proto != IP_PROTO_TCP))
if (ipv6->vtc != 0x60 || ipv6->tcflow != 0 || ipv6->flow != 0 ||
!sixlowpan_islinklocal(&ipv6->srcipaddr) ||
!sixlowpan_ismacbased(&ipv6->srcipaddr, &ieee->i_rimeaddr) ||
!sixlowpan_islinklocal(&ipv6->destipaddr) ||
!sixlowpan_ismacbased(&ipv6->destipaddr, destmac) ||
(ipv6->proto != IP_PROTO_ICMP6 && ipv6->proto != IP_PROTO_UDP &&
ipv6->proto != IP_PROTO_TCP))
{
/* IPV6 DISPATCH
* Something cannot be compressed, use IPV6 DISPATCH,
@@ -148,7 +148,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
*g_rimeptr = SIXLOWPAN_DISPATCH_IPV6;
g_rime_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
memcpy(g_rimeptr + g_rime_hdrlen, destip, IPv6_HDRLEN);
memcpy(g_rimeptr + g_rime_hdrlen, ipv6, IPv6_HDRLEN);
g_rime_hdrlen += IPv6_HDRLEN;
g_uncomp_hdrlen += IPv6_HDRLEN;
}
@@ -161,13 +161,13 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
hc1[RIME_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_HC1;
g_uncomp_hdrlen += IPv6_HDRLEN;
switch (destip->proto)
switch (ipv6->proto)
{
case IP_PROTO_ICMP6:
/* HC1 encoding and ttl */
hc1[RIME_HC1_ENCODING] = 0xfc;
hc1[RIME_HC1_TTL] = destip->ttl;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
@@ -176,7 +176,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
/* HC1 encoding and ttl */
hc1[RIME_HC1_ENCODING] = 0xfe;
hc1[RIME_HC1_TTL] = destip->ttl;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#endif /* CONFIG_NET_TCP */
@@ -206,7 +206,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
/* HC_UDP encoding, ttl, src and dest ports, checksum */
hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] = 0xe0;
hcudp[RIME_HC1_HC_UDP_TTL] = destip->ttl;
hcudp[RIME_HC1_HC_UDP_TTL] = ipv6->ttl;
hcudp[RIME_HC1_HC_UDP_PORTS] =
(uint8_t)((htons(udp->srcport) - SIXLOWPAN_UDP_PORT_MIN) << 4) +
(uint8_t)((htons(udp->destport) - SIXLOWPAN_UDP_PORT_MIN));
@@ -221,7 +221,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
/* HC1 encoding and ttl */
hc1[RIME_HC1_ENCODING] = 0xfa;
hc1[RIME_HC1_TTL] = destip->ttl;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
}
break;
@@ -257,24 +257,24 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
uint16_t iplen)
{
FAR struct ipv6_hdr_s *destip = IPv6BUF(&ieee->i_dev);
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF(&ieee->i_dev);
FAR uint8_t *hc1 = RIME_HC1_PTR;
/* Format the IPv6 header in the device d_buf */
/* Set version, traffic clase, and flow label */
destip->vtc = 0x60; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
destip->tcf = 0; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
destip->flow = 0; /* 16-bit flow label (LS) */
ipv6->vtc = 0x60; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
ipv6->tcf = 0; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
ipv6->flow = 0; /* 16-bit flow label (LS) */
/* Use stateless auto-configuration to set source and destination IP
* addresses.
*/
sixlowpan_ipfromrime(&g_pktaddrs[PACKETBUF_ADDR_SENDER],
&destip->srcipaddr);
&ipv6->srcipaddr);
sixlowpan_ipfromrime(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER],
&destip->destipaddr);
&ipv6->destipaddr);
g_uncomp_hdrlen += IPv6_HDRLEN;
/* len[], proto, and ttl depend on the encoding */
@@ -282,15 +282,15 @@ int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
switch (hc1[RIME_HC1_ENCODING] & 0x06)
{
case SIXLOWPAN_HC1_NH_ICMP6:
destip->proto = IP_PROTO_ICMP6;
destip->ttl = hc1[RIME_HC1_TTL];
ipv6->proto = IP_PROTO_ICMP6;
ipv6->ttl = hc1[RIME_HC1_TTL];
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#if CONFIG_NET_TCP
case SIXLOWPAN_HC1_NH_TCP:
destip->proto = IP_PROTO_TCP;
destip->ttl = hc1[RIME_HC1_TTL];
ipv6->proto = IP_PROTO_TCP;
ipv6->ttl = hc1[RIME_HC1_TTL];
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#endif /* CONFIG_NET_TCP */
@@ -301,7 +301,7 @@ int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
FAR struct udp_hdr_s *udp = UDPIPv6BUF(&ieee->i_dev);
FAR uint8_t *hcudp = RIME_HC1_HC_UDP_PTR;
destip->proto = IP_PROTO_UDP;
ipv6->proto = IP_PROTO_UDP;
if ((hcudp[RIME_HC1_HC_UDP_HC1_ENCODING] & 0x01) != 0)
{
/* UDP header is compressed with HC_UDP */
@@ -315,7 +315,7 @@ int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
/* IP TTL */
destip->ttl = hcudp[RIME_HC1_HC_UDP_TTL];
ipv6->ttl = hcudp[RIME_HC1_HC_UDP_TTL];
/* UDP ports, len, checksum */
@@ -347,25 +347,25 @@ int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
{
/* This is not a fragmented packet */
destip->len[0] = 0;
destip->len[1] = ieee->i_dev.d_len - g_rime_hdrlen + /* REVISIT */
g_uncomp_hdrlen - IPv6_HDRLEN;
ipv6->len[0] = 0;
ipv6->len[1] = ieee->i_dev.d_len - g_rime_hdrlen + /* REVISIT */
g_uncomp_hdrlen - IPv6_HDRLEN;
}
else
{
/* This is a 1st fragment */
destip->len[0] = (iplen - IPv6_HDRLEN) >> 8;
destip->len[1] = (iplen - IPv6_HDRLEN) & 0x00FF;
ipv6->len[0] = (iplen - IPv6_HDRLEN) >> 8;
ipv6->len[1] = (iplen - IPv6_HDRLEN) & 0x00FF;
}
/* length field in UDP header */
#if CONFIG_NET_UDP
if (destip->proto == IP_PROTO_UDP)
if (ipv6->proto == IP_PROTO_UDP)
{
FAR struct udp_hdr_s *udp = UDPIPv6BUF(&ieee->i_dev);
memcpy(&udp->udplen, &destip->len[0], 2);
memcpy(&udp->udplen, &ipv6->len[0], 2);
}
#endif
+73 -11
View File
@@ -89,7 +89,7 @@
* The fragment header is used when the payload is too large to fit in a
* single IEEE 802.15.4 frame. The fragment header contains three fields:
* Datagram size, datagram tag and datagram offset.
*
*
* 1. Datagram size describes the total (un-fragmented) payload.
* 2. Datagram tag identifies the set of fragments and is used to match
* fragments of the same payload.
@@ -225,6 +225,68 @@
#define FRAME_SIZE(ieee,iob) \
((iob)->io_len)
/* Address compressibility test macros **************************************/
/* Check whether we can compress the IID in address 'a' to 16 bits. This is
* used for unicast addresses only, and is true if the address is on the
* format <PREFIX>::0000:00ff:fe00:XXXX
*
* NOTE: we currently assume 64-bits prefixes
*/
/* Check whether we can compress the IID in address 'a' to 16 bits. This is
* used for unicast addresses only, and is true if the address is on the
* format <PREFIX>::0000:00ff:fe00:XXXX.
*
* NOTE: we currently assume 64-bits prefixes. Big-endian, network order is
* assumed.
*/
#define SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(a) \
((((a)[4]) == 0x0000) && (((a)[5]) == 0x00ff) && (((a)[6]) == 0xfe00))
/* Check whether the 9-bit group-id of the compressed multicast address is
* known. It is true if the 9-bit group is the all nodes or all routers
* group. Parameter 'a' is typed uint8_t *
*/
#define SIXLOWPAN_IS_MCASTADDR_DECOMPRESSABLE(a) \
(((*a & 0x01) == 0) && \
((*(a + 1) == 0x01) || (*(a + 1) == 0x02)))
/* Check whether the 112-bit group-id of the multicast address is mappable
* to a 9-bit group-id. It is true if the group is the all nodes or all
* routers group:
*
* XXXX:0000:0000:0000:0000:0000:0000:0001 All nodes address
* XXXX:0000:0000:0000:0000:0000:0000:0002 All routers address
*/
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE(a) \
((a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && \
((a)[7] == 0x0001 || (a)[7] == 0x0002))
/* FFXX:0000:0000:0000:0000:00XX:XXXX:XXXX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE48(a) \
((a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (((a)[5] & 0xff00) == 0))
/* FFXX:0000:0000:0000:0000:0000:00XX:XXXX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE32(a) \
((a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && ((a)[6] & 0xff00) == 0)
/* FF02:0000:0000:0000:0000:0000:0000:00XX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE8(a) \
((((a)[0] & 0x00ff) == 0x0002) && \
(a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && \
(((a)[7] & 0xff00) == 0x0000))
/* General helper macros ****************************************************/
#define GETINT16(ptr,index) \
@@ -538,7 +600,7 @@ void sixlowpan_hc06_initialize(void);
#endif
/****************************************************************************
* Name: sixlowpan_hc06_initialize
* Name: sixlowpan_compresshdr_hc06
*
* Description:
* Compress IP/UDP header
@@ -555,7 +617,7 @@ void sixlowpan_hc06_initialize(void);
*
* Input Parameters:
* ieee - A reference to the IEE802.15.4 network device state
* destip - The IPv6 header to be compressed
* ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* iob - The IOB into which the compressed header should be saved.
@@ -567,13 +629,13 @@ void sixlowpan_hc06_initialize(void);
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *destip,
FAR const struct ipv6_hdr_s *ipv6,
FAR const struct rimeaddr_s *destmac,
FAR struct iob_s *iob);
#endif
/****************************************************************************
* Name: sixlowpan_hc06_initialize
* Name: sixlowpan_uncompresshdr_hc06
*
* Description:
* Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put them in
@@ -612,11 +674,11 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
* uip_buf buffer.
*
* Input Parmeters:
* ieee - A reference to the IEE802.15.4 network device state
* destip - The IPv6 header to be compressed
* ieee - A reference to the IEE802.15.4 network device state
* ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* iob - The IOB into which the compressed header should be saved.
* destination field
* iob - The IOB into which the compressed header should be saved.
*
* Returned Value:
* None
@@ -625,7 +687,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *destip,
FAR const struct ipv6_hdr_s *ipv6,
FAR const struct rimeaddr_s *destmac,
FAR struct iob_s *iob);
#endif
@@ -673,7 +735,7 @@ int sixlowpan_frame_hdralloc(FAR struct iob_s *iob, int size);
* and sixlowpan_ismacbased
*
* Description:
* sixlowpan_ipfromrime: Create a link local IPv6 address from a rime
* sixlowpan_ipfromrime: Create a link local IPv6 address from a rime
* address.
*
* sixlowpan_rimefromip: Extract the rime address from a link local IPv6