6loWPAN: Add basic call path to interface with the MAC layer through the MAC network driver. Logic has not yet been implemented. This is just a structural change in preparation for additional changes.

This commit is contained in:
Gregory Nutt 2017-05-02 16:03:26 -06:00
parent 2ece0c57dd
commit 4ec14bb2e4
4 changed files with 296 additions and 42 deletions

View File

@ -402,6 +402,8 @@
* frame list.
*/
struct ieee802154_frame_meta_s; /* Forward reference */
struct ieee802154_driver_s
{
/* This definitiona must appear first in the structure definition to
@ -498,6 +500,33 @@ struct ieee802154_driver_s
systime_t i_time;
#endif /* CONFIG_NET_6LOWPAN_FRAG */
/* MAC network driver callback functions **********************************/
/**************************************************************************
* Name: mac802154_get_mhrlen
*
* Description:
* Calculate the MAC header length given the frame meta-data.
*
**************************************************************************/
CODE int (*i_get_mhrlen)(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta);
/**************************************************************************
* Name: mac802154_req_data
*
* Description:
* The MCPS-DATA.request primitive requests the transfer of a data SPDU
* (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
* Confirmation is returned via the
* struct ieee802154_maccb_s->conf_data callback.
*
**************************************************************************/
CODE int (*i_req_data)(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta,
FAR struct iob_s *frames);
};
/****************************************************************************

View File

@ -479,7 +479,7 @@ struct ieee802154_frame_meta_s
enum ieee802154_addr_mode_e src_addr_mode; /* Source Address Mode */
struct ieee802154_addr_s dest_addr; /* Destination Address */
uint8_t msdu_handle; /* Handle assoc. with MSDU */
uint8_t msdu_handle; /* Handle assoc. with MSDU */
/* Number of bytes contained in the MAC Service Data Unit (MSDU)
* to be transmitted by the MAC sublayer enitity

View File

@ -83,6 +83,10 @@
#define LO_WDDELAY (1*CLK_TCK)
/* Fake value for MAC header length */
#define MAC_HDRLEN 9
/****************************************************************************
* Private Types
****************************************************************************/
@ -98,6 +102,8 @@ struct lo_driver_s
uint16_t lo_panid; /* Fake PAN ID for testing */
WDOG_ID lo_polldog; /* TX poll timer */
struct work_s lo_work; /* For deferring poll work to the work queue */
FAR struct iob_s *head; /* Head of IOBs queued for loopback */
FAR struct iob_s *tail; /* Tail of IOBs queued for loopback */
/* This holds the information visible to the NuttX network */
@ -117,33 +123,39 @@ static uint8_t g_iobuffer[CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE];
/* Polling logic */
static int lo_txpoll(FAR struct net_driver_s *dev);
static int lo_loopback(FAR struct net_driver_s *dev);
static void lo_loopback_work(FAR void *arg);
static void lo_poll_work(FAR void *arg);
static void lo_poll_expiry(int argc, wdparm_t arg, ...);
/* NuttX callback functions */
static int lo_ifup(FAR struct net_driver_s *dev);
static int lo_ifdown(FAR struct net_driver_s *dev);
static int lo_ifup(FAR struct net_driver_s *dev);
static int lo_ifdown(FAR struct net_driver_s *dev);
static void lo_txavail_work(FAR void *arg);
static int lo_txavail(FAR struct net_driver_s *dev);
static int lo_txavail(FAR struct net_driver_s *dev);
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
#ifdef CONFIG_NET_IGMP
static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
#endif
#endif
#ifdef CONFIG_NETDEV_IOCTL
static int lo_ioctl(FAR struct net_driver_s *dev, int cmd,
unsigned long arg);
#endif
static int lo_get_mhrlen(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta);
static int lo_req_data(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta,
FAR struct iob_s *frames);
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: lo_txpoll
* Name: lo_loopback
*
* Description:
* Check if the network has any outgoing packets ready to send. This is
@ -162,7 +174,7 @@ static int lo_ioctl(FAR struct net_driver_s *dev, int cmd,
*
****************************************************************************/
static int lo_txpoll(FAR struct net_driver_s *dev)
static int lo_loopback(FAR struct net_driver_s *dev)
{
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private;
FAR struct iob_s *head;
@ -270,6 +282,34 @@ static int lo_txpoll(FAR struct net_driver_s *dev)
return 0;
}
/****************************************************************************
* Name: lo_loopback_work
*
* Description:
* Perform loopback of received frames.
*
* Parameters:
* arg - The argument passed when work_queue() as called.
*
* Returned Value:
* OK on success
*
* Assumptions:
* The network is locked
*
****************************************************************************/
static void lo_loopback_work(FAR void *arg)
{
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)arg;
/* Perform the loopback */
net_lock();
(void)lo_loopback(&priv->lo_ieee.i_dev);
net_unlock();
}
/****************************************************************************
* Name: lo_poll_work
*
@ -295,7 +335,7 @@ static void lo_poll_work(FAR void *arg)
net_lock();
priv->lo_txdone = false;
(void)devif_timer(&priv->lo_ieee.i_dev, lo_txpoll);
(void)devif_timer(&priv->lo_ieee.i_dev, lo_loopback);
/* Was something received and looped back? */
@ -304,7 +344,7 @@ static void lo_poll_work(FAR void *arg)
/* Yes, poll again for more TX data */
priv->lo_txdone = false;
(void)devif_poll(&priv->lo_ieee.i_dev, lo_txpoll);
(void)devif_poll(&priv->lo_ieee.i_dev, lo_loopback);
}
/* Setup the watchdog poll timer again */
@ -458,7 +498,7 @@ static void lo_txavail_work(FAR void *arg)
/* If so, then poll the network for new XMIT data */
priv->lo_txdone = false;
(void)devif_poll(&priv->lo_ieee.i_dev, lo_txpoll);
(void)devif_poll(&priv->lo_ieee.i_dev, lo_loopback);
}
while (priv->lo_txdone);
}
@ -492,8 +532,8 @@ static int lo_txavail(FAR struct net_driver_s *dev)
ninfo("Available: %u\n", work_available(&priv->lo_work));
/* Is our single work structure available? It may not be if there are
* pending interrupt actions and we will have to ignore the Tx
* availability action.
* pending actions and we will have to ignore the Tx availability
* action.
*/
if (work_available(&priv->lo_work))
@ -644,6 +684,92 @@ static int lo_ioctl(FAR struct net_driver_s *dev, int cmd,
}
#endif
/****************************************************************************
* Name: lo_get_mhrlen
*
* Description:
* Calculate the MAC header length given the frame meta-data.
*
****************************************************************************/
static int lo_get_mhrlen(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta)
{
return MAC_HDRLEN;
}
/****************************************************************************
* Name: lo_req_data
*
* Description:
* The MCPS-DATA.request primitive requests the transfer of a data SPDU
* (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
* Confirmation is returned via the
* struct ieee802154_maccb_s->conf_data callback.
*
****************************************************************************/
static int lo_req_data(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta,
FAR struct iob_s *frames)
{
FAR struct lo_driver_s *priv;
FAR struct iob_s *iob;
DEBUGASSERT(netdev != NULL && netdev->i_dev.d_private != NULL && iob != NULL);
priv = (FAR struct lo_driver_s *)netdev->i_dev.d_private;
/* Add the incoming list of frames to queue of frames to loopback */
for (iob = frames; iob != NULL; iob = frames)
{
/* Increment statistics */
NETDEV_RXPACKETS(&priv->lo_ieee.i_dev);
/* Remove the IOB from the queue */
frames = iob->io_flink;
iob->io_flink = NULL;
/* Just zero the MAC header for test purposes */
DEBUGASSERT(iob->io_offset == MAC_HDRLEN);
memset(iob->io_data, 0, MAC_HDRLEN);
/* Add the IOB to the tail of teh queue of frames to be looped back */
if (priv->tail == NULL)
{
priv->head = iob;
}
else
{
priv->tail->io_flink = iob;
}
/* Find the new tail of the IOB queue */
for (priv->tail = iob, iob = iob->io_flink;
iob != NULL;
priv->tail = iob, iob = iob->io_flink);
}
/* Is our single work structure available? It may not be if there are
* pending actions and we will have to ignore the Tx availability
* action.
*/
if (work_available(&priv->lo_work))
{
/* Schedule to serialize the poll on the worker thread. */
work_queue(LPBKWORK, &priv->lo_work, lo_loopback_work, priv, 0);
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -666,7 +792,8 @@ static int lo_ioctl(FAR struct net_driver_s *dev, int cmd,
int ieee8021514_loopback(void)
{
FAR struct lo_driver_s *priv;
FAR struct lo_driver_s *priv;
FAR struct ieee802154_driver_s *ieee;
FAR struct net_driver_s *dev;
ninfo("Initializing\n");
@ -679,27 +806,33 @@ int ieee8021514_loopback(void)
memset(priv, 0, sizeof(struct lo_driver_s));
dev = &priv->lo_ieee.i_dev;
dev->d_ifup = lo_ifup; /* I/F up (new IP address) callback */
dev->d_ifdown = lo_ifdown; /* I/F down callback */
dev->d_txavail = lo_txavail; /* New TX data callback */
ieee = &priv->lo_ieee;
dev = &ieee->i_dev;
dev->d_ifup = lo_ifup; /* I/F up (new IP address) callback */
dev->d_ifdown = lo_ifdown; /* I/F down callback */
dev->d_txavail = lo_txavail; /* New TX data callback */
#ifdef CONFIG_NET_IGMP
dev->d_addmac = lo_addmac; /* Add multicast MAC address */
dev->d_rmmac = lo_rmmac; /* Remove multicast MAC address */
dev->d_addmac = lo_addmac; /* Add multicast MAC address */
dev->d_rmmac = lo_rmmac; /* Remove multicast MAC address */
#endif
#ifdef CONFIG_NETDEV_IOCTL
dev->d_ioctl = lo_ioctl; /* Handle network IOCTL commands */
dev->d_ioctl = lo_ioctl; /* Handle network IOCTL commands */
#endif
dev->d_buf = g_iobuffer; /* Attach the IO buffer */
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
/* Create a watchdog for timing polling for and timing of transmissions */
priv->lo_polldog = wd_create(); /* Create periodic poll timer */
dev->d_buf = g_iobuffer; /* Attach the IO buffer */
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
/* Initialize the DSN to a "random" value */
priv->lo_ieee.i_dsn = 42;
ieee->i_dsn = 42;
/* Initialize the Network frame-related callbacks */
ieee->i_get_mhrlen = lo_get_mhrlen; /* Get MAC header length */
ieee->i_req_data = lo_req_data; /* Enqueue frame for transmission */
/* Create a watchdog for timing polling for and timing of transmissions */
priv->lo_polldog = wd_create(); /* Create periodic poll timer */
/* Register the loopabck device with the OS so that socket IOCTLs can b
* performed.

View File

@ -257,6 +257,11 @@ static void macnet_ipv6multicast(FAR struct macnet_driver_s *priv);
static int macnet_ioctl(FAR struct net_driver_s *dev, int cmd,
unsigned long arg);
#endif
static int macnet_get_mhrlen(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta);
static int macnet_req_data(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta,
FAR struct iob_s *frames);
/****************************************************************************
* Private Functions
@ -1494,6 +1499,86 @@ static int macnet_ioctl(FAR struct net_driver_s *dev, int cmd,
}
#endif
/****************************************************************************
* Name: macnet_get_mhrlen
*
* Description:
* Calculate the MAC header length given the frame meta-data.
*
****************************************************************************/
static int macnet_get_mhrlen(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta)
{
FAR struct macnet_driver_s *priv;
DEBUGASSERT(netdev != NULL && netdev->i_dev.d_private != NULL && iob != NULL);
priv = (FAR struct macnet_driver_s *)netdev->i_dev.d_private;
return mac802154_get_mhrlen(priv->md_mac, meta);
}
/****************************************************************************
* Name: macnet_req_data
*
* Description:
* The MCPS-DATA.request primitive requests the transfer of a data SPDU
* (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
* Confirmation is returned via the
* struct ieee802154_maccb_s->conf_data callback.
*
****************************************************************************/
static int macnet_req_data(FAR struct ieee802154_driver_s *netdev,
FAR struct ieee802154_frame_meta_s *meta,
FAR struct iob_s *frames)
{
FAR struct macnet_driver_s *priv;
struct ieee802154_data_req_s req;
FAR struct iob_s *iob;
int ret;
DEBUGASSERT(netdev != NULL && netdev->i_dev.d_private != NULL && iob != NULL);
priv = (FAR struct macnet_driver_s *)netdev->i_dev.d_private;
/* Add the incoming list of frames to the MAC's outgoing queue */
for (iob = frames; iob != NULL; iob = frames)
{
/* Increment statistics */
NETDEV_RXPACKETS(&priv->lo_ieee.i_dev);
/* Remove the IOB from the queue */
frames = iob->io_flink;
iob->io_flink = NULL;
/* Transfer the frame to the MAC */
req.meta = mets;
req.frame = iob;
ret = mac802154_req_data(priv->md_mac, req);
if (ret < 0)
{
wlerr("ERROR: mac802154_req_data failed: %d\n", ret);
iob_free(iob);
for (iob = frames; ; iob != NULL; iob = frames)
{
/* Remove the IOB from the queue and free */
frames = iob->io_flink;
iob_free(iob);
}
return ret;
}
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -1517,7 +1602,8 @@ static int macnet_ioctl(FAR struct net_driver_s *dev, int cmd,
int mac802154netdev_register(MACHANDLE mac)
{
FAR struct macnet_driver_s *priv;
FAR struct net_driver_s *dev;
FAR struct ieee802154_driver_s *ieee;
FAR struct net_driver_s *dev;
FAR struct ieee802154_maccb_s *maccb;
FAR uint8_t *pktbuf;
int ret;
@ -1549,28 +1635,34 @@ int mac802154netdev_register(MACHANDLE mac)
/* Initialize the driver structure */
dev = &priv->md_dev.i_dev;
dev->d_buf = pktbuf; /* Single packet buffer */
dev->d_ifup = macnet_ifup; /* I/F up (new IP address) callback */
dev->d_ifdown = macnet_ifdown; /* I/F down callback */
dev->d_txavail = macnet_txavail; /* New TX data callback */
ieee = &priv->lo_ieee;
dev = &ieee->i_dev;
dev->d_buf = pktbuf; /* Single packet buffer */
dev->d_ifup = macnet_ifup; /* I/F up (new IP address) callback */
dev->d_ifdown = macnet_ifdown; /* I/F down callback */
dev->d_txavail = macnet_txavail; /* New TX data callback */
#ifdef CONFIG_NET_IGMP
dev->d_addmac = macnet_addmac; /* Add multicast MAC address */
dev->d_rmmac = macnet_rmmac; /* Remove multicast MAC address */
dev->d_addmac = macnet_addmac; /* Add multicast MAC address */
dev->d_rmmac = macnet_rmmac; /* Remove multicast MAC address */
#endif
#ifdef CONFIG_NETDEV_IOCTL
dev->d_ioctl = macnet_ioctl; /* Handle network IOCTL commands */
dev->d_ioctl = macnet_ioctl; /* Handle network IOCTL commands */
#endif
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
/* Create a watchdog for timing polling for and timing of transmisstions */
priv->md_mac = mac; /* Save the MAC interface instance */
priv->md_txpoll = wd_create(); /* Create periodic poll timer */
priv->md_txtimeout = wd_create(); /* Create TX timeout timer */
priv->md_mac = mac; /* Save the MAC interface instance */
priv->md_txpoll = wd_create(); /* Create periodic poll timer */
priv->md_txtimeout = wd_create(); /* Create TX timeout timer */
DEBUGASSERT(priv->md_txpoll != NULL && priv->md_txtimeout != NULL);
/* Initialize the Network frame-related callbacks */
ieee->i_get_mhrlen = macnet_get_mhrlen; /* Get MAC header length */
ieee->i_req_data = macnet_req_data; /* Enqueue frame for transmission */
/* Initialize the MAC callbacks */
priv->md_cb.mc_priv = priv;