diff --git a/configs/clicker2-stm32/mrf24j40-mac/defconfig b/configs/clicker2-stm32/mrf24j40-mac/defconfig index 109b2bc704..2b48ad0f11 100644 --- a/configs/clicker2-stm32/mrf24j40-mac/defconfig +++ b/configs/clicker2-stm32/mrf24j40-mac/defconfig @@ -9,6 +9,14 @@ CONFIG_ARCH_STACKDUMP=y CONFIG_BOARD_INITIALIZE=y CONFIG_BOARD_LOOPSPERMSEC=16717 CONFIG_BUILTIN=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_WARN=y +CONFIG_DEBUG_WIRELESS_ERROR=y +CONFIG_DEBUG_WIRELESS_INFO=y +CONFIG_DEBUG_WIRELESS_WARN=y +CONFIG_DEBUG_WIRELESS=y CONFIG_DISABLE_POLL=y CONFIG_DRIVERS_IEEE802154=y CONFIG_DRIVERS_WIRELESS=y @@ -41,6 +49,8 @@ CONFIG_NSH_READLINE=y CONFIG_PREALLOC_MQ_MSGS=4 CONFIG_PREALLOC_TIMERS=4 CONFIG_PREALLOC_WDOGS=8 +CONFIG_RAMLOG_SYSLOG=y +CONFIG_RAMLOG=y CONFIG_RAM_SIZE=131072 CONFIG_RAM_START=0x20000000 CONFIG_RAW_BINARY=y diff --git a/drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.c b/drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.c index a6dc0c6e0f..8d9a70c4c4 100644 --- a/drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.c +++ b/drivers/wireless/ieee802154/mrf24j40/mrf24j40_radif.c @@ -549,6 +549,7 @@ int mrf24j40_getattr(FAR struct ieee802154_radio_s *radio, attrval->phy.chan = dev->chan; ret = IEEE802154_STATUS_SUCCESS; } + break; default: ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE; diff --git a/include/nuttx/wireless/ieee802154/ieee802154_ioctl.h b/include/nuttx/wireless/ieee802154/ieee802154_device.h similarity index 77% rename from include/nuttx/wireless/ieee802154/ieee802154_ioctl.h rename to include/nuttx/wireless/ieee802154/ieee802154_device.h index f14ce00559..f09e7075d1 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_ioctl.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_device.h @@ -1,6 +1,6 @@ /************************************************************************************ - * include/nuttx/wireless/ieee802154/ieee802154_ioctl.h - * IEEE802.15.4 character driver IOCTL commands + * include/nuttx/wireless/ieee802154/ieee802154_device.h + * IEEE802.15.4 character driver * * Copyright (C) 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -34,12 +34,8 @@ * ************************************************************************************/ -/* This file includes common definitions to be used in all wireless character drivers - * (when applicable). - */ - -#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_IOCTL_H -#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_IOCTL_H +#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_DEVICE_H +#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_DEVICE_H /************************************************************************************ * Included Files @@ -56,21 +52,10 @@ * Pre-processor Definitions ************************************************************************************/ -/* IEEE 802.15.4 MAC Character Driver IOCTL commands ********************************/ - -#define MAC802154IOC_NOTIFY_REGISTER _WLCIOC(IEEE802154_FIRST) -#define MAC802154IOC_GET_EVENT _WLCIOC(IEEE802154_FIRST+1) -#define MAC802154IOC_ENABLE_EVENTS _WLCIOC(IEEE802154_FIRST+2) - /************************************************************************************ * Public Types ************************************************************************************/ -struct mac802154dev_notify_s -{ - uint8_t mn_signo; /* Signal number to use in the notification */ -}; - struct mac802154dev_txframe_s { struct ieee802154_frame_meta_s meta; @@ -86,4 +71,4 @@ struct mac802154dev_rxframe_s }; #endif /* CONFIG_WIRELESS_IEEE802154 */ -#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_IOCTL_H */ +#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_DEVICE_H */ diff --git a/include/nuttx/wireless/ieee802154/ieee802154_mac.h b/include/nuttx/wireless/ieee802154/ieee802154_mac.h index 22e26bd07f..87a387c394 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_mac.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_mac.h @@ -125,22 +125,28 @@ * Request and Response primitives. */ -#define MAC802154IOC_MLME_ASSOC_REQUEST _MAC802154IOC(0x0003) -#define MAC802154IOC_MLME_ASSOC_RESPONSE _MAC802154IOC(0x0004) -#define MAC802154IOC_MLME_DISASSOC_REQUEST _MAC802154IOC(0x0005) -#define MAC802154IOC_MLME_GET_REQUEST _MAC802154IOC(0x0006) -#define MAC802154IOC_MLME_GTS_REQUEST _MAC802154IOC(0x0007) -#define MAC802154IOC_MLME_ORPHAN_RESPONSE _MAC802154IOC(0x0008) -#define MAC802154IOC_MLME_RESET_REQUEST _MAC802154IOC(0x0009) -#define MAC802154IOC_MLME_RXENABLE_REQUEST _MAC802154IOC(0x000A) -#define MAC802154IOC_MLME_SCAN_REQUEST _MAC802154IOC(0x000B) -#define MAC802154IOC_MLME_SET_REQUEST _MAC802154IOC(0x000C) -#define MAC802154IOC_MLME_START_REQUEST _MAC802154IOC(0x000D) -#define MAC802154IOC_MLME_SYNC_REQUEST _MAC802154IOC(0x000E) -#define MAC802154IOC_MLME_POLL_REQUEST _MAC802154IOC(0x000F) -#define MAC802154IOC_MLME_DPS_REQUEST _MAC802154IOC(0x0010) -#define MAC802154IOC_MLME_SOUNDING_REQUEST _MAC802154IOC(0x0011) -#define MAC802154IOC_MLME_CALIBRATE_REQUEST _MAC802154IOC(0x0012) +#define MAC802154IOC_MLME_ASSOC_REQUEST _MAC802154IOC(0x0000) +#define MAC802154IOC_MLME_ASSOC_RESPONSE _MAC802154IOC(0x0001) +#define MAC802154IOC_MLME_DISASSOC_REQUEST _MAC802154IOC(0x0002) +#define MAC802154IOC_MLME_GET_REQUEST _MAC802154IOC(0x0003) +#define MAC802154IOC_MLME_GTS_REQUEST _MAC802154IOC(0x0004) +#define MAC802154IOC_MLME_ORPHAN_RESPONSE _MAC802154IOC(0x0005) +#define MAC802154IOC_MLME_RESET_REQUEST _MAC802154IOC(0x0006) +#define MAC802154IOC_MLME_RXENABLE_REQUEST _MAC802154IOC(0x0007) +#define MAC802154IOC_MLME_SCAN_REQUEST _MAC802154IOC(0x0008) +#define MAC802154IOC_MLME_SET_REQUEST _MAC802154IOC(0x0009) +#define MAC802154IOC_MLME_START_REQUEST _MAC802154IOC(0x000A) +#define MAC802154IOC_MLME_SYNC_REQUEST _MAC802154IOC(0x000B) +#define MAC802154IOC_MLME_POLL_REQUEST _MAC802154IOC(0x000C) +#define MAC802154IOC_MLME_DPS_REQUEST _MAC802154IOC(0x000D) +#define MAC802154IOC_MLME_SOUNDING_REQUEST _MAC802154IOC(0x000E) +#define MAC802154IOC_MLME_CALIBRATE_REQUEST _MAC802154IOC(0x000F) + +/* Non-standard MAC ioctl calls */ + +#define MAC802154IOC_NOTIFY_REGISTER _MAC802154IOC(0x00FD) +#define MAC802154IOC_GET_EVENT _MAC802154IOC(0x00FE) +#define MAC802154IOC_ENABLE_EVENTS _MAC802154IOC(0x00FF) /* IEEE 802.15.4 MAC Interface **********************************************/ @@ -1579,6 +1585,10 @@ union ieee802154_macarg_u /* To be determined */ /* MAC802154IOC_MLME_DPS_REQUEST */ /* To be determined */ /* MAC802154IOC_MLME_SOUNDING_REQUEST */ /* To be determined */ /* MAC802154IOC_MLME_CALIBRATE_REQUEST */ + + uint8_t signo; /* MAC802154IOC_NOTIFY_REGISTER */ + struct ieee802154_notif_s notif; /* MAC802154IOC_GET_EVENT */ + bool enable; /* MAC802154IOC_ENABLE_EVENTS */ }; #if defined(CONFIG_NET_6LOWPAN) || defined(CONFIG_NET_IEEE802154) diff --git a/include/nuttx/wireless/ioctl.h b/include/nuttx/wireless/ioctl.h index 1d9c38dd8d..ea3abc0e1c 100644 --- a/include/nuttx/wireless/ioctl.h +++ b/include/nuttx/wireless/ioctl.h @@ -96,11 +96,6 @@ #define NRF24L01_FIRST (CC3000_FIRST + CC3000_NCMDS) #define NRF24L01_NCMDS 14 -/* See include/nuttx/wireless/ieee802154/ieee802154_ioctl.h */ - -#define IEEE802154_FIRST (NRF24L01_FIRST + NRF24L01_NCMDS) -#define IEEE802154_NCMDS 2 - /************************************************************************************ * Public Types ************************************************************************************/ diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h index ded8c5a659..6eaa352582 100644 --- a/include/sys/ioctl.h +++ b/include/sys/ioctl.h @@ -70,12 +70,6 @@ # include -#ifdef CONFIG_IEEE802154_MAC_DEV -/* Include ieee802.15.4 character driver IOCTL definitions */ - -# include -#endif - #endif /* CONFIG_WIRELESS_IEEE802154 */ #endif /* CONFIG_NSOCKET_DESCRIPTORS > 0 */ diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c index 7bc0d6c4c9..fc16cba0ec 100644 --- a/wireless/ieee802154/mac802154.c +++ b/wireless/ieee802154/mac802154.c @@ -344,7 +344,7 @@ void mac802154_createdatareq(FAR struct ieee802154_privmac_s *priv, txdesc->frame = iob; txdesc->frametype = IEEE802154_FRAME_COMMAND; - /* Save a copy of the destination addressing infromation into the tx descriptor. + /* Save a copy of the destination addressing information into the tx descriptor. * We only do this for commands to help with handling their progession. */ @@ -1384,8 +1384,7 @@ static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv, } else if (txdesc->destaddr.mode == IEEE802154_ADDRMODE_EXTENDED) { - if (memcmp(&txdesc->destaddr.eaddr[0], &ind->src.eaddr[0], - sizeof(IEEE802154_EADDRSIZE)) == 0) + if (IEEE802154_EADDRCMP(txdesc->destaddr.eaddr, ind->src.eaddr)) { /* Remove the transaction from the queue */ diff --git a/wireless/ieee802154/mac802154_device.c b/wireless/ieee802154/mac802154_device.c index 1d634f9018..d3c689d933 100644 --- a/wireless/ieee802154/mac802154_device.c +++ b/wireless/ieee802154/mac802154_device.c @@ -52,7 +52,7 @@ #include -#include +#include #include #include "mac802154.h" @@ -120,9 +120,9 @@ struct mac802154_chardevice_s #ifndef CONFIG_DISABLE_SIGNALS /* MAC Service notification information */ - bool notify_registered; - struct mac802154dev_notify_s md_notify; - pid_t md_notify_pid; + bool md_notify_registered; + uint8_t md_notify_signo; + pid_t md_notify_pid; #endif }; @@ -620,6 +620,8 @@ static int mac802154dev_ioctl(FAR struct file *filep, int cmd, { FAR struct inode *inode; FAR struct mac802154_chardevice_s *dev; + FAR union ieee802154_macarg_u *macarg = + (FAR union ieee802154_macarg_u *)((uintptr_t)arg); int ret; DEBUGASSERT(filep != NULL && filep->f_priv != NULL && @@ -637,47 +639,32 @@ static int mac802154dev_ioctl(FAR struct file *filep, int cmd, return ret; } - /* Handle the ioctl command */ - switch (cmd) { #ifndef CONFIG_DISABLE_SIGNALS - /* Command: MAC802154IOC_MLME_REGISTER, MAC802154IOC_MCPS_REGISTER + /* Command: MAC802154IOC_NOTIFY_REGISTER * Description: Register to receive a signal whenever there is a * event primitive sent from the MAC layer. - * Argument: A read-only pointer to an instance of struct - * mac802154dev_notify_s + * Argument: The signal number to use. * Return: Zero (OK) on success. Minus one will be returned on * failure with the errno value set appropriately. */ case MAC802154IOC_NOTIFY_REGISTER: { - FAR struct mac802154dev_notify_s *notify = - (FAR struct mac802154dev_notify_s *)((uintptr_t)arg); + /* Save the notification events */ - if (notify) - { - /* Save the notification events */ + dev->md_notify_signo = macarg->signo; + dev->md_notify_pid = getpid(); + dev->md_notify_registered = true; - dev->md_notify.mn_signo = notify->mn_signo; - dev->md_notify_pid = getpid(); - dev->notify_registered = true; - - ret = OK; - } - else - { - ret = -EINVAL; - } + ret = OK; } break; #endif case MAC802154IOC_GET_EVENT: { - FAR struct ieee802154_notif_s *usr_notif = - (FAR struct ieee802154_notif_s *)((uintptr_t)arg); FAR struct ieee802154_notif_s *notif; while (1) @@ -692,7 +679,7 @@ static int mac802154dev_ioctl(FAR struct file *filep, int cmd, if (notif != NULL) { - memcpy(usr_notif, notif, sizeof(struct ieee802154_notif_s)); + memcpy(&macarg->notif, notif, sizeof(struct ieee802154_notif_s)); /* Free the notification */ @@ -743,7 +730,7 @@ static int mac802154dev_ioctl(FAR struct file *filep, int cmd, case MAC802154IOC_ENABLE_EVENTS: { - dev->enableevents = (bool)arg; + dev->enableevents = macarg->enable; ret = OK; } break; @@ -782,7 +769,7 @@ static void mac802154dev_notify(FAR struct mac802154_maccb_s *maccb, * notifications. */ - if (dev->enableevents && (dev->md_open != NULL || dev->notify_registered)) + if (dev->enableevents && (dev->md_open != NULL || dev->md_notify_registered)) { mac802154dev_pushevent(dev, notif); @@ -797,15 +784,15 @@ static void mac802154dev_notify(FAR struct mac802154_maccb_s *maccb, } #ifndef CONFIG_DISABLE_SIGNALS - if (dev->notify_registered) + if (dev->md_notify_registered) { #ifdef CONFIG_CAN_PASS_STRUCTS union sigval value; value.sival_int = (int)notif->notiftype; - (void)sigqueue(dev->md_notify_pid, dev->md_notify.mn_signo, value); + (void)sigqueue(dev->md_notify_pid, dev->md_notify_signo, value); #else - (void)sigqueue(dev->md_notify_pid, dev->md_notify.mn_signo, + (void)sigqueue(dev->md_notify_pid, dev->md_notify_signo, (FAR void *)notif->notiftype); #endif } @@ -928,7 +915,7 @@ int mac802154dev_register(MACHANDLE mac, int minor) dev->event_tail = NULL; dev->enableevents = true; - dev->notify_registered = false; + dev->md_notify_registered = false; /* Initialize the MAC callbacks */ diff --git a/wireless/ieee802154/mac802154_internal.h b/wireless/ieee802154/mac802154_internal.h index 58301bca5a..f54d70dc6a 100644 --- a/wireless/ieee802154/mac802154_internal.h +++ b/wireless/ieee802154/mac802154_internal.h @@ -797,7 +797,7 @@ static inline void mac802154_setcoordaddr(FAR struct ieee802154_privmac_s *priv, static inline void mac802154_setrxonidle(FAR struct ieee802154_privmac_s *priv, bool rxonidle) { - priv->rxonidle = true; + priv->rxonidle = rxonidle; if (priv->rxonidle) { mac802154_rxenable(priv); diff --git a/wireless/ieee802154/mac802154_netdev.c b/wireless/ieee802154/mac802154_netdev.c index 4d7f2a9c00..54f4d8f942 100644 --- a/wireless/ieee802154/mac802154_netdev.c +++ b/wireless/ieee802154/mac802154_netdev.c @@ -140,15 +140,32 @@ struct macnet_driver_s /* This holds the information visible to the NuttX network */ struct radio_driver_s md_dev; /* Interface understood by the network */ - /* Cast compatible with struct macnet_driver_s */ + /* Cast compatible with struct macnet_driver_s */ /* For internal use by this driver */ + sem_t md_exclsem; /* Exclusive access to struct */ struct macnet_callback_s md_cb; /* Callback information */ MACHANDLE md_mac; /* Contained MAC interface */ bool md_bifup; /* true:ifup false:ifdown */ WDOG_ID md_txpoll; /* TX poll timer */ struct work_s md_pollwork; /* Defer poll work to the work queue */ + + /* Hold a list of events */ + + bool md_enableevents : 1; /* Are events enabled? */ + bool md_eventpending : 1; /* Is there a get event using the semaphore? */ + sem_t md_eventsem; /* Signaling semaphore for waiting get event */ + FAR struct ieee802154_notif_s *md_eventhead; + FAR struct ieee802154_notif_s *md_eventtail; + +#ifndef CONFIG_DISABLE_SIGNALS + /* MAC Service notification information */ + + bool md_notify_registered; + uint8_t md_notify_signo; + pid_t md_notify_pid; +#endif }; /**************************************************************************** @@ -160,6 +177,11 @@ struct macnet_driver_s static int macnet_advertise(FAR struct net_driver_s *dev); static inline void macnet_netmask(FAR struct net_driver_s *dev); +static inline void macnet_pushevent(FAR struct macnet_driver_s *priv, + FAR struct ieee802154_notif_s *notif); +static inline FAR struct ieee802154_notif_s * + macnet_popevent(FAR struct macnet_driver_s *priv); + /* IEE802.15.4 MAC callback functions ***************************************/ static void macnet_notify(FAR struct mac802154_maccb_s *maccb, @@ -167,11 +189,6 @@ static void macnet_notify(FAR struct mac802154_maccb_s *maccb, static int macnet_rxframe(FAR struct mac802154_maccb_s *maccb, FAR struct ieee802154_data_ind_s *ind); -/* Asynchronous confirmations to requests (most not implemented) */ - -static void macnet_conf_data(FAR struct macnet_driver_s *priv, - FAR const struct ieee802154_data_conf_s *conf); - /* Asynchronous event indications, replied to synchronously with responses. * (none are implemented). */ @@ -371,6 +388,63 @@ static inline void macnet_netmask(FAR struct net_driver_s *dev) #endif } +/**************************************************************************** + * Name: macnet_pushevent + * + * Description: + * Push event onto the event queue + * + * Assumptions: + * Called with the device struct locked. + * + ****************************************************************************/ + +static inline void macnet_pushevent(FAR struct macnet_driver_s *priv, + FAR struct ieee802154_notif_s *notif) +{ + notif->flink = NULL; + if (!priv->md_eventhead) + { + priv->md_eventhead = notif; + priv->md_eventtail = notif; + } + else + { + priv->md_eventtail->flink = notif; + priv->md_eventtail = notif; + } +} + +/**************************************************************************** + * Name: macnet_popevent + * + * Description: + * Pop an event off of the event queue + * + * Assumptions: + * Called with the device struct locked. + * + ****************************************************************************/ + +static inline FAR struct ieee802154_notif_s * + macnet_popevent(FAR struct macnet_driver_s *priv) +{ + FAR struct ieee802154_notif_s *notif = priv->md_eventhead; + + if (notif) + { + priv->md_eventhead = notif->flink; + if (!priv->md_eventhead) + { + priv->md_eventhead = NULL; + } + + notif->flink = NULL; + } + + return notif; +} + /**************************************************************************** * Name: macnet_notify * @@ -388,21 +462,55 @@ static void macnet_notify(FAR struct mac802154_maccb_s *maccb, DEBUGASSERT(cb != NULL && cb->mc_priv != NULL); priv = cb->mc_priv; - switch (notif->notiftype) - { - case IEEE802154_NOTIFY_CONF_DATA: - { - macnet_conf_data(priv, ¬if->u.dataconf); - } - break; + /* Get exclusive access to the driver structure. We don't care about any + * signals so if we see one, just go back to trying to get access again */ - default: - break; + while (sem_wait(&priv->md_exclsem) < 0); + + /* If there is a registered notification receiver, queue the event and signal + * the receiver. Events should be popped from the queue from the application + * at a reasonable rate in order for the MAC layer to be able to allocate new + * notifications. + */ + + if (priv->md_enableevents) + { + macnet_pushevent(priv, notif); + + /* Check if there is a read waiting for data */ + + if (priv->md_eventpending) + { + /* Wake the thread waiting for the data transmission */ + + priv->md_eventpending = false; + sem_post(&priv->md_eventsem); + } + +#ifndef CONFIG_DISABLE_SIGNALS + if (priv->md_notify_registered) + { +#ifdef CONFIG_CAN_PASS_STRUCTS + union sigval value; + value.sival_int = (int)notif->notiftype; + (void)sigqueue(priv->md_notify_pid, priv->md_notify_signo, value); +#else + (void)sigqueue(priv->md_notify_pid, priv->md_notify_signo, + (FAR void *)notif->notiftype); +#endif + } +#endif + } + else + { + /* Just free the event if the driver is closed and there isn't a registered + * signal number. + */ + + mac802154_notif_free(priv->md_mac, notif); } - /* Free the event notification */ - - mac802154_notif_free(priv->md_mac, notif); + sem_post(&priv->md_exclsem); } /**************************************************************************** @@ -504,19 +612,6 @@ static int macnet_rxframe(FAR struct mac802154_maccb_s *maccb, return OK; } -/**************************************************************************** - * Name: macnet_conf_data - * - * Description: - * Data frame was received by remote device - * - ****************************************************************************/ - -static void macnet_conf_data(FAR struct macnet_driver_s *priv, - FAR const struct ieee802154_data_conf_s *conf) -{ -} - /**************************************************************************** * Name: macnet_txpoll_callback * @@ -993,6 +1088,13 @@ static int macnet_ioctl(FAR struct net_driver_s *dev, int cmd, FAR struct macnet_driver_s *priv = (FAR struct macnet_driver_s *)dev->d_private; int ret = -EINVAL; + ret = sem_wait(&priv->md_exclsem); + if (ret < 0) + { + wlerr("ERROR: sem_wait failed: %d\n", ret); + return ret; + } + /* Check for IOCTLs aimed at the IEEE802.15.4 MAC layer */ if (_MAC802154IOCVALID(cmd)) @@ -1003,7 +1105,100 @@ static int macnet_ioctl(FAR struct net_driver_s *dev, int cmd, if (netmac != NULL) { unsigned long macarg = (unsigned int)((uintptr_t)&netmac->u); - ret = mac802154_ioctl(priv->md_mac, cmd, macarg); + + switch (cmd) + { + #ifndef CONFIG_DISABLE_SIGNALS + /* Command: MAC802154IOC_NOTIFY_REGISTER + * Description: Register to receive a signal whenever there is a + * event primitive sent from the MAC layer. + * Argument: A read-only pointer to an instance of struct + * macnet_notify_s + * Return: Zero (OK) on success. Minus one will be returned on + * failure with the errno value set appropriately. + */ + + case MAC802154IOC_NOTIFY_REGISTER: + { + /* Save the notification events */ + + priv->md_notify_signo = netmac->u.signo; + priv->md_notify_pid = getpid(); + priv->md_notify_registered = true; + ret = OK; + } + break; + #endif + case MAC802154IOC_GET_EVENT: + { + FAR struct ieee802154_notif_s *notif; + + while (1) + { + /* Try popping an event off the queue */ + + notif = macnet_popevent(priv); + + /* If there was an event to pop off, copy it into the user + * data and free it from the MAC layer's memory. + */ + + if (notif != NULL) + { + memcpy(&netmac->u, notif, sizeof(struct ieee802154_notif_s)); + + /* Free the notification */ + + mac802154_notif_free(priv->md_mac, notif); + ret = OK; + break; + } + + /* There can only be one getevent pending at a time */ + + if (priv->md_eventpending) + { + ret = -EAGAIN; + break; + } + + priv->md_eventpending = true; + sem_post(&priv->md_exclsem); + + /* Wait to be signaled when an event is queued */ + + if (sem_wait(&priv->md_eventsem) < 0) + { + DEBUGASSERT(errno == EINTR); + priv->md_eventpending = false; + return -EINTR; + } + + /* Get exclusive access again, then loop back around and try and + * pop an event off the queue + */ + + ret = sem_wait(&priv->md_exclsem); + if (ret < 0) + { + wlerr("ERROR: sem_wait failed: %d\n", ret); + return ret; + } + } + } + break; + case MAC802154IOC_ENABLE_EVENTS: + { + priv->md_enableevents = netmac->u.enable; + ret = OK; + } + break; + default: + { + ret = mac802154_ioctl(priv->md_mac, cmd, macarg); + } + break; + } } } @@ -1016,7 +1211,8 @@ static int macnet_ioctl(FAR struct net_driver_s *dev, int cmd, ret = mac802154_ioctl(priv->md_mac, cmd, arg); } - return ret; + sem_post(&priv->md_exclsem); + return ret; } #endif @@ -1262,6 +1458,10 @@ int mac802154netdev_register(MACHANDLE mac) priv->md_mac = mac; /* Save the MAC interface instance */ priv->md_txpoll = wd_create(); /* Create periodic poll timer */ + /* Setup a locking semaphore for exclusive device driver access */ + + sem_init(&priv->md_exclsem, 0, 1); + DEBUGASSERT(priv->md_txpoll != NULL); /* Set the network mask. */ @@ -1274,6 +1474,18 @@ int mac802154netdev_register(MACHANDLE mac) radio->r_req_data = macnet_req_data; /* Enqueue frame for transmission */ radio->r_properties = macnet_properties; /* Return radio properies */ + /* Initialize fields related to MAC event handling */ + + priv->md_eventpending = false; + sem_init(&priv->md_eventsem, 0, 0); + sem_setprotocol(&priv->md_eventsem, SEM_PRIO_NONE); + + priv->md_eventhead = NULL; + priv->md_eventtail = NULL; + + priv->md_enableevents = false; + priv->md_notify_registered = false; + /* Initialize the MAC callbacks */ priv->md_cb.mc_priv = priv; diff --git a/wireless/ieee802154/mac802154_poll.c b/wireless/ieee802154/mac802154_poll.c index a7d61f4a0d..c14b409dfd 100644 --- a/wireless/ieee802154/mac802154_poll.c +++ b/wireless/ieee802154/mac802154_poll.c @@ -131,7 +131,7 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req) * shall be used. Extended addressing shall be used otherwise. */ - if (IEEE802154_SADDRCMP(priv->addr.saddr, &IEEE802154_SADDR_BCAST)) + if (priv->addr.saddr[0] >= 0xfe && priv->addr.saddr[1] == 0xff) { mac802154_createdatareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_EXTENDED, txdesc); diff --git a/wireless/ieee802154/mac802154_reset.c b/wireless/ieee802154/mac802154_reset.c index a573df21c8..f48c6bfe98 100644 --- a/wireless/ieee802154/mac802154_reset.c +++ b/wireless/ieee802154/mac802154_reset.c @@ -86,6 +86,12 @@ int mac802154_req_reset(MACHANDLE mac, bool resetattr) if (resetattr) { + /* We do not reset the extended address. The extended address must be + * manually overwritten. + */ + + priv->radio->reset(priv->radio); + priv->isassoc = false; /* Not associated with a PAN */ priv->trackingbeacon = false; /* Not tracking beacon by default */ priv->sfspec.assocpermit = false; /* Dev (if coord) not accepting assoc */ @@ -109,21 +115,22 @@ int mac802154_req_reset(MACHANDLE mac, bool resetattr) priv->trans_persisttime = 0x01F4; - /* Reset the Coordinator address */ + /* Reset the short address and PAN ID. The extended address does not + * get reset but must be set at the radio layer again. The only time the + * MAC layer sets the extended address internally is immediately after + * this function is called in mac802154_create() + */ + + priv->addr.mode = IEEE802154_ADDRMODE_EXTENDED; + mac802154_seteaddr(priv, priv->addr.eaddr); + mac802154_setsaddr(priv, IEEE802154_SADDR_UNSPEC); + mac802154_setpanid(priv, IEEE802154_PANID_UNSPEC); priv->pandesc.coordaddr.mode = IEEE802154_ADDRMODE_NONE; - IEEE802154_PANIDCOPY(priv->pandesc.coordaddr.panid, &IEEE802154_PANID_UNSPEC); - IEEE802154_SADDRCOPY(priv->pandesc.coordaddr.saddr, &IEEE802154_SADDR_UNSPEC); - IEEE802154_EADDRCOPY(priv->pandesc.coordaddr.eaddr, &IEEE802154_EADDR_UNSPEC); + mac802154_setcoordeaddr(priv, IEEE802154_EADDR_UNSPEC); + mac802154_setcoordsaddr(priv, IEEE802154_SADDR_UNSPEC); - /* Reset the device's address */ - - priv->addr.mode = IEEE802154_ADDRMODE_NONE; - IEEE802154_PANIDCOPY(priv->addr.panid, &IEEE802154_PANID_UNSPEC); - IEEE802154_SADDRCOPY(priv->addr.saddr, &IEEE802154_SADDR_UNSPEC); - IEEE802154_EADDRCOPY(priv->addr.eaddr, &IEEE802154_EADDR_UNSPEC); - - priv->radio->reset(priv->radio); + mac802154_setdevmode(priv, IEEE802154_DEVMODE_ENDPOINT); /* The radio is in control of certain attributes, but we keep a mirror * for easy access. Copy in the radio's values now that they've been @@ -133,9 +140,9 @@ int mac802154_req_reset(MACHANDLE mac, bool resetattr) priv->radio->getattr(priv->radio, IEEE802154_ATTR_MAC_MAX_FRAME_WAITTIME, &attr); priv->max_frame_waittime = attr.mac.max_frame_waittime; - - mac802154_setdevmode(priv, IEEE802154_DEVMODE_ENDPOINT); } + priv->nrxusers = 0; + return OK; }