6loWPAN: Add a little more send logic.

This commit is contained in:
Gregory Nutt 2017-03-30 15:38:56 -06:00
parent c3289afa9c
commit 2aca4d4ebd
8 changed files with 1061 additions and 62 deletions

View File

@ -323,6 +323,27 @@ struct rimeaddr_s
* manage the fragmentation. 'struct ieee802154_driver_s' is cast
* compatible with 'struct net_driver_s' when CONFIG_NET_MULTINIC is not
* defined or when dev->d_lltype == NET_LL_IEEE802154.
*
* The IEEE802.15.4 MAC network driver has reponsibility for initializing
* this structure. In general, all fields must be set to NULL. In
* addtion:
*
* 1) i_panid must be set to identify the network. It may be set to 0xfff
* if the device is not associated.
* 2) i_dsn must be set to a random value. After that, it will be managed
* by the network.
* 3) i_nodeaddr must be set after the MAC is assigned an address.
*
* Frame Organization:
*
* Content Offset
* +----------------+ 0
* | Frame Header |
* +----------------+ i_dataoffset
* | Data |
* +----------------+ i_framelen
* | Unused |
* +----------------+ CONFIG_NET_6LOWPAN_FRAMELEN
*/
struct ieee802154_driver_s
@ -344,7 +365,8 @@ struct ieee802154_driver_s
* requesting new framesusing break-off fram buffers. That frame buffer
* management must be controlled by the IEEE802.15.4 MAC driver.
*
* Driver provied frame buffers should be 16-bit aligned.
* Driver provided frame buffers should of size CONFIG_NET_6LOWPAN_FRAMELEN
* and should be 16-bit aligned.
*/
FAR uint8_t *i_frame;
@ -360,6 +382,31 @@ struct ieee802154_driver_s
uint16_t i_framelen;
/* i_panid. The PAN ID is 16-bit number that identifies the network. It
* must be unique to differentiate a network. All the nodes in the same
* network should have the same PAN ID. This value must be provided to
* the network from the IEEE802.15.4 MAC driver.
*
* If this value is 0xffff, the device is not associated.
*/
uint16_t i_panid;
/* i_node_addr. The address assigned to this node. */
struct rimeaddr_s i_nodeaddr;
/* i_dsn. The sequence number in the range 0x00-0xff added to the
* transmitted data or MAC command frame. The default is a random value
* within that range.
*
* This field must be initialized to a random number by the IEEE802.15.4
* MAC driver. It sill be subsequently incremented on each frame by the
* network logic.
*/
uint8_t i_dsn;
/* The following fields are device-specific metadata used by the 6loWPAN
* stack and should not be modified by the IEEE802.15.4 MAC network drvier.
*/
@ -385,9 +432,9 @@ struct ieee802154_driver_s
uint8_t i_rime_hdrlen;
/* Next available pointer into header */
/* Offset first available byte for the payload after header region. */
uint8_t i_hdrptr;
uint8_t i_dataoffset;
/* Packet buffer metadata: Attributes and addresses */

View File

@ -136,7 +136,7 @@ config NET_6LOWPAN_RIMEADDR_SIZE
---help---
Only the values 2 and 8 are supported
config NET_SIXLOWPAN_MAXAGE
config NET_6LOWPAN_MAXAGE
int "Packet reassembly timeout"
default 20
---help---
@ -150,11 +150,11 @@ config NET_6LOWPAN_MAX_MACTRANSMITS
layer should resend packets if no link-layer ACK wasreceived. This
only makes sense with the csma_driver.
config NET_SIXLOWPAN_MAXPAYLOAD
config NET_6LOWPAN_MAXPAYLOAD
int "Max packet size"
default 102
---help---
CONFIG_NET_SIXLOWPAN_MAXPAYLOAD specifies the maximum size of packets
NET_6LOWPAN_MAXPAYLOAD specifies the maximum size of packets
before they get fragmented. The default is 127 bytes (the maximum size
of a 802.15.4 frame) - 25 bytes (for the 802.15.4 MAClayer header). This
can be increased for systems with larger packet sizes.

View File

