6loWPAN: Add a little bit of HC1 compression logic.
This commit is contained in:
parent
7a4af75fcf
commit
64afba55dd
@ -53,6 +53,17 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
|
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Buffer access helpers */
|
||||||
|
|
||||||
|
#define IPv6BUF(dev) \
|
||||||
|
((FAR struct ipv6_hdr_s *)((dev)->d_buf))
|
||||||
|
#define UDPIPv6BUF(dev) \
|
||||||
|
((FAR struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -136,14 +147,127 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
|||||||
* fragment.
|
* fragment.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* Zero (OK) is returned on success, on failure a negater errno value is
|
||||||
|
* returned.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||||
uint16_t iplen)
|
uint16_t iplen)
|
||||||
{
|
{
|
||||||
/* REVISIT: To be provided */
|
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 */
|
||||||
|
|
||||||
|
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],
|
||||||
|
&ipv6->srcipaddr);
|
||||||
|
sixlowpan_ipfromrime(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER],
|
||||||
|
&ipv6->destipaddr);
|
||||||
|
g_uncomp_hdrlen += IPv6_HDRLEN;
|
||||||
|
|
||||||
|
/* len[], proto, and ttl depend on the encoding */
|
||||||
|
|
||||||
|
switch (hc1[RIME_HC1_ENCODING] & 0x06)
|
||||||
|
{
|
||||||
|
case SIXLOWPAN_HC1_NH_ICMP6:
|
||||||
|
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:
|
||||||
|
ipv6->proto = IP_PROTO_TCP;
|
||||||
|
ipv6->ttl = hc1[RIME_HC1_TTL];
|
||||||
|
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_NET_TCP */
|
||||||
|
|
||||||
|
#if CONFIG_NET_UDP
|
||||||
|
case SIXLOWPAN_HC1_NH_UDP:
|
||||||
|
{
|
||||||
|
FAR struct udp_hdr_s *udp = UDPIPv6BUF(&ieee->i_dev);
|
||||||
|
FAR uint8_t *hcudp = RIME_HC1_HC_UDP_PTR;
|
||||||
|
|
||||||
|
ipv6->proto = IP_PROTO_UDP;
|
||||||
|
if ((hcudp[RIME_HC1_HC_UDP_HC1_ENCODING] & 0x01) != 0)
|
||||||
|
{
|
||||||
|
/* UDP header is compressed with HC_UDP */
|
||||||
|
|
||||||
|
if (hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] !=
|
||||||
|
SIXLOWPAN_HC_UDP_ALL_C)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: sixlowpan (uncompress_hdr), packet not supported");
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IP TTL */
|
||||||
|
|
||||||
|
ipv6->ttl = hcudp[RIME_HC1_HC_UDP_TTL];
|
||||||
|
|
||||||
|
/* UDP ports, len, checksum */
|
||||||
|
|
||||||
|
udp->srcport =
|
||||||
|
htons(SIXLOWPAN_UDP_PORT_MIN + (hcudp[RIME_HC1_HC_UDP_PORTS] >> 4));
|
||||||
|
udp->destport =
|
||||||
|
htons(SIXLOWPAN_UDP_PORT_MIN + (hcudp[RIME_HC1_HC_UDP_PORTS] & 0x0F));
|
||||||
|
|
||||||
|
memcpy(&udp->udpchksum, &hcudp[RIME_HC1_HC_UDP_CHKSUM], 2);
|
||||||
|
|
||||||
|
g_uncomp_hdrlen += UIP_UDPH_LEN;
|
||||||
|
g_rime_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_NET_UDP */
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EPROTONOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IP length field. */
|
||||||
|
|
||||||
|
if (iplen == 0)
|
||||||
|
{
|
||||||
|
/* This is not a fragmented packet */
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
ipv6->len[0] = (iplen - IPv6_HDRLEN) >> 8;
|
||||||
|
ipv6->len[1] = (iplen - IPv6_HDRLEN) & 0x00FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* length field in UDP header */
|
||||||
|
|
||||||
|
#if CONFIG_NET_UDP
|
||||||
|
if (ipv6->proto == IP_PROTO_UDP)
|
||||||
|
{
|
||||||
|
FAR struct udp_hdr_s *udp = UDPIPv6BUF(&ieee->i_dev);
|
||||||
|
memcpy(&udp->udplen, &ipv6->len[0], 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */
|
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */
|
||||||
|
@ -700,8 +700,12 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
|||||||
|
|
||||||
ipv6hdr = (FAR struct ipv6_hdr_s *)(ieee->i_dev.d_buf);
|
ipv6hdr = (FAR struct ipv6_hdr_s *)(ieee->i_dev.d_buf);
|
||||||
|
|
||||||
/* Get the Rime MAC address of the destination */
|
/* Get the Rime MAC address of the destination. This
|
||||||
#warning Missing logic
|
* assumes an encoding of the MAC address in the IPv6
|
||||||
|
* address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
|
||||||
|
|
||||||
/* Convert the outgoing packet into a frame list. */
|
/* Convert the outgoing packet into a frame list. */
|
||||||
|
|
||||||
|
@ -663,5 +663,27 @@ 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
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* sixlowpan_ipfromrime: Use stateless auto-configuration to create an IP
|
||||||
|
* address from a rime address.
|
||||||
|
*
|
||||||
|
* sixlowpan_rimefromip: Assume stateless auto-configuration to extrate
|
||||||
|
* the rime address from an IP 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 xxxx xxxx xxxx 8-byte Rime address
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN */
|
#endif /* CONFIG_NET_6LOWPAN */
|
||||||
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
||||||
|
@ -167,8 +167,11 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
|||||||
|
|
||||||
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
|
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
|
||||||
|
|
||||||
/* Get the Rime MAC address of the destination */
|
/* Get the Rime MAC address of the destination This assumes an encoding
|
||||||
#warning Missing logic
|
* of the MAC address in the IPv6 address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sixlowpan_rimefromip(conn->u.ipv6.raddr, &destmac);
|
||||||
|
|
||||||
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
|
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
|
||||||
* packet.
|
* packet.
|
||||||
|
@ -168,8 +168,11 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
|
|||||||
|
|
||||||
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
|
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
|
||||||
|
|
||||||
/* Get the Rime MAC address of the destination */
|
/* Get the Rime MAC address of the destination This assumes an encoding
|
||||||
#warning Missing logic
|
* of the MAC address in the IPv6 address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sixlowpan_rimefromip(conn->u.ipv6.raddr, &destmac);
|
||||||
|
|
||||||
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
|
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
|
||||||
* packet.
|
* packet.
|
||||||
|
@ -66,8 +66,11 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/net/sixlowpan.h>
|
||||||
|
|
||||||
#include "sixlowpan/sixlowpan_internal.h"
|
#include "sixlowpan/sixlowpan_internal.h"
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
@ -96,4 +99,60 @@ int sixlowpan_frame_hdralloc(FAR struct iob_s *iob, int size)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_ipfromrime
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Use stateless auto-configuration to create an IP address from a rime
|
||||||
|
* 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 xxxx xxxx xxxx 8-byte Rime address
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
|
||||||
|
net_ipv6addr_t ipaddr)
|
||||||
|
{
|
||||||
|
memset(ipaddr, 0, sizeof(net_ipv6addr_t));
|
||||||
|
ipaddr[0] = 0xfe80;
|
||||||
|
|
||||||
|
/* We consider only links with IEEE EUI-64 identifier or IEEE 48-bit MAC
|
||||||
|
* addresses. NOTE: that CONFIG_NET_6LOWPAN_RIMEADDR_SIZE may be 2 or
|
||||||
|
* 8. In the case of 2, we treat the address like an 8 byte address with
|
||||||
|
* the lower bytes set to zero.
|
||||||
|
*
|
||||||
|
* REVISIT: This is just a guess so that I can continue making forward
|
||||||
|
* progress. What is the correct policy?
|
||||||
|
*/
|
||||||
|
|
||||||
|
memcpy(&ipaddr[4], rime, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: sixlowpan_rimefromip
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Assume stateless auto-configuration to extrate the rime address from
|
||||||
|
* an IP 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 xxxx xxxx xxxx 8-byte Rime address
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
|
||||||
|
FAR struct rimeaddr_s *rime)
|
||||||
|
{
|
||||||
|
/* REVISIT: See notes about 2 byte addresses in sixlowpan_ipfromrime() */
|
||||||
|
|
||||||
|
DEBUGASSERT(ipaddr[0] == 0xfe80);
|
||||||
|
|
||||||
|
memcpy(rime, &ipaddr[4], CONFIG_NET_6LOWPAN_RIMEADDR_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN */
|
#endif /* CONFIG_NET_6LOWPAN */
|
||||||
|
Loading…
Reference in New Issue
Block a user