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:
parent
2ece0c57dd
commit
4ec14bb2e4
@ -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);
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user