6loWPAN: Add option to dump buffers. Fix some issues with calculation of the IEEE802.15.4 header size.

This commit is contained in:
Gregory Nutt 2017-04-04 12:31:22 -06:00
parent a6ae7d4ae3
commit 1f394a61b3
10 changed files with 226 additions and 57 deletions

View File

@ -131,7 +131,7 @@ config NET_ETHERNET
no need to define anything special in the configuration file to use
Ethernet -- it is the default).
menuconfig NET_6LOWPAN
config NET_6LOWPAN
bool "IEEE 802.15.4 6LoWPAN support"
default n
select NETDEV_MULTINIC if NET_ETHERNET || NET_LOOPBACK || NET_SLIP || NET_TUN

View File

@ -3,7 +3,8 @@
# see the file kconfig-language.txt in the NuttX tools repository.
#
if NET_6LOWPAN
menu "6LoWPAN Configuration"
depends on NET_6LOWPAN
config NET_6LOWPAN_FRAG
bool "6loWPAN Fragmentation"
@ -190,4 +191,13 @@ config NET_6LOWPAN_TCP_RECVWNDO
the application is slow to process incoming data, or high (32768
bytes) if the application processes data quickly.
endif # NET_6LOWPAN
config NET_6LOWPAN_DUMPBUFFER
bool "Enable dumping of buffer data"
default n
depends on DEBUG_NET_INFO
---help---
Enable dumping of all packet and frame buffers coming into and out
of the 6loWPAN logic. This will generate a large volume of data if
selected.
endmenu # 6LoWPAN Configuration

View File

@ -261,12 +261,12 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Pre-calculate frame header length. */
framer_hdrlen = sixlowpan_hdrlen(ieee, ieee->i_panid);
framer_hdrlen = sixlowpan_send_hdrlen(ieee, ieee->i_panid);
if (framer_hdrlen < 0)
{
/* Failed to determine the size of the header failed. */
nerr("ERROR: sixlowpan_hdrlen() failed: %d\n", framer_hdrlen);
nerr("ERROR: sixlowpan_send_hdrlen() failed: %d\n", framer_hdrlen);
return framer_hdrlen;
}
@ -340,6 +340,8 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
ninfo("First fragment: length %d, tag %d\n",
g_rime_payloadlen, ieee->i_dgramtag);
sixlowpan_dumpbuffer("Outgoing frame",
(FAR const uint8_t *)iob->io_data, iob->io_len);
/* Add the first frame to the IOB queue */
@ -412,6 +414,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
ninfo("sixlowpan output: fragment offset %d, length %d, tag %d\n",
outlen >> 3, g_rime_payloadlen, ieee->i_dgramtag);
sixlowpan_dumpbuffer("Outgoing frame",
(FAR const uint8_t *)iob->io_data,
iob->io_len);
/* Add the next frame to the tail of the IOB queue */
@ -449,6 +454,10 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
buflen - g_uncomp_hdrlen);
iob->io_len = buflen - g_uncomp_hdrlen + g_frame_hdrlen;
ninfo("Non-fragmented: length %d\n", iob->io_len);
sixlowpan_dumpbuffer("Outgoing frame",
(FAR const uint8_t *)iob->io_data, iob->io_len);
/* Add the first frame to the IOB queue */
ieee->i_framelist = iob;

View File

