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
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
****************************************************************************/
|
||||
@ -136,14 +147,127 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
* fragment.
|
||||
*
|
||||
* 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,
|
||||
uint16_t iplen)
|
||||
int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
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 */
|
||||
|
@ -700,8 +700,12 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
||||
|
||||
ipv6hdr = (FAR struct ipv6_hdr_s *)(ieee->i_dev.d_buf);
|
||||
|
||||
/* Get the Rime MAC address of the destination */
|
||||
#warning Missing logic
|
||||
/* Get the Rime MAC address of the destination. This
|
||||
* assumes an encoding of the MAC address in the IPv6
|
||||
* address.
|
||||
*/
|
||||
|
||||
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
|
||||
|
||||
/* 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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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 /* _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);
|
||||
|
||||
/* Get the Rime MAC address of the destination */
|
||||
#warning Missing logic
|
||||
/* Get the Rime MAC address of the destination This assumes an encoding
|
||||
* 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
|
||||
* 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);
|
||||
|
||||
/* Get the Rime MAC address of the destination */
|
||||
#warning Missing logic
|
||||
/* Get the Rime MAC address of the destination This assumes an encoding
|
||||
* 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
|
||||
* packet.
|
||||
|
@ -66,8 +66,11 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/net/sixlowpan.h>
|
||||
|
||||
#include "sixlowpan/sixlowpan_internal.h"
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
@ -96,4 +99,60 @@ int sixlowpan_frame_hdralloc(FAR struct iob_s *iob, int size)
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user