Squashed commit of the following:
Merged in merlin17/nuttx/mac802154-sock (pull request #479) wireless/ieee802154: Adds support for receiving MAC events via IOCTL through socket interface. Other small fixes and cleanup * ioctl: Cleans up MAC802154IOC values * wireless/ieee802154: Cleans up MAC802154IOC_NOTIFY_REGISTER logic in character driver * wireless/ieee802154/mac802154_netdev: Adds support for MAC event notification via IOCTL * wireless/ieee802154/mac802154: Changes reset logic. No longer reset extended address. * wireless/ieee802154: Cleans up MAC802154IOC logic Moves MAC802154IOC from ieee802154_ioctl.h and renames ieee802154_ioctl.h to ieee802154_device.h since it only contains types relevant to the MAC char device now. * wireless/ieee802154/mac802154_device: Cleans up IOCTL logic for recent changes. * drivers/wireless/ieee802154/mrf24j40: Adds missing break in case statement * wireless/ieee802154/mac802154_netdev: Starts adding support for passing MAC events via IOCTL * wireless/ieee802154/mac802154: Fixes issue with receiver enable logic * wireless/ieee802154/mac802154: Fixes issue where extended address is cleared and not rewritten after radio reset * configs/clicker2-stm32/mrf24j40-mac: Enables RAMLOG and wireless driver logging * wireless/ieee802154/mac802154: Fixes poll logic meant to automatically choose address mode based on short address range. Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
parent
37a29cf3a3
commit
9af6b7cdae
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
@ -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)
|
||||
|
@ -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
|
||||
************************************************************************************/
|
||||
|
@ -70,12 +70,6 @@
|
||||
|
||||
# include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
|
||||
#ifdef CONFIG_IEEE802154_MAC_DEV
|
||||
/* Include ieee802.15.4 character driver IOCTL definitions */
|
||||
|
||||
# include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_WIRELESS_IEEE802154 */
|
||||
#endif /* CONFIG_NSOCKET_DESCRIPTORS > 0 */
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
|
||||
#include <nuttx/mm/iob.h>
|
||||
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_device.h>
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
|
||||
#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 */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user