@ -40,7 +40,7 @@ ifeq ($(CONFIG_NET_6LOWPAN),y)
# Include IEEE 802.15.4 file in the build
NET_CSRCS += sixlowpan_initialize.c sixlowpan_globals.c sixlowpan_utils.c
NET_CSRCS += sixlowpan_input.c sixlowpan_send.c
NET_CSRCS += sixlowpan_input.c sixlowpan_send.c sixlowpan_framer.c
NET_CSRCS += sixlowpan_compressor.c
ifeq ($(CONFIG_NET_TCP),y)

View File

@ -0,0 +1,606 @@
/****************************************************************************
* net/sixlowpan/sixlowpan_framer.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Derives from Contiki:
*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
* Authors: Adam Dunkels <adam@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
* Niclas Finne <nfi@sics.se>
* Mathilde Durvy <mdurvy@cisco.com>
* Julien Abeille <jabeille@cisco.com>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
*
* 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 of the Institute 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 INSTITUTE 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 INSTITUTE 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 <stdbool.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include "nuttx/net/net.h"
#include "nuttx/net/sixlowpan.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Private Types
****************************************************************************/
/* Structure that contains the lengths of the various addressing and
* security fields in the 802.15.4 header.
*/
struct field_length_s
{
uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */
uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */
uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */
uint8_t src_addr_len; /**< Length (in bytes) of source address field */
uint8_t aux_sec_len; /**< Length (in bytes) of aux security header field */
};
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: sixlowpan_addrlen
*
* Description:
* Return the address length associated with a 2-bit address mode
*
* Input parameters:
* addrmode - The address mode
*
* Returned Value:
* The address length associated with the address mode.
*
****************************************************************************/
static inline uint8_t sixlowpan_addrlen(uint8_t addrmode)
{
switch (addrmode)
{
case FRAME802154_SHORTADDRMODE: /* 16-bit address */
return 2;
case FRAME802154_LONGADDRMODE: /* 64-bit address */
return 8;
default:
return 0;
}
}
/****************************************************************************
* Function: sixlowpan_isbroadcast
*
* Description:
* Return the address length associated with a 2-bit address mode
*
* Input parameters:
* addrmode - The address mode
*
* Returned Value:
* The address length associated with the address mode.
*
****************************************************************************/
static bool sixlowpan_isbroadcast(uint8_t mode, FAR uint8_t *addr)
{
int i = ((mode == FRAME802154_SHORTADDRMODE) ? 2 : 8);
while (i-- > 0)
{
if (addr[i] != 0xff)
{
return false;
}
}
return true;
}
/****************************************************************************
* Function: sixlowpan_addrnull
*
* Description:
* If the output address is NULL in the Rime buf, then it is broadcast
* on the 802.15.4 network.
*
* Input parameters:
* addrmode - The address mode
*
* Returned Value:
* The address length associated with the address mode.
*
****************************************************************************/
static bool sixlowpan_addrnull(FAR uint8_t *addr)
{
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
int i = 2;
#else
int i = 8;
#endif
while (i-- > 0)
{
if (addr[i] != 0x00)
{
return false;
}
}
return true;
}
/****************************************************************************
* Function: sixlowpan_fieldlengths
*
* Description:
* Return the lengths associated fields of the IEEE802.15.4 header.
*
* Input parameters:
* finfo - IEEE802.15.4 header info (input)
* flen - Field length info (output)
*
* Returned Value:
* None
*
****************************************************************************/
static void sixlowpan_fieldlengths(FAR struct frame802154_s *finfo,
FAR struct field_length_s *flen)
{
/* Initialize to all zero */
memset(flen, 0, sizeof(struct field_length_s));
/* Determine lengths of each field based on fcf and other args */
if ((finfo->fcf.dest_addr_mode & 3) != 0)
{
flen->dest_pid_len = 2;
}
if ((finfo->fcf.src_addr_mode & 3) != 0)
{
flen->src_pid_len = 2;
}
/* Set PAN ID compression bit if src pan id matches dest pan id. */
if ((finfo->fcf.dest_addr_mode & 3) != 0 &&
(finfo->fcf.src_addr_mode & 3) != 0 &&
finfo->src_pid == finfo->dest_pid)
{
finfo->fcf.panid_compression = 1;
/* Compressed header, only do dest pid */
/* flen->src_pid_len = 0; */
}
/* Determine address lengths */
flen->dest_addr_len = sixlowpan_addrlen(finfo->fcf.dest_addr_mode & 3);
flen->src_addr_len = sixlowpan_addrlen(finfo->fcf.src_addr_mode & 3);
/* Aux security header */
#if 0 /* TODO Aux security header not yet implemented */
if ((finfo->fcf.security_enabled & 1) != 0)
{
switch(finfo->aux_hdr.security_control.key_id_mode)
{
case 0:
flen->aux_sec_len = 5; /* Minimum value */
break;
case 1:
flen->aux_sec_len = 6;
break;
case 2:
flen->aux_sec_len = 10;
break;
case 3:
flen->aux_sec_len = 14;
break;
default:
break;
}
}
#endif
}
/****************************************************************************
* Function: sixlowpan_fieldlengths
*
* Description:
* Return the lengths associated fields of the IEEE802.15.4 header.
*
* Input parameters:
* finfo - IEEE802.15.4 header info (input)
* flen - Field length info (output)
*
* Returned Value:
* None
*
****************************************************************************/
static int sixlowpan_flen_hdrlen(FAR const struct field_length_s *flen)
{
return 3 + flen->dest_pid_len + flen->dest_addr_len +
flen->src_pid_len + flen->src_addr_len + flen->aux_sec_len;
}
/****************************************************************************
* Function: sixlowpan_802154_hdrlen
*
* Description:
* Calculates the length of the frame header. This function is meant to
* be called by a higher level function, that interfaces to a MAC.
*
* Input parameters:
* finfo - IEEE802.15.4 header info that specifies the frame to send.
*
* Returned Value:
* The length of the frame header.
*
****************************************************************************/
static int sixlowpan_802154_hdrlen(FAR struct frame802154_s *finfo)
{
struct field_length_s flen;
sixlowpan_fieldlengths(finfo, &flen);
return sixlowpan_flen_hdrlen(&flen);
}
/****************************************************************************
* Function: sixlowpan_setup_params
*
* Description:
* Configure frame parmeters structure.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* params - Where to put the parmeters
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* None.
*
****************************************************************************/
static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
FAR struct frame802154_s *params,
uint16_t dest_panid)
{
bool rcvrnull;
/* Initialize all prameters to all zero */
memset(&params, 0, sizeof(params));
/* Reset to an empty frame */
ieee->i_framelen = 0;
ieee->i_dataoffset = 0;
/* Build the FCF (Only non-zero elements need to be initialized). */
params->fcf.frame_type = FRAME802154_DATAFRAME;
params->fcf.frame_pending = ieee->i_pktattrs[PACKETBUF_ATTR_PENDING];
/* If the output address is NULL in the Rime buf, then it is broadcast
* on the 802.15.4 network.
*/
rcvrnull = sixlowpan_addrnull(ieee->i_pktaddrs[PACKETBUF_ADDR_RECEIVER].u8);
if (rcvrnull)
{
params->fcf.ack_required = ieee->i_pktattrs[PACKETBUF_ATTR_MAC_ACK];
}
/* Insert IEEE 802.15.4 (2003) version bit. */
params->fcf.frame_version = FRAME802154_IEEE802154_2003;
/* Increment and set the data sequence number. */
if (ieee->i_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] != 0)
{
params->seq = ieee->i_pktattrs[PACKETBUF_ATTR_MAC_SEQNO];
}
else
{
params->seq = ieee->i_dsn++;
ieee->i_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] = params->seq;
}
/* Complete the addressing fields. */
/* Set the source and destination PAN ID. */
params->src_pid = ieee->i_panid;
params->dest_pid = dest_panid;
/* If the output address is NULL in the Rime buf, then it is broadcast
* on the 802.15.4 network.
*/
if (rcvrnull)
{
/* Broadcast requires short address mode. */
params->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
params->dest_addr[0] = 0xff;
params->dest_addr[1] = 0xff;
}
else
{
/* Copy the destination address */
rimeaddr_copy((struct rimeaddr_s *)&params->dest_addr,
ieee->i_pktaddrs[PACKETBUF_ADDR_RECEIVER].u8);
/* Use short address mode if so configured */
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
params->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
#else
params->fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
#endif
}
/* Set the source address to the node address assigned to the device */
rimeaddr_copy((struct rimeaddr_s *)&params->src_addr, &ieee->i_nodeaddr.u8);
/* Configure the payload address and length */
params->payload = FRAME_DATA_START(ieee);
params->payload_len = FRAME_DATA_SIZE(ieee);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: sixlowpan_hdrlen
*
* Description:
* This function is before the first frame has been sent in order to
* determine what the size of the IEEE802.15.4 header will be. No frame
* buffer is required to make this determination.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
* errno value is return on failure.
*
****************************************************************************/
int sixlowpan_hdrlen(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid)
{
struct frame802154_s params;
/* Set up the frame parameters */
sixlowpan_setup_params(ieee, &params, dest_panid);
/* Return the length of the header */
return sixlowpan_802154_hdrlen(&params);
}
/****************************************************************************
* Function: sixlowpan_802154_framecreate
*
* Description:
* Creates a frame for transmission over the air. This function is meant
* to be called by a higher level function, that interfaces to a MAC.
*
* Input parameters:
* finfo - Pointer to struct EEE802.15.4 header structure that specifies
* the frame to send.
* buf - Pointer to the buffer to use for the frame.
* buflen - The length of the buffer to use for the frame.
* finfo - I that specifies the frame to send.
*
* Returned Value:
* The length of the frame header or 0 if there was insufficient space in
* the buffer for the frame headers.
*
****************************************************************************/
int sixlowpan_802154_framecreate(FAR struct frame802154_s *finfo,
FAR uint8_t *buf, int buflen)
{
struct field_length_s flen;
uint8_t pos;
int hdrlen;
int i;
sixlowpan_fieldlengths(finfo, &flen);
hdrlen = sixlowpan_flen_hdrlen(&flen);
if (hdrlen > buflen)
{
/* Too little space for headers. */
return 0;
}
/* 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);
/* Sequence number */
buf[2] = finfo->seq;
pos = 3;
/* Destination PAN ID */
if (flen.dest_pid_len == 2)
{
buf[pos++] = finfo->dest_pid & 0xff;
buf[pos++] = (finfo->dest_pid >> 8) & 0xff;
}
/* Destination address */
for (i = flen.dest_addr_len; i > 0; i--)
{
buf[pos++] = finfo->dest_addr[i - 1];
}
/* Source PAN ID */
if (flen.src_pid_len == 2)
{
buf[pos++] = finfo->src_pid & 0xff;
buf[pos++] = (finfo->src_pid >> 8) & 0xff;
}
/* Source address */
for (i = flen.src_addr_len; i > 0; i--)
{
buf[pos++] = finfo->src_addr[i - 1];
}
/* Aux header */
#if 0 /* TODO Aux security header not yet implemented */
if (flen.aux_sec_len)
{
pos += flen.aux_sec_len;
}
#endif
DEBUGASSERT(pos == hdrlen);
return (int)pos;
}
/****************************************************************************
* Function: sixlowpan_framecreate
*
* Description:
* This function is called after the IEEE802.15.4 MAC driver polls for
* TX data. It creates the IEEE802.15.4 header in the frame buffer.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
* errno value is return on failure.
*
****************************************************************************/
int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid)
{
struct frame802154_s params;
int len;
int ret;
/* Set up the frame parameters */
sixlowpan_setup_params(ieee, &params, dest_panid);
/* Get the length of the header */
len = sixlowpan_802154_hdrlen(&params);
/* Allocate space for the header in the frame buffer */
ret = sixlowpan_frame_hdralloc(ieee, len);
if (ret < 0)
{
wlerr("ERROR: Header too large: %u\n", len);
return ret;
}
/* Then create the frame */
sixlowpan_802154_framecreate(&params, FRAME_HDR_START(ieee), len);
wlinfo("Frame type: %02x Data len: %d %u (%u)\n",
params.fcf.frame_type, len, FRAME_DATA_SIZE(ieee),
FRAME_SIZE(ieee));
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
wlinfo("Dest address: %02x:%02x\n",
params.dest_addr[0], params.dest_addr[1]);
#else
wlinfo("Dest address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
params.dest_addr[0], params.dest_addr[1], params.dest_addr[2],
params.dest_addr[3], params.dest_addr[4], params.dest_addr[5],
params.dest_addr[6], params.dest_addr[7]);
#endif
return len;
}
#endif /* CONFIG_NET_6LOWPAN */

