6loWPAN: Add an IOCTL to set the IEEE802.15.4 PAN ID

This commit is contained in:
Gregory Nutt 2017-04-19 18:06:43 -06:00
parent 6a2c43b0c1
commit 9281cd558e
5 changed files with 146 additions and 36 deletions

View File

@ -233,6 +233,12 @@
#define _MTDIOCVALID(c) (_IOC_TYPE(c)==_MTDIOCBASE)
#define _MTDIOC(nr) _IOC(_MTDIOCBASE,nr)
/* Socket IOCTLs ************************************************************/
/* See include/nuttx/net/ioctl.h */
#define _SIOCVALID(c) (_IOC_TYPE(c)==_SIOCBASE)
#define _SIOC(nr) _IOC(_SIOCBASE,nr)
/* NuttX ARP driver ioctl definitions (see netinet/arp.h) *******************/
#define _ARPIOCVALID(c) (_IOC_TYPE(c)==_ARPIOCBASE)

View File

@ -51,9 +51,6 @@
* masks, and hardware address, and a few others
*/
#define _SIOCVALID(c) (_IOC_TYPE(c)==_SIOCBASE)
#define _SIOC(nr) _IOC(_SIOCBASE,nr)
/* IPv4 interface control operations */
#define SIOCGIFADDR _SIOC(0x0001) /* Get IP address */

View File

@ -37,8 +37,8 @@
* (when applicable).
*/
#ifndef __INCLUDE_NUTTX_WIRELESS_H
#define __INCLUDE_NUTTX_WIRELESS_H
#ifndef __INCLUDE_NUTTX_WIRELESS_WIRELESS_H
#define __INCLUDE_NUTTX_WIRELESS_WIRELESS_H
/************************************************************************************
* Included Files
@ -63,6 +63,7 @@
* interface.
*/
/* IEEE802.11 */
/* Wireless identification */
#define SIOCSIWCOMMIT _WLIOC(0x0001) /* Commit pending changes to driver */
@ -153,8 +154,24 @@
#define SIOCSIWPMKSA _WLIOC(0x0032) /* PMKSA cache operation */
#define WL_FIRSTCHAR 0x0033
#define WL_NNETCMDS 0x0032
/* IEEE802.15.4 6loWPAN
*
* IEEE802.15.4 IOCTLs may be directed at one of three layers:
*
* 1. To the 6loWPAN network layer, as documented here,
* 2. To the IEEE802.15.4 MAC layer, as documented in,
* include/nuttx/wireless/ieee802154/ioeee802154_mac.h, or to
* 3. To the IEEE802.15.4 radio device layer, as documented in,
* include/nuttx/wireless/ieee802154/ioeee802154_radio.h.
*
* SIOCSWPANID - Join the specified PAN ID
*/
#define SIOCSWPANID _WLIOC(0x0033) /* Join PAN ID */
#define SIOCGWPANID _WLIOC(0x0034) /* Return PAN ID */
#define WL_FIRSTCHAR 0x0035
#define WL_NNETCMDS 0x0034
/* Character Driver IOCTL commands *************************************************/
/* Non-compatible, NuttX only IOCTL definitions for use with low-level wireless
@ -162,23 +179,23 @@
* requires a file descriptor created by the open() interface.
*/
#define WLIOC_SETRADIOFREQ _WLIOC(0x0033) /* arg: Pointer to uint32_t, frequency
#define WLIOC_SETRADIOFREQ _WLIOC(0x0035) /* arg: Pointer to uint32_t, frequency
* value (in Mhz) */
#define WLIOC_GETRADIOFREQ _WLIOC(0x0034) /* arg: Pointer to uint32_t, frequency
#define WLIOC_GETRADIOFREQ _WLIOC(0x0036) /* arg: Pointer to uint32_t, frequency
* value (in Mhz) */
#define WLIOC_SETADDR _WLIOC(0x0035) /* arg: Pointer to address value, format
#define WLIOC_SETADDR _WLIOC(0x0037) /* arg: Pointer to address value, format
* of the address is driver specific */
#define WLIOC_GETADDR _WLIOC(0x0036) /* arg: Pointer to address value, format
#define WLIOC_GETADDR _WLIOC(0x0038) /* arg: Pointer to address value, format
* of the address is driver specific */
#define WLIOC_SETTXPOWER _WLIOC(0x0037) /* arg: Pointer to int32_t, output power
#define WLIOC_SETTXPOWER _WLIOC(0x0039) /* arg: Pointer to int32_t, output power
* (in dBm) */
#define WLIOC_GETTXPOWER _WLIOC(0x0038) /* arg: Pointer to int32_t, output power
#define WLIOC_GETTXPOWER _WLIOC(0x003a) /* arg: Pointer to int32_t, output power
* (in dBm) */
/* Device-specific IOCTL commands **************************************************/
#define WL_FIRST 0x0001 /* First common command */
#define WL_NCMDS 0x0038 /* Number of common commands */
#define WL_NCMDS 0x003a /* Number of common commands */
/* User defined ioctl commands are also supported. These will be forwarded
* by the upper-half QE driver to the lower-half QE driver via the ioctl()
@ -355,5 +372,35 @@ struct iw_event
union iwreq_data u; /* Fixed IOCTL payload */
};
/* 6loWPAN */
/* This structure is used with the SIOCSWPANID IOCTL command to select the
* PAN ID to join.
*/
struct sixlowpan_panid_s
{
uint16_t panid; /* The PAN ID to join */
};
/* This union defines the data payload of an 6loWPAN or SIOCGWPANID ioctl
* command and is used in struct sixlowpan_req_s below.
*/
union sixlowpan_data
{
struct sixlowpan_panid_s panid; /* PAN ID to join */
};
/* This is the structure used to exchange data in wireless IOCTLs. This
* structure is the same as 'struct ifreq', but defined for use with
* 6loWPAN IOCTLs.
*/
struct sixlowpan_req_s
{
char ifr_name[IFNAMSIZ]; /* Interface name, e.g. "wpan0" */
union sixlowpan_data u; /* Data payload */
};
#endif /* CONFIG_DRIVERS_WIRELESS */
#endif /* __INCLUDE_NUTTX_WIRELESS_H */
#endif /* __INCLUDE_NUTTX_WIRELESS_WIRELESS_H */

