6LoWPAN: Loopback driver needs to initialize the MAC meta data; Address decompression logic must have the MAC address to handle the most common compression cases.
This commit is contained in:
parent
bc8ad02ee5
commit
922454d515
4 changed files with 179 additions and 53 deletions
|
@ -109,43 +109,58 @@ static FAR uint8_t *g_hc06ptr;
|
|||
/* Uncompression of linklocal
|
||||
*
|
||||
* 0 -> 16 bytes from packet
|
||||
* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet
|
||||
* 1 -> 2 bytes from prefix - 16 bytes from packet
|
||||
* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet
|
||||
* 3 -> 2 bytes from prefix - infer 8 bytes from MAC address
|
||||
* 3 -> 2 bytes from prefix - Infer 2 or 8 bytes from MAC address
|
||||
*
|
||||
* 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 };
|
||||
static const uint16_t g_unc_llconf[] =
|
||||
{
|
||||
0x000f, 0x0028, 0x0022, 0x0120
|
||||
};
|
||||
|
||||
/* 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 MAC address
|
||||
* 1 -> 8 bytes from prefix - Bunch of zeroes and 8 bytes from packet
|
||||
* 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX and 2 bytes from packet
|
||||
* 3 -> 8 bytes from prefix - Infer 2 or 8 bytes from MAC address
|
||||
*/
|
||||
|
||||
static const uint8_t g_unc_ctxconf[] = { 0x00, 0x88, 0x82, 0x80 };
|
||||
static const uint16_t g_unc_ctxconf[] =
|
||||
{
|
||||
0x0000, 0x0088, 0x0082, 0x0180
|
||||
};
|
||||
|
||||
/* 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 MAC address
|
||||
* 1 -> 2 bytes from prefix - Bunch of zeroes 5 bytes from packet
|
||||
* 2 -> 2 bytes from prefix - Zeroes + 3 bytes from packet
|
||||
* 3 -> 2 bytes from prefix - Infer 1 bytes from MAC address
|
||||
*/
|
||||
|
||||
static const uint8_t g_unc_mxconf[] = { 0x0f, 0x25, 0x23, 0x21 };
|
||||
static const uint16_t g_unc_mxconf[] =
|
||||
{
|
||||
0x000f, 0x0025, 0x0023, 0x0121
|
||||
};
|
||||
|
||||
/* Link local prefix */
|
||||
|
||||
static const uint8_t g_llprefix[] = { 0xfe, 0x80 };
|
||||
static const uint8_t g_llprefix[] =
|
||||
{
|
||||
0xfe, 0x80
|
||||
};
|
||||
|
||||
/* TTL uncompression values */
|
||||
|
||||
static const uint8_t g_ttl_values[] = { 0, 1, 64, 255 };
|
||||
static const uint8_t g_ttl_values[] =
|
||||
{
|
||||
0, 1, 64, 255
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -297,43 +312,114 @@ static uint8_t compress_laddr(FAR const net_ipv6addr_t ipaddr,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void uncompress_addr(FAR net_ipv6addr_t ipaddr, uint8_t const prefix[],
|
||||
uint8_t prefpost)
|
||||
static void uncompress_addr(FAR const struct ieee802154_addr_s *addr,
|
||||
FAR const uint8_t *prefix, uint16_t prefpost,
|
||||
FAR net_ipv6addr_t ipaddr)
|
||||
{
|
||||
uint8_t prefcount = prefpost >> 4;
|
||||
uint8_t postcount = prefpost & 0x0f;
|
||||
FAR const uint8_t *srcptr;
|
||||
bool fullmac = false;
|
||||
bool usemac = (prefpost & 0x0100) != 0;
|
||||
uint8_t prefcount = (prefpost >> 4) & 0xf;
|
||||
uint8_t postcount = prefpost & 0x0f;
|
||||
|
||||
/* The value 16 is encoded as 0xf in the 4 bit-fields. */
|
||||
|
||||
prefcount = prefcount == 15 ? 16 : prefcount;
|
||||
postcount = postcount == 15 ? 16 : postcount;
|
||||
|
||||
/* Select the data source */
|
||||
|
||||
srcptr = g_hc06ptr;
|
||||
if (usemac)
|
||||
{
|
||||
bool saddr = (addr->mode == IEEE802154_ADDRMODE_SHORT);
|
||||
uint16_t addrsize = saddr ? NET_6LOWPAN_SADDRSIZE: NET_6LOWPAN_EADDRSIZE;
|
||||
|
||||
/* Select the source the address data */
|
||||
|
||||
srcptr = saddr ? addr->saddr : addr->eaddr;
|
||||
|
||||
/* If the provided postcount is zero and we are taking data from the
|
||||
* MAC address, set postcount to the address length.
|
||||
*/
|
||||
|
||||
if (postcount == 0)
|
||||
{
|
||||
postcount = addrsize;
|
||||
}
|
||||
|
||||
/* If we are converting the entire MAC address, then we need to some some
|
||||
* special bit operations.
|
||||
*/
|
||||
|
||||
fullmac = (postcount == addrsize);
|
||||
}
|
||||
|
||||
/* Copy any prefix */
|
||||
|
||||
if (prefcount > 0)
|
||||
{
|
||||
memcpy(ipaddr, prefix, prefcount);
|
||||
}
|
||||
|
||||
/* Clear bytes between int prefcount and postcount */
|
||||
|
||||
if (prefcount + postcount < 16)
|
||||
{
|
||||
FAR uint8_t *iptr = (FAR uint8_t *)&ipaddr[0];
|
||||
FAR uint8_t *destptr = (FAR uint8_t *)&ipaddr[0];
|
||||
|
||||
memset(&iptr[prefcount], 0, 16 - (prefcount + postcount));
|
||||
memset(&destptr[prefcount], 0, 16 - (prefcount + postcount));
|
||||
}
|
||||
|
||||
/* Copy the remaining data from the source */
|
||||
|
||||
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;
|
||||
ipaddr[5] = HTONS(0x00ff);
|
||||
ipaddr[6] = HTONS(0xfe00);
|
||||
}
|
||||
|
||||
g_hc06ptr += postcount;
|
||||
/* If the postcount is even then take extra care with endian-ness */
|
||||
|
||||
if ((postcount & 1) == 0)
|
||||
{
|
||||
int destndx = 8 - (postcount >> 1);
|
||||
int i;
|
||||
|
||||
for (i = destndx; i < 8; i++)
|
||||
{
|
||||
ipaddr[i] = (uint16_t)srcptr[0] << 8 | (uint16_t)srcptr[1];
|
||||
srcptr += 2;
|
||||
}
|
||||
|
||||
/* If the was a standard MAC based address then toggle */
|
||||
|
||||
if (fullmac)
|
||||
{
|
||||
ipaddr[destndx] ^= 0x200;
|
||||
}
|
||||
}
|
||||
|
||||
/* postcount is odd... */
|
||||
|
||||
else
|
||||
{
|
||||
FAR uint8_t *destptr = (FAR uint8_t *)&ipaddr[0];
|
||||
int offset = 16 - postcount;
|
||||
|
||||
memcpy(&destptr[offset], srcptr, postcount);
|
||||
}
|
||||
|
||||
/* If we took the data from packet, then update the packet pointer */
|
||||
|
||||
if (!usemac)
|
||||
{
|
||||
g_hc06ptr += postcount;
|
||||
}
|
||||
}
|
||||
else if (prefcount > 0)
|
||||
{
|
||||
|
@ -342,9 +428,10 @@ static void uncompress_addr(FAR net_ipv6addr_t ipaddr, uint8_t const prefix[],
|
|||
nwarn("WARNING: No IID based configuration\n");
|
||||
}
|
||||
|
||||
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]);
|
||||
ninfo("Uncompressing %d + %d => %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04\n",
|
||||
prefcount, postcount,
|
||||
ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3],
|
||||
ipaddr[4], ipaddr[5], ipaddr[6], ipaddr[7]);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -860,20 +947,22 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
|||
* appropriate values
|
||||
*
|
||||
* Input Parmeters:
|
||||
* 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 first
|
||||
* fragment.
|
||||
* iob - Pointer to the IOB containing the received frame.
|
||||
* fptr - Pointer to frame to be compressed.
|
||||
* bptr - Output goes here. Normally this is a known offset into d_buf,
|
||||
* may be redirected to a "bitbucket" on the case of FRAGN frames.
|
||||
* ind - MAC header meta data including node addressing information.
|
||||
* 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 first
|
||||
* fragment.
|
||||
* iob - Pointer to the IOB containing the received frame.
|
||||
* fptr - Pointer to frame to be compressed.
|
||||
* bptr - Output goes here. Normally this is a known offset into d_buf,
|
||||
* may be redirected to a "bitbucket" on the case of FRAGN frames.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
||||
void sixlowpan_uncompresshdr_hc06(FAR const struct ieee802154_data_ind_s *ind,
|
||||
uint16_t iplen, FAR struct iob_s *iob,
|
||||
FAR uint8_t *fptr, FAR uint8_t *bptr)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr;
|
||||
|
@ -1014,8 +1103,9 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
|||
* address.
|
||||
*/
|
||||
|
||||
uncompress_addr(ipv6->srcipaddr,
|
||||
tmp != 0 ? addrcontext->prefix : NULL, g_unc_ctxconf[tmp]);
|
||||
uncompress_addr(&ind->src,
|
||||
tmp != 0 ? addrcontext->prefix : NULL,
|
||||
g_unc_ctxconf[tmp], ipv6->srcipaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1024,7 +1114,8 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
|||
* address.
|
||||
*/
|
||||
|
||||
uncompress_addr(ipv6->srcipaddr, g_llprefix, g_unc_llconf[tmp]);
|
||||
uncompress_addr(&ind->src, g_llprefix, g_unc_llconf[tmp],
|
||||
ipv6->srcipaddr);
|
||||
}
|
||||
|
||||
/* Destination address */
|
||||
|
@ -1059,7 +1150,8 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
|||
g_hc06ptr++;
|
||||
}
|
||||
|
||||
uncompress_addr(ipv6->destipaddr, prefix, g_unc_mxconf[tmp]);
|
||||
uncompress_addr(&ind->dest, prefix, g_unc_mxconf[tmp],
|
||||
ipv6->destipaddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1082,13 +1174,17 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
|||
return;
|
||||
}
|
||||
|
||||
uncompress_addr(ipv6->destipaddr, addrcontext->prefix, g_unc_ctxconf[tmp]);
|
||||
uncompress_addr(&ind->src, addrcontext->prefix,
|
||||
g_unc_ctxconf[tmp], ipv6->destipaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not address context based => link local M = 0, DAC = 0 - same as SAC */
|
||||
/* Not address context based => link local M = 0, DAC = 0 - same
|
||||
* as SAC.
|
||||
*/
|
||||
|
||||
uncompress_addr(ipv6->destipaddr, g_llprefix, g_unc_llconf[tmp]);
|
||||
uncompress_addr(&ind->src,g_llprefix, g_unc_llconf[tmp],
|
||||
ipv6->destipaddr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -532,7 +532,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
|||
if ((hc1[SIXLOWPAN_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC)
|
||||
{
|
||||
ninfo("IPHC Dispatch\n");
|
||||
sixlowpan_uncompresshdr_hc06(fragsize, iob, fptr, bptr);
|
||||
sixlowpan_uncompresshdr_hc06(ind, fragsize, iob, fptr, bptr);
|
||||
}
|
||||
else
|
||||
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */
|
||||
|
|
|
@ -441,13 +441,14 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
|||
* appropriate values
|
||||
*
|
||||
* Input Parmeters:
|
||||
* 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 first
|
||||
* fragment.
|
||||
* iob - Pointer to the IOB containing the received frame.
|
||||
* fptr - Pointer to frame to be compressed.
|
||||
* bptr - Output goes here. Normally this is a known offset into d_buf,
|
||||
* may be redirected to a "bitbucket" on the case of FRAGN frames.
|
||||
* ind - MAC header meta data including node addressing information.
|
||||
* 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 first
|
||||
* fragment.
|
||||
* iob - Pointer to the IOB containing the received frame.
|
||||
* fptr - Pointer to frame to be compressed.
|
||||
* bptr - Output goes here. Normally this is a known offset into d_buf,
|
||||
* may be redirected to a "bitbucket" on the case of FRAGN frames.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
@ -455,7 +456,8 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
||||
void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
||||
void sixlowpan_uncompresshdr_hc06(FAR const struct ieee802154_data_ind_s *ind,
|
||||
uint16_t iplen, FAR struct iob_s *iob,
|
||||
FAR uint8_t *fptr, FAR uint8_t *bptr);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ static uint8_t g_iobuffer[CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE];
|
|||
|
||||
static uint8_t g_eaddr[IEEE802154_EADDRSIZE] =
|
||||
{
|
||||
0x00, 0xfa, 0xde, 0x00, 0xde, 0xad, 0xbe, 0xef
|
||||
0x0c, 0xfa, 0xde, 0x00, 0xde, 0xad, 0xbe, 0xef
|
||||
};
|
||||
|
||||
static uint8_t g_saddr[IEEE802154_SADDRSIZE] =
|
||||
|
@ -131,6 +131,16 @@ static uint8_t g_panid[IEEE802154_PANIDSIZE] =
|
|||
0xca, 0xfe
|
||||
};
|
||||
|
||||
static const uint8_t g_src_eaddr[IEEE802154_EADDRSIZE] =
|
||||
{
|
||||
0x0a, 0xfa, 0xde, 0x00, 0xde, 0xad, 0xbe, 0xef
|
||||
};
|
||||
|
||||
static const uint8_t g_src_saddr[IEEE802154_SADDRSIZE] =
|
||||
{
|
||||
0x12, 0x34
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
@ -289,8 +299,26 @@ static int lo_loopback(FAR struct net_driver_s *dev)
|
|||
FAR struct iob_s *iob;
|
||||
int ret;
|
||||
|
||||
/* Create some fake metadata */
|
||||
|
||||
memset(&ind, 0, sizeof(struct ieee802154_data_ind_s));
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
ind.src.mode = IEEE802154_ADDRMODE_EXTENDED;
|
||||
ind.dest.mode = IEEE802154_ADDRMODE_EXTENDED;
|
||||
#else
|
||||
ind.src.mode = IEEE802154_ADDRMODE_SHORT;
|
||||
ind.dest.mode = IEEE802154_ADDRMODE_SHORT;
|
||||
#endif
|
||||
|
||||
IEEE802154_PANIDCOPY(ind.src.panid, g_panid);
|
||||
IEEE802154_SADDRCOPY(ind.src.saddr, g_src_saddr);
|
||||
IEEE802154_EADDRCOPY(ind.src.eaddr, g_src_eaddr);
|
||||
|
||||
IEEE802154_PANIDCOPY(ind.dest.panid, g_panid);
|
||||
IEEE802154_SADDRCOPY(ind.dest.saddr, g_saddr);
|
||||
IEEE802154_EADDRCOPY(ind.dest.eaddr, g_eaddr);
|
||||
|
||||
/* Loop while there framelist to be sent, i.e., while the freme list is not
|
||||
* emtpy. Sending, of course, just means relaying back through the network
|
||||
* for this driver.
|
||||
|
|
Loading…
Reference in a new issue