View File

@ -20,6 +20,7 @@
* 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
@ -44,7 +45,7 @@
****************************************************************************/
/* FOR HC-06 COMPLIANCE TODO:
*
*
* -Add compression options to UDP, currently only supports
* both ports compressed or both ports elided
* -Verify TC/FL compression works

View File

@ -4,9 +4,28 @@
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Parts of this file derive from Contiki:
*
* Copyright (c) 2008, Swedish Institute of Computer Science
* All rights reserved.
*
* Additional fixes for AVR contributed by:
* Colin O'Flynn coflynn@newae.com
* Eric Gnoske egnoske@gmail.com
* Blake Leverett bleverett@gmail.com
* Mike Vidales mavida404@gmail.com
* Kevin Brown kbrown3@uccs.edu
* Nate Bohlmann nate@elfwerks.com
*
* Additional fixes for MSP430 contributed by:
* Joakim Eriksson
* Niclas Finne
* Nicolas Tsiftes
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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.
@ -14,23 +33,21 @@
* 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.
* 3. Neither the name of the copyright holders nor the names of
* 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
* 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.
*
****************************************************************************/
#ifndef _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H
@ -64,11 +81,64 @@
#define rimeaddr_cmp(addr1,addr2) \
(memcmp(addr1, addr2, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE) == 0)
/* Frame buffer helpers */
#define FRAME_RESET(ieee) \
do \
{ \
(ieee)->i_dataoffset = 0; \
(ieee)->i_framelen = 0; \
} \
while (0)
#define FRAME_HDR_START(ieee) \
((ieee)->i_frame)
#define FRAME_HDR_SIZE(ieee) \
((ieee)->i_dataoffset)
#define FRAME_DATA_START(ieee) \
((FAR uint8_t *)((ieee)->i_frame) + (ieee)->i_dataoffset)
#define FRAME_DATA_SIZE(ieee) \
((ieee)->i_framelen - (ieee)->i_dataoffset)
#define FRAME_REMAINING(ieee) \
(CONFIG_NET_6LOWPAN_FRAMELEN - (ieee)->i_framelen)
#define FRAME_SIZE(ieee) \
((ieee)->i_framelen)
/* These are some definitions of element values used in the FCF. See the
* IEEE802.15.4 spec for details.
*/
#define FRAME802154_BEACONFRAME 0x00
#define FRAME802154_DATAFRAME 0x01
#define FRAME802154_ACKFRAME 0x02
#define FRAME802154_CMDFRAME 0x03
#define FRAME802154_BEACONREQ 0x07
#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_NOBEACONS 0x0f
#define FRAME802154_BROADCASTADDR 0xffff
#define FRAME802154_BROADCASTPANDID 0xffff
#define FRAME802154_IEEE802154_2003 0x00
#define FRAME802154_IEEE802154_2006 0x01
#define FRAME802154_SECURITY_LEVEL_NONE 0
#define FRAME802154_SECURITY_LEVEL_128 3
/****************************************************************************
* Public Types
****************************************************************************/
/* IPv6 + TCP header */
/* IPv^ TCP/UDP Definitions *************************************************/
/* IPv6 + TCP header. Cast compatible based on IPv6 protocol field. */
struct ipv6tcp_hdr_s
{
@ -92,6 +162,71 @@ struct ipv6icmp_hdr_s
struct icmpv6_iphdr_s icmp;
};
/* IEEE802.15.4 Frame Definitions *******************************************/
/* The IEEE 802.15.4 frame has a number of constant/fixed fields that can be
* counted to make frame construction and max payload calculations easier.
* These include:
*
* 1. FCF - 2 bytes - Fixed
* 2. Sequence number - 1 byte - Fixed
* 3. Addressing fields - 4 - 20 bytes - Variable
* 4. Aux security header - 0 - 14 bytes - Variable
* 5. CRC - 2 bytes - Fixed
*/
/* Defines the bitfields of the frame control field (FCF). */
struct frame802154_fcf_s
{
uint8_t frame_type; /* 3 bit. Frame type field, see 802.15.4 */
uint8_t security_enabled; /* 1 bit. True if security is used in this frame */
uint8_t frame_pending; /* 1 bit. True if sender has more data to send */
uint8_t ack_required; /* 1 bit. Is an ack frame required? */
uint8_t panid_compression; /* 1 bit. Is this a compressed header? */
/* 3 bit. Unused bits */
uint8_t dest_addr_mode; /* 2 bit. Destination address mode, see 802.15.4 */
uint8_t frame_version; /* 2 bit. 802.15.4 frame version */
uint8_t src_addr_mode; /* 2 bit. Source address mode, see 802.15.4 */
};
/* 802.15.4 security control bitfield. See section 7.6.2.2.1 in 802.15.4
* specification.
*/
struct frame802154_scf_s
{
uint8_t security_level; /* 3 bit. security level */
uint8_t key_id_mode; /* 2 bit. Key identifier mode */
uint8_t reserved; /* 3 bit. Reserved bits */
};
/* 802.15.4 Aux security header */
struct frame802154_aux_hdr_s
{
struct frame802154_scf_s security_control; /* Security control bitfield */
uint32_t frame_counter; /* Frame counter, used for security */
uint8_t key[9]; /* The key itself, or an index to the key */
};
/* Parameters used by the frame802154_create() function. These parameters
* are used in the 802.15.4 frame header. See the 802.15.4 specification
* for details.
*/
struct frame802154_s
{
struct frame802154_fcf_s fcf; /* Frame control field */
uint8_t seq; /* Sequence number */
uint16_t dest_pid; /* Destination PAN ID */
uint8_t dest_addr[8]; /* Destination address */
uint16_t src_pid; /* Source PAN ID */
uint8_t src_addr[8]; /* Source address */
struct frame802154_aux_hdr_s aux_hdr; /* Aux security header */
uint8_t *payload; /* Pointer to 802.15.4 frame payload */
uint8_t payload_len; /* Length of payload field */
};
/****************************************************************************
* Public Data
****************************************************************************/
@ -157,6 +292,49 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
FAR const struct ipv6_hdr_s *ipv6, FAR const void *buf,
size_t len, FAR const struct rimeaddr_s *raddr);
/****************************************************************************
* Function: sixlowpan_hdrlen
*
* Description:
* This function is before the first frame has been sent in order to
* determine what the size of the IEEE802.15.4 header will be. No frame
* buffer is required to make this determination.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
* errno value is return on failure.
*
****************************************************************************/
int sixlowpan_hdrlen(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid);
/****************************************************************************
* Function: sixlowpan_framecreate
*
* Description:
* This function is called after the IEEE802.15.4 MAC driver polls for
* TX data. It creates the IEEE802.15.4 header in the frame buffer.
*
* Input parameters:
* ieee - A reference IEEE802.15.4 MAC network device structure.
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
* is not associated.
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
* errno value is return on failure.
*
****************************************************************************/
int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
uint16_t dest_panid);
/****************************************************************************
* Name: sixlowpan_hc06_initialize
*
@ -293,15 +471,15 @@ void sixlowpan_uncompresshdr_hc1(FAR struct net_driver_s *dev,
#endif
/****************************************************************************
* Name: sixlowpan_pktbuf_reset
* Name: sixlowpan_frame_hdralloc
*
* Description:
* Reset all attributes and addresses in the packet buffer metadata in the
* provided IEEE802.15.4 MAC driver structure.
* Allocate space for a header within the frame buffer (i_frame).
*
****************************************************************************/
void sixlowpan_pktbuf_reset(FAR struct ieee802154_driver_s *ieee);
int sixlowpan_frame_hdralloc(FAR struct ieee802154_driver_s *ieee,
int size);
#endif /* CONFIG_NET_6LOWPAN */
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */

