mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
6loWPAN: A little HC1 compression logic.
This commit is contained in:
@@ -203,7 +203,10 @@ void sixlowpan_hc06_initialize(void)
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* ieee - A reference to the IEE802.15.4 network device state
|
* 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:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
|
|||||||
@@ -114,8 +114,10 @@
|
|||||||
*
|
*
|
||||||
* Input Parmeters:
|
* Input Parmeters:
|
||||||
* ieee - A reference to the IEE802.15.4 network device state
|
* 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
|
* destaddr - L2 destination address, needed to compress the IP
|
||||||
* destination field
|
* destination field
|
||||||
|
* iob - The IOB into which the compressed header should be saved.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -123,9 +125,109 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
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 ****************************************************/
|
/* General helper macros ****************************************************/
|
||||||
|
|
||||||
#define GETINT16(ptr,index) \
|
#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) \
|
#define PUTINT16(ptr,index,value) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
@@ -396,6 +396,7 @@ extern struct rimeaddr_s g_pktaddrs[PACKETBUF_NUM_ADDRS];
|
|||||||
|
|
||||||
struct net_driver_s; /* Forward reference */
|
struct net_driver_s; /* Forward reference */
|
||||||
struct ieee802154_driver_s; /* Forward reference */
|
struct ieee802154_driver_s; /* Forward reference */
|
||||||
|
struct ipv6_hdr_s; /* Forward reference */
|
||||||
struct rimeaddr_s; /* Forward reference */
|
struct rimeaddr_s; /* Forward reference */
|
||||||
struct iob_s; /* Forward reference */
|
struct iob_s; /* Forward reference */
|
||||||
|
|
||||||
@@ -559,7 +560,10 @@ void sixlowpan_hc06_initialize(void);
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* ieee - A reference to the IEE802.15.4 network device state
|
* 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:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -567,8 +571,10 @@ void sixlowpan_hc06_initialize(void);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
||||||
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *dev,
|
void sixlowpan_compresshdr_hc06(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
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -612,8 +618,10 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
|||||||
*
|
*
|
||||||
* Input Parmeters:
|
* Input Parmeters:
|
||||||
* ieee - A reference to the IEE802.15.4 network device state
|
* 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
|
* destaddr - L2 destination address, needed to compress the IP
|
||||||
* destination field
|
* destination field
|
||||||
|
* iob - The IOB into which the compressed header should be saved.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -622,7 +630,9 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
|
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
|
||||||
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
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
|
#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);
|
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:
|
* Description:
|
||||||
* sixlowpan_ipfromrime: Use stateless auto-configuration to create an IP
|
* sixlowpan_ipfromrime: Create a link local IPv6 address from a rime
|
||||||
* address from a rime address.
|
* address.
|
||||||
*
|
*
|
||||||
* sixlowpan_rimefromip: Assume stateless auto-configuration to extrate
|
* sixlowpan_rimefromip: Extract the rime address from a link local IPv6
|
||||||
* the rime address from an IP address
|
* address.
|
||||||
|
*
|
||||||
|
* sixlowpan_islinklocal and sixlowpan_ismacbased will return true for
|
||||||
|
* address created in this fashion.
|
||||||
*
|
*
|
||||||
* 128 112 96 80 64 48 32 16
|
* 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
|
* 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,
|
void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
|
||||||
net_ipv6addr_t ipaddr);
|
net_ipv6addr_t ipaddr);
|
||||||
void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
|
void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
|
||||||
FAR struct rimeaddr_s *rime);
|
FAR struct rimeaddr_s *rime);
|
||||||
|
bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
|
||||||
|
FAR const struct rimeaddr_s *rime);
|
||||||
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN */
|
#endif /* CONFIG_NET_6LOWPAN */
|
||||||
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
||||||
|
|||||||
@@ -103,8 +103,7 @@ int sixlowpan_frame_hdralloc(FAR struct iob_s *iob, int size)
|
|||||||
* Name: sixlowpan_ipfromrime
|
* Name: sixlowpan_ipfromrime
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Use stateless auto-configuration to create an IP address from a rime
|
* Create a link local IPv6 address from a rime address:
|
||||||
* address:
|
|
||||||
*
|
*
|
||||||
* 128 112 96 80 64 48 32 16
|
* 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);
|
memcpy(&ipaddr[4], rime, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE);
|
||||||
|
ipaddr[4] ^= 0x0200;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sixlowpan_rimefromip
|
* Name: sixlowpan_rimefromip
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Assume stateless auto-configuration to extrate the rime address from
|
* Extract the rime address from a link local IPv6 address:
|
||||||
* an IP address:
|
|
||||||
*
|
*
|
||||||
* 128 112 96 80 64 48 32 16
|
* 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
|
* 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);
|
DEBUGASSERT(ipaddr[0] == 0xfe80);
|
||||||
|
|
||||||
memcpy(rime, &ipaddr[4], CONFIG_NET_6LOWPAN_RIMEADDR_SIZE);
|
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 */
|
#endif /* CONFIG_NET_6LOWPAN */
|
||||||
|
|||||||
Reference in New Issue
Block a user