2016-06-14 16:52:57 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Intel Corporation.
|
|
|
|
*
|
2017-01-19 09:01:01 +08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2016-06-14 16:52:57 +08:00
|
|
|
*/
|
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @brief Public IEEE 802.15.4 Radio API
|
|
|
|
*/
|
|
|
|
|
2018-09-15 01:43:44 +08:00
|
|
|
#ifndef ZEPHYR_INCLUDE_NET_IEEE802154_RADIO_H_
|
|
|
|
#define ZEPHYR_INCLUDE_NET_IEEE802154_RADIO_H_
|
2016-11-12 06:13:24 +08:00
|
|
|
|
|
|
|
#include <device.h>
|
|
|
|
#include <net/net_if.h>
|
2018-03-16 16:07:30 +08:00
|
|
|
#include <net/net_pkt.h>
|
2017-12-07 17:13:56 +08:00
|
|
|
#include <net/ieee802154.h>
|
2016-11-12 06:13:24 +08:00
|
|
|
|
2017-07-24 21:23:14 +08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2017-07-20 21:29:45 +08:00
|
|
|
/**
|
|
|
|
* @addtogroup ieee802154
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2017-09-04 19:06:49 +08:00
|
|
|
enum ieee802154_hw_caps {
|
2020-02-25 18:16:05 +08:00
|
|
|
IEEE802154_HW_FCS = BIT(0), /* Frame Check-Sum supported */
|
|
|
|
IEEE802154_HW_PROMISC = BIT(1), /* Promiscuous mode supported */
|
|
|
|
IEEE802154_HW_FILTER = BIT(2), /* Filter PAN ID, long/short addr */
|
|
|
|
IEEE802154_HW_CSMA = BIT(3), /* CSMA-CA supported */
|
|
|
|
IEEE802154_HW_2_4_GHZ = BIT(4), /* 2.4Ghz radio supported */
|
|
|
|
IEEE802154_HW_TX_RX_ACK = BIT(5), /* Handles ACK request on TX */
|
|
|
|
IEEE802154_HW_SUB_GHZ = BIT(6), /* Sub-GHz radio supported */
|
net: ieee802154_radio: Allow to specify TX mode
Even though radio driver can report in its capabilities that it does
support CSMA CA, there's no way in the driver to select how the frame
should be transmitted (with CSMA or without). As layers above radio
driver (Thread, Zigbee) can expect that both TX modes are available, we
need to extend the API to allow either of these modes.
This commits extends the API `tx` function with an extra parameter,
`ieee802154_tx_mode`, which informs the driver how the packet should be
transmitted. Currently, the following modes are specified:
* direct (regular tx, no cca, just how it worked so far),
* CCA before transmission,
* CSMA CA before transmission,
* delayed TX,
* delayed TX with CCA
Assume that radios that reported CSMA CA capability transmit in CSMA CA
mode by default, all others will support direct mode.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-02-28 20:57:49 +08:00
|
|
|
IEEE802154_HW_ENERGY_SCAN = BIT(7), /* Energy scan supported */
|
|
|
|
IEEE802154_HW_TXTIME = BIT(8), /* TX at specified time supported */
|
2017-09-04 19:06:49 +08:00
|
|
|
};
|
|
|
|
|
2017-09-05 19:50:36 +08:00
|
|
|
enum ieee802154_filter_type {
|
|
|
|
IEEE802154_FILTER_TYPE_IEEE_ADDR,
|
|
|
|
IEEE802154_FILTER_TYPE_SHORT_ADDR,
|
|
|
|
IEEE802154_FILTER_TYPE_PAN_ID,
|
2018-03-19 16:53:29 +08:00
|
|
|
IEEE802154_FILTER_TYPE_SRC_IEEE_ADDR,
|
|
|
|
IEEE802154_FILTER_TYPE_SRC_SHORT_ADDR,
|
2017-09-05 19:50:36 +08:00
|
|
|
};
|
|
|
|
|
2020-02-28 22:41:05 +08:00
|
|
|
enum ieee802154_event {
|
|
|
|
IEEE802154_EVENT_TX_STARTED /* Data transmission started */
|
|
|
|
};
|
|
|
|
|
2020-05-28 00:26:57 +08:00
|
|
|
typedef void (*energy_scan_done_cb_t)(struct device *dev, int16_t max_ed);
|
2020-02-28 22:41:05 +08:00
|
|
|
|
|
|
|
typedef void (*ieee802154_event_cb_t)(struct device *dev,
|
|
|
|
enum ieee802154_event evt,
|
|
|
|
void *event_params);
|
|
|
|
|
2017-09-05 19:50:36 +08:00
|
|
|
struct ieee802154_filter {
|
|
|
|
/** @cond ignore */
|
|
|
|
union {
|
2020-05-28 00:26:57 +08:00
|
|
|
uint8_t *ieee_addr;
|
|
|
|
uint16_t short_addr;
|
|
|
|
uint16_t pan_id;
|
2017-09-05 19:50:36 +08:00
|
|
|
};
|
|
|
|
/* @endcond */
|
|
|
|
};
|
|
|
|
|
net: ieee802154_radio: Allow to specify TX mode
Even though radio driver can report in its capabilities that it does
support CSMA CA, there's no way in the driver to select how the frame
should be transmitted (with CSMA or without). As layers above radio
driver (Thread, Zigbee) can expect that both TX modes are available, we
need to extend the API to allow either of these modes.
This commits extends the API `tx` function with an extra parameter,
`ieee802154_tx_mode`, which informs the driver how the packet should be
transmitted. Currently, the following modes are specified:
* direct (regular tx, no cca, just how it worked so far),
* CCA before transmission,
* CSMA CA before transmission,
* delayed TX,
* delayed TX with CCA
Assume that radios that reported CSMA CA capability transmit in CSMA CA
mode by default, all others will support direct mode.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-02-28 20:57:49 +08:00
|
|
|
/** IEEE802.15.4 Transmission mode. */
|
|
|
|
enum ieee802154_tx_mode {
|
|
|
|
/** Transmit packet immediately, no CCA. */
|
|
|
|
IEEE802154_TX_MODE_DIRECT,
|
|
|
|
|
|
|
|
/** Perform CCA before packet transmission. */
|
|
|
|
IEEE802154_TX_MODE_CCA,
|
|
|
|
|
|
|
|
/** Perform full CSMA CA procedure before packet transmission. */
|
|
|
|
IEEE802154_TX_MODE_CSMA_CA,
|
|
|
|
|
|
|
|
/** Transmit packet in the future, at specified time, no CCA. */
|
|
|
|
IEEE802154_TX_MODE_TXTIME,
|
|
|
|
|
|
|
|
/** Transmit packet in the future, perform CCA before transmission. */
|
|
|
|
IEEE802154_TX_MODE_TXTIME_CCA,
|
|
|
|
};
|
|
|
|
|
2020-03-05 21:37:44 +08:00
|
|
|
/** IEEE802.15.4 Frame Pending Bit table address matching mode. */
|
|
|
|
enum ieee802154_fpb_mode {
|
|
|
|
/** The pending bit shall be set only for addresses found in the list.
|
|
|
|
*/
|
|
|
|
IEEE802154_FPB_ADDR_MATCH_THREAD,
|
|
|
|
|
|
|
|
/** The pending bit shall be cleared for short addresses found in
|
|
|
|
* the list.
|
|
|
|
*/
|
|
|
|
IEEE802154_FPB_ADDR_MATCH_ZIGBEE,
|
|
|
|
};
|
|
|
|
|
2019-04-15 15:36:42 +08:00
|
|
|
/** IEEE802.15.4 driver configuration types. */
|
|
|
|
enum ieee802154_config_type {
|
|
|
|
/** Indicates how radio driver should set Frame Pending bit in ACK
|
|
|
|
* responses for Data Requests. If enabled, radio driver should
|
|
|
|
* determine whether to set the bit or not based on the information
|
2020-03-05 21:37:44 +08:00
|
|
|
* provided with ``IEEE802154_CONFIG_ACK_FPB`` config and FPB address
|
|
|
|
* matching mode specified. Otherwise, Frame Pending bit should be set
|
|
|
|
* to ``1``(see IEEE Std 802.15.4-2006, 7.2.2.3.1).
|
2019-04-15 15:36:42 +08:00
|
|
|
*/
|
|
|
|
IEEE802154_CONFIG_AUTO_ACK_FPB,
|
|
|
|
|
|
|
|
/** Indicates whether to set ACK Frame Pending bit for specific address
|
|
|
|
* or not. Disabling the Frame Pending bit with no address provided
|
|
|
|
* (NULL pointer) should disable it for all enabled addresses.
|
|
|
|
*/
|
|
|
|
IEEE802154_CONFIG_ACK_FPB,
|
2020-03-19 19:48:17 +08:00
|
|
|
|
2020-03-19 21:45:01 +08:00
|
|
|
/** Indicates whether the device is a PAN coordinator. */
|
|
|
|
IEEE802154_CONFIG_PAN_COORDINATOR,
|
|
|
|
|
2020-03-19 19:48:17 +08:00
|
|
|
/** Enable/disable promiscuous mode. */
|
|
|
|
IEEE802154_CONFIG_PROMISCUOUS,
|
2020-02-28 22:41:05 +08:00
|
|
|
|
|
|
|
/** Specifies new radio event handler. Specifying NULL as a handler
|
|
|
|
* will disable radio events notification.
|
|
|
|
*/
|
|
|
|
IEEE802154_CONFIG_EVENT_HANDLER
|
2019-04-15 15:36:42 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/** IEEE802.15.4 driver configuration data. */
|
|
|
|
struct ieee802154_config {
|
|
|
|
/** Configuration data. */
|
|
|
|
union {
|
|
|
|
/** ``IEEE802154_CONFIG_AUTO_ACK_FPB`` */
|
|
|
|
struct {
|
|
|
|
bool enabled;
|
2020-03-05 21:37:44 +08:00
|
|
|
enum ieee802154_fpb_mode mode;
|
2019-04-15 15:36:42 +08:00
|
|
|
} auto_ack_fpb;
|
|
|
|
|
|
|
|
/** ``IEEE802154_CONFIG_ACK_FPB`` */
|
|
|
|
struct {
|
2020-05-28 00:26:57 +08:00
|
|
|
uint8_t *addr;
|
2019-04-15 15:36:42 +08:00
|
|
|
bool extended;
|
|
|
|
bool enabled;
|
|
|
|
} ack_fpb;
|
2020-03-19 19:48:17 +08:00
|
|
|
|
2020-03-19 21:45:01 +08:00
|
|
|
/** ``IEEE802154_CONFIG_PAN_COORDINATOR`` */
|
|
|
|
bool pan_coordinator;
|
|
|
|
|
2020-03-19 19:48:17 +08:00
|
|
|
/** ``IEEE802154_CONFIG_PROMISCUOUS`` */
|
|
|
|
bool promiscuous;
|
2020-02-28 22:41:05 +08:00
|
|
|
|
|
|
|
/** ``IEEE802154_CONFIG_EVENT_HANDLER`` */
|
|
|
|
ieee802154_event_cb_t event_handler;
|
2019-04-15 15:36:42 +08:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2019-02-26 20:22:53 +08:00
|
|
|
/**
|
|
|
|
* @brief IEEE 802.15.4 radio interface API.
|
|
|
|
*
|
|
|
|
*/
|
2016-11-12 06:13:24 +08:00
|
|
|
struct ieee802154_radio_api {
|
|
|
|
/**
|
|
|
|
* Mandatory to get in first position.
|
|
|
|
* A network device should indeed provide a pointer on such
|
|
|
|
* net_if_api structure. So we make current structure pointer
|
|
|
|
* that can be casted to a net_if_api structure pointer.
|
|
|
|
*/
|
|
|
|
struct net_if_api iface_api;
|
|
|
|
|
2017-09-04 19:06:49 +08:00
|
|
|
/** Get the device capabilities */
|
|
|
|
enum ieee802154_hw_caps (*get_capabilities)(struct device *dev);
|
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
/** Clear Channel Assesment - Check channel's activity */
|
|
|
|
int (*cca)(struct device *dev);
|
|
|
|
|
|
|
|
/** Set current channel */
|
2020-05-28 00:26:57 +08:00
|
|
|
int (*set_channel)(struct device *dev, uint16_t channel);
|
2016-11-12 06:13:24 +08:00
|
|
|
|
2018-03-19 16:53:29 +08:00
|
|
|
/** Set/Unset filters (for IEEE802154_HW_FILTER ) */
|
|
|
|
int (*filter)(struct device *dev,
|
|
|
|
bool set,
|
|
|
|
enum ieee802154_filter_type type,
|
|
|
|
const struct ieee802154_filter *filter);
|
2017-09-05 19:50:36 +08:00
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
/** Set TX power level in dbm */
|
2020-05-28 00:26:57 +08:00
|
|
|
int (*set_txpower)(struct device *dev, int16_t dbm);
|
2016-11-12 06:13:24 +08:00
|
|
|
|
2017-04-05 14:37:44 +08:00
|
|
|
/** Transmit a packet fragment */
|
net: ieee802154_radio: Allow to specify TX mode
Even though radio driver can report in its capabilities that it does
support CSMA CA, there's no way in the driver to select how the frame
should be transmitted (with CSMA or without). As layers above radio
driver (Thread, Zigbee) can expect that both TX modes are available, we
need to extend the API to allow either of these modes.
This commits extends the API `tx` function with an extra parameter,
`ieee802154_tx_mode`, which informs the driver how the packet should be
transmitted. Currently, the following modes are specified:
* direct (regular tx, no cca, just how it worked so far),
* CCA before transmission,
* CSMA CA before transmission,
* delayed TX,
* delayed TX with CCA
Assume that radios that reported CSMA CA capability transmit in CSMA CA
mode by default, all others will support direct mode.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-02-28 20:57:49 +08:00
|
|
|
int (*tx)(struct device *dev, enum ieee802154_tx_mode mode,
|
|
|
|
struct net_pkt *pkt, struct net_buf *frag);
|
2016-11-12 06:13:24 +08:00
|
|
|
|
|
|
|
/** Start the device */
|
|
|
|
int (*start)(struct device *dev);
|
|
|
|
|
|
|
|
/** Stop the device */
|
|
|
|
int (*stop)(struct device *dev);
|
2017-09-11 15:59:25 +08:00
|
|
|
|
2019-04-15 15:36:42 +08:00
|
|
|
/** Set specific radio driver configuration. */
|
|
|
|
int (*configure)(struct device *dev,
|
|
|
|
enum ieee802154_config_type type,
|
|
|
|
const struct ieee802154_config *config);
|
|
|
|
|
2017-09-11 15:59:25 +08:00
|
|
|
#ifdef CONFIG_NET_L2_IEEE802154_SUB_GHZ
|
|
|
|
/** Get the available amount of Sub-GHz channels */
|
2020-05-28 00:26:57 +08:00
|
|
|
uint16_t (*get_subg_channel_count)(struct device *dev);
|
2017-09-11 15:59:25 +08:00
|
|
|
#endif /* CONFIG_NET_L2_IEEE802154_SUB_GHZ */
|
2018-03-19 18:20:26 +08:00
|
|
|
|
|
|
|
/** Run an energy detection scan.
|
2020-04-01 17:45:18 +08:00
|
|
|
* Note: channel must be set prior to request this function.
|
|
|
|
* duration parameter is in ms.
|
2018-03-19 18:20:26 +08:00
|
|
|
*/
|
|
|
|
int (*ed_scan)(struct device *dev,
|
2020-05-28 00:26:57 +08:00
|
|
|
uint16_t duration,
|
2020-02-25 18:16:05 +08:00
|
|
|
energy_scan_done_cb_t done_cb);
|
2018-11-15 17:21:08 +08:00
|
|
|
};
|
2016-11-12 06:13:24 +08:00
|
|
|
|
2019-11-26 17:04:32 +08:00
|
|
|
/* Make sure that the network interface API is properly setup inside
|
|
|
|
* IEEE 802154 radio API struct (it is the first one).
|
|
|
|
*/
|
|
|
|
BUILD_ASSERT(offsetof(struct ieee802154_radio_api, iface_api) == 0);
|
|
|
|
|
2018-03-16 16:07:30 +08:00
|
|
|
#define IEEE802154_AR_FLAG_SET (0x20)
|
|
|
|
|
2017-11-16 18:11:51 +08:00
|
|
|
/**
|
|
|
|
* @brief Check if AR flag is set on the frame inside given net_pkt
|
|
|
|
*
|
2019-01-16 21:29:05 +08:00
|
|
|
* @param frag A valid pointer on a net_buf structure, must not be NULL,
|
2018-03-16 16:07:30 +08:00
|
|
|
* and its length should be at least made of 1 byte (ACK frames
|
|
|
|
* are the smallest frames on 15.4 and made of 3 bytes, not
|
|
|
|
* not counting the FCS part).
|
2017-11-16 18:11:51 +08:00
|
|
|
*
|
|
|
|
* @return True if AR flag is set, False otherwise
|
|
|
|
*/
|
2019-01-16 21:29:05 +08:00
|
|
|
static inline bool ieee802154_is_ar_flag_set(struct net_buf *frag)
|
2018-03-16 16:07:30 +08:00
|
|
|
{
|
2019-01-16 21:29:05 +08:00
|
|
|
return (*frag->data & IEEE802154_AR_FLAG_SET);
|
2018-03-16 16:07:30 +08:00
|
|
|
}
|
2017-11-16 18:11:51 +08:00
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
/**
|
|
|
|
* @brief Radio driver ACK handling function that hw drivers should use
|
|
|
|
*
|
|
|
|
* @details ACK handling requires fast handling and thus such function
|
2017-05-03 08:21:56 +08:00
|
|
|
* helps to hook directly the hw drivers to the radio driver.
|
2016-11-12 06:13:24 +08:00
|
|
|
*
|
|
|
|
* @param iface A valid pointer on a network interface that received the packet
|
2017-04-05 14:37:44 +08:00
|
|
|
* @param pkt A valid pointer on a packet to check
|
2016-11-12 06:13:24 +08:00
|
|
|
*
|
|
|
|
* @return NET_OK if it was handled, NET_CONTINUE otherwise
|
|
|
|
*/
|
2019-02-14 21:33:22 +08:00
|
|
|
#ifndef CONFIG_IEEE802154_RAW_MODE
|
2016-11-12 06:13:24 +08:00
|
|
|
extern enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
|
2017-04-05 14:37:44 +08:00
|
|
|
struct net_pkt *pkt);
|
2017-11-16 18:11:51 +08:00
|
|
|
#else /* CONFIG_IEEE802154_RAW_MODE */
|
|
|
|
|
|
|
|
static inline enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
|
|
|
|
struct net_pkt *pkt)
|
|
|
|
{
|
|
|
|
return NET_CONTINUE;
|
|
|
|
}
|
2019-02-14 21:33:22 +08:00
|
|
|
#endif /* CONFIG_IEEE802154_RAW_MODE */
|
2017-11-16 18:11:51 +08:00
|
|
|
|
2019-02-14 21:33:22 +08:00
|
|
|
/**
|
|
|
|
* @brief Initialize L2 stack for a given interface
|
|
|
|
*
|
|
|
|
* @param iface A valid pointer on a network interface
|
|
|
|
*/
|
|
|
|
#ifndef CONFIG_IEEE802154_RAW_MODE
|
|
|
|
void ieee802154_init(struct net_if *iface);
|
|
|
|
#else
|
2017-11-16 18:11:51 +08:00
|
|
|
#define ieee802154_init(_iface_)
|
|
|
|
#endif /* CONFIG_IEEE802154_RAW_MODE */
|
2017-10-09 17:49:28 +08:00
|
|
|
|
2017-07-24 21:23:14 +08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-07-20 21:29:45 +08:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2018-09-15 01:43:44 +08:00
|
|
|
#endif /* ZEPHYR_INCLUDE_NET_IEEE802154_RADIO_H_ */
|