6loWPAN: A little HC1 compression logic.
This commit is contained in:
parent
64afba55dd
commit
5af0909275
4 changed files with 171 additions and 19 deletions
|
|
@ -203,7 +203,10 @@ void sixlowpan_hc06_initialize(void)
|
|||
*
|
||||
* Input Parameters:
|
||||
* ieee - A reference to the IEE802.15.4 network device state
|
||||
* destaddr - L2 destination address, needed to compress IP dest
|
||||
* ipv6 - The IPv6 header to be compressed
|
||||
* destaddr - L2 destination address, needed to compress the IP
|
||||
* destination field
|
||||
* iob - The IOB into which the compressed header should be saved.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
|
|
|||
|
|
@ -114,8 +114,10 @@
|
|||
*
|
||||
* Input Parmeters:
|
||||
* ieee - A reference to the IEE802.15.4 network device state
|
||||
* ipv6 - The IPv6 header to be compressed
|
||||
* destaddr - L2 destination address, needed to compress the IP
|
||||
* destination field
|
||||
* iob - The IOB into which the compressed header should be saved.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
|
@ -123,9 +125,109 @@
|
|||
****************************************************************************/
|
||||
|
||||
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR struct rimeaddr_s *destaddr)
|
||||
FAR const struct ipv6_hdr_s *ipv6,
|
||||
FAR const struct rimeaddr_s *destaddr,
|
||||
FAR struct iob_s *iob)
|
||||
{
|
||||
/* REVISIT: To be provided */
|
||||
FAR uint8_t *hc1 = RIME_HC1_PTR;
|
||||
|
||||
/* Check if all the assumptions for full compression are valid */
|
||||
|
||||
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, destaddr) ||
|
||||
(ipv6->proto != IP_PROTO_ICMP6 && ipv6->proto != IP_PROTO_UDP &&
|
||||
ipv6->proto != IP_PROTO_TCP))
|
||||
{
|
||||
/* IPV6 DISPATCH
|
||||
* Something cannot be compressed, use IPV6 DISPATCH,
|
||||
* compress nothing, copy IPv6 header in rime buffer
|
||||
*/
|
||||
|
||||
*g_rimeptr = SIXLOWPAN_DISPATCH_IPV6;
|
||||
g_rime_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
|
||||
memcpy(g_rimeptr + g_rime_hdrlen, ipv6, IPv6_HDRLEN);
|
||||
g_rime_hdrlen += IPv6_HDRLEN;
|
||||
g_uncomp_hdrlen += IPv6_HDRLEN;
|
||||
}
|
||||
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
|
||||
*/
|
||||
|
||||
hc1[RIME_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_HC1;
|
||||
g_uncomp_hdrlen += IPv6_HDRLEN;
|
||||
switch (ipv6->proto)
|
||||
{
|
||||
case IP_PROTO_ICMP6:
|
||||
/* HC1 encoding and ttl */
|
||||
|
||||
hc1[RIME_HC1_ENCODING] = 0xfc;
|
||||
hc1[RIME_HC1_TTL] = ipv6->ttl;
|
||||
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||
break;
|
||||
|
||||
#if CONFIG_NET_TCP
|
||||
case IP_PROTO_TCP:
|
||||
/* HC1 encoding and ttl */
|
||||
|
||||
hc1[RIME_HC1_ENCODING] = 0xfe;
|
||||
hc1[RIME_HC1_TTL] = ipv6->ttl;
|
||||
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||
break;
|
||||
#endif /* CONFIG_NET_TCP */
|
||||
|
||||
#if CONFIG_NET_UDP
|
||||
case IP_PROTO_UDP:
|
||||
FAR struct udp_hdr_s *udp = UDPIPv6BUF(dev);
|
||||
|
||||
/* Try to compress UDP header (we do only full compression). This
|
||||
* is feasible if both src and dest ports are between
|
||||
* SIXLOWPAN_UDP_PORT_MIN and SIXLOWPAN_UDP_PORT_MIN + 15
|
||||
*/
|
||||
|
||||
ninfo("local/remote port %u/%u\n", udp->srcport, udp->destport);
|
||||
|
||||
if (htons(udp->srcport) >= SIXLOWPAN_UDP_PORT_MIN &&
|
||||
htons(udp->srcport) < SIXLOWPAN_UDP_PORT_MAX &&
|
||||
htons(udp->destport) >= SIXLOWPAN_UDP_PORT_MIN &&
|
||||
htons(udp->destport) < SIXLOWPAN_UDP_PORT_MAX)
|
||||
{
|
||||
FAR uint8_t *hcudp = RIME_HC1_HC_UDP_PTR;
|
||||
|
||||
/* HC1 encoding */
|
||||
|
||||
hcudp[RIME_HC1_HC_UDP_HC1_ENCODING] = 0xfb;
|
||||
|
||||
/* HC_UDP encoding, ttl, src and dest ports, checksum */
|
||||
|
||||
hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] = 0xe0;
|
||||
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));
|
||||
|
||||
memcpy(&hcudp[RIME_HC1_HC_UDP_CHKSUM], &udp->udpchksum, 2);
|
||||
|
||||
g_rime_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
|
||||
g_uncomp_hdrlen += UIP_UDPH_LEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HC1 encoding and ttl */
|
||||
|
||||
hc1[RIME_HC1_ENCODING] = 0xfa;
|
||||
hc1[RIME_HC1_TTL] = ipv6->ttl;
|
||||
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_NET_UDP */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@
|
|||
/* General helper macros ****************************************************/
|
||||
|
||||
#define GETINT16(ptr,index) \
|
||||
((((uint16_t)((ptr)[index]) << 8)) | ((uint16_t)(((ptr)[(index) + 1]))))
|
||||
((((uint16_t)((ptr)[index])) << 8) | ((uint16_t)(((ptr)[(index) + 1]))))
|
||||
#define PUTINT16(ptr,index,value) \
|
||||
do \
|
||||
{ \
|
||||
|
|
@ -396,6 +396,7 @@ extern struct rimeaddr_s g_pktaddrs[PACKETBUF_NUM_ADDRS];
|
|||
|
||||
struct net_driver_s; /* Forward reference */
|
||||
struct ieee802154_driver_s; /* Forward reference */
|
||||
struct ipv6_hdr_s; /* Forward reference */
|
||||
struct rimeaddr_s; /* Forward reference */
|
||||
struct iob_s; /* Forward reference */
|
||||
|
||||
|
|
@ -559,7 +560,10 @@ void sixlowpan_hc06_initialize(void);
|
|||
*
|
||||
* Input Parameters:
|
||||
* ieee - A reference to the IEE802.15.4 network device state
|
||||
* destaddr - L2 destination address, needed to compress IP dest
|
||||
* ipv6 - The IPv6 header to be compressed
|
||||
* destaddr - L2 destination address, needed to compress the IP
|
||||
* destination field
|
||||
* iob - The IOB into which the compressed header should be saved.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
|
@ -567,8 +571,10 @@ void sixlowpan_hc06_initialize(void);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
||||
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *dev,
|
||||
FAR struct rimeaddr_s *destaddr);
|
||||
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ipv6_hdr_s *ipv6,
|
||||
FAR const struct rimeaddr_s *destaddr,
|
||||
FAR struct iob_s *iob);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -612,8 +618,10 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
|||
*
|
||||
* Input Parmeters:
|
||||
* ieee - A reference to the IEE802.15.4 network device state
|
||||
* ipv6 - The IPv6 header to be compressed
|
||||
* destaddr - L2 destination address, needed to compress the IP
|
||||
* destination field
|
||||
* iob - The IOB into which the compressed header should be saved.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
|
@ -622,7 +630,9 @@ 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 struct rimeaddr_s *destaddr);
|
||||
FAR const struct ipv6_hdr_s *ipv6,
|
||||
FAR const struct rimeaddr_s *destaddr,
|
||||
FAR struct iob_s *iob);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -664,26 +674,34 @@ void sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
|||
int sixlowpan_frame_hdralloc(FAR struct iob_s *iob, int size);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_ipfromrime and sixlowpan_rimefromip
|
||||
* Name: sixlowpan_islinklocal, sixlowpan_ipfromrime, sixlowpan_rimefromip,
|
||||
* and sixlowpan_ismacbased
|
||||
*
|
||||
* Description:
|
||||
* sixlowpan_ipfromrime: Use stateless auto-configuration to create an IP
|
||||
* address from a rime address.
|
||||
* sixlowpan_ipfromrime: Create a link local IPv6 address from a rime
|
||||
* address.
|
||||
*
|
||||
* sixlowpan_rimefromip: Assume stateless auto-configuration to extrate
|
||||
* the rime address from an IP address
|
||||
* sixlowpan_rimefromip: Extract the rime address from a link local IPv6
|
||||
* address.
|
||||
*
|
||||
* sixlowpan_islinklocal and sixlowpan_ismacbased will return true for
|
||||
* address created in this fashion.
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 xxxx xxxx 0000 0000 2-byte Rime address (VALID?)
|
||||
* fe80 0000 0000 0000 xxxx 0000 0000 0000 2-byte Rime address (VALID?)
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define sixlowpan_islinklocal(ipaddr) ((ipaddr)[0] = NTOHS(0xfe80))
|
||||
|
||||
void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
|
||||
net_ipv6addr_t ipaddr);
|
||||
void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
|
||||
FAR struct rimeaddr_s *rime);
|
||||
bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct rimeaddr_s *rime);
|
||||
|
||||
#endif /* CONFIG_NET_6LOWPAN */
|
||||
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
||||
|
|
|
|||
|
|
@ -103,8 +103,7 @@ int sixlowpan_frame_hdralloc(FAR struct iob_s *iob, int size)
|
|||
* Name: sixlowpan_ipfromrime
|
||||
*
|
||||
* Description:
|
||||
* Use stateless auto-configuration to create an IP address from a rime
|
||||
* address:
|
||||
* Create a link local IPv6 address from a rime address:
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
|
|
@ -129,18 +128,18 @@ void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
|
|||
*/
|
||||
|
||||
memcpy(&ipaddr[4], rime, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE);
|
||||
ipaddr[4] ^= 0x0200;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_rimefromip
|
||||
*
|
||||
* Description:
|
||||
* Assume stateless auto-configuration to extrate the rime address from
|
||||
* an IP address:
|
||||
* Extract the rime address from a link local IPv6 address:
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 xxxx xxxx 0000 0000 2-byte Rime address (VALID?)
|
||||
* fe80 0000 0000 0000 xxxx 0000 0000 0000 2-byte Rime address (VALID?)
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address
|
||||
*
|
||||
****************************************************************************/
|
||||
|
|
@ -153,6 +152,36 @@ void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
|
|||
DEBUGASSERT(ipaddr[0] == 0xfe80);
|
||||
|
||||
memcpy(rime, &ipaddr[4], CONFIG_NET_6LOWPAN_RIMEADDR_SIZE);
|
||||
rime->u8[0] ^= 0x02;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_ismacbased
|
||||
*
|
||||
* Description:
|
||||
* Extract the rime address from a link local IPv6 address:
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 xxxx 0000 0000 0000 2-byte Rime address (VALID?)
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct rimeaddr_s *rime)
|
||||
{
|
||||
FAR const uint8_t *rimeptr = rime->u8;
|
||||
|
||||
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
|
||||
return ((ipaddr[4] == (GETINT16(rimeptr, 0) ^ 0x0200)) &&
|
||||
ipaddr[5] == 0 && ipaddr[6] == 0 && ipaddr[7] == 0);
|
||||
#else /* CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 8 */
|
||||
return ((ipaddr[4] == (GETINT16(rimeptr, 0) ^ 0x0200)) &&
|
||||
ipaddr[5] == GETINT16(rimeptr, 2) &&
|
||||
ipaddr[6] == GETINT16(rimeptr, 4) &&
|
||||
ipaddr[7] == GETINT16(rimeptr, 6));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_6LOWPAN */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue