6loWPAN: Add HC06 decompression logic; Remove outboard compressor hooks.
This commit is contained in:
parent
5a56d3cce7
commit
d16fc98c74
@ -526,6 +526,17 @@ bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1,
|
|||||||
const net_ipv6addr_t mask);
|
const net_ipv6addr_t mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: net_ipv6addr_prefixcmp
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Compare two IPv6 address prefixes.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define net_ipv6addr_prefixcmp(addr1, addr2, length) \
|
||||||
|
(memcmp(addr1, addr2, length >> 3) == 0)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: net_ipaddr_mask
|
* Function: net_ipaddr_mask
|
||||||
*
|
*
|
||||||
|
@ -477,30 +477,6 @@ struct ieee802154_driver_s
|
|||||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The structure of a next header compressor. This compressor is provided
|
|
||||||
* by architecture-specific logic outside of the network stack.
|
|
||||||
*
|
|
||||||
* TODO: needs more parameters when compressing extension headers, etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct sixlowpan_nhcompressor_s
|
|
||||||
{
|
|
||||||
CODE int (*is_compressable)(uint8_t next_header);
|
|
||||||
|
|
||||||
/* Compress next header (TCP/UDP, etc) - ptr points to next header to
|
|
||||||
* compress.
|
|
||||||
*/
|
|
||||||
|
|
||||||
CODE int (*compress)(FAR uint8_t *compressed, FAR uint8_t *uncompressed_len);
|
|
||||||
|
|
||||||
/* Uncompress next header (TCP/UDP, etc) - ptr points to next header to
|
|
||||||
* uncompress.
|
|
||||||
*/
|
|
||||||
|
|
||||||
CODE int (*uncompress)(FAR uint8_t *compressed, FAR uint8_t *lowpanbuf,
|
|
||||||
FAR uint8_t *uncompressed_len);
|
|
||||||
};
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -560,21 +536,4 @@ struct sixlowpan_nhcompressor_s
|
|||||||
|
|
||||||
int sixlowpan_input(FAR struct ieee802154_driver_s *ieee);
|
int sixlowpan_input(FAR struct ieee802154_driver_s *ieee);
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Function: sixlowpan_set_compressor
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Configure to use the architecture-specific compressor.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* compressor - A reference to the new compressor to be used. This may
|
|
||||||
* be a NULL value to disable the compressor.
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void sixlowpan_set_compressor(FAR struct sixlowpan_nhcompressor_s *compressor);
|
|
||||||
|
|
||||||
#endif /* __INCLUDE_NUTTX_NET_SIXLOWOAN_H */
|
#endif /* __INCLUDE_NUTTX_NET_SIXLOWOAN_H */
|
||||||
|
@ -41,7 +41,7 @@ ifeq ($(CONFIG_NET_6LOWPAN),y)
|
|||||||
|
|
||||||
NET_CSRCS += sixlowpan_initialize.c sixlowpan_globals.c sixlowpan_utils.c
|
NET_CSRCS += sixlowpan_initialize.c sixlowpan_globals.c sixlowpan_utils.c
|
||||||
NET_CSRCS += sixlowpan_input.c sixlowpan_send.c sixlowpan_framer.c
|
NET_CSRCS += sixlowpan_input.c sixlowpan_send.c sixlowpan_framer.c
|
||||||
NET_CSRCS += sixlowpan_framelist.c sixlowpan_compressor.c
|
NET_CSRCS += sixlowpan_framelist.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_NET_TCP),y)
|
ifeq ($(CONFIG_NET_TCP),y)
|
||||||
NET_CSRCS += sixlowpan_tcpsend.c
|
NET_CSRCS += sixlowpan_tcpsend.c
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* net/sixlowpan/sixlowpan_compressor.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in
|
|
||||||
* the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
|
||||||
* used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
||||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
||||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Included Files
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
|
||||||
|
|
||||||
#include "nuttx/net/net.h"
|
|
||||||
|
|
||||||
#include "sixlowpan/sixlowpan_internal.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Function: sixlowpan_set_compressor
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Configure to use the architecture-specific compressor.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* compressor - A reference to the new compressor to be used. This may
|
|
||||||
* be a NULL value to disable the compressor.
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void sixlowpan_set_compressor(FAR struct sixlowpan_nhcompressor_s *compressor)
|
|
||||||
{
|
|
||||||
/* Make sure that the compressor is not in use */
|
|
||||||
|
|
||||||
net_lock();
|
|
||||||
|
|
||||||
/* Then instantiate the new compressor */
|
|
||||||
|
|
||||||
g_sixlowpan_compressor = compressor;
|
|
||||||
net_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN */
|
|
@ -47,10 +47,6 @@
|
|||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* A pointer to the optional, architecture-specific compressor */
|
|
||||||
|
|
||||||
FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor;
|
|
||||||
|
|
||||||
/* The following data values are used to hold intermediate settings while
|
/* The following data values are used to hold intermediate settings while
|
||||||
* processing IEEE802.15.4 frames. These globals are shared with incoming
|
* processing IEEE802.15.4 frames. These globals are shared with incoming
|
||||||
* and outgoing frame processing and possibly with mutliple IEEE802.15.4 MAC
|
* and outgoing frame processing and possibly with mutliple IEEE802.15.4 MAC
|
||||||
|
@ -58,12 +58,26 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
|
#include <nuttx/net/ip.h>
|
||||||
|
|
||||||
#include "sixlowpan/sixlowpan_internal.h"
|
#include "sixlowpan/sixlowpan_internal.h"
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define IPv6BUF(ieee) \
|
||||||
|
((FAR struct ipv6_hdr_s *)&(ieee)->i_dev.d_buf)
|
||||||
|
#define UDPIPv6BUF(ieee) \
|
||||||
|
((FAR struct udp_hdr_s *)&(ieee)->i_dev.d_buf[IPv6_HDRLEN])
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -83,7 +97,12 @@ struct sixlowpan_addrcontext_s
|
|||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* HC06 specific variables */
|
/* HC06 specific variables **************************************************/
|
||||||
|
/* Use of global variables simplifies the logic and is safe in the multi-
|
||||||
|
* device environment because access is serialized via the network lock.
|
||||||
|
*
|
||||||
|
* But note that state may NOT be preserved from packet-to-packet.
|
||||||
|
*/
|
||||||
|
|
||||||
#if CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 0
|
#if CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 0
|
||||||
/* Addresses contexts for IPHC. */
|
/* Addresses contexts for IPHC. */
|
||||||
@ -92,6 +111,180 @@ static struct sixlowpan_addrcontext_s
|
|||||||
g_hc06_addrcontexts[CONFIG_NET_6LOWPAN_MAXADDRCONTEXT];
|
g_hc06_addrcontexts[CONFIG_NET_6LOWPAN_MAXADDRCONTEXT];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Pointer to the byte where to write next inline field. */
|
||||||
|
|
||||||
|
static FAR uint8_t *g_hc06ptr;
|
||||||
|
|
||||||
|
/* Constant Data ************************************************************/
|
||||||
|
/* Uncompression of linklocal
|
||||||
|
*
|
||||||
|
* 0 -> 16 bytes from packet
|
||||||
|
* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet
|
||||||
|
* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet
|
||||||
|
* 3 -> 2 bytes from prefix - infer 8 bytes from lladdr
|
||||||
|
*
|
||||||
|
* NOTE: => the uncompress function does change 0xf to 0x10
|
||||||
|
* NOTE: 0x00 => no-autoconfig => unspecified
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const uint8_t g_unc_llconf[] = { 0x0f, 0x28, 0x22, 0x20 };
|
||||||
|
|
||||||
|
/* Uncompression of ctx-based
|
||||||
|
*
|
||||||
|
* 0 -> 0 bits from packet [unspecified / reserved]
|
||||||
|
* 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet
|
||||||
|
* 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX + 2 from packet
|
||||||
|
* 3 -> 8 bytes from prefix - infer 8 bytes from lladdr
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const uint8_t g_unc_ctxconf[] = { 0x00, 0x88, 0x82, 0x80 };
|
||||||
|
|
||||||
|
/* Uncompression of ctx-based
|
||||||
|
*
|
||||||
|
* 0 -> 0 bits from packet
|
||||||
|
* 1 -> 2 bytes from prefix - bunch of zeroes 5 from packet
|
||||||
|
* 2 -> 2 bytes from prefix - zeroes + 3 from packet
|
||||||
|
* 3 -> 2 bytes from prefix - infer 1 bytes from lladdr
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const uint8_t g_unc_mxconf[] = { 0x0f, 0x25, 0x23, 0x21 };
|
||||||
|
|
||||||
|
/* Link local prefix */
|
||||||
|
|
||||||
|
static const uint8_t g_llprefix[] = { 0xfe, 0x80 };
|
||||||
|
|
||||||
|
/* TTL uncompression values */
|
||||||
|
|
||||||
|
static const uint8_t g_ttl_values[] = { 0, 1, 64, 255 };
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: find_addrcontext_bynumber
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Find the address context with the given number.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static FAR struct sixlowpan_addrcontext_s *
|
||||||
|
find_addrcontext_bynumber(uint8_t number)
|
||||||
|
{
|
||||||
|
/* Remove code to avoid warnings and save flash if no address context is
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 0
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < CONFIG_NET_6LOWPAN_MAXADDRCONTEXT; i++)
|
||||||
|
{
|
||||||
|
if ((g_hc06_addrcontexts[i].used == 1) &&
|
||||||
|
g_hc06_addrcontexts[i].number == number)
|
||||||
|
{
|
||||||
|
return &g_hc06_addrcontexts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 0 */
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: find_addrcontext_bynumber
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Find the address context corresponding to the prefix ipaddr.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static FAR struct sixlowpan_addrcontext_s *
|
||||||
|
find_addrcontext_byprefix(FAR net_ipv6addr_t *ipaddr)
|
||||||
|
{
|
||||||
|
#if CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 0
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Remove code to avoid warnings and save flash if no address context is used */
|
||||||
|
|
||||||
|
for (i = 0; i < CONFIG_NET_6LOWPAN_MAXADDRCONTEXT; i++)
|
||||||
|
{
|
||||||
|
if ((g_hc06_addrcontexts[i].used == 1) &&
|
||||||
|
net_ipv6addr_prefixcmp(&g_hc06_addrcontexts[i].prefix, ipaddr, 64))
|
||||||
|
{
|
||||||
|
return &g_hc06_addrcontexts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 0 */
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: uncompress_addr
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Uncompress addresses based on a prefix and a postfix with zeroes in
|
||||||
|
* between. If the postfix is zero in length it will use the link address
|
||||||
|
* to configure the IP address (autoconf style).
|
||||||
|
*
|
||||||
|
* prefpost takes a byte where the first nibble specify prefix count
|
||||||
|
* and the second postfix count (NOTE: 15/0xf => 16 bytes copy).
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void uncompress_addr(FAR net_ipv6addr_t ipaddr, uint8_t const prefix[],
|
||||||
|
uint8_t prefpost, FAR struct rimeaddr_s *macaddr)
|
||||||
|
{
|
||||||
|
uint8_t prefcount = prefpost >> 4;
|
||||||
|
uint8_t postcount = prefpost & 0x0f;
|
||||||
|
|
||||||
|
/* Full nibble 15 => 16 */
|
||||||
|
|
||||||
|
prefcount = prefcount == 15 ? 16 : prefcount;
|
||||||
|
postcount = postcount == 15 ? 16 : postcount;
|
||||||
|
|
||||||
|
if (prefcount > 0)
|
||||||
|
{
|
||||||
|
memcpy(ipaddr, prefix, prefcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefcount + postcount < 16)
|
||||||
|
{
|
||||||
|
FAR uint8_t *iptr = (FAR uint8_t *)&ipaddr[0];
|
||||||
|
|
||||||
|
memset(&iptr[prefcount], 0, 16 - (prefcount + postcount));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (postcount > 0)
|
||||||
|
{
|
||||||
|
FAR uint8_t *iptr = (FAR uint8_t *)&ipaddr[0];
|
||||||
|
|
||||||
|
memcpy(&iptr[16 - postcount], g_hc06ptr, postcount);
|
||||||
|
if (postcount == 2 && prefcount < 11)
|
||||||
|
{
|
||||||
|
/* 16 bits uncompression => 0000:00ff:fe00:XXXX */
|
||||||
|
|
||||||
|
iptr[11] = 0xff;
|
||||||
|
iptr[12] = 0xfe;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hc06ptr += postcount;
|
||||||
|
}
|
||||||
|
else if (prefcount > 0)
|
||||||
|
{
|
||||||
|
/* No IID based configuration if no prefix and no data => unspec */
|
||||||
|
|
||||||
|
sixlowpan_ipfromrime(macaddr, ipaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ninfo("Uncompressing %d + %d => %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||||
|
prefcount, postcount, ipaddr[0], ipaddr[2], ipaddr[3], ipaddr[5],
|
||||||
|
ipaddr[5], ipaddr[6], ipaddr[7]);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -197,9 +390,9 @@ void sixlowpan_hc06_initialize(void)
|
|||||||
* | L4 data ... |
|
* | L4 data ... |
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*
|
*
|
||||||
* NOTE: The g_addr_context number 00 is reserved for the link local prefix.
|
* NOTE: The address context number 00 is reserved for the link local
|
||||||
* For unicast addresses, if we cannot compress the prefix, we neither
|
* prefix. For unicast addresses, if we cannot compress the prefix, we
|
||||||
* compress the IID.
|
* neither compress the IID.
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -237,7 +430,7 @@ void sixlowpan_compresshdr_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
|
||||||
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
|
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
|
||||||
* inferred from the L2 length), non 0 if the packet is a 1st
|
* inferred from the L2 length), non 0 if the packet is a first
|
||||||
* fragment.
|
* fragment.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -248,8 +441,348 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
|||||||
void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
||||||
uint16_t iplen)
|
uint16_t iplen)
|
||||||
{
|
{
|
||||||
/* REVISIT: To be provided */
|
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF(ieee);
|
||||||
|
FAR uint8_t *iphc = RIME_IPHC_BUF;
|
||||||
|
uint8_t iphc0;
|
||||||
|
uint8_t iphc1;
|
||||||
|
uint8_t tmp;
|
||||||
|
|
||||||
|
/* At least two byte will be used for the encoding */
|
||||||
|
|
||||||
|
g_hc06ptr = g_rimeptr + g_rime_hdrlen + 2;
|
||||||
|
|
||||||
|
iphc0 = iphc[0];
|
||||||
|
iphc1 = iphc[1];
|
||||||
|
|
||||||
|
/* Another if the CID flag is set */
|
||||||
|
|
||||||
|
if (iphc1 & SIXLOWPAN_IPHC_CID)
|
||||||
|
{
|
||||||
|
ninfo("IPHC: CID flag set - increase header with one\n");
|
||||||
|
g_hc06ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Traffic class and flow label */
|
||||||
|
|
||||||
|
if ((iphc0 & SIXLOWPAN_IPHC_FL_C) == 0)
|
||||||
|
{
|
||||||
|
/* Flow label are carried inline */
|
||||||
|
|
||||||
|
if ((iphc0 & SIXLOWPAN_IPHC_TC_C) == 0)
|
||||||
|
{
|
||||||
|
/* Traffic class is carried inline */
|
||||||
|
|
||||||
|
memcpy(&ipv6->tcf, g_hc06ptr + 1, 3);
|
||||||
|
tmp = *g_hc06ptr;
|
||||||
|
g_hc06ptr += 4;
|
||||||
|
|
||||||
|
/* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */
|
||||||
|
/* set version, pick highest DSCP bits and set in vtc */
|
||||||
|
|
||||||
|
ipv6->vtc = 0x60 | ((tmp >> 2) & 0x0f);
|
||||||
|
|
||||||
|
/* ECN rolled down two steps + lowest DSCP bits at top two bits */
|
||||||
|
|
||||||
|
ipv6->tcf = ((tmp >> 2) & 0x30) | (tmp << 6) | (ipv6->tcf & 0x0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Traffic class is compressed (set version and no TC) */
|
||||||
|
|
||||||
|
ipv6->vtc = 0x60;
|
||||||
|
|
||||||
|
/* Highest flow label bits + ECN bits */
|
||||||
|
|
||||||
|
ipv6->tcf = (*g_hc06ptr & 0x0f) | ((*g_hc06ptr >> 2) & 0x30);
|
||||||
|
memcpy(&ipv6->flow, g_hc06ptr + 1, 2);
|
||||||
|
g_hc06ptr += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Version is always 6! */
|
||||||
|
/* Version and flow label are compressed */
|
||||||
|
|
||||||
|
if ((iphc0 & SIXLOWPAN_IPHC_TC_C) == 0)
|
||||||
|
{
|
||||||
|
/* Traffic class is inline */
|
||||||
|
|
||||||
|
ipv6->vtc = 0x60 | ((*g_hc06ptr >> 2) & 0x0f);
|
||||||
|
ipv6->tcf = ((*g_hc06ptr << 6) & 0xC0) | ((*g_hc06ptr >> 2) & 0x30);
|
||||||
|
ipv6->flow = 0;
|
||||||
|
g_hc06ptr += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Traffic class is compressed */
|
||||||
|
|
||||||
|
ipv6->vtc = 0x60;
|
||||||
|
ipv6->tcf = 0;
|
||||||
|
ipv6->flow = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next Header */
|
||||||
|
|
||||||
|
if ((iphc0 & SIXLOWPAN_IPHC_NH_C) == 0)
|
||||||
|
{
|
||||||
|
/* Next header is carried inline */
|
||||||
|
|
||||||
|
ipv6->proto = *g_hc06ptr;
|
||||||
|
ninfo("IPHC: next header inline: %d\n", ipv6->proto);
|
||||||
|
g_hc06ptr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hop limit */
|
||||||
|
|
||||||
|
if ((iphc0 & 0x03) != SIXLOWPAN_IPHC_TTL_I)
|
||||||
|
{
|
||||||
|
ipv6->ttl = g_ttl_values[iphc0 & 0x03];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ipv6->ttl = *g_hc06ptr;
|
||||||
|
g_hc06ptr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put the source address compression mode SAM in the tmp var */
|
||||||
|
|
||||||
|
tmp = ((iphc1 & SIXLOWPAN_IPHC_SAM_11) >> SIXLOWPAN_IPHC_SAM_BIT) & 0x03;
|
||||||
|
|
||||||
|
/* Address context based compression */
|
||||||
|
|
||||||
|
if (iphc1 & SIXLOWPAN_IPHC_SAC)
|
||||||
|
{
|
||||||
|
FAR struct sixlowpan_addrcontext_s *addrcontext;
|
||||||
|
uint8_t sci = (iphc1 & SIXLOWPAN_IPHC_CID) ? iphc[2] >> 4 : 0;
|
||||||
|
|
||||||
|
/* Source address - check address context != NULL only if SAM bits are != 0 */
|
||||||
|
|
||||||
|
if (tmp != 0)
|
||||||
|
{
|
||||||
|
addrcontext = find_addrcontext_bynumber(sci);
|
||||||
|
if (addrcontext == NULL)
|
||||||
|
{
|
||||||
|
ninfo("sixlowpan uncompress_hdr: error address context not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If tmp == 0 we do not have a Address context and therefore no prefix */
|
||||||
|
|
||||||
|
uncompress_addr(ipv6->srcipaddr,
|
||||||
|
tmp != 0 ? addrcontext->prefix : NULL, g_unc_ctxconf[tmp],
|
||||||
|
(FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_SENDER]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No compression and link local */
|
||||||
|
|
||||||
|
uncompress_addr(ipv6->srcipaddr, g_llprefix, g_unc_llconf[tmp],
|
||||||
|
(FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_SENDER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destination address */
|
||||||
|
/* put the destination address compression mode into tmp */
|
||||||
|
|
||||||
|
tmp = ((iphc1 & SIXLOWPAN_IPHC_DAM_11) >> SIXLOWPAN_IPHC_DAM_BIT) & 0x03;
|
||||||
|
|
||||||
|
/* Multicast compression */
|
||||||
|
|
||||||
|
if (iphc1 & SIXLOWPAN_IPHC_M)
|
||||||
|
{
|
||||||
|
/* Address context based multicast compression */
|
||||||
|
|
||||||
|
if (iphc1 & SIXLOWPAN_IPHC_DAC)
|
||||||
|
{
|
||||||
|
/* TODO: implement this */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* non-address context based multicast compression
|
||||||
|
*
|
||||||
|
* DAM_00: 128 bits
|
||||||
|
* DAM_01: 48 bits FFXX::00XX:XXXX:XXXX
|
||||||
|
* DAM_10: 32 bits FFXX::00XX:XXXX
|
||||||
|
* DAM_11: 8 bits FF02::00XX
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint8_t prefix[] = { 0xff, 0x02 };
|
||||||
|
if (tmp > 0 && tmp < 3)
|
||||||
|
{
|
||||||
|
prefix[1] = *g_hc06ptr;
|
||||||
|
g_hc06ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uncompress_addr(ipv6->destipaddr, prefix, g_unc_mxconf[tmp], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* no multicast */
|
||||||
|
/* Context based */
|
||||||
|
|
||||||
|
if (iphc1 & SIXLOWPAN_IPHC_DAC)
|
||||||
|
{
|
||||||
|
FAR struct sixlowpan_addrcontext_s *addrcontext;
|
||||||
|
uint8_t dci = (iphc1 & SIXLOWPAN_IPHC_CID) ? iphc[2] & 0x0f : 0;
|
||||||
|
|
||||||
|
addrcontext = find_addrcontext_bynumber(dci);
|
||||||
|
|
||||||
|
/* All valid cases below need the address context! */
|
||||||
|
|
||||||
|
if (addrcontext == NULL)
|
||||||
|
{
|
||||||
|
ninfo("sixlowpan uncompress_hdr: error address context not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uncompress_addr(ipv6->destipaddr, addrcontext->prefix, g_unc_ctxconf[tmp],
|
||||||
|
(FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_RECEIVER]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Not address context based => link local M = 0, DAC = 0 - same as SAC */
|
||||||
|
|
||||||
|
uncompress_addr(ipv6->destipaddr, g_llprefix, g_unc_llconf[tmp],
|
||||||
|
(FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_RECEIVER]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_uncomp_hdrlen += IPv6_HDRLEN;
|
||||||
|
|
||||||
|
/* Next header processing - continued */
|
||||||
|
|
||||||
|
if ((iphc0 & SIXLOWPAN_IPHC_NH_C))
|
||||||
|
{
|
||||||
|
FAR struct udp_hdr_s *udp = UDPIPv6BUF(ieee);
|
||||||
|
|
||||||
|
/* The next header is compressed, NHC is following */
|
||||||
|
|
||||||
|
if ((*g_hc06ptr & SIXLOWPAN_NHC_UDP_MASK) == SIXLOWPAN_NHC_UDP_ID)
|
||||||
|
{
|
||||||
|
uint8_t checksum_compressed;
|
||||||
|
|
||||||
|
ipv6->proto = IP_PROTO_UDP;
|
||||||
|
checksum_compressed = *g_hc06ptr & SIXLOWPAN_NHC_UDP_CHECKSUMC;
|
||||||
|
|
||||||
|
ninfo("IPHC: Incoming header value: %i\n", *g_hc06ptr);
|
||||||
|
|
||||||
|
switch (*g_hc06ptr & SIXLOWPAN_NHC_UDP_CS_P_11)
|
||||||
|
{
|
||||||
|
case SIXLOWPAN_NHC_UDP_CS_P_00:
|
||||||
|
/* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */
|
||||||
|
|
||||||
|
memcpy(&udp->srcport, g_hc06ptr + 1, 2);
|
||||||
|
memcpy(&udp->destport, g_hc06ptr + 3, 2);
|
||||||
|
|
||||||
|
ninfo("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n",
|
||||||
|
htons(udp->srcport),
|
||||||
|
htons(udp->destport));
|
||||||
|
|
||||||
|
g_hc06ptr += 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIXLOWPAN_NHC_UDP_CS_P_01:
|
||||||
|
/* 1 byte for NHC + source 16bit inline, dest = 0xF0 + 8 bit
|
||||||
|
* inline
|
||||||
|
*/
|
||||||
|
|
||||||
|
ninfo("IPHC: Decompressing destination\n");
|
||||||
|
|
||||||
|
memcpy(&udp->srcport, g_hc06ptr + 1, 2);
|
||||||
|
udp->destport =
|
||||||
|
htons(SIXLOWPAN_UDP_8_BIT_PORT_MIN + (*(g_hc06ptr + 3)));
|
||||||
|
|
||||||
|
ninfo("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
|
||||||
|
htons(udp->srcport),
|
||||||
|
htons(udp->destport));
|
||||||
|
|
||||||
|
g_hc06ptr += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIXLOWPAN_NHC_UDP_CS_P_10:
|
||||||
|
/* 1 byte for NHC + source = 0xF0 + 8bit inline, dest = 16 bit
|
||||||
|
* inline
|
||||||
|
*/
|
||||||
|
|
||||||
|
ninfo("IPHC: Decompressing source\n");
|
||||||
|
|
||||||
|
udp->srcport =
|
||||||
|
htons(SIXLOWPAN_UDP_8_BIT_PORT_MIN + (*(g_hc06ptr + 1)));
|
||||||
|
memcpy(&udp->destport, g_hc06ptr + 2, 2);
|
||||||
|
|
||||||
|
ninfo("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
|
||||||
|
htons(udp->srcport),
|
||||||
|
htons(udp->destport));
|
||||||
|
|
||||||
|
g_hc06ptr += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIXLOWPAN_NHC_UDP_CS_P_11:
|
||||||
|
/* 1 byte for NHC, 1 byte for ports */
|
||||||
|
|
||||||
|
udp->srcport =
|
||||||
|
htons(SIXLOWPAN_UDP_4_BIT_PORT_MIN +
|
||||||
|
(*(g_hc06ptr + 1) >> 4));
|
||||||
|
udp->destport =
|
||||||
|
htons(SIXLOWPAN_UDP_4_BIT_PORT_MIN +
|
||||||
|
((*(g_hc06ptr + 1)) & 0x0F));
|
||||||
|
ninfo("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n",
|
||||||
|
htons(udp->srcport),
|
||||||
|
htons(udp->destport));
|
||||||
|
|
||||||
|
g_hc06ptr += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
nerr("ERROR: Error unsupported UDP compression\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checksum_compressed)
|
||||||
|
{
|
||||||
|
/* Has_checksum, default */
|
||||||
|
|
||||||
|
memcpy(&udp->udpchksum, g_hc06ptr, 2);
|
||||||
|
g_hc06ptr += 2;
|
||||||
|
ninfo("IPHC: sixlowpan uncompress_hdr: checksum included\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nwarn("WARNING: checksum *NOT* included\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_uncomp_hdrlen += UDP_HDRLEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_rime_hdrlen = g_hc06ptr - g_rimeptr;
|
||||||
|
|
||||||
|
/* 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 + g_uncomp_hdrlen - IPv6_HDRLEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is a first fragment */
|
||||||
|
|
||||||
|
ipv6->len[0] = (iplen - IPv6_HDRLEN) >> 8;
|
||||||
|
ipv6->len[1] = (iplen - IPv6_HDRLEN) & 0x00ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Length field in UDP header */
|
||||||
|
|
||||||
|
if (ipv6->proto == IP_PROTO_UDP)
|
||||||
|
{
|
||||||
|
FAR struct udp_hdr_s *udp = UDPIPv6BUF(ieee);
|
||||||
|
memcpy(&udp->udplen, &ipv6->len[0], 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */
|
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */
|
||||||
|
@ -335,11 +335,6 @@ struct frame802154_s
|
|||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* A pointer to the optional, architecture-specific compressor */
|
|
||||||
|
|
||||||
struct sixlowpan_nhcompressor_s; /* Foward reference */
|
|
||||||
extern FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor;
|
|
||||||
|
|
||||||
/* The following data values are used to hold intermediate settings while
|
/* The following data values are used to hold intermediate settings while
|
||||||
* processing IEEE802.15.4 frames. These globals are shared with incoming
|
* processing IEEE802.15.4 frames. These globals are shared with incoming
|
||||||
* and outgoing frame processing and possibly with mutliple IEEE802.15.4 MAC
|
* and outgoing frame processing and possibly with mutliple IEEE802.15.4 MAC
|
||||||
@ -593,7 +588,7 @@ void sixlowpan_compresshdr_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
|
||||||
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
|
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
|
||||||
* inferred from the L2 length), non 0 if the packet is a 1st
|
* inferred from the L2 length), non 0 if the packet is a first
|
||||||
* fragment.
|
* fragment.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -650,7 +645,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
|||||||
* 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
|
||||||
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
|
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
|
||||||
* inferred from the L2 length), non 0 if the packet is a 1st
|
* inferred from the L2 length), non 0 if the packet is a first
|
||||||
* fragment.
|
* fragment.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
|
Loading…
Reference in New Issue
Block a user