@ -383,7 +383,7 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
****************************************************************************/
/****************************************************************************
* Function: sixlowpan_hdrlen
* Function: sixlowpan_send_hdrlen
*
* Description:
* This function is before the first frame has been sent in order to
@ -401,7 +401,7 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
*
****************************************************************************/
int sixlowpan_hdrlen(FAR struct ieee802154_driver_s *ieee,
int sixlowpan_send_hdrlen(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid)
{
struct frame802154_s params;
@ -453,18 +453,18 @@ int sixlowpan_802154_framecreate(FAR struct frame802154_s *finfo,
return 0;
}
/* OK, now we have field lengths. Time to actually construct
* the outgoing frame, and store it in the provided buffer
/* OK, now we have field lengths. Time to actually construct the outgoing
* frame, and store it in the provided buffer
*/
buf[0] = (finfo->fcf.frame_type & 7) |
((finfo->fcf.security_enabled & 1) << 3) |
((finfo->fcf.frame_pending & 1) << 4) |
((finfo->fcf.ack_required & 1) << 5) |
((finfo->fcf.panid_compression & 1) << 6);
buf[1] = ((finfo->fcf.dest_addr_mode & 3) << 2) |
((finfo->fcf.frame_version & 3) << 4) |
((finfo->fcf.src_addr_mode & 3) << 6);
buf[0] = ((finfo->fcf.frame_type & 7) << FRAME802154_FRAMETYPE_SHIFT) |
((finfo->fcf.security_enabled & 1) << FRAME802154_SECENABLED_SHIFT) |
((finfo->fcf.frame_pending & 1) << FRAME802154_FRAMEPENDING_SHIFT) |
((finfo->fcf.ack_required & 1) << FRAME802154_ACKREQUEST_SHIFT) |
((finfo->fcf.panid_compression & 1) << FRAME802154_PANIDCOMP_SHIFT);
buf[1] = ((finfo->fcf.dest_addr_mode & 3) << FRAME802154_DSTADDR_SHIFT) |
((finfo->fcf.frame_version & 3) << FRAME802154_VERSION_SHIFT) |
((finfo->fcf.src_addr_mode & 3) << FRAME802154_SRCADDR_SHIFT);
/* Sequence number */
@ -483,7 +483,7 @@ int sixlowpan_802154_framecreate(FAR struct frame802154_s *finfo,
for (i = flen.dest_addr_len; i > 0; i--)
{
buf[pos++] = finfo->dest_addr[i - 1];
buf[pos++] = finfo->dest_addr[i - 1];
}
/* Source PAN ID */

View File

@ -455,8 +455,9 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
uint8_t iphc1;
uint8_t tmp;
ninfodumpbuffer("IPv6 before compression", (FAR const uint8_t *)ipv6,
sizeof(struct ipv6_hdr_s));
sixlowpan_dumpbuffer("IPv6 before compression",
(FAR const uint8_t *)ipv6,
sizeof(struct ipv6_hdr_s));
g_hc06ptr = fptr + 2;

View File

@ -119,7 +119,7 @@
* ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* fptr - Pointer to frame data payload.
* fptr - Pointer to frame to be compressed.
*
* Returned Value:
* None
@ -144,15 +144,18 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
ipv6->proto != IP_PROTO_TCP))
{
/* IPV6 DISPATCH
* Something cannot be compressed, use IPV6 DISPATCH,
* compress nothing, copy IPv6 header in rime buffer
* Something cannot be compressed, use IPV6 DISPATCH, compress
* nothing, copy IPv6 header in rime buffer
*/
*fptr = SIXLOWPAN_DISPATCH_IPV6;
g_frame_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
memcpy(fptr + g_frame_hdrlen, ipv6, IPv6_HDRLEN);
g_frame_hdrlen += IPv6_HDRLEN;
g_uncomp_hdrlen += IPv6_HDRLEN;
/* IPv6 dispatch header (1 byte) */
hc1[RIME_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_IPV6;
g_frame_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
memcpy(fptr + g_frame_hdrlen, ipv6, IPv6_HDRLEN);
g_frame_hdrlen += IPv6_HDRLEN;
g_uncomp_hdrlen += IPv6_HDRLEN;
}
else
{
@ -169,8 +172,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
/* HC1 encoding and ttl */
hc1[RIME_HC1_ENCODING] = 0xfc;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#if CONFIG_NET_TCP
@ -178,8 +181,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
/* HC1 encoding and ttl */
hc1[RIME_HC1_ENCODING] = 0xfe;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#endif /* CONFIG_NET_TCP */
@ -217,8 +220,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
memcpy(&hcudp[RIME_HC1_HC_UDP_CHKSUM], &udp->udpchksum, 2);
g_frame_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
g_uncomp_hdrlen += UDP_HDRLEN;
g_frame_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
g_uncomp_hdrlen += UDP_HDRLEN;
}
else
{

View File

@ -87,6 +87,94 @@
#define IPv6BUF(dev) ((FAR struct ipv6_hdr_s *)((dev)->d_buf))
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: sixlowpan_recv_hdrlen
*
* Description:
* Get the length of the IEEE802.15.4 header on the received frame.
*
* Input Parameters:
* ieee - The IEEE802.15.4 MAC network driver interface.
* iob - The IOB containing the frame.
*
* Returned Value:
* Ok is returned on success; Othewise a negated errno value is returned.
*
* Assumptions:
* Network is locked
*
****************************************************************************/
int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr)
{
uint16_t hdrlen;
uint8_t addrmode;
/* Minimum header: 2 byte FCF + 1 byte sequence number */
hdrlen = 3;
/* Account for destination address size */
addrmode = (fptr[1] & FRAME802154_DSTADDR_MASK) >> FRAME802154_DSTADDR_SHIFT;
if (addrmode == FRAME802154_SHORTADDRMODE)
{
/* 2 byte dest PAN + 2 byte dest short address */
hdrlen += 4;
}
else if (addrmode == FRAME802154_LONGADDRMODE)
{
/* 2 byte dest PAN + 6 byte dest long address */
hdrlen += 10;
}
else if (addrmode != FRAME802154_NOADDR)
{
nwarn("WARNING: Unrecognized address mode\n");
return -ENOSYS;
}
else if ((fptr[0] & (1 << FRAME802154_PANIDCOMP_SHIFT)) != 0)
{
nwarn("WARNING: PAN compression, but no destination address\n");
return -EINVAL;
}
/* Account for source address size */
addrmode = (fptr[1] & FRAME802154_SRCADDR_MASK) >> FRAME802154_SRCADDR_SHIFT;
if (addrmode == FRAME802154_NOADDR)
{
return hdrlen;
}
else
{
if ((fptr[0] & (1 << FRAME802154_PANIDCOMP_SHIFT)) == 0)
{
hdrlen += 2;
}
/* Add the length of the source address */
if (addrmode == FRAME802154_SHORTADDRMODE)
{
return hdrlen + 2;
}
else if (addrmode == FRAME802154_LONGADDRMODE)
{
return hdrlen + 8;
}
}
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -128,6 +216,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
uint8_t fragoffset = 0; /* Offset of the fragment in the IP packet */
bool isfrag = false;
int reqsize; /* Required buffer size */
int hdrsize; /* Size of the IEEE802.15.4 header */
#if CONFIG_NET_6LOWPAN_FRAG
bool isfirstfrag = false;
@ -141,11 +230,18 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
*/
g_uncomp_hdrlen = 0;
g_frame_hdrlen = 0;
g_frame_hdrlen = 0;
/* The MAC puts the 15.4 payload inside the RIME data buffer */
/* Get a pointer to the payload following the IEEE802.15.4 frame header. */
payptr = &iob->io_data[PACKETBUF_HDR_SIZE];
hdrsize = sixlowpan_recv_hdrlen(iob->io_data);
if (hdrsize < 0)
{
nwarn("Invalid IEEE802.15.2 header: %d\n", hdrsize);
return hdrsize;
}
payptr = &iob->io_data[hdrsize];
#if CONFIG_NET_6LOWPAN_FRAG
/* Since we don't support the mesh and broadcast header, the first header
@ -476,8 +572,9 @@ copypayload:
}
#endif /* CONFIG_NET_6LOWPAN_FRAG */
ninfodumpbuffer("IPv6 header", (FAR const uint8_t *)IPv6BUF(&ieee->i_dev),
IPv6_HDRLEN);
sixlowpan_dumpbuffer("IPv6 header",
(FAR const uint8_t *)IPv6BUF(&ieee->i_dev),
IPv6_HDRLEN);
return OK;
}
@ -497,6 +594,10 @@ copypayload:
static int sixlowpan_dispatch(FAR struct ieee802154_driver_s *ieee)
{
sixlowpan_dumpbuffer("Incoming packet",
(FAR const uint8_t *)IPv6BUF(&ieee->i_dev),
ieee->i_dev.d_len);
#ifdef CONFIG_NET_PKT
/* When packet sockets are enabled, feed the frame into the packet tap */
@ -591,6 +692,9 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
FRAME_IOB_REMOVE(ieee, iob);
DEBUGASSERT(iob != NULL);
sixlowpan_dumpbuffer("Incoming frame",
(FAR const uint8_t *)iob->io_data, iob->io_len);
/* Process the frame, decompressing it into the packet buffer */
ret = sixlowpan_frame_process(ieee, iob);

View File

@ -121,33 +121,47 @@
* IEEE802.15.4 spec for details.
*/
#define FRAME802154_BEACONFRAME 0x00
#define FRAME802154_DATAFRAME 0x01
#define FRAME802154_ACKFRAME 0x02
#define FRAME802154_CMDFRAME 0x03
#define FRAME802154_FRAMETYPE_SHIFT (0) /* Bits 0-2: Frame type */
#define FRAME802154_FRAMETYPE_MASK (7 << FRAME802154_FRAMETYPE_SHIFT)
#define FRAME802154_SECENABLED_SHIFT (3) /* Bit 3: Security enabled */
#define FRAME802154_FRAMEPENDING_SHIFT (4) /* Bit 4: Frame pending */
#define FRAME802154_ACKREQUEST_SHIFT (5) /* Bit 5: ACK request */
#define FRAME802154_PANIDCOMP_SHIFT (6) /* Bit 6: PANID compression */
/* Bits 7-9: Reserved */
#define FRAME802154_DSTADDR_SHIFT (2) /* Bits 10-11: Dest address mode */
#define FRAME802154_DSTADDR_MASK (3 << FRAME802154_DSTADDR_SHIFT)
#define FRAME802154_VERSION_SHIFT (4) /* Bit 12-13: Frame version */
#define FRAME802154_VERSION_MASK (3 << FRAME802154_VERSION_SHIFT)
#define FRAME802154_SRCADDR_SHIFT (6) /* Bits 14-15: Source address mode */
#define FRAME802154_SRCADDR_MASK (3 << FRAME802154_SRCADDR_SHIFT)
#define FRAME802154_BEACONREQ 0x07
/* Unshifted values for use in struct frame802154_fcf_s */
#define FRAME802154_IEEERESERVED 0x00
#define FRAME802154_NOADDR 0x00 /* Only valid for ACK or Beacon frames */
#define FRAME802154_SHORTADDRMODE 0x02
#define FRAME802154_LONGADDRMODE 0x03
#define FRAME802154_BEACONFRAME (0)
#define FRAME802154_DATAFRAME (1)
#define FRAME802154_ACKFRAME (2)
#define FRAME802154_CMDFRAME (3)
#define FRAME802154_BEACONREQ (7)
#define FRAME802154_IEEERESERVED (0)
#define FRAME802154_NOADDR (0) /* Only valid for ACK or Beacon frames */
#define FRAME802154_SHORTADDRMODE (2)
#define FRAME802154_LONGADDRMODE (3)
#define FRAME802154_NOBEACONS 0x0f
#define FRAME802154_BROADCASTADDR 0xffff
#define FRAME802154_BROADCASTPANDID 0xffff
#define FRAME802154_IEEE802154_2003 0x00
#define FRAME802154_IEEE802154_2006 0x01
#define FRAME802154_IEEE802154_2003 (0)
#define FRAME802154_IEEE802154_2006 (1)
#define FRAME802154_SECURITY_LEVEL_NONE 0
#define FRAME802154_SECURITY_LEVEL_128 3
#define FRAME802154_SECURITY_LEVEL_NONE (0)
#define FRAME802154_SECURITY_LEVEL_128 (3)
/* Packet buffer Definitions */
#define PACKETBUF_HDR_SIZE 48
#define PACKETBUF_ATTR_PACKET_TYPE_DATA 0
#define PACKETBUF_ATTR_PACKET_TYPE_ACK 1
#define PACKETBUF_ATTR_PACKET_TYPE_STREAM 2
@ -295,6 +309,14 @@
} \
while(0)
/* Debug ********************************************************************/
#ifdef CONFIG_NET_6LOWPAN_DUMPBUFFER
# define sixlowpan_dumpbuffer(m,b,s) ninfodumpbuffer(m,b,s)
#else
# define sixlowpan_dumpbuffer(m,b,s)
#endif
/****************************************************************************
* Public Types
****************************************************************************/
@ -492,7 +514,7 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
uint16_t timeout);
/****************************************************************************
* Function: sixlowpan_hdrlen
* Function: sixlowpan_send_hdrlen
*
* Description:
* This function is before the first frame has been sent in order to
@ -510,7 +532,7 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
*
****************************************************************************/
int sixlowpan_hdrlen(FAR struct ieee802154_driver_s *ieee,
int sixlowpan_send_hdrlen(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid);
/****************************************************************************
@ -617,7 +639,7 @@ void sixlowpan_hc06_initialize(void);
* ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* fptr - Pointer to frame data payload.
* fptr - Pointer to frame to be compressed.
*
* Returned Value:
* None
@ -678,6 +700,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
* ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* fptr - Pointer to frame to be compressed.
*
* Returned Value:
* None

View File

@ -55,6 +55,14 @@
#if defined(CONFIG_NET_6LOWPAN) && defined(CONFIG_NET_TCP)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Buffer access helpers */
#define IPv6BUF(dev) ((FAR struct ipv6_hdr_s *)((dev)->d_buf))
/****************************************************************************
* Private Functions
****************************************************************************/
@ -156,6 +164,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
int ret;
ninfo("buflen %lu\n", (unsigned long)buflen);
sixlowpan_dumpbuffer("Outgoing TCP payload", buf, buflen);
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
DEBUGASSERT(psock->s_type == SOCK_STREAM);
@ -368,6 +377,8 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
/* Double check */
ninfo("d_len %u\n", dev->d_len);
sixlowpan_dumpbuffer("Outgoing TCP packet",
(FAR const uint8_t *)IPv6BUF(dev), dev->d_len);
if (dev != NULL && dev->d_len > 0)
{

View File

@ -167,9 +167,13 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
uint16_t timeout;
int ret;
ninfo("buflen %lu\n", (unsigned long)buflen);
DEBUGASSERT(psock != NULL && psock->s_crefs > 0 && to != NULL);
DEBUGASSERT(psock->s_type == SOCK_DGRAM);
sixlowpan_dumpbuffer("Outgoing UDP payload", buf, buflen);
if (psock == NULL || to == NULL)
{
return (ssize_t)-EINVAL;
@ -352,9 +356,13 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
FAR struct udp_conn_s *conn;
struct sockaddr_in6 to;
ninfo("buflen %lu\n", (unsigned long)buflen);
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
DEBUGASSERT(psock->s_type == SOCK_DGRAM);
sixlowpan_dumpbuffer("Outgoing UDP payload", buf, buflen);
/* Make sure that this is a valid socket */
if (psock != NULL || psock->s_crefs <= 0)