diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h index 9b000ceb05c..86aaefae180 100644 --- a/include/nuttx/fs/ioctl.h +++ b/include/nuttx/fs/ioctl.h @@ -372,19 +372,19 @@ #define _LOOPIOCVALID(c) (_IOC_TYPE(c)==_LOOPBASE) #define _LOOPIOC(nr) _IOC(_LOOPBASE,nr) -/* Modem driver ioctl definitions ********************************************/ +/* Modem driver ioctl definitions *******************************************/ /* see nuttx/include/modem/ioctl.h */ #define _MODEMIOCVALID(c) (_IOC_TYPE(c)==_MODEMBASE) #define _MODEMIOC(nr) _IOC(_MODEMBASE,nr) -/* I2C driver ioctl definitions **********************************************/ +/* I2C driver ioctl definitions *********************************************/ /* see nuttx/include/i2c/i2c_master.h */ #define _I2CIOCVALID(c) (_IOC_TYPE(c)==_I2CBASE) #define _I2CIOC(nr) _IOC(_I2CBASE,nr) -/* SPI driver ioctl definitions **********************************************/ +/* SPI driver ioctl definitions *********************************************/ /* see nuttx/include/spi/spi_transfer.h */ #define _SPIIOCVALID(c) (_IOC_TYPE(c)==_SPIBASE) @@ -396,7 +396,7 @@ #define _GPIOCVALID(c) (_IOC_TYPE(c)==_GPIOBASE) #define _GPIOC(nr) _IOC(_GPIOBASE,nr) -/* Contactless driver ioctl definitions ****************************************/ +/* Contactless driver ioctl definitions *************************************/ /* (see nuttx/include/contactless/ioctl.h */ #define _CLIOCVALID(c) (_IOC_TYPE(c)==_CLIOCBASE) diff --git a/include/nuttx/net/sixlowpan.h b/include/nuttx/net/sixlowpan.h index 7463763bff5..66c84ac58f4 100644 --- a/include/nuttx/net/sixlowpan.h +++ b/include/nuttx/net/sixlowpan.h @@ -53,6 +53,7 @@ #include +#include #include /**************************************************************************** @@ -280,7 +281,7 @@ #define PACKETBUF_NUM_ATTRS 24 - /* Addresses (indices into i_pktaddr) */ +/* Addresses (indices into i_pktaddr) */ #define PACKETBUF_ADDR_SENDER 0 #define PACKETBUF_ADDR_RECEIVER 1 @@ -289,6 +290,62 @@ #define PACKETBUF_NUM_ADDRS 4 +/* Frame buffer helper macros. + * + * The IEEE802.15.4 MAC driver structures includes a list of IOB + * structures, i_framelist, containing frames to be sent by the driver or + * that were received by the driver. The IOB structure is defined in + * include/nuttx/net/iob.h. The length of data in the IOB is provided by + * the io_len field of the IOB structure. + * + * NOTE that IOBs must be configured such that CONFIG_IOB_BUFSIZE >= + * CONFIG_NET_6LOWPAN_FRAMELEN + * + * 1. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver + * structure with i_framelist set to NULL. At the conclusion of the + * poll, if there are frames to be sent, they will have been added to + * the i_framelist. The non-empty frame list is the indication that + * there is data to be sent. + * + * The IEEE802.15.4 may use the FRAME_IOB_EMPTY() macro to determine + * if there there frames to be sent. If so, it should remove each + * frame from the frame list using the FRAME_IOB_REMOVE() macro and send + * it. That macro will return NULL when all of the frames have been + * sent. + * + * After sending each frame, the driver must return the IOB to the pool + * of free IOBs using the FROM_IOB_FREE() macro. + */ + + +#define FRAME_IOB_EMPTY(ieee) ((ieee)->framelist == NULL) +#define FRAME_IOB_REMOVE(ieee, iob) \ + do \ + { \ + (iob) = (ieee)->i_framelist; \ + (ieee)->i_framelist = (iob)->io_flink; \ + (iob)->io_flink = NULL; \ + } \ + while (0) +#define FRAME_IOB_FREE(iob) iob_free(iob) + +/* 2. When receiving data, the IEEE802.15.4 MAC driver should receive the + * frame data directly into the payload area of an IOB structure. That + * IOB structure may be obtained using the FRAME_IOB_ALLOC() macro. The + * single frame should be added to the frame list using FRAME_IOB_ADD() + * (it will be a list of length one) . The MAC driver should then inform + * the network of the by calling sixlowpan_input(). + */ + +#define FRAME_IOB_ALLOC() iob_alloc(false) +#define FRAME_IOB_ADD(ieee, iob) \ + do \ + { \ + (iob)->io_flink = (ieee)->i_framelist; \ + (ieee)->i_framelist = (iob); \ + } \ + while (0) + /**************************************************************************** * Public Types ****************************************************************************/ @@ -305,18 +362,20 @@ struct rimeaddr_s * difference is that fragmentation must be supported. * * The IEEE802.15.4 MAC does not use the d_buf packet buffer directly. - * Rather, it uses a smaller frame buffer, i_frame. + * Rather, it uses a list smaller frame buffers, i_framelist. * - * - The packet fragment data is provided to the i_frame buffer each time - * that the IEEE802.15.4 MAC needs to send more data. The length of - * the frame is provided in i_frame. + * - The packet fragment data is provided to an IOB in the i_framelist + * buffer each time that the IEEE802.15.4 MAC needs to send more data. + * The length of the frame is provided in the io_len field of the IOB. * - * In this case, the d_buf holds the packet data yet to be sent; d_len - * holds the size of entire packet. + * In this case, the d_buf is not used at all and, if fact, may be + * NULL. * * - Received frames are provided by IEEE802.15.4 MAC to the network - * via i_frame with length i_framelen for reassembly in d_buf; d_len - * will hold the size of the reassembled packet. + * via and IOB in i_framelist with length io_len for reassembly in + * d_buf; d_len will hold the size of the reassembled packet. + * + * In this case, a d_buf of size CONFIG_NET_6LOWPAN_MTU must be provided. * * This is accomplished by "inheriting" the standard 'struct net_driver_s' * and appending the frame buffer as well as other metadata needed to @@ -328,26 +387,49 @@ struct rimeaddr_s * 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 + * 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. - * 4) On network TX poll operations, the IEEE802.15.4 MAC needs to provide - * the i_frame buffer with size greater than or equal to - * CONFIG_NET_6LOWPAN_FRAMELEN. No dev.d_buf need be provided in this - * case. The entire is TX is performed using only the i_frame buffer. - * 5) On network input RX oprations, both buffers must be provided. The size - * of the i_frame buffer is, again, greater than or equal to - * CONFIG_NET_6LOWPAN_FRAMELEN. The larger dev.d_buf must have a size - * of at least the advertised MTU of the protocol, CONFIG_NET_6LOWPAN_MTU. - * If fragmentation is enabled, then the logical packet size may be - * significantly larger than the size of the frame buffer. The dev.d_buf - * is used for de-compressing each frame and reassembling any fragmented - * packets to create the full input packet that is provided to the - * application. * - * Frame Organization: + * 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. + * + * 4. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver + * structure with i_framelist set to NULL. At the conclusion of the + * poll, if there are frames to be sent, they will have been added to + * the i_framelist. The non-empty frame list at the conclusion of the + * TX poll is the indication that is data to be sent. + * + * The IEEE802.15.4 may use the FRAME_IOB_EMPTY() macro to determine + * if there there frames to be sent. If so, it should remove each + * frame from the frame list using the FRAME_IOB_REMOVE() macro and send + * it. That macro will return NULL when all of the frames have been + * sent. + * + * After sending each frame, the driver must return the IOB to the pool + * of free IOBs using the FROM_IOB_FREE() macro. + * + * 5. When receiving data both buffers must be provided: + * + * The IEEE802.15.4 MAC driver should receive the frame data directly + * into the payload area of an IOB structure. That IOB structure may be + * obtained using the FRAME_IOB_ALLOC() macro. The single frame should + * be added to the frame list using FRAME_IOB_ADD() (it will be a list of + * length one). + * + * The larger dev.d_buf must have a size of at least the advertised MTU + * of the protocol, CONFIG_NET_6LOWPAN_MTU. If fragmentation is enabled, + * then the logical packet size may be significantly larger than the + * size of the frame buffer. The dev.d_buf is used for de-compressing + * each frame and reassembling any fragmented packets to create the full + * input packet that is provided to the application. + * + * The MAC driver should then inform the network of the by calling + * sixlowpan_input(). + * + * Frame Organization. The IOB data is retained in the io_data[] field of the + * IOB structure like: * * Content Offset * +------------------+ 0 @@ -355,7 +437,7 @@ struct rimeaddr_s * +------------------+ i_dataoffset * | Procotol Headers | * | Data Payload | - * +------------------+ i_framelen + * +------------------+ io_len * | Unused | * +------------------+ CONFIG_NET_6LOWPAN_FRAMELEN */ @@ -370,31 +452,21 @@ struct ieee802154_driver_s /* IEEE802.15.4 MAC-specific definitions follow. */ - /* The i_frame array is used to hold outgoing frame. When the - * IEEE802.15.4 device polls for new data, the outgoing frame containing - * the next fragment is placed in i_frame. + /* The i_framelist is used to hold a outgoing frames contained in IOB + * structures. When the IEEE802.15.4 device polls for new TX data, the + * outgoing frame(s) containing the packet fragments are placed in IOBs + * and queued in i_framelist. * - * The network will handle only a single outgong frame at a time. The - * IEEE802.15.4 MAC driver design may be concurrently sending and - * requesting new framesusing break-off fram buffers. That frame buffer - * management must be controlled by the IEEE802.15.4 MAC driver. + * The i_framelist is similary used to hold incoming frames in IOB + * structures. The IEEE802.15.4 MAC driver must receive frames in an IOB, + * place the IOB in the i_framelist, and call sixlowpan_input(). * - * Driver provided frame buffers should of size CONFIG_NET_6LOWPAN_FRAMELEN - * and should be 16-bit aligned. + * The IEEE802.15.4 MAC driver design may be concurrently sending and + * requesting new frames using lists of IOBs. That IOB frame buffer + * management must be managed by the IEEE802.15.4 MAC driver. */ - FAR uint8_t *i_frame; - - /* The length of valid data in the i_frame buffer. - * - * When the network device driver calls the network input function, - * i_framelen should be set to zero. If there is frame to be sent - * by the network, i_framelen will be set to indicate the size of - * frame to be sent. The value zero means that there is no frame - * to be sent. - */ - - uint16_t i_framelen; + FAR struct iob_s *i_framelist; /* 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 diff --git a/net/sixlowpan/sixlowpan_framer.c b/net/sixlowpan/sixlowpan_framer.c index 2b528dea10d..3c753f35308 100644 --- a/net/sixlowpan/sixlowpan_framer.c +++ b/net/sixlowpan/sixlowpan_framer.c @@ -277,9 +277,10 @@ static int sixlowpan_802154_hdrlen(FAR struct frame802154_s *finfo) * * Input parameters: * ieee - A reference IEEE802.15.4 MAC network device structure. - * params - Where to put the parmeters + * iob - The IOB in which to create the frame. * dest_panid - PAN ID of the destination. May be 0xffff if the destination * is not associated. + * params - Where to put the parmeters * * Returned Value: * None. @@ -287,8 +288,8 @@ static int sixlowpan_802154_hdrlen(FAR struct frame802154_s *finfo) ****************************************************************************/ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee, - FAR struct frame802154_s *params, - uint16_t dest_panid) + FAR struct iob_s *iob, uint16_t dest_panid, + FAR struct frame802154_s *params) { bool rcvrnull; @@ -298,7 +299,6 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee, /* Reset to an empty frame */ - ieee->i_framelen = 0; ieee->i_dataoffset = 0; /* Build the FCF (Only non-zero elements need to be initialized). */ @@ -370,10 +370,13 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee, rimeaddr_copy((struct rimeaddr_s *)¶ms->src_addr, &ieee->i_nodeaddr.u8); - /* Configure the payload address and length */ + /* Configure the (optional) payload address and length */ - params->payload = FRAME_DATA_START(ieee); - params->payload_len = FRAME_DATA_SIZE(ieee); + if (iob != NULL) + { + params->payload = FRAME_DATA_START(ieee, iob); + params->payload_len = FRAME_DATA_SIZE(ieee, iob); + } } /**************************************************************************** @@ -406,7 +409,7 @@ int sixlowpan_hdrlen(FAR struct ieee802154_driver_s *ieee, /* Set up the frame parameters */ - sixlowpan_setup_params(ieee, ¶ms, dest_panid); + sixlowpan_setup_params(ieee, NULL, dest_panid, ¶ms); /* Return the length of the header */ @@ -521,6 +524,7 @@ int sixlowpan_802154_framecreate(FAR struct frame802154_s *finfo, * * Input parameters: * ieee - A reference IEEE802.15.4 MAC network device structure. + * iob - The IOB in which to create the frame. * dest_panid - PAN ID of the destination. May be 0xffff if the destination * is not associated. * @@ -531,7 +535,7 @@ int sixlowpan_802154_framecreate(FAR struct frame802154_s *finfo, ****************************************************************************/ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee, - uint16_t dest_panid) + FAR struct iob_s *iob, uint16_t dest_panid) { struct frame802154_s params; int len; @@ -539,7 +543,7 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee, /* Set up the frame parameters */ - sixlowpan_setup_params(ieee, ¶ms, dest_panid); + sixlowpan_setup_params(ieee, iob, dest_panid, ¶ms); /* Get the length of the header */ @@ -547,7 +551,7 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee, /* Allocate space for the header in the frame buffer */ - ret = sixlowpan_frame_hdralloc(ieee, len); + ret = sixlowpan_frame_hdralloc(ieee, iob, len); if (ret < 0) { wlerr("ERROR: Header too large: %u\n", len); @@ -556,11 +560,11 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee, /* Then create the frame */ - sixlowpan_802154_framecreate(¶ms, FRAME_HDR_START(ieee), len); + sixlowpan_802154_framecreate(¶ms, FRAME_HDR_START(ieee, iob), len); wlinfo("Frame type: %02x Data len: %d %u (%u)\n", - params.fcf.frame_type, len, FRAME_DATA_SIZE(ieee), - FRAME_SIZE(ieee)); + params.fcf.frame_type, len, FRAME_DATA_SIZE(ieee, iob), + FRAME_SIZE(ieee, iob)); #if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2 wlinfo("Dest address: %02x:%02x\n", params.dest_addr[0], params.dest_addr[1]); diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index 6828c141285..a1166aed353 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -87,24 +87,23 @@ do \ { \ (ieee)->i_dataoffset = 0; \ - (ieee)->i_framelen = 0; \ } \ while (0) -#define FRAME_HDR_START(ieee) \ - ((ieee)->i_frame) -#define FRAME_HDR_SIZE(ieee) \ +#define FRAME_HDR_START(ieee,iob) \ + ((iob)->io_data) +#define FRAME_HDR_SIZE(ieee,iob) \ ((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_DATA_START(ieee,iob) \ + ((FAR uint8_t *)((iob)->io_data) + (ieee)->i_dataoffset) +#define FRAME_DATA_SIZE(ieee,iob) \ + ((iob)->io_len - (ieee)->i_dataoffset) -#define FRAME_REMAINING(ieee) \ - (CONFIG_NET_6LOWPAN_FRAMELEN - (ieee)->i_framelen) -#define FRAME_SIZE(ieee) \ - ((ieee)->i_framelen) +#define FRAME_REMAINING(ieee,iob) \ + (CONFIG_NET_6LOWPAN_FRAMELEN - (iob)->io_len) +#define FRAME_SIZE(ieee,iob) \ + ((iob)->io_len) /* These are some definitions of element values used in the FCF. See the * IEEE802.15.4 spec for details. @@ -254,6 +253,7 @@ extern FAR struct sixlowpan_rime_sniffer_s *g_sixlowpan_sniffer; struct net_driver_s; /* Forward reference */ struct ieee802154_driver_s; /* Forward reference */ struct rimeaddr_s; /* Forward reference */ +struct iob_s; /* Forward reference */ /**************************************************************************** * Name: sixlowpan_send @@ -263,12 +263,11 @@ struct rimeaddr_s; /* Forward reference */ * it to be sent on an 802.15.4 network using 6lowpan. Called from common * UDP/TCP send logic. * - * The payload data is in the caller 'buf' and is of length 'len'. - * Compressed headers will be added and if necessary the packet is - * fragmented. The resulting packet/fragments are put in dev->d_buf and - * the first frame will be delivered to the 802.15.4 MAC. via ieee->i_frame. - * - * Input Parmeters: + * The payload data is in the caller 'buf' and is of length 'len'. + * Compressed headers will be added and if necessary the packet is + * fragmented. The resulting packet/fragments are put in ieee->i_framelist + * and the entire list of frames will be delivered to the 802.15.4 MAC via + * ieee->i_framelist. * * Input Parameters: * dev - The IEEE802.15.4 MAC network driver interface. @@ -323,6 +322,7 @@ int sixlowpan_hdrlen(FAR struct ieee802154_driver_s *ieee, * * Input parameters: * ieee - A reference IEEE802.15.4 MAC network device structure. + * iob - The IOB in which to create the frame. * dest_panid - PAN ID of the destination. May be 0xffff if the destination * is not associated. * @@ -333,7 +333,7 @@ int sixlowpan_hdrlen(FAR struct ieee802154_driver_s *ieee, ****************************************************************************/ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee, - uint16_t dest_panid); + FAR struct iob_s *iob, uint16_t dest_panid); /**************************************************************************** * Name: sixlowpan_hc06_initialize @@ -474,12 +474,12 @@ void sixlowpan_uncompresshdr_hc1(FAR struct net_driver_s *dev, * Name: sixlowpan_frame_hdralloc * * Description: - * Allocate space for a header within the frame buffer (i_frame). + * Allocate space for a header within the frame buffer (IOB). * ****************************************************************************/ int sixlowpan_frame_hdralloc(FAR struct ieee802154_driver_s *ieee, - int size); + FAR struct iob_s *iob, int size); #endif /* CONFIG_NET_6LOWPAN */ #endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */ diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index ad72cce3836..1b8ab0e07d2 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -218,7 +218,7 @@ static int sixlowpan_send_frame(FAR struct ieee802154_driver_s *ieee, #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; + iob->io_len = 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 */ @@ -240,12 +240,11 @@ static int sixlowpan_send_frame(FAR struct ieee802154_driver_s *ieee, * it to be sent on an 802.15.4 network using 6lowpan. Called from common * UDP/TCP send logic. * - * The payload data is in the caller 'buf' and is of length 'len'. - * Compressed headers will be added and if necessary the packet is - * fragmented. The resulting packet/fragments are put in dev->d_buf and - * the first frame will be delivered to the 802.15.4 MAC. via ieee->i_frame. - * - * Input Parmeters: + * The payload data is in the caller 'buf' and is of length 'len'. + * Compressed headers will be added and if necessary the packet is + * fragmented. The resulting packet/fragments are put in ieee->i_framelist + * and the entire list of frames will be delivered to the 802.15.4 MAC via + * ieee->i_framelist. * * Input Parameters: * dev - The IEEE802.15.4 MAC network driver interface. @@ -380,7 +379,7 @@ int sixlowpan_send(FAR struct net_driver_s *dev, { /* Failed to determine the size of the header failed. */ - nerr("ERROR: sixlowpan_framecreate() failed: %d\n", framer_hdrlen); + nerr("ERROR: sixlowpan_hdrlen() failed: %d\n", framer_hdrlen); return framer_hdrlen; } diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c index f00eaeae4c3..946fc919711 100644 --- a/net/sixlowpan/sixlowpan_utils.c +++ b/net/sixlowpan/sixlowpan_utils.c @@ -44,7 +44,9 @@ * SUCH DAMAGE. * ****************************************************************************/ -/* Frame Organization: + +/* Frame Organization. The IOB data is retained in the io_data[] field of the + * IOB structure like: * * Content Offset * +------------------+ 0 @@ -52,7 +54,7 @@ * +------------------+ i_dataoffset * | Procotol Headers | * | Data Payload | - * +------------------+ i_framelen + * +------------------+ io_len * | Unused | * +------------------+ CONFIG_NET_6LOWPAN_FRAMELEN */ @@ -85,12 +87,12 @@ ****************************************************************************/ int sixlowpan_frame_hdralloc(FAR struct ieee802154_driver_s *ieee, - int size) + FAR struct iob_s *iob, int size) { - if (size <= FRAME_REMAINING(ieee)) + if (size <= FRAME_REMAINING(ieee, iob)) { ieee->i_dataoffset += size; - ieee->i_framelen += size; + iob->io_len += size; return OK; }