View File

@ -61,6 +61,7 @@
#ifdef CONFIG_NET_6LOWPAN
# include <nuttx/net/sixlowpan.h>
# include <nuttx/wireless/wireless.h>
#endif
#ifdef CONFIG_NET_IGMP
@ -321,32 +322,73 @@ static void ioctl_set_ipv6addr(FAR net_ipv6addr_t outaddr,
#endif
/****************************************************************************
* Name: netdev_wifr_dev
* Name: netdev_sixlowpan_ioctl
*
* Description:
* Verify the struct iwreq and get the Wireless device.
* Perform 6loWPAN network device specific operations.
*
* Parameters:
* req - The argument of the ioctl cmd
* psock Socket structure
* dev Ethernet driver device structure
* cmd The ioctl command
* req The argument of the ioctl cmd
*
* Return:
* A pointer to the driver structure on success; NULL on failure.
* >=0 on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
*
****************************************************************************/
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NETDEV_WIRELESS_IOCTL)
static FAR struct net_driver_s *netdev_wifr_dev(FAR struct iwreq *req)
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
static int netdev_sixlowpan_ioctl(FAR struct socket *psock, int cmd,
FAR struct sixlowpan_req_s *req)
{
if (req != NULL)
{
/* Find the network device associated with the device name
* in the request data.
*/
FAR struct ieee802154_driver_s *ieee;
int ret = -ENOTTY;
return netdev_findbyname(req->ifrn_name);
/* Verify that this is a valid wireless network IOCTL command */
if (_WLIOCVALID(cmd) && (unsigned)_IOC_NR(cmd) <= WL_NNETCMDS)
{
switch (cmd)
{
case SIOCSWPANID: /* Join PAN ID */
{
ieee = (FAR struct ieee802154_driver_s *)netdev_findbyname(req->ifr_name);
if (ieee == NULL)
{
ret = -ENODEV;
}
else
{
ieee->i_panid = req->u.panid.panid;
ret = OK;
}
}
break;
case SIOCGWPANID: /* Return PAN ID */
{
ieee = (FAR struct ieee802154_driver_s *)netdev_findbyname(req->ifr_name);
if (ieee == NULL)
{
ret = -ENODEV;
}
else
{
req->u.panid.panid = ieee->i_panid;
ret = OK;
}
}
break;
default:
return -ENOTTY;
}
}
return NULL;
return ret;
}
#endif
@ -381,8 +423,8 @@ static int netdev_wifr_ioctl(FAR struct socket *psock, int cmd,
{
/* Get the wireless device associated with the IOCTL command */
dev = netdev_wifr_dev(req);
if (dev)
dev = netdev_findbyname(req->ifrn_name);
if (dev != NULL)
{
/* Just forward the IOCTL to the wireless driver */
@ -1209,7 +1251,11 @@ int psock_ioctl(FAR struct socket *psock, int cmd, unsigned long arg)
* non-NULL.
*/
#ifdef CONFIG_DRIVERS_WIRELESS
if (!_SIOCVALID(cmd) && !_WLIOCVALID(cmd))
#else
if (!_SIOCVALID(cmd))
#endif
{
ret = -ENOTTY;
goto errout;
@ -1227,13 +1273,27 @@ int psock_ioctl(FAR struct socket *psock, int cmd, unsigned long arg)
ret = netdev_ifr_ioctl(psock, cmd, (FAR struct ifreq *)((uintptr_t)arg));
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NETDEV_WIRELESS_IOCTL)
/* Check a wireless network command */
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
/* Check for a 6loWPAN network command */
if (ret == -ENOTTY)
{
ret = netdev_wifr_ioctl(psock, cmd,
(FAR struct iwreq *)((uintptr_t)arg));
FAR struct sixlowpan_req_s *slpreq;
slpreq = (FAR struct sixlowpan_req_s *)((uintptr_t)arg);
ret = netdev_sixlowpan_ioctl(psock, cmd, slpreq);
}
#endif
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NETDEV_WIRELESS_IOCTL)
/* Check for a wireless network command */
if (ret == -ENOTTY)
{
FAR struct iwreq *wifrreq;
wifrreq = (FAR struct sixlowpan_req_s *)((uintptr_t)arg);
ret = netdev_wifr_ioctl(psock, cmd, wifrreq);
}
#endif

View File

@ -47,7 +47,7 @@ The length of the fragment header length is four bytes for the first header
(FRAG1) and five bytes for all subsequent headers (FRAGN). For example,
this is a HC1 compressed first frame of a packet
41 88 01 0000 3412 cdab ### 9-byte MAC header
41 88 01 cefa 3412 cdab ### 9-byte MAC header
c50e 000b ### 4-byte FRAG1 header
42 ### SIXLOWPAN_DISPATCH_HC1
fb ### RIME_HC1_HC_UDP_HC1_ENCODING
@ -64,7 +64,7 @@ this is a HC1 compressed first frame of a packet
This is the second frame of the same transfer:
41 88 01 0000 3412 cdab ### 9-byte MAC header
41 88 01 cefa 3412 cdab ### 9-byte MAC header
e50e 000b 0a ### 5 byte FRAGN header
42 ### SIXLOWPAN_DISPATCH_HC1
fb ### RIME_HC1_HC_UDP_HC1_ENCODING