View File

@ -4,6 +4,18 @@
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Parts of this file derive from Contiki:
*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
* Authors: Adam Dunkels <adam@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
* Niclas Finne <nfi@sics.se>
* Mathilde Durvy <mdurvy@cisco.com>
* Julien Abeille <jabeille@cisco.com>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -11,25 +23,23 @@
* 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
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute 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.
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*
****************************************************************************/
@ -68,6 +78,7 @@
*
* Description:
* Setup some packet buffer attributes
*
* Input Parameters:
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
* ipv6 - Pointer to the IPv6 header to "compress"
@ -158,6 +169,42 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
ieee->i_uncomp_hdrlen += IPv6_HDRLEN;
}
/****************************************************************************
* Name: sixlowpan_send_frame
*
* Description:
* Send one frame when the IEEE802.15.4 MAC device next polls.
*
* Input Parameters:
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
* ipv6 - Pointer to the IPv6 header to "compress"
*
* Returned Value:
* None
*
****************************************************************************/
static int sixlowpan_send_frame(FAR struct ieee802154_driver_s *ieee)
{
/* Prepare the frame */
#warning Missing logic
/* Set up for the TX poll */
/* When polled, then we need to call sixlowpan_framecreate() to create the
* frame and copy the payload data into the frame.
*/
#if 0 /* Just some notes of what needs to be done in interrupt handler */
framer_hdrlen = sixlowpan_createframe(ieee, ieee->i_panid);
memcpy(ieee->i_rimeptr + ieee->i_rime_hdrlen, (uint8_t *)ipv6 + ieee->i_uncomp_hdrlen, len - ieee->i_uncomp_hdrlen);
dev->i_framelen = len - ieee->i_uncomp_hdrlen + ieee->i_rime_hdrlen;
#endif
#warning Missing logic
/* Notify the IEEE802.14.5 MAC driver that we have data to be sent */
#warning Missing logic
/* Wait for the transfer to complete */
#warning Missing logic
return -ENOSYS;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -203,29 +250,49 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
int framer_hdrlen; /* Framer header length */
struct rimeaddr_s dest; /* The MAC address of the destination of the packet */
uint16_t outlen; /* Number of bytes processed. */
uint16_t outlen = 0; /* Number of bytes processed. */
/* Initialize device-specific data */
FRAME_RESET(ieee);
ieee->i_uncomp_hdrlen = 0;
ieee->i_rime_hdrlen = 0;
/* REVISIT: Do I need this rimeptr? */
ieee->i_rimeptr = &dev->d_buf[PACKETBUF_HDR_SIZE];
/* Reset rime buffer, packet buffer metatadata */
sixlowpan_pktbuf_reset(ieee);
memset(ieee->i_pktattrs, 0, PACKETBUF_NUM_ATTRS * sizeof(uint16_t));
memset(ieee->i_pktaddrs, 0, PACKETBUF_NUM_ADDRS * sizeof(struct rimeaddr_s));
ieee->i_rimeptr = &dev->d_buf[PACKETBUF_HDR_SIZE];
ieee->i_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] = CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
ieee->i_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] =
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
#ifdef CONFIG_NET_6LOWPAN_SNIFFER
if (g_sixlowpan_sniffer != NULL)
{
/* Reset rime buffer, packet buffer metatadata */
memset(ieee->i_pktattrs, 0, PACKETBUF_NUM_ATTRS * sizeof(uint16_t));
memset(ieee->i_pktaddrs, 0, PACKETBUF_NUM_ADDRS * sizeof(struct rimeaddr_s));
ieee->i_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] =
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
/* Call the attribution when the callback comes, but set attributes here */
sixlowpan_set_pktattrs(ieee, ipv6);
}
#endif
/* Reset rime buffer, packet buffer metatadata */
memset(ieee->i_pktattrs, 0, PACKETBUF_NUM_ATTRS * sizeof(uint16_t));
memset(ieee->i_pktaddrs, 0, PACKETBUF_NUM_ADDRS * sizeof(struct rimeaddr_s));
ieee->i_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] =
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
/* Set stream mode for all TCP packets, except FIN packets. */
if (ipv6->proto == IP_PROTO_TCP)
@ -281,8 +348,94 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
ninfo("Header of len %d\n", ieee->i_rime_hdrlen);
/* Calculate frame header length. */
#warning Missing logic
rimeaddr_copy(&ieee->i_pktaddrs[PACKETBUF_ADDR_RECEIVER], &dest);
/* Pre-calculate frame header length. */
framer_hdrlen = sixlowpan_hdrlen(ieee, ieee->i_panid);
if (framer_hdrlen < 0)
{
/* Failed to determine the size of the header failed. */
nerr("ERROR: sixlowpan_framecreate() failed: %d\n", framer_hdrlen);
return framer_hdrlen;
}
/* Check if we need to fragment the packet into several frames */
if ((int)len - (int)ieee->i_uncomp_hdrlen >
(int)CONFIG_NET_6LOWPAN_MAXPAYLOAD - framer_hdrlen -
(int)ieee->i_rime_hdrlen)
{
#if CONFIG_NET_6LOWPAN_FRAG
/* The outbound IPv6 packet is too large to fit into a single 15.4
* packet, so we fragment it into multiple packets and send them.
* The first fragment contains frag1 dispatch, then
* IPv6/HC1/HC06/HC_UDP dispatchs/headers.
* The following fragments contain only the fragn dispatch.
*/
ninfo("Fragmentation sending packet len %d\n", len);
/* Create 1st Fragment */
# warning Missing logic
/* Move HC1/HC06/IPv6 header */
# warning Missing logic
/* FRAG1 dispatch + header
* Note that the length is in units of 8 bytes
*/
# warning Missing logic
/* Copy payload and send */
# warning Missing logic
/* Check TX result. */
# warning Missing logic
/* Set outlen to what we already sent from the IP payload */
# warning Missing logic
/* Create following fragments
* Datagram tag is already in the buffer, we need to set the
* FRAGN dispatch and for each fragment, the offset
*/
# warning Missing logic
while (outlen < len)
{
/* Copy payload and send */
# warning Missing logic
ninfo("sixlowpan output: fragment offset %d, len %d, tag %d\n",
outlen >> 3, g_rime_payloadlen, g_mytag);
# warning Missing logic
sixlowpan_send_frame(ieee);
/* Check tx result. */
# warning Missing logic
}
return -ENOSYS;
#else
nerr("ERROR: Packet too large: %d\n", len);
nerr(" Cannot to be sent without fragmentation support\n");
nerr(" dropping packet\n");
return -E2BIG;
#endif
}
else
{
/* The packet does not need to be fragmented just copy the "payload"
* and send in one frame.
*/
return sixlowpan_send_frame(ieee);
}
return -ENOSYS;
}

View File

@ -44,6 +44,17 @@
* SUCH DAMAGE.
*
****************************************************************************/
/* Frame Organization:
*
* Content Offset
* +----------------+ 0
* | Frame Header |
* +----------------+ i_dataoffset
* | Data |
* +----------------+ i_framelen
* | Unused |
* +----------------+ CONFIG_NET_6LOWPAN_FRAMELEN
*/
/****************************************************************************
* Included Files
@ -52,6 +63,7 @@
#include <nuttx/config.h>
#include <string.h>
#include <errno.h>
#include "nuttx/net/sixlowpan.h"
@ -64,22 +76,24 @@
****************************************************************************/
/****************************************************************************
* Name: sixlowpan_pktbuf_reset
* Name: sixlowpan_frame_hdralloc
*
* Description:
* Reset all attributes and addresses in the packet buffer metadata in the
* provided IEEE802.15.4 MAC driver structure.
* Allocate space for a header within the packet buffer (dev->d_buf).
*
****************************************************************************/
void sixlowpan_pktbuf_reset(FAR struct ieee802154_driver_s *ieee)
int sixlowpan_frame_hdralloc(FAR struct ieee802154_driver_s *ieee,
int size)
{
ieee->i_dev.d_len = 0;
ieee->i_rimeptr = 0;
ieee->i_hdrptr = PACKETBUF_HDR_SIZE;
if (size <= FRAME_REMAINING(ieee))
{
ieee->i_dataoffset += size;
ieee->i_framelen += size;
return OK;
}
memset(ieee->i_pktattrs, 0, PACKETBUF_NUM_ATTRS * sizeof(uint16_t));
memset(ieee->i_pktaddrs, 0, PACKETBUF_NUM_ADDRS * sizeof(struct rimeaddr_s));
return -ENOMEM;
}
#endif /* CONFIG_NET_6LOWPAN */