Merge branch 'ieee802154'
This commit is contained in:
commit
58c85705c0
21
TODO
21
TODO
@ -1234,14 +1234,14 @@ o Network (net/, drivers/net)
|
||||
|
||||
Title: ICMPv6 FOR 6loWPAN
|
||||
Description: The current ICMPv6 and neighbor-related logic only works with
|
||||
Ethernet MAC. For 6loWPAN, a new more conservative ICMPv6
|
||||
definitions is provided by RFC 6775. This RFC needs to be
|
||||
supported in order to support ping6 on a 6loWPAN network.
|
||||
Ethernet MAC. For 6loWPAN, a new more conservative IPv6
|
||||
neigbor discovery is provided by RFC 6775. This RFC needs to
|
||||
be supported in order to support ping6 on a 6loWPAN network.
|
||||
If RFC 6775 were implemented, then arbitrary IPv6 addresses,
|
||||
including addresses from DHCPv6 could be used.
|
||||
can
|
||||
|
||||
UPDATE: With ICMPv6 neighbor discovery, any IPv6 address may
|
||||
UPDATE: With IPv6 neighbor discovery, any IPv6 address may
|
||||
be associated with any short or extended address. In fact,
|
||||
that is the whole purpose of the neighbor discover logic: It
|
||||
plays the same role as ARP in IPv4; it ultimately just manages
|
||||
@ -1256,15 +1256,18 @@ o Network (net/, drivers/net)
|
||||
Most of the 6loWPAN compression algorithms exploit this to
|
||||
compress the IPv6 address to nothing but a bit indicating
|
||||
that the IP address derives from the node address. So I
|
||||
think ICMPv6 is useless in the current implementation.
|
||||
think IPv6 neighbor discover is useless in the current
|
||||
implementation.
|
||||
|
||||
If we want to use ICMPv6, we could dispense with the all MAC
|
||||
based addressing. But if we want to retain the more compact
|
||||
MAC-based addressing, then we don't need ICMPv6.
|
||||
If we want to use IPv6 neighbor discovery, we could dispense
|
||||
with the all MAC based addressing. But if we want to retain
|
||||
the more compact MAC-based addressing, then we don't need
|
||||
IPv6 neighbor discovery.
|
||||
|
||||
So, the full neighbor discovery logic is not currently useful,
|
||||
but it would still be nice to have enough in place to support
|
||||
ping6.
|
||||
ping6. Full neighbor support would probably be necessary if we
|
||||
wanted to route 6LoWPAN frames outside of the WPAN.
|
||||
|
||||
Status: Open
|
||||
Priority: Low for now. I don't plan on implementing this. It would
|
||||
|
@ -365,7 +365,7 @@ Configurations
|
||||
nsh> i8 /dev/ieee0 startpan
|
||||
nsh> i8 acceptassoc
|
||||
|
||||
2. Assocate and endpoint device with the WPAN. On the endpoint
|
||||
2. Assocate an endpoint device with the WPAN. On the endpoint
|
||||
device:
|
||||
|
||||
nsh> i8 /dev/ieee0 assoc
|
||||
@ -432,7 +432,7 @@ Configurations
|
||||
5. Configuration instructions: Basic PAN configuration is the same as
|
||||
for the ieee802154-mac configuration with the exception that after
|
||||
the PAN has been configured with the i8sak utility, you must
|
||||
explicity bring the network up:
|
||||
explicity bring the network up on each node:
|
||||
|
||||
nsh> ifup wpan0
|
||||
|
||||
|
@ -1137,12 +1137,14 @@ CONFIG_IOB_THROTTLE=8
|
||||
CONFIG_WIRELESS=y
|
||||
CONFIG_WIRELESS_IEEE802154=y
|
||||
CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef
|
||||
CONFIG_IEEE802154_MAC_DEV=y
|
||||
CONFIG_MAC802154_HPWORK=y
|
||||
CONFIG_IEEE802154_NTXDESC=3
|
||||
CONFIG_IEEE802154_IND_PREALLOC=20
|
||||
CONFIG_IEEE802154_IND_IRQRESERVE=10
|
||||
CONFIG_IEEE802154_MACDEV=y
|
||||
CONFIG_IEEE802154_MACDEV_RECVRPRIO=0
|
||||
CONFIG_IEEE802154_NETDEV=y
|
||||
CONFIG_IEEE802154_NETDEV_RECVRPRIO=1
|
||||
CONFIG_IEEE802154_NETDEV_HPWORK=y
|
||||
# CONFIG_IEEE802154_LOOPBACK is not set
|
||||
|
||||
@ -1448,7 +1450,7 @@ CONFIG_NSH_DISABLE_GET=y
|
||||
# CONFIG_NSH_DISABLE_HELP is not set
|
||||
# CONFIG_NSH_DISABLE_HEXDUMP is not set
|
||||
# CONFIG_NSH_DISABLE_IFCONFIG is not set
|
||||
CONFIG_NSH_DISABLE_IFUPDOWN=y
|
||||
# CONFIG_NSH_DISABLE_IFUPDOWN is not set
|
||||
# CONFIG_NSH_DISABLE_KILL is not set
|
||||
# CONFIG_NSH_DISABLE_LOSETUP is not set
|
||||
CONFIG_NSH_DISABLE_LOSMART=y
|
||||
|
@ -393,6 +393,7 @@ CONFIG_STM32_HAVE_I2C2=y
|
||||
CONFIG_STM32_HAVE_I2C3=y
|
||||
CONFIG_STM32_HAVE_SPI2=y
|
||||
CONFIG_STM32_HAVE_SPI3=y
|
||||
CONFIG_STM32_HAVE_I2S3=y
|
||||
# CONFIG_STM32_HAVE_SPI4 is not set
|
||||
# CONFIG_STM32_HAVE_SPI5 is not set
|
||||
# CONFIG_STM32_HAVE_SPI6 is not set
|
||||
@ -431,6 +432,7 @@ CONFIG_STM32_PWR=y
|
||||
# CONFIG_STM32_SPI1 is not set
|
||||
# CONFIG_STM32_SPI2 is not set
|
||||
CONFIG_STM32_SPI3=y
|
||||
# CONFIG_STM32_I2S3 is not set
|
||||
CONFIG_STM32_SYSCFG=y
|
||||
# CONFIG_STM32_TIM1 is not set
|
||||
# CONFIG_STM32_TIM2 is not set
|
||||
@ -968,6 +970,7 @@ CONFIG_MM_IOB=y
|
||||
CONFIG_IOB_NBUFFERS=8
|
||||
CONFIG_IOB_BUFSIZE=196
|
||||
CONFIG_IOB_NCHAINS=0
|
||||
CONFIG_IOB_THROTTLE=0
|
||||
|
||||
#
|
||||
# Audio Support
|
||||
@ -980,11 +983,12 @@ CONFIG_IOB_NCHAINS=0
|
||||
CONFIG_WIRELESS=y
|
||||
CONFIG_WIRELESS_IEEE802154=y
|
||||
CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef
|
||||
CONFIG_IEEE802154_MAC_DEV=y
|
||||
CONFIG_MAC802154_HPWORK=y
|
||||
CONFIG_IEEE802154_NTXDESC=3
|
||||
CONFIG_IEEE802154_IND_PREALLOC=20
|
||||
CONFIG_IEEE802154_IND_IRQRESERVE=10
|
||||
CONFIG_IEEE802154_MACDEV=y
|
||||
CONFIG_IEEE802154_MACDEV_RECVRPRIO=0
|
||||
|
||||
#
|
||||
# Binary Loader
|
||||
@ -1162,10 +1166,10 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024
|
||||
CONFIG_EXAMPLES_NSH=y
|
||||
CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
|
||||
# CONFIG_EXAMPLES_NULL is not set
|
||||
# CONFIG_EXAMPLES_NX is not set
|
||||
# CONFIG_EXAMPLES_NXFFS is not set
|
||||
# CONFIG_EXAMPLES_NXHELLO is not set
|
||||
# CONFIG_EXAMPLES_NXIMAGE is not set
|
||||
# CONFIG_EXAMPLES_NX is not set
|
||||
# CONFIG_EXAMPLES_NXLINES is not set
|
||||
# CONFIG_EXAMPLES_NXTERM is not set
|
||||
# CONFIG_EXAMPLES_NXTEXT is not set
|
||||
|
@ -270,7 +270,7 @@ static int stm32_mrf24j40_devsetup(FAR struct stm32_priv_s *priv)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IEEE802154_MAC_DEV
|
||||
#ifdef CONFIG_IEEE802154_MACDEV
|
||||
/* If want to call these APIs from userspace, you have to wrap the MAC
|
||||
* interface in a character device viamac802154dev_register().
|
||||
*/
|
||||
|
@ -710,11 +710,11 @@ CONFIG_IOB_THROTTLE=8
|
||||
CONFIG_WIRELESS=y
|
||||
CONFIG_WIRELESS_IEEE802154=y
|
||||
CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef
|
||||
# CONFIG_IEEE802154_MAC_DEV is not set
|
||||
CONFIG_MAC802154_HPWORK=y
|
||||
CONFIG_IEEE802154_NTXDESC=3
|
||||
CONFIG_IEEE802154_IND_PREALLOC=20
|
||||
CONFIG_IEEE802154_IND_IRQRESERVE=10
|
||||
# CONFIG_IEEE802154_MACDEV is not set
|
||||
# CONFIG_IEEE802154_NETDEV is not set
|
||||
CONFIG_IEEE802154_LOOPBACK=y
|
||||
CONFIG_IEEE802154_LOOPBACK_HPWORK=y
|
||||
|
@ -1,4 +1,35 @@
|
||||
Optimal 6loWPAN Configuration
|
||||
6LoWPAN Addressing
|
||||
------------------
|
||||
|
||||
The current 6LoWPAN implementation uses only link local, MAC-based
|
||||
addressing addressing (as discussed in more detail below). Thus if you know
|
||||
the node addressing, then you know the IPv6 address (and vice-versa)
|
||||
|
||||
IPv6 Neighbor Discovery is not supported. The current ICMPv6 and neighbor-
|
||||
related logic only works with Ethernet MAC. For 6LoWPAN, a
|
||||
new more conservative IPv6 neigbor discovery is provided by RFC 6775 which
|
||||
is not currently suppored. With IPv6 neighbor discovery, any IPv6 address
|
||||
may be associated with any short or extended address. In fact, that is the
|
||||
whole purpose of the neighbor discover logic: It plays the same role as ARP
|
||||
in IPv4; it ultimately just manages a neighbor table that, like the arp
|
||||
table, provides the mapping between IP addresses and node addresses.
|
||||
|
||||
The NuttX, Contiki-based 6LoWPAN implementation circumvents the need for
|
||||
the neighbor discovery logic by using only MAC-based addressing, i.e., the
|
||||
lower two or eight bytes of the IP address are the node address.
|
||||
|
||||
Most of the 6LoWPAN compression algorithms exploit this kind of addressing
|
||||
to compress the IPv6 address to nothing but a single bit indicating that the
|
||||
IP address derives from the node address. In this use case, IPv6 neighbor
|
||||
discover is not useful: If we want to use IPv6 neighbor discovery, we could
|
||||
dispense with the all MAC based addressing. But if we want to retain the
|
||||
more compact MAC-based addressing, then we don't need IPv6 neighbor discovery.
|
||||
|
||||
However, it would still be nice to have enough in place to support ping6.
|
||||
Full neighbor support would be necessary if we wanted to route 6LoWPAN frames
|
||||
outside of the WPAN.
|
||||
|
||||
Optimal 6LoWPAN Configuration
|
||||
-----------------------------
|
||||
|
||||
1. Link local IP addresses:
|
||||
|
@ -88,12 +88,12 @@ bool sched_addprioritized(FAR struct tcb_s *tcb, DSEG dq_queue_t *list)
|
||||
ASSERT(sched_priority >= SCHED_PRIORITY_MIN);
|
||||
|
||||
/* Search the list to find the location to insert the new Tcb.
|
||||
* Each is list is maintained in ascending sched_priority order.
|
||||
* Each is list is maintained in descending sched_priority order.
|
||||
*/
|
||||
|
||||
for (next = (FAR struct tcb_s *)list->head;
|
||||
(next && sched_priority <= next->sched_priority);
|
||||
next = next->flink);
|
||||
next = next->flink);
|
||||
|
||||
/* Add the tcb to the spot found in the list. Check if the tcb
|
||||
* goes at the end of the list. NOTE: This could only happen if list
|
||||
|
@ -21,14 +21,6 @@ config IEEE802154_DEFAULT_EADDR
|
||||
---help---
|
||||
Set the default extended address to be used by MAC networks on init
|
||||
|
||||
config IEEE802154_MAC_DEV
|
||||
bool "Character driver for IEEE 802.15.4 MAC layer"
|
||||
default n
|
||||
depends on WIRELESS_IEEE802154
|
||||
---help---
|
||||
Enable the device driver to expose the IEEE 802.15.4 MAC layer
|
||||
access to user space as IOCTLs
|
||||
|
||||
choice
|
||||
prompt "IEEE 802.15.4 work queue"
|
||||
default MAC802154_LPWORK if SCHED_LPWORK
|
||||
@ -83,6 +75,36 @@ config IEEE802154_IND_IRQRESERVE
|
||||
Non-interrupt logic will also first attempt to allocate from the
|
||||
general, pre-allocated structure pool. If that fails, it will
|
||||
dynamically allocate the meta data structure with an additional cost in performance.
|
||||
|
||||
config IEEE802154_MACDEV
|
||||
bool "Character driver for IEEE 802.15.4 MAC layer"
|
||||
default n
|
||||
depends on WIRELESS_IEEE802154
|
||||
---help---
|
||||
Enable the device driver to expose the IEEE 802.15.4 MAC layer
|
||||
access to user space as IOCTLs
|
||||
|
||||
if IEEE802154_MACDEV
|
||||
|
||||
config IEEE802154_MACDEV_RECVRPRIO
|
||||
int "Priority of frame receiver registerd with the MAC layer"
|
||||
default 0
|
||||
---help---
|
||||
When the MAC layer receives an incoming data frame, it passes the frame
|
||||
to registered receivers, in order of receiver priority, until one of the
|
||||
receivers claim the frame.
|
||||
|
||||
An example case would be when 6LoWPAN and the MAC character driver are
|
||||
enabled. Both have receivers registered with the MAC. The 6LoWPAN layer
|
||||
should get assigned a higher priority than the character driver. In this
|
||||
case, the 6LoWPAN receiver will receive the frame first. If the frame is
|
||||
a 6LoWPAN frame, it will claim the frame and the MAC will not pass the
|
||||
frame to any additional receivers. If it does not claim the frame, the
|
||||
MAC layer will call the next highest priority receiver, in this case,
|
||||
the MAC character driver (which should always be lowest priority since
|
||||
it is a "catch-all" type receiver).
|
||||
|
||||
endif # IEEE802154_MACDEV
|
||||
|
||||
config IEEE802154_NETDEV
|
||||
bool "IEEE802154 6loWPAN Network Device"
|
||||
@ -95,6 +117,24 @@ config IEEE802154_NETDEV
|
||||
|
||||
if IEEE802154_NETDEV
|
||||
|
||||
config IEEE802154_NETDEV_RECVRPRIO
|
||||
int "Priority of frame receiver registerd with the MAC layer"
|
||||
default 1
|
||||
---help---
|
||||
When the MAC layer receives an incoming data frame, it passes the frame
|
||||
to registered receivers, in order of receiver priority, until one of the
|
||||
receivers claim the frame.
|
||||
|
||||
An example case would be when 6LoWPAN and the MAC character driver are
|
||||
enabled. Both have receivers registered with the MAC. The 6LoWPAN layer
|
||||
should get assigned a higher priority than the character driver. In this
|
||||
case, the 6LoWPAN receiver will receive the frame first. If the frame is
|
||||
a 6LoWPAN frame, it will claim the frame and the MAC will not pass the
|
||||
frame to any additional receivers. If it does not claim the frame, the
|
||||
MAC layer will call the next highest priority receiver, in this case,
|
||||
the MAC character driver (which should always be lowest priority since
|
||||
it is a "catch-all" type receiver).
|
||||
|
||||
choice
|
||||
prompt "Work queue"
|
||||
default IEEE802154_NETDEV_LPWORK if SCHED_LPWORK
|
||||
|
@ -46,7 +46,7 @@ CSRCS += mac802154_sync.c
|
||||
|
||||
# Include wireless devices build support
|
||||
|
||||
ifeq ($(CONFIG_IEEE802154_MAC_DEV),y)
|
||||
ifeq ($(CONFIG_IEEE802154_MACDEV),y)
|
||||
CSRCS += mac802154_device.c
|
||||
endif
|
||||
|
||||
|
@ -628,11 +628,13 @@ static void mac802154_txdone_worker(FAR void *arg)
|
||||
notif->notiftype = IEEE802154_NOTIFY_CONF_DATA;
|
||||
|
||||
/* Release the MAC, call the callback, get exclusive access again */
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
priv->cb->notify(priv->cb, notif);
|
||||
mac802154_notify(priv, notif);
|
||||
mac802154_takesem(&priv->exclsem, false);
|
||||
}
|
||||
break;
|
||||
|
||||
case IEEE802154_FRAME_COMMAND:
|
||||
{
|
||||
switch (priv->curr_cmd)
|
||||
@ -640,10 +642,13 @@ static void mac802154_txdone_worker(FAR void *arg)
|
||||
case IEEE802154_CMD_ASSOC_REQ:
|
||||
mac802154_txdone_assocreq(priv, txdesc);
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_ASSOC_RESP:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_DISASSOC_NOT:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_DATA_REQ:
|
||||
/* Data requests can be sent for 3 different reasons.
|
||||
*
|
||||
@ -663,23 +668,31 @@ static void mac802154_txdone_worker(FAR void *arg)
|
||||
case MAC802154_OP_ASSOC:
|
||||
mac802154_txdone_datareq_assoc(priv, txdesc);
|
||||
break;
|
||||
|
||||
case MAC802154_OP_POLL:
|
||||
mac802154_txdone_datareq_poll(priv, txdesc);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_PANID_CONF_NOT:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_ORPHAN_NOT:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_BEACON_REQ:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_COORD_REALIGN:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_GTS_REQ:
|
||||
break;
|
||||
|
||||
default:
|
||||
/* We can deallocate the data conf notification as it is no
|
||||
* longer needed. We can't use the public function here
|
||||
@ -688,10 +701,12 @@ static void mac802154_txdone_worker(FAR void *arg)
|
||||
|
||||
privnotif->flink = priv->notif_free;
|
||||
priv->notif_free = privnotif;
|
||||
priv->nnotif = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
/* We can deallocate the data conf notification as it is no longer
|
||||
@ -907,22 +922,30 @@ static void mac802154_rxframe_worker(FAR void *arg)
|
||||
case IEEE802154_CMD_ASSOC_REQ:
|
||||
mac802154_rx_assocreq(priv, ind);
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_ASSOC_RESP:
|
||||
mac802154_rx_assocresp(priv, ind);
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_DISASSOC_NOT:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_DATA_REQ:
|
||||
mac802154_rx_datareq(priv, ind);
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_PANID_CONF_NOT:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_ORPHAN_NOT:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_BEACON_REQ:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_COORD_REALIGN:
|
||||
break;
|
||||
|
||||
case IEEE802154_CMD_GTS_REQ:
|
||||
break;
|
||||
}
|
||||
@ -1096,8 +1119,7 @@ static void mac802154_rx_dataframe(FAR struct ieee802154_privmac_s *priv,
|
||||
/* Release the MAC */
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
priv->cb->notify(priv->cb, notif);
|
||||
mac802154_notify(priv, notif);
|
||||
|
||||
/* If there was data, pass it along */
|
||||
|
||||
@ -1108,26 +1130,48 @@ static void mac802154_rx_dataframe(FAR struct ieee802154_privmac_s *priv,
|
||||
}
|
||||
else
|
||||
{
|
||||
FAR struct mac802154_maccb_s *cb;
|
||||
|
||||
notify_with_lock:
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
notify_without_lock:
|
||||
|
||||
/* If there is a registered MCPS callback receiver registered,
|
||||
* send the frame, otherwise, throw it out.
|
||||
/* If there are registered MCPS callback receivers registered,
|
||||
* then forward the frame in priority order. If there are no
|
||||
* registered receivers or if none of the receivers accept the
|
||||
* data frame then drop the frame.
|
||||
*/
|
||||
|
||||
if (priv->cb->rxframe != NULL)
|
||||
for (cb = priv->cb; cb != NULL; cb = cb->flink)
|
||||
{
|
||||
priv->cb->rxframe(priv->cb, ind);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Free the data indication struct from the pool */
|
||||
int ret;
|
||||
|
||||
ieee802154_ind_free(ind);
|
||||
/* Does this MAC client want frames? */
|
||||
|
||||
if (cb->rxframe != NULL)
|
||||
{
|
||||
/* Yes.. Offer this frame to the receiver */
|
||||
|
||||
ret = cb->rxframe(cb, ind);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* The receiver accepted and disposed of the frame and
|
||||
* its metadata. We are done.
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We get here if the there are no registered receivers or if
|
||||
* all of the registered receivers declined the frame.
|
||||
* Free the data indication struct from the pool
|
||||
*/
|
||||
|
||||
ieee802154_ind_free(ind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,18 +58,22 @@
|
||||
* Public Data Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Callback operations to notify the next highest layer of various asynchronous
|
||||
* events, usually triggered by some previous request or response invoked by the
|
||||
* upper layer.
|
||||
/* Callback operations to notify the next highest layer of various
|
||||
* asynchronous events, usually triggered by some previous request or
|
||||
* response invoked by the upper layer.
|
||||
*/
|
||||
|
||||
struct mac802154_maccb_s
|
||||
{
|
||||
CODE void (*notify)(FAR const struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_notif_s *notif);
|
||||
FAR struct mac802154_maccb_s *flink; /* Implements a singly linked list */
|
||||
uint8_t prio; /* RX frame callback priority */
|
||||
|
||||
CODE void (*rxframe)(FAR const struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_data_ind_s *ind);
|
||||
/* Callback methods */
|
||||
|
||||
CODE void (*notify)(FAR struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_notif_s *notif);
|
||||
CODE int (*rxframe)(FAR struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_data_ind_s *ind);
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -93,7 +97,7 @@ struct iob_s; /* Forward reference */
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_bind(MACHANDLE mac, FAR const struct mac802154_maccb_s *cb);
|
||||
int mac802154_bind(MACHANDLE mac, FAR struct mac802154_maccb_s *cb);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_ioctl
|
||||
|
@ -480,7 +480,7 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv,
|
||||
/* Release the MAC, call the callback, get exclusive access again */
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
priv->cb->notify(priv->cb, notif);
|
||||
mac802154_notify(priv, notif);
|
||||
mac802154_takesem(&priv->exclsem, false);
|
||||
}
|
||||
else
|
||||
@ -612,7 +612,7 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv,
|
||||
/* Release the MAC, call the callback, get exclusive access again */
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
priv->cb->notify(priv->cb, notif);
|
||||
mac802154_notify(priv, notif);
|
||||
mac802154_takesem(&priv->exclsem, false);
|
||||
}
|
||||
else
|
||||
@ -708,8 +708,7 @@ void mac802154_rx_assocreq(FAR struct ieee802154_privmac_s *priv,
|
||||
|
||||
/* Notify the next highest layer of the association status */
|
||||
|
||||
priv->cb->notify(priv->cb, notif);
|
||||
|
||||
mac802154_notify(priv, notif);
|
||||
return;
|
||||
|
||||
errout_with_sem:
|
||||
@ -804,7 +803,7 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv,
|
||||
|
||||
/* Notify the next highest layer of the association status */
|
||||
|
||||
priv->cb->notify(priv->cb, notif);
|
||||
mac802154_notify(priv, notif);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -853,5 +852,5 @@ static void mac802154_timeout_assoc(FAR struct ieee802154_privmac_s *priv)
|
||||
notif->u.assocconf.status = IEEE802154_STATUS_NO_DATA;
|
||||
notif->u.assocconf.saddr = IEEE802154_SADDR_UNSPEC;
|
||||
|
||||
priv->cb->notify(priv->cb, notif);
|
||||
mac802154_notify(priv, notif);
|
||||
}
|
||||
|
@ -69,12 +69,48 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_bind(MACHANDLE mac, FAR const struct mac802154_maccb_s *cb)
|
||||
int mac802154_bind(MACHANDLE mac, FAR struct mac802154_maccb_s *cb)
|
||||
{
|
||||
FAR struct ieee802154_privmac_s *priv =
|
||||
(FAR struct ieee802154_privmac_s *)mac;
|
||||
FAR struct mac802154_maccb_s *next;
|
||||
FAR struct mac802154_maccb_s *prev;
|
||||
|
||||
/* Add the MAC client callback structure to the list of MAC callbacks in
|
||||
* priority order.
|
||||
*
|
||||
* Search the list to find the location to insert the new instance.
|
||||
* The list is maintained in descending priority order.
|
||||
*/
|
||||
|
||||
for (prev = NULL, next = priv->cb;
|
||||
(next != NULL && cb->prio <= next->prio);
|
||||
prev = next, next = next->flink);
|
||||
|
||||
/* Add the instance to the spot found in the list. Check if the instance
|
||||
* goes at the head of the list.
|
||||
*/
|
||||
|
||||
if (prev == NULL)
|
||||
{
|
||||
cb->flink = priv->cb; /* May be NULL */
|
||||
priv->cb = cb;
|
||||
}
|
||||
|
||||
/* No.. the instance goes between prev and next */
|
||||
|
||||
else
|
||||
{
|
||||
cb->flink = next; /* May be NULL */
|
||||
prev->flink = cb;
|
||||
}
|
||||
|
||||
/* Keep track of the number of clients requesting notification */
|
||||
|
||||
if (cb->notify != NULL)
|
||||
{
|
||||
priv->nclients++;
|
||||
}
|
||||
|
||||
priv->cb = cb;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -141,10 +141,9 @@ static inline void mac802154dev_pushevent(FAR struct mac802154_chardevice_s *dev
|
||||
static inline FAR struct ieee802154_notif_s *
|
||||
mac802154dev_popevent(FAR struct mac802154_chardevice_s *dev);
|
||||
|
||||
static void mac802154dev_notify(FAR const struct mac802154_maccb_s *maccb,
|
||||
static void mac802154dev_notify(FAR struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_notif_s *notif);
|
||||
|
||||
static void mac802154dev_rxframe(FAR const struct mac802154_maccb_s *maccb,
|
||||
static int mac802154dev_rxframe(FAR struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_data_ind_s *ind);
|
||||
|
||||
static int mac802154dev_open(FAR struct file *filep);
|
||||
@ -762,7 +761,7 @@ static int mac802154dev_ioctl(FAR struct file *filep, int cmd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mac802154dev_notify(FAR const struct mac802154_maccb_s *maccb,
|
||||
static void mac802154dev_notify(FAR struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_notif_s *notif)
|
||||
{
|
||||
FAR struct mac802154dev_callback_s *cb =
|
||||
@ -826,8 +825,20 @@ static void mac802154dev_notify(FAR const struct mac802154_maccb_s *maccb,
|
||||
mac802154dev_givesem(&dev->md_exclsem);
|
||||
}
|
||||
|
||||
static void mac802154dev_rxframe(FAR const struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_data_ind_s *ind)
|
||||
/****************************************************************************
|
||||
* Name: mac802154dev_rxframe
|
||||
*
|
||||
* Description:
|
||||
* Handle received frames forward by the IEEE 802.15.4 MAC.
|
||||
*
|
||||
* Returned Value:
|
||||
* any failure. On success, the ind and its contained iob will be freed.
|
||||
* The ind will be intact if this function returns a failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mac802154dev_rxframe(FAR struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_data_ind_s *ind)
|
||||
{
|
||||
FAR struct mac802154dev_callback_s *cb =
|
||||
(FAR struct mac802154dev_callback_s *)maccb;
|
||||
@ -858,6 +869,7 @@ static void mac802154dev_rxframe(FAR const struct mac802154_maccb_s *maccb,
|
||||
/* Release the driver */
|
||||
|
||||
mac802154dev_givesem(&dev->md_exclsem);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -923,6 +935,8 @@ int mac802154dev_register(MACHANDLE mac, int minor)
|
||||
dev->md_cb.mc_priv = dev;
|
||||
|
||||
maccb = &dev->md_cb.mc_cb;
|
||||
maccb->flink = NULL;
|
||||
maccb->prio = CONFIG_IEEE802154_MACDEV_RECVRPRIO;
|
||||
maccb->notify = mac802154dev_notify;
|
||||
maccb->rxframe = mac802154dev_rxframe;
|
||||
|
||||
|
@ -147,10 +147,12 @@ typedef void (*mac802154_worker_t)(FAR struct ieee802154_privmac_s *priv);
|
||||
struct ieee802154_privmac_s
|
||||
{
|
||||
FAR struct ieee802154_radio_s *radio; /* Contained IEEE802.15.4 radio dev */
|
||||
FAR const struct mac802154_maccb_s *cb; /* Contained MAC callbacks */
|
||||
FAR struct mac802154_maccb_s *cb; /* Head of a list of MAC callbacks */
|
||||
FAR struct mac802154_radiocb_s radiocb; /* Interface to bind to radio */
|
||||
|
||||
sem_t exclsem; /* Support exclusive access */
|
||||
sem_t exclsem; /* Support exclusive access */
|
||||
uint8_t nclients; /* Number of notification clients */
|
||||
uint8_t nnotif; /* Number of remaining notifications */
|
||||
|
||||
/* Only support a single command at any given time. As of now I see no
|
||||
* condition where you need to have more than one command frame simultaneously
|
||||
|
@ -128,9 +128,10 @@ static uint16_t g_panid = 0xcafe;
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* IP address conversion */
|
||||
/* Utility functions */
|
||||
|
||||
static void lo_addr2ip(FAR struct net_driver_s *dev);
|
||||
static inline void lo_netmask(FAR struct net_driver_s *dev);
|
||||
|
||||
/* Polling logic */
|
||||
|
||||
@ -170,7 +171,7 @@ static int lo_req_data(FAR struct ieee802154_driver_s *netdev,
|
||||
*
|
||||
* Description:
|
||||
* Create a MAC-based IP address from the IEEE 802.15.14 short or extended
|
||||
* address of the MAC.
|
||||
* address assigned to the node.
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
@ -189,8 +190,8 @@ static void lo_addr2ip(FAR struct net_driver_s *dev)
|
||||
dev->d_ipv6addr[4] = (uint16_t)g_eaddr[0] << 8 | (uint16_t)g_eaddr[1];
|
||||
dev->d_ipv6addr[5] = (uint16_t)g_eaddr[2] << 8 | (uint16_t)g_eaddr[3];
|
||||
dev->d_ipv6addr[6] = (uint16_t)g_eaddr[4] << 8 | (uint16_t)g_eaddr[5];
|
||||
dev->d_ipv6addr[6] = (uint16_t)g_eaddr[6] << 8 | (uint16_t)g_eaddr[6];
|
||||
dev->d_ipv6addr[6] ^= 0x200;
|
||||
dev->d_ipv6addr[7] = (uint16_t)g_eaddr[6] << 8 | (uint16_t)g_eaddr[6];
|
||||
dev->d_ipv6addr[4] ^= 0x200;
|
||||
}
|
||||
#else
|
||||
static void lo_addr2ip(FAR struct net_driver_s *dev)
|
||||
@ -201,12 +202,45 @@ static void lo_addr2ip(FAR struct net_driver_s *dev)
|
||||
dev->d_ipv6addr[3] = 0;
|
||||
dev->d_ipv6addr[4] = 0;
|
||||
dev->d_ipv6addr[5] = HTONS(0x00ff);
|
||||
dev->d_ipv6addr[0] = HTONS(0xfe00);
|
||||
dev->d_ipv6addr[0] = htons(g_saddr) ^ 0x0200;
|
||||
dev->d_ipv6addr[6] ^= 0x200;
|
||||
dev->d_ipv6addr[6] = HTONS(0xfe00);
|
||||
dev->d_ipv6addr[7] = htons(g_saddr);
|
||||
dev->d_ipv6addr[7] ^= 0x200;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lo_netmask
|
||||
*
|
||||
* Description:
|
||||
* Create a netmask of a MAC-based IP address which may be based on either
|
||||
* the IEEE 802.15.14 short or extended address of the MAC.
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lo_netmask(FAR struct net_driver_s *dev)
|
||||
{
|
||||
dev->d_ipv6netmask[0] = 0xffff;
|
||||
dev->d_ipv6netmask[1] = 0xffff;
|
||||
dev->d_ipv6netmask[2] = 0xffff;
|
||||
dev->d_ipv6netmask[3] = 0xffff;
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
dev->d_ipv6netmask[4] = 0;
|
||||
dev->d_ipv6netmask[5] = 0;
|
||||
dev->d_ipv6netmask[6] = 0;
|
||||
dev->d_ipv6netmask[7] = 0;
|
||||
#else
|
||||
dev->d_ipv6netmask[4] = 0xffff;
|
||||
dev->d_ipv6netmask[5] = 0xffff;
|
||||
dev->d_ipv6netmask[6] = 0xffff;
|
||||
dev->d_ipv6netmask[7] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lo_loopback
|
||||
*
|
||||
@ -861,8 +895,9 @@ int ieee8021514_loopback(void)
|
||||
dev->d_buf = g_iobuffer; /* Attach the IO buffer */
|
||||
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
|
||||
|
||||
/* Advertise our MAC-based IP address */
|
||||
/* Set the network mask and advertise our MAC-based IP address */
|
||||
|
||||
lo_netmask(dev);
|
||||
lo_addr2ip(dev);
|
||||
|
||||
/* Initialize the Network frame-related callbacks */
|
||||
|
@ -109,7 +109,7 @@ struct macnet_callback_s
|
||||
{
|
||||
/* This holds the information visible to the MAC layer */
|
||||
|
||||
struct mac802154_maccb_s mc_cb; /* Interface understood by the MAC layer */
|
||||
struct mac802154_maccb_s mc_cb; /* Interface understood by the MAC layer */
|
||||
FAR struct macnet_driver_s *mc_priv; /* Our priv data */
|
||||
};
|
||||
|
||||
@ -136,11 +136,16 @@ struct macnet_driver_s
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Utility functions ********************************************************/
|
||||
|
||||
static int macnet_advertise(FAR struct net_driver_s *dev);
|
||||
static inline void macnet_netmask(FAR struct net_driver_s *dev);
|
||||
|
||||
/* IEE802.15.4 MAC callback functions ***************************************/
|
||||
|
||||
static void macnet_notify(FAR const struct mac802154_maccb_s *maccb,
|
||||
static void macnet_notify(FAR struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_notif_s *notif);
|
||||
static void macnet_rxframe(FAR const 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 */
|
||||
@ -162,7 +167,7 @@ static void macnet_conf_start(FAR struct macnet_driver_s *priv,
|
||||
static void macnet_conf_poll(FAR struct macnet_driver_s *priv,
|
||||
FAR struct ieee802154_poll_conf_s *conf);
|
||||
|
||||
/* Asynchronous event indications, replied to synchronously with responses */
|
||||
/* Asynchronous event indications, replied to synchronously with responses */
|
||||
|
||||
static void macnet_ind_associate(FAR struct macnet_driver_s *priv,
|
||||
FAR struct ieee802154_assoc_ind_s *conf);
|
||||
@ -216,6 +221,133 @@ static int macnet_req_data(FAR struct ieee802154_driver_s *netdev,
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: macnet_advertise
|
||||
*
|
||||
* Description:
|
||||
* Advertise the MAC and IPv6 address for this node.
|
||||
*
|
||||
* Creates a MAC-based IP address from the IEEE 802.15.14 short or extended
|
||||
* address assigned to the node.
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int macnet_advertise(FAR struct net_driver_s *dev)
|
||||
{
|
||||
struct ieee802154_netmac_s arg;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
uint8_t *eaddr;
|
||||
|
||||
/* Get the eaddr from the MAC */
|
||||
|
||||
memcpy(arg.ifr_name, dev->d_ifname, IFNAMSIZ);
|
||||
arg.u.getreq.attr = IEEE802154_ATTR_MAC_EXTENDED_ADDR;
|
||||
ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST,
|
||||
(unsigned long)((uintptr_t)&arg));
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("ERROR: MAC802154IOC_MLME_GET_REQUEST failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the IP address based on the eaddr */
|
||||
|
||||
eaddr = arg.u.getreq.attrval.mac.eaddr;
|
||||
memcpy(dev->d_mac.ieee802154.u8, eaddr, 8);
|
||||
|
||||
dev->d_ipv6addr[0] = HTONS(0xfe80);
|
||||
dev->d_ipv6addr[1] = 0;
|
||||
dev->d_ipv6addr[2] = 0;
|
||||
dev->d_ipv6addr[3] = 0;
|
||||
dev->d_ipv6addr[4] = (uint16_t)eaddr[0] << 8 | (uint16_t)eaddr[1];
|
||||
dev->d_ipv6addr[5] = (uint16_t)eaddr[2] << 8 | (uint16_t)eaddr[3];
|
||||
dev->d_ipv6addr[6] = (uint16_t)eaddr[4] << 8 | (uint16_t)eaddr[5];
|
||||
dev->d_ipv6addr[7] = (uint16_t)eaddr[6] << 8 | (uint16_t)eaddr[6];
|
||||
dev->d_ipv6addr[4] ^= 0x200;
|
||||
return OK;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Get the saddr from the MAC */
|
||||
|
||||
memcpy(arg.ifr_name, dev->d_ifname, IFNAMSIZ);
|
||||
arg.u.getreq.attr = IEEE802154_ATTR_MAC_SHORT_ADDRESS;
|
||||
ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST,
|
||||
(unsigned long)((uintptr_t)&arg));
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("ERROR: MAC802154IOC_MLME_GET_REQUEST failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
union
|
||||
{
|
||||
uint16_t u16;
|
||||
uint8_t u8[2];
|
||||
} u;
|
||||
|
||||
u.u16 = arg.u.getreq.attrval.mac.saddr;
|
||||
dev->d_mac.ieee802154.u8[0] = u.u8[0];
|
||||
dev->d_mac.ieee802154.u8[1] = u.u8[1];
|
||||
|
||||
/* Set the IP address based on the saddr */
|
||||
|
||||
dev->d_ipv6addr[0] = HTONS(0xfe80);
|
||||
dev->d_ipv6addr[1] = 0;
|
||||
dev->d_ipv6addr[2] = 0;
|
||||
dev->d_ipv6addr[3] = 0;
|
||||
dev->d_ipv6addr[4] = 0;
|
||||
dev->d_ipv6addr[5] = HTONS(0x00ff);
|
||||
dev->d_ipv6addr[6] = HTONS(0xfe00);
|
||||
dev->d_ipv6addr[7] = u.u16;
|
||||
dev->d_ipv6addr[7] ^= 0x200;
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: macnet_netmask
|
||||
*
|
||||
* Description:
|
||||
* Create a netmask of a MAC-based IP address which may be based on either
|
||||
* the IEEE 802.15.14 short or extended address of the MAC.
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void macnet_netmask(FAR struct net_driver_s *dev)
|
||||
{
|
||||
dev->d_ipv6netmask[0] = 0xffff;
|
||||
dev->d_ipv6netmask[1] = 0xffff;
|
||||
dev->d_ipv6netmask[2] = 0xffff;
|
||||
dev->d_ipv6netmask[3] = 0xffff;
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
dev->d_ipv6netmask[4] = 0;
|
||||
dev->d_ipv6netmask[5] = 0;
|
||||
dev->d_ipv6netmask[6] = 0;
|
||||
dev->d_ipv6netmask[7] = 0;
|
||||
#else
|
||||
dev->d_ipv6netmask[4] = 0xffff;
|
||||
dev->d_ipv6netmask[5] = 0xffff;
|
||||
dev->d_ipv6netmask[6] = 0xffff;
|
||||
dev->d_ipv6netmask[7] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: macnet_notify
|
||||
*
|
||||
@ -223,7 +355,7 @@ static int macnet_req_data(FAR struct ieee802154_driver_s *netdev,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void macnet_notify(FAR const struct mac802154_maccb_s *maccb,
|
||||
static void macnet_notify(FAR struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_notif_s *notif)
|
||||
{
|
||||
FAR struct macnet_callback_s *cb =
|
||||
@ -244,17 +376,27 @@ static void macnet_notify(FAR const struct mac802154_maccb_s *maccb,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Free the event notification */
|
||||
|
||||
mac802154_notif_free(priv->md_mac, notif);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: macnet_rxframe
|
||||
*
|
||||
* Description:
|
||||
* Handle received frames forward by the IEEE 802.15.4 MAC.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure. On success, the ind and its contained iob will be freed.
|
||||
* The ind will be intact if this function returns a failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void macnet_rxframe(FAR const struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_data_ind_s *ind)
|
||||
static int macnet_rxframe(FAR struct mac802154_maccb_s *maccb,
|
||||
FAR struct ieee802154_data_ind_s *ind)
|
||||
{
|
||||
FAR struct macnet_callback_s *cb =
|
||||
(FAR struct macnet_callback_s *)maccb;
|
||||
@ -264,10 +406,31 @@ static void macnet_rxframe(FAR const struct mac802154_maccb_s *maccb,
|
||||
DEBUGASSERT(cb != NULL && cb->mc_priv != NULL);
|
||||
priv = cb->mc_priv;
|
||||
|
||||
/* Extract the IOB containing the frame from the struct ieee802154_data_ind_s */
|
||||
/* Ignore the frame if the network is not up */
|
||||
|
||||
if (!priv->md_bifup)
|
||||
{
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
||||
/* Peek the IOB contained the frame in the struct ieee802154_data_ind_s */
|
||||
|
||||
DEBUGASSERT(priv != NULL && ind != NULL && ind->frame != NULL);
|
||||
iob = ind->frame;
|
||||
iob = ind->frame;
|
||||
|
||||
/* If the frame is not a 6LoWPAN frame, then return an error. The first
|
||||
* byte following the MAC head at the io_offset should be a valid IPHC
|
||||
* header.
|
||||
*/
|
||||
|
||||
if ((iob->io_data[iob->io_offset] & SIXLOWPAN_DISPATCH_NALP_MASK) ==
|
||||
SIXLOWPAN_DISPATCH_NALP)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Remove the IOB containing the frame. */
|
||||
|
||||
ind->frame = NULL;
|
||||
|
||||
/* Transfer the frame to the network logic */
|
||||
@ -279,6 +442,7 @@ static void macnet_rxframe(FAR const struct mac802154_maccb_s *maccb,
|
||||
*/
|
||||
|
||||
ieee802154_ind_free(ind);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -624,34 +788,43 @@ static void macnet_txpoll_expiry(int argc, wdparm_t arg, ...)
|
||||
|
||||
static int macnet_ifup(FAR struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct macnet_driver_s *priv = (FAR struct macnet_driver_s *)dev->d_private;
|
||||
FAR struct macnet_driver_s *priv =
|
||||
(FAR struct macnet_driver_s *)dev->d_private;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
ninfo("Bringing up: %d.%d.%d.%d\n",
|
||||
dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
|
||||
(dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
ninfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||
dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2],
|
||||
dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5],
|
||||
dev->d_ipv6addr[6], dev->d_ipv6addr[7]);
|
||||
/* Set the IP address based on the addressing assigned to the node */
|
||||
|
||||
ret = macnet_advertise(dev);
|
||||
if (ret >= 0)
|
||||
{
|
||||
ninfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||
dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2],
|
||||
dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5],
|
||||
dev->d_ipv6addr[6], dev->d_ipv6addr[7]);
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
ninfo(" Node: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
dev->d_mac.ieee802154.u8[0], dev->d_mac.ieee802154.u8[1],
|
||||
dev->d_mac.ieee802154.u8[2], dev->d_mac.ieee802154.u8[3],
|
||||
dev->d_mac.ieee802154.u8[4], dev->d_mac.ieee802154.u8[5],
|
||||
dev->d_mac.ieee802154.u8[6], dev->d_mac.ieee802154.u8[7]);
|
||||
#else
|
||||
ninfo(" Node: %02x:%02x\n",
|
||||
dev->d_mac.ieee802154.u8[0], dev->d_mac.ieee802154.u8[1]);
|
||||
#endif
|
||||
|
||||
/* Initialize PHYs, the IEEE 802.15.4 interface, and setup up IEEE 802.15.4 interrupts */
|
||||
#warning Missing logic
|
||||
/* Set and activate a timer process */
|
||||
|
||||
/* Setup up address filtering */
|
||||
(void)wd_start(priv->md_txpoll, TXPOLL_WDDELAY, macnet_txpoll_expiry,
|
||||
1, (wdparm_t)priv);
|
||||
|
||||
/* Set and activate a timer process */
|
||||
/* The interface is now up */
|
||||
|
||||
(void)wd_start(priv->md_txpoll, TXPOLL_WDDELAY, macnet_txpoll_expiry, 1,
|
||||
(wdparm_t)priv);
|
||||
priv->md_bifup = true;
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
/* Enable the IEEE 802.15.4 radio */
|
||||
|
||||
priv->md_bifup = true;
|
||||
return OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -993,7 +1166,7 @@ static int macnet_req_data(FAR struct ieee802154_driver_s *netdev,
|
||||
*
|
||||
* Description:
|
||||
* Register a network driver to access the IEEE 802.15.4 MAC layer from
|
||||
* a socket using 6loWPAN
|
||||
* a socket using 6LoWPAN
|
||||
*
|
||||
* Input Parameters:
|
||||
* mac - Pointer to the mac layer struct to be registered.
|
||||
@ -1062,6 +1235,10 @@ int mac802154netdev_register(MACHANDLE mac)
|
||||
|
||||
DEBUGASSERT(priv->md_txpoll != NULL);
|
||||
|
||||
/* Set the network mask. */
|
||||
|
||||
macnet_netmask(dev);
|
||||
|
||||
/* Initialize the Network frame-related callbacks */
|
||||
|
||||
ieee->i_get_mhrlen = macnet_get_mhrlen; /* Get MAC header length */
|
||||
@ -1072,6 +1249,8 @@ int mac802154netdev_register(MACHANDLE mac)
|
||||
priv->md_cb.mc_priv = priv;
|
||||
|
||||
maccb = &priv->md_cb.mc_cb;
|
||||
maccb->flink = NULL;
|
||||
maccb->prio = CONFIG_IEEE802154_NETDEV_RECVRPRIO;
|
||||
maccb->notify = macnet_notify;
|
||||
maccb->rxframe = macnet_rxframe;
|
||||
|
||||
|
@ -74,18 +74,38 @@ int mac802154_notif_free(MACHANDLE mac,
|
||||
{
|
||||
FAR struct ieee802154_privmac_s *priv =
|
||||
(FAR struct ieee802154_privmac_s *)mac;
|
||||
FAR struct mac802154_notif_s *privnotif = (FAR struct mac802154_notif_s *)notif;
|
||||
FAR struct mac802154_notif_s *privnotif =
|
||||
(FAR struct mac802154_notif_s *)notif;
|
||||
|
||||
/* Get exclusive access to the MAC */
|
||||
|
||||
mac802154_takesem(&priv->exclsem, false);
|
||||
|
||||
privnotif->flink = priv->notif_free;
|
||||
priv->notif_free = privnotif;
|
||||
mac802154_givesem(&priv->notif_sem);
|
||||
/* We know how many clients have registered for notifications. Each must
|
||||
* call mac802154_notif_free() before we can release the notification
|
||||
* resource.
|
||||
*/
|
||||
|
||||
if (priv->nnotif < 2)
|
||||
{
|
||||
/* This is the free from the last notification */
|
||||
|
||||
privnotif->flink = priv->notif_free;
|
||||
priv->notif_free = privnotif;
|
||||
priv->nnotif = 0;
|
||||
|
||||
mac802154_givesem(&priv->notif_sem);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* More calls are expected. Decrement the count of expected calls
|
||||
* and preserve the notification resources.
|
||||
*/
|
||||
|
||||
priv->nnotif--;
|
||||
}
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
@ -125,6 +145,7 @@ void mac802154_notifpool_init(FAR struct ieee802154_privmac_s *priv)
|
||||
pool++;
|
||||
remaining--;
|
||||
}
|
||||
|
||||
sem_init(&priv->notif_sem, 0, CONFIG_MAC802154_NNOTIF);
|
||||
}
|
||||
|
||||
@ -165,6 +186,7 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
||||
{
|
||||
privnotif = priv->notif_free;
|
||||
priv->notif_free = privnotif->flink;
|
||||
priv->nnotif = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -200,9 +222,44 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
||||
|
||||
privnotif = priv->notif_free;
|
||||
priv->notif_free = privnotif->flink;
|
||||
priv->nnotif = 0;
|
||||
}
|
||||
|
||||
*notif = (FAR struct ieee802154_notif_s *)privnotif;
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_notify
|
||||
*
|
||||
* Description:
|
||||
* Notify every register MAC client.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mac802154_notify(FAR struct ieee802154_privmac_s *priv,
|
||||
FAR struct ieee802154_notif_s *notif)
|
||||
{
|
||||
FAR struct mac802154_maccb_s *cb;
|
||||
|
||||
/* Set the notification count so that the notification resources will be
|
||||
* preserved until the final notification.
|
||||
*/
|
||||
|
||||
priv->nnotif = priv->nclients;
|
||||
|
||||
/* Try to notify every registered MAC client */
|
||||
|
||||
for (cb = priv->cb; cb != NULL; cb = cb->flink)
|
||||
{
|
||||
/* Does this client want notifications? */
|
||||
|
||||
if (cb->notify != NULL)
|
||||
{
|
||||
/* Yes.. Notify */
|
||||
|
||||
cb->notify(cb, notif);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,8 @@
|
||||
|
||||
struct mac802154_notif_s
|
||||
{
|
||||
struct ieee802154_notif_s pub;
|
||||
FAR struct mac802154_notif_s *flink;
|
||||
struct ieee802154_notif_s pub; /* Publically visible structure */
|
||||
FAR struct mac802154_notif_s *flink; /* Supports a singly linked list */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -79,4 +79,7 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
|
||||
FAR struct ieee802154_notif_s **notif,
|
||||
bool allow_interrupt);
|
||||
|
||||
void mac802154_notify(FAR struct ieee802154_privmac_s *priv,
|
||||
FAR struct ieee802154_notif_s *notif);
|
||||
|
||||
#endif /* __WIRELESS_IEEE802154__MAC802154_NOTIF_H */
|
@ -50,8 +50,6 @@
|
||||
#include <debug.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/mm/iob.h>
|
||||
|
||||
#include "mac802154.h"
|
||||
#include "mac802154_internal.h"
|
||||
|
||||
@ -83,7 +81,6 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req)
|
||||
{
|
||||
FAR struct ieee802154_privmac_s *priv =
|
||||
(FAR struct ieee802154_privmac_s *)mac;
|
||||
FAR struct iob_s *iob;
|
||||
FAR struct ieee802154_txdesc_s *txdesc;
|
||||
int ret;
|
||||
|
||||
@ -221,7 +218,7 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv,
|
||||
/* Release the MAC, call the callback, get exclusive access again */
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
priv->cb->notify(priv->cb, notif);
|
||||
mac802154_notify(priv, notif);
|
||||
mac802154_takesem(&priv->exclsem, false);
|
||||
}
|
||||
else
|
||||
@ -261,7 +258,7 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mac802154_timeout_poll(FAR struct ieee802154_privmac_s *priv)
|
||||
void mac802154_timeout_poll(FAR struct ieee802154_privmac_s *priv)
|
||||
{
|
||||
FAR struct ieee802154_notif_s *notif;
|
||||
|
||||
@ -286,5 +283,5 @@ static void mac802154_timeout_poll(FAR struct ieee802154_privmac_s *priv)
|
||||
notif->notiftype = IEEE802154_NOTIFY_CONF_POLL;
|
||||
notif->u.pollconf.status = IEEE802154_STATUS_NO_DATA;
|
||||
|
||||
priv->cb->notify(priv->cb, notif);
|
||||
mac802154_notify(priv, notif);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user