diff --git a/include/nuttx/net/sixlowpan.h b/include/nuttx/net/sixlowpan.h index 855948b4e8..fd2301632d 100644 --- a/include/nuttx/net/sixlowpan.h +++ b/include/nuttx/net/sixlowpan.h @@ -426,15 +426,12 @@ struct rimeaddr_s * this structure. In general, all fields must be set to NULL. In * addtion: * - * 1. i_panid must be set to identify the network. It may be set to 0xfff - * if the device is not associated. - * - * 2. i_dsn must be set to a random value. After that, it will be managed + * 1. i_dsn must be set to a random value. After that, it will be managed * by the network. * - * 3. i_nodeaddr must be set after the MAC is assigned an address. + * 2. i_nodeaddr must be set after the MAC is assigned an address. * - * 4. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver + * 3. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver * structure with i_framelist set to NULL. At the conclusion of the * poll, if there are frames to be sent, they will have been added to * the i_framelist. The non-empty frame list at the conclusion of the @@ -449,7 +446,7 @@ struct rimeaddr_s * After sending each frame, the driver must return the IOB to the pool * of free IOBs using the FROM_IOB_FREE() macro. * - * 5. When receiving data both buffers must be provided: + * 4. When receiving data both buffers must be provided: * * The IEEE802.15.4 MAC driver should receive the frame data directly * into the payload area of an IOB structure. That IOB structure may be @@ -500,16 +497,6 @@ struct ieee802154_driver_s FAR struct iob_s *i_framelist; /* Driver Configuration ***************************************************/ - /* i_panid. The PAN ID is 16-bit number that identifies the network. It - * must be unique to differentiate a network. All the nodes in the same - * network should have the same PAN ID. This value must be provided to - * the network from the IEEE802.15.4 MAC driver. - * - * If this value is 0xffff, the device is not associated. - */ - - uint16_t i_panid; - /* i_node_addr. The address assigned to this node. */ struct rimeaddr_s i_nodeaddr; diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 96eff51998..7f194d1c1a 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -1301,21 +1301,6 @@ int psock_ioctl(FAR struct socket *psock, int cmd, unsigned long arg) { int ret; - /* Check if this is a valid command. In all cases, arg is a pointer that has - * been cast to unsigned long. Verify that the value of the to-be-pointer is - * non-NULL. - */ - -#ifdef CONFIG_DRIVERS_WIRELESS - if (!_SIOCVALID(cmd) && !_WLIOCVALID(cmd)) -#else - if (!_SIOCVALID(cmd)) -#endif - { - ret = -ENOTTY; - goto errout; - } - /* Verify that the psock corresponds to valid, allocated socket */ if (psock == NULL || psock->s_crefs <= 0) diff --git a/net/sixlowpan/sixlowpan.h b/net/sixlowpan/sixlowpan.h index 05ce9496c9..fe4451c093 100644 --- a/net/sixlowpan/sixlowpan.h +++ b/net/sixlowpan/sixlowpan.h @@ -79,7 +79,7 @@ struct sockaddr; /* Forward reference */ void sixlowpan_initialize(void); /**************************************************************************** - * Function: psock_6lowpan_tcp_send + * Name: psock_6lowpan_tcp_send * * Description: * psock_6lowpan_tcp_send() call may be used only when the TCP socket is in a @@ -107,7 +107,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, #endif /**************************************************************************** - * Function: sixlowpan_tcp_send + * Name: sixlowpan_tcp_send * * Description: * TCP output comes through three different mechansims. Either from: @@ -139,7 +139,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, void sixlowpan_tcp_send(FAR struct net_driver_s *dev); /**************************************************************************** - * Function: psock_6lowpan_udp_send + * Name: psock_6lowpan_udp_send * * Description: * psock_6lowpan_udp_send() call may be used with connectionlesss UDP @@ -167,7 +167,7 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf, #endif /**************************************************************************** - * Function: psock_6lowpan_udp_sendto + * Name: psock_6lowpan_udp_sendto * * Description: * If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index ee9487a101..e392c02298 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -217,6 +217,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, struct rimeaddr_s bcastmac; uint16_t pktlen; uint16_t paysize; + uint16_t dest_panid; #ifdef CONFIG_NET_6LOWPAN_FRAG uint16_t outlen = 0; #endif @@ -286,9 +287,18 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_SENDER], &ieee->i_nodeaddr); rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER], destmac); + /* Get the destination PAN ID. + * + * REVISIT: For now I am assuming that the source and destination + * PAN IDs are the same. + */ + + dest_panid = 0xffff; + (void)sixlowpan_src_panid(ieee, &dest_panid); + /* Pre-calculate frame header length. */ - framer_hdrlen = sixlowpan_send_hdrlen(ieee, ieee->i_panid); + framer_hdrlen = sixlowpan_send_hdrlen(ieee, dest_panid); if (framer_hdrlen < 0) { /* Failed to determine the size of the header failed. */ @@ -349,7 +359,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Create 1st Fragment */ /* Add the frame header using the pre-allocated IOB. */ - verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid); + verify = sixlowpan_framecreate(ieee, iob, dest_panid); DEBUGASSERT(verify == framer_hdrlen); UNUSED(verify); @@ -513,7 +523,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Add the frame header to the preallocated IOB. */ - verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid); + verify = sixlowpan_framecreate(ieee, iob, dest_panid); DEBUGASSERT(verify == framer_hdrlen); UNUSED(verify); diff --git a/net/sixlowpan/sixlowpan_framer.c b/net/sixlowpan/sixlowpan_framer.c index 66f8a1c3fb..4ec877d2d5 100644 --- a/net/sixlowpan/sixlowpan_framer.c +++ b/net/sixlowpan/sixlowpan_framer.c @@ -82,7 +82,7 @@ struct field_length_s ****************************************************************************/ /**************************************************************************** - * Function: sixlowpan_addrlen + * Name: sixlowpan_addrlen * * Description: * Return the address length associated with a 2-bit address mode @@ -109,7 +109,7 @@ static inline uint8_t sixlowpan_addrlen(uint8_t addrmode) } /**************************************************************************** - * Function: sixlowpan_addrnull + * Name: sixlowpan_addrnull * * Description: * If the output address is NULL in the Rime buf, then it is broadcast @@ -140,7 +140,7 @@ static bool sixlowpan_addrnull(FAR uint8_t *addr) /**************************************************************************** - * Function: sixlowpan_fieldlengths + * Name: sixlowpan_fieldlengths * * Description: * Return the lengths associated fields of the IEEE802.15.4 header. @@ -228,7 +228,7 @@ static void sixlowpan_fieldlengths(FAR struct frame802154_s *finfo, } /**************************************************************************** - * Function: sixlowpan_fieldlengths + * Name: sixlowpan_fieldlengths * * Description: * Return the lengths associated fields of the IEEE802.15.4 header. @@ -249,7 +249,7 @@ static int sixlowpan_flen_hdrlen(FAR const struct field_length_s *flen) } /**************************************************************************** - * Function: sixlowpan_802154_hdrlen + * Name: sixlowpan_802154_hdrlen * * Description: * Calculates the length of the frame header. This function is meant to @@ -272,7 +272,7 @@ static int sixlowpan_802154_hdrlen(FAR struct frame802154_s *finfo) } /**************************************************************************** - * Function: sixlowpan_setup_params + * Name: sixlowpan_setup_params * * Description: * Configure frame parmeters structure. @@ -293,6 +293,7 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee, uint16_t dest_panid, FAR struct frame802154_s *params) { + uint16_t src_panid; bool rcvrnull; /* Initialize all prameters to all zero */ @@ -331,9 +332,14 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee, } /* Complete the addressing fields. */ + /* Get the source PAN ID from the IEEE802.15.4 radio driver */ + + src_panid = 0xffff; + (void)sixlowpan_src_panid(ieee, &src_panid); + /* Set the source and destination PAN ID. */ - params->src_pid = ieee->i_panid; + params->src_pid = src_panid; params->dest_pid = dest_panid; /* If the output address is NULL in the Rime buf, then it is broadcast @@ -382,7 +388,7 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee, ****************************************************************************/ /**************************************************************************** - * Function: sixlowpan_send_hdrlen + * Name: sixlowpan_send_hdrlen * * Description: * This function is before the first frame has been sent in order to @@ -415,7 +421,7 @@ int sixlowpan_send_hdrlen(FAR struct ieee802154_driver_s *ieee, } /**************************************************************************** - * Function: sixlowpan_802154_framecreate + * Name: sixlowpan_802154_framecreate * * Description: * Creates a frame for transmission over the air. This function is meant @@ -514,7 +520,7 @@ int sixlowpan_802154_framecreate(FAR struct frame802154_s *finfo, } /**************************************************************************** - * Function: sixlowpan_framecreate + * Name: sixlowpan_framecreate * * Description: * This function is called after eiether (1) the IEEE802.15.4 MAC driver diff --git a/net/sixlowpan/sixlowpan_input.c b/net/sixlowpan/sixlowpan_input.c index bfa74da13a..bccd97677b 100644 --- a/net/sixlowpan/sixlowpan_input.c +++ b/net/sixlowpan/sixlowpan_input.c @@ -680,7 +680,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, } /**************************************************************************** - * Function: sixlowpan_dispatch + * Name: sixlowpan_dispatch * * Description: * Inject the packet in d_buf into the network for normal packet processing. diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index 392bc376b7..08b2fc445c 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -344,7 +344,7 @@ int sixlowpan_send(FAR struct net_driver_s *dev, uint16_t timeout); /**************************************************************************** - * Function: sixlowpan_send_hdrlen + * Name: sixlowpan_send_hdrlen * * Description: * This function is before the first frame has been sent in order to @@ -366,7 +366,7 @@ int sixlowpan_send_hdrlen(FAR struct ieee802154_driver_s *ieee, uint16_t dest_panid); /**************************************************************************** - * Function: sixlowpan_framecreate + * Name: sixlowpan_framecreate * * Description: * This function is called after the IEEE802.15.4 MAC driver polls for @@ -606,5 +606,23 @@ void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr, bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr, FAR const struct rimeaddr_s *rime); +/**************************************************************************** + * Name: sixlowpan_src_panid + * + * Description: + * Get the source PAN ID from the IEEE802.15.4 radio. + * + * Input parameters: + * ieee - A reference IEEE802.15.4 MAC network device structure. + * panid - The location in which to return the PAN ID. 0xfff may be + * returned if the device is not associated. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int sixlowpan_src_panid(FAR struct ieee802154_driver_s *ieee, + FAR uint16_t *panid); #endif /* CONFIG_NET_6LOWPAN */ #endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */ diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index 1dd8f86c66..3ad68554ae 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -93,7 +93,7 @@ struct sixlowpan_send_s ****************************************************************************/ /**************************************************************************** - * Function: send_timeout + * Name: send_timeout * * Description: * Check for send timeout. @@ -134,7 +134,7 @@ static inline bool send_timeout(FAR struct sixlowpan_send_s *sinfo) } /**************************************************************************** - * Function: send_interrupt + * Name: send_interrupt * * Description: * This function is called from the interrupt level to perform the actual diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index 3ee39e72ed..2bb6c49130 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -136,7 +136,7 @@ static uint16_t sixlowpan_tcp_chksum(FAR struct ipv6tcp_hdr_s *ipv6tcp, ****************************************************************************/ /**************************************************************************** - * Function: psock_6lowpan_tcp_send + * Name: psock_6lowpan_tcp_send * * Description: * psock_6lowpan_tcp_send() call may be used only when the TCP socket is in a @@ -348,7 +348,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, } /**************************************************************************** - * Function: sixlowpan_tcp_send + * Name: sixlowpan_tcp_send * * Description: * TCP output comes through three different mechansims. Either from: diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index f8f62e528b..a29197eec7 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -125,7 +125,7 @@ static uint16_t sixlowpan_udp_chksum(FAR struct ipv6udp_hdr_s *ipv6udp, ****************************************************************************/ /**************************************************************************** - * Function: psock_6lowpan_udp_sendto + * Name: psock_6lowpan_udp_sendto * * Description: * If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) @@ -323,7 +323,7 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, } /**************************************************************************** - * Function: psock_6lowpan_udp_send + * Name: psock_6lowpan_udp_send * * Description: * psock_6lowpan_udp_send() call may be used with connectionlesss UDP diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c index dcda6be652..7e1a6ac2ee 100644 --- a/net/sixlowpan/sixlowpan_utils.c +++ b/net/sixlowpan/sixlowpan_utils.c @@ -54,8 +54,10 @@ #include #include #include +#include #include +#include #include "sixlowpan/sixlowpan_internal.h" @@ -156,4 +158,39 @@ bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr, #endif } +/**************************************************************************** + * Name: sixlowpan_src_panid + * + * Description: + * Get the source PAN ID from the IEEE802.15.4 radio. + * + * Input parameters: + * ieee - A reference IEEE802.15.4 MAC network device structure. + * panid - The location in which to return the PAN ID. 0xfff may be + * returned if the device is not associated. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int sixlowpan_src_panid(FAR struct ieee802154_driver_s *ieee, + FAR uint16_t *panid) +{ + FAR struct net_driver_s *dev = &ieee->i_dev; + struct ieee802154_netradio_s arg; + int ret; + + memcpy(arg.ifr_name, ieee->i_dev.d_ifname, IFNAMSIZ); + ret = dev->d_ioctl(dev, PHY802154IOC_GET_PANID, (unsigned long)((uintptr_t)&arg)); + if (ret < 0) + { + wlerr("ERROR: PHY802154IOC_GET_PANID failed: %d\n", ret); + return ret; + } + + *panid = arg.u.panid; + return OK; +} + #endif /* CONFIG_NET_6LOWPAN */ diff --git a/wireless/ieee802154/mac802154_loopback.c b/wireless/ieee802154/mac802154_loopback.c index b3c0c4cdf5..13243baed0 100644 --- a/wireless/ieee802154/mac802154_loopback.c +++ b/wireless/ieee802154/mac802154_loopback.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include "mac802154.h" @@ -94,6 +95,7 @@ struct lo_driver_s { bool lo_bifup; /* true:ifup false:ifdown */ bool lo_txdone; /* One RX packet was looped back */ + 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 */ @@ -131,6 +133,10 @@ static int lo_addmac(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 /**************************************************************************** * Private Functions @@ -371,11 +377,11 @@ static int lo_ifup(FAR struct net_driver_s *dev) priv->lo_ieee.i_nodeaddr.u8[2], priv->lo_ieee.i_nodeaddr.u8[3], priv->lo_ieee.i_nodeaddr.u8[4], priv->lo_ieee.i_nodeaddr.u8[5], priv->lo_ieee.i_nodeaddr.u8[6], priv->lo_ieee.i_nodeaddr.u8[7], - priv->lo_ieee.i_panid); + priv->lo_panid); #else ninfo(" Node: %02x:%02x PANID=%04x\n", priv->lo_ieee.i_nodeaddr.u8[0], priv->lo_ieee.i_nodeaddr.u8[1], - priv->lo_ieee.i_panid); + priv->lo_panid); #endif /* Set and activate a timer process */ @@ -570,6 +576,74 @@ static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) } #endif +/**************************************************************************** + * Name: macnet_ioctl + * + * Description: + * Handle network IOCTL commands directed to this device. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * cmd - The IOCTL command + * arg - The argument for the IOCTL command + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_IOCTL +static int lo_ioctl(FAR struct net_driver_s *dev, int cmd, + unsigned long arg) +{ + FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private; + int ret = -ENOTTY; + +#if 0 + /* Check for IOCTLs aimed at the IEEE802.15.4 MAC layer */ + + if (_MAC802154IOCVALID(cmd)) + { + FAR struct ieee802154_netmac_s *netmac = + (FAR struct ieee802154_netmac_s *)arg; + } + + /* No, check for IOCTLs aimed at the IEEE802.15.4 radio layer */ + + else +#endif + if (_PHY802154IOCVALID(cmd)) + { + FAR struct ieee802154_netradio_s *netradio = + (FAR struct ieee802154_netradio_s *)arg; + + /* Pick out radio settings of interest. There is, of course, no + * radio in this loopback. + */ + + switch (cmd) + { + case PHY802154IOC_SET_PANID: + priv->lo_panid = netradio->u.panid; + ret = OK; + break; + + case PHY802154IOC_GET_PANID: + netradio->u.panid = priv->lo_panid; + ret = OK; + break; + + default: + break; + } + } + + return ret; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -612,6 +686,9 @@ int ieee8021514_loopback(void) #ifdef CONFIG_NET_IGMP 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 */ #endif dev->d_buf = g_iobuffer; /* Attach the IO buffer */ dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */