1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/include/net/ieee802154/radio.h
2020-12-04 09:40:55 +01:00

1264 lines
40 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2020 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup drivers_ieee802154_hal IEEE802.15.4 Radio Hardware Abstraction Layer
* @ingroup drivers
* @experimental This API is experimental and in an early state - expect
* changes!
* @brief This is a Hardware Abstraction Layer for IEEE802.15.4 compatible
* radios.
* @{
*
* @author José I. Alamos <jose.alamos@haw-hamburg.de>
*/
#ifndef NET_IEEE802154_RADIO_H
#define NET_IEEE802154_RADIO_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include "iolist.h"
#include "sys/uio.h"
#include "byteorder.h"
#include "net/eui64.h"
/**
* @brief Forward declaration of the radio ops structure.
*/
typedef struct ieee802154_radio_ops ieee802154_radio_ops_t;
/**
* @brief IEEE802.15.4 Radio capabilities
*
* These flags represent the hardware capabilities of a given device.
*/
typedef enum {
/**
* @brief the device supports frame retransmissions with CSMA-CA
*
* The device supports sending with CSMA-CA and retransmissions. If the
* CSMA-CA fails, the device reports a @ref TX_STATUS_MEDIUM_BUSY when
* calling @ref ieee802154_radio_ops::confirm_transmit. In case CSMA-CA
* succeeds and the ACK frame is expected, the
* device reports a @ref TX_STATUS_SUCCESS if the ACK frame is received
* during any retransmission attempt. Otherwise, it reports a @ref
* TX_STATUS_NO_ACK
*
* ACK frames are not indicated to the upper layer.
*
* @note it's implicit that a radio supports @ref
* IEEE802154_CAP_AUTO_CSMA if this cap is available
*/
IEEE802154_CAP_FRAME_RETRANS,
/**
* @brief the device supports Auto CSMA-CA
*
* The device supports performing CSMA-CA before transmitting a frame. If
* CSMA-CA procedure succeeds, the device sends the frame and reports a
* @ref TX_STATUS_SUCCESS when calling @ref
* ieee802154_radio_ops::confirm_transmit. If it fails, the device reports
* @ref TX_STATUS_MEDIUM_BUSY.
*/
IEEE802154_CAP_AUTO_CSMA,
/**
* @brief the device support ACK timeout interrupt
*
* The device will automatically attempt to receive and handle the ACK
* frame if expected.
* If the ACK frame is not received, the device reports @ref
* TX_STATUS_NO_ACK when calling @ref ieee802154_radio_ops::confirm_transmit.
* Otherwise, it reports @ref TX_STATUS_SUCCESS.
*
* The ACK frame is not indicated to the upper layer.
*/
IEEE802154_CAP_IRQ_ACK_TIMEOUT,
/**
* @brief the device supports the IEEE802.15.4 2.4 GHz band
*
* It's assumed that @ref IEEE802154_CAP_IRQ_TX_DONE is present.
*/
IEEE802154_CAP_24_GHZ,
/**
* @brief the device support the IEEE802.15.4 Sub GHz band
*/
IEEE802154_CAP_SUB_GHZ,
/**
* @brief the device reports when the transmission is done
*/
IEEE802154_CAP_IRQ_TX_DONE,
/**
* @brief the device reports the start of a frame (SFD) when received.
*/
IEEE802154_CAP_IRQ_RX_START,
/**
* @brief the device reports the start of a frame (SFD) was sent.
*/
IEEE802154_CAP_IRQ_TX_START,
/**
* @brief the device reports the end of the CCA procedure
*/
IEEE802154_CAP_IRQ_CCA_DONE,
/**
* @brief the device provides the number of retransmissions
*
* It's assumed that @ref IEEE802154_CAP_FRAME_RETRANS is present.
*/
IEEE802154_CAP_FRAME_RETRANS_INFO,
/**
* @brief the device retains all register values when off.
*/
IEEE802154_CAP_REG_RETENTION,
} ieee802154_rf_caps_t;
/**
* @brief Transmission status
*/
typedef enum {
/**
* @brief the transceiver successfully sent a frame.
*
* Depending of the type of transmissions and available caps, this could
* mean one of the following:
*
* If the device supports @ref IEEE802154_CAP_FRAME_RETRANS or
* @ref IEEE802154_CAP_IRQ_ACK_TIMEOUT this means either:
* - The frame was sent without ACK Req bit
* - The frame was sent with the ACK Req bit and a valid ACK was received.
*
* Otherwise, this notifies that a frame was sent.
*/
TX_STATUS_SUCCESS,
/**
* @brief the transceiver received a valid ACK with the frame pending bit
*
* This status is present only if the device supports @ref
* IEEE802154_CAP_FRAME_RETRANS or @ref IEEE802154_CAP_IRQ_ACK_TIMEOUT.
*/
TX_STATUS_FRAME_PENDING,
/**
* @brief the transceiver ran out of retransmission
*
* This status is present only if the device supports @ref
* IEEE802154_CAP_FRAME_RETRANS or @ref IEEE802154_CAP_IRQ_ACK_TIMEOUT.
*/
TX_STATUS_NO_ACK,
/**
* @brief the CSMA-CA algorithm or CCA failed to measure a clear channel
*/
TX_STATUS_MEDIUM_BUSY,
} ieee802154_tx_status_t;
/**
* @brief IEEE802.15.4 transceiver states (not to confuse with device states)
*/
typedef enum {
/**
* @brief the transceiver state is off
*/
IEEE802154_TRX_STATE_TRX_OFF,
/**
* @brief the transceiver is ready to receive/receiving frames
*/
IEEE802154_TRX_STATE_RX_ON,
/**
* @brief the transceiver is ready to transmit/transmitting a frame
*/
IEEE802154_TRX_STATE_TX_ON,
} ieee802154_trx_state_t;
/**
* @brief IEEE802.15.4 Radio HAL events
*
* To follow the IEEE802.15.4 convention, an event that responds to a Request
* is a confirmation (Confirm). Otherwise an Indication.
*/
typedef enum {
/**
* @brief the transceiver detected a valid SFD
*
* This event is present if radio has @ref IEEE802154_CAP_IRQ_RX_START cap.
*/
IEEE802154_RADIO_INDICATION_RX_START,
/**
* @brief the transceiver sent out a valid SFD
*
* This event is present if radio has @ref IEEE802154_CAP_IRQ_TX_START cap.
*
* @note The SFD of an outgoing ACK (AUTOACK) should not be indicated
*/
IEEE802154_RADIO_INDICATION_TX_START,
/**
* @brief the transceiver received a frame and lies in the
* internal framebuffer.
*
* This indication should be generated only if CRC is valid and the frame
* passes the address matching filter (this includes ACK and Beacon frames).
* The latter only applies if the radio is not in promiscuous mode.
*
* The transceiver or driver MUST handle the ACK reply if the Ack Request
* bit is set in the received frame and promiscuous mode is disabled.
*
* The transceiver will be in a "FB Lock" state where no more frames are
* received. This is done in order to avoid overwriting the Frame Buffer
* with new frame arrivals. In order to leave this state, the upper layer
* must set the transceiver state (@ref
* ieee802154_radio_ops::request_set_trx_state).
*/
IEEE802154_RADIO_INDICATION_RX_DONE,
/**
* @brief the transceiver either finished sending a frame, the retransmission
* procedure or the channel activity detection prior transmission.
*
* This event is present if radio has @ref IEEE802154_CAP_IRQ_TX_DONE cap.
* The upper layer should immediately call @ref
* ieee802154_radio_ops::confirm_transmit when on this event.
*/
IEEE802154_RADIO_CONFIRM_TX_DONE,
/**
* @brief the CCA procedure finished
*
* This event is present if radio has @ref IEEE802154_CAP_IRQ_CCA_DONE.
*/
IEEE802154_RADIO_CONFIRM_CCA,
} ieee802154_trx_ev_t;
/**
* @brief CSMA-CA exponential backoff parameters.
*/
typedef struct {
uint8_t min; /**< minimum value of the exponential backoff */
uint8_t max; /**< maximum value of the exponential backoff */
} ieee802154_csma_be_t;
/**
* @brief RX information associated to a frame
*/
typedef struct {
/**
* @brief RSSI of the received frame.
*
* The RSSI is a measure of the RF power in dBm for the received frame.
* The minimum and maximum values are 0 (-174 dBm) and 254 (80 dBm).
*/
uint8_t rssi;
uint8_t lqi; /**< LQI of the received frame */
} ieee802154_rx_info_t;
/**
* @brief TX information of the last transmitted frame.
*/
typedef struct {
ieee802154_tx_status_t status; /**< status of the last transmission */
int8_t retrans; /**< number of frame retransmissions of the last TX */
} ieee802154_tx_info_t;
/**
* @brief Forward declaration of the IEEE802.15.4 device descriptor
*/
typedef struct ieee802154_dev ieee802154_dev_t;
/**
* @brief Prototype of the IEEE802.15.4 device event callback
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] status the status
*/
typedef void (*ieee802154_cb_t)(ieee802154_dev_t *dev,
ieee802154_trx_ev_t status);
/**
* @brief the IEEE802.15.4 device descriptor
*/
struct ieee802154_dev {
/**
* @brief pointer to the operations of the device
*/
const ieee802154_radio_ops_t *driver;
/**
* @brief pointer to the context of the device
*/
void *ctx;
/**
* @brief the event callback of the device
*/
ieee802154_cb_t cb;
};
/**
* @brief IEEE802.15.4 CCA modes
*/
typedef enum {
/**
* @brief CCA using first mode (energy detection)
*/
IEEE802154_CCA_MODE_ED_THRESHOLD,
/**
* @brief CCA using second mode (carrier sensing)
*/
IEEE802154_CCA_MODE_CARRIER_SENSING,
/**
* @brief CCA using third mode (energy detection AND carrier sensing)
*/
IEEE802154_CCA_MODE_ED_THRESH_AND_CS,
/**
* @brief CCA using third mode (energy detection OR carrier sensing)
*/
IEEE802154_CCA_MODE_ED_THRESH_OR_CS,
} ieee802154_cca_mode_t;
/**
* @brief RX mode configuration
*/
typedef enum {
/**
* @brief Auto ACK is disabled
*/
IEEE802154_RX_AACK_DISABLED,
/**
* @brief Auto ACK is enabled
*/
IEEE802154_RX_AACK_ENABLED,
/**
* @brief Auto ACK is enabled and frame pending bit set in the next ACK frame
*/
IEEE802154_RX_AACK_FRAME_PENDING,
/**
* @brief Radio is in promiscuous mode
*/
IEEE802154_RX_PROMISC,
/**
* @brief Radio is ready to receive ACK frames
*
* This mode is optional. If a radio decides to implement it, the radio
* should allow ACK frames (and block ACK frames in all other RX modes).
* Note that this mode cannot guarantee that only ACK frames will be
* received.
*
* Expected to be implemented when either @ref IEEE802154_CAP_FRAME_RETRANS
* or @ref IEEE802154_CAP_IRQ_ACK_TIMEOUT is not there.
*/
IEEE802154_RX_WAIT_FOR_ACK,
} ieee802154_rx_mode_t;
/**
* @brief Holder of the PHY configuration
*/
typedef struct {
uint16_t channel; /**< IEEE802.15.4 channel number */
uint8_t page; /**< IEEE802.15.4 channel page */
int8_t pow; /**< TX power in dBm */
} ieee802154_phy_conf_t;
/**
* @brief Radio ops struct declaration
*/
struct ieee802154_radio_ops {
/**
* @brief Write a frame into the framebuffer.
*
* This function shouldn't do any checks, so the frame MUST be valid. The
* previous content of the framebuffer is replaced by @p psdu.
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] psdu PSDU frame to be sent
*
* @return 0 on success
* @return negative errno on error
*/
int (*write)(ieee802154_dev_t *dev, const iolist_t *psdu);
/**
* @brief Request the transmission of a preloaded frame
*
* @ref ieee802154_radio_ops::confirm_transmit MUST be used to finish the
* transmission.
*
* @pre the PHY state is @ref IEEE802154_TRX_STATE_TX_ON and the frame
* is already in the framebuffer.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return 0 on success
* @return negative errno on error
*/
int (*request_transmit)(ieee802154_dev_t *dev);
/**
* @brief Confirmation function for @ref ieee802154_radio_ops::request_transmit.
*
* This function must be called to finish the transmission procedure and
* get the transmission status. This function should be called on @ref
* IEEE802154_RADIO_CONFIRM_TX_DONE. If no interrupt is available, this
* function can be polled.
*
* @pre the device is on
* @pre call to @ref ieee802154_radio_ops::request_transmit was successful.
*
* @post the state is @ref IEEE802154_TRX_STATE_TX_ON.
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[out] info the TX information. Pass NULL
* if the information is not needed. If the radio supports AutoCCA, the
* status should indicate transmission done or channel busy. If the radio
* supports frame retransmissions, the status should indicate if medium
* was busy, no ACK was received or transmission succeeded.
*
* @return 0 on success
* @return -EAGAIN if the transmission has not finished yet.
* @return negative errno on error
*/
int (*confirm_transmit)(ieee802154_dev_t *dev, ieee802154_tx_info_t *info);
/**
* @brief Get the length of the received PSDU frame.
*
* @pre the device is on
* @pre the radio already received a frame (e.g
* @ref ieee802154_dev::cb with @ref IEEE802154_RADIO_INDICATION_RX_DONE).
*
* @post the frame buffer is still protected against new frame arrivals.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return length of the frame
*/
int (*len)(ieee802154_dev_t *dev);
/**
* @brief Read a frame from the internal framebuffer
*
* This function reads the received frame from the internal framebuffer.
* It should try to copy the received PSDU frame into @p buf. The FCS
* field will **not** be copied and its size **not** be taken into account
* for the return value.
*
* @post It's not safe to call this function again before setting the
* transceiver state to @ref IEEE802154_TRX_STATE_RX_ON (thus flushing
* the RX FIFO).
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[out] buf buffer to write the received PSDU frame into.
* @param[in] size size of @p buf
* @param[in] info information of the received frame (LQI, RSSI). Can be
* NULL if this information is not needed.
*
* @return number of bytes written in @p buffer (0 if @p buf == NULL)
* @return -ENOBUFS if the frame doesn't fit in @p
*/
int (*read)(ieee802154_dev_t *dev, void *buf, size_t size, ieee802154_rx_info_t *info);
/**
* @brief Turn off the device
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* When this function returns, the radio shall be off.
*
* @post the device is off (and thus, the transceiver state is @ref
* IEEE802154_TRX_STATE_TRX_OFF)
*
* @return 0 on success
* @return negative errno on error
*/
int (*off)(ieee802154_dev_t *dev);
/**
* @brief Request to turn on the device
*
* @note @ref ieee802154_radio_ops::confirm_on MUST be used to finish the
* procedure.
*
* @pre the init function of the radio succeeded.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return 0 on success
* @return negative errno on error
*/
int (*request_on)(ieee802154_dev_t *dev);
/**
* @brief Confirmation function for @ref ieee802154_radio_ops::request_on.
*
* @pre call to @ref ieee802154_radio_ops::request_on was successful.
*
* @post the transceiver state is @ref IEEE802154_TRX_STATE_TRX_OFF
* During boot or in case the radio doesn't support @ref
* IEEE802154_CAP_REG_RETENTION when @ref off was called, the
* Physical Information Base will be undefined. Thus, take into
* consideration that the following functions should be called right after
* the radio is turned on again:
* - @ref set_cca_threshold
* - @ref set_cca_mode
* - @ref config_phy
* - @ref set_csma_params
* - @ref set_rx_mode
* - @ref set_hw_addr_filter
* - @ref set_frame_retrans (if available)
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return 0 if the device is on
* @return -EAGAIN if the device is still busy turning on
* @return negative errno on error
*/
int (*confirm_on)(ieee802154_dev_t *dev);
/**
* @brief Request a PHY state change
*
* @note @ref ieee802154_radio_ops::confirm_set_trx_state MUST be used to
* finish the state transition. Also, setting the state to
* @ref IEEE802154_TRX_STATE_RX_ON flushes the RX FIFO.
*
* @pre the device is on
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] state the new state
*
* @return 0 on success
* @return -EBUSY if the transceiver is busy
* @return negative number on error
*/
int (*request_set_trx_state)(ieee802154_dev_t *dev,
ieee802154_trx_state_t state);
/**
* @brief Confirmation function for @ref
* ieee802154_radio_ops::request_set_trx_state
*
* @pre call to @ref ieee802154_radio_ops::request_set_trx_state was
* successful.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return 0 if the state transition was successful
* @return -EAGAIN if the transition has not finished yet
* @return negative errno on error
*/
int (*confirm_set_trx_state)(ieee802154_dev_t *dev);
/**
* @brief Request Stand-Alone Clear Channel Assessment
*
* @pre the state is @ref IEEE802154_TRX_STATE_RX_ON
*
* @note @ref ieee802154_radio_ops::confirm_cca MUST be used to
* finish the CCA procedure and get the channel status.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @post the state is @ref IEEE802154_TRX_STATE_RX_ON
*
* @return 0 if request was OK
* @return -EAGAIN if the request cannot be performed immediately.
* @return negative errno on error
*/
int (*request_cca)(ieee802154_dev_t *dev);
/**
* @brief Confirmation function for @ref ieee802154_radio_ops::request_cca
*
* This function must be called to finish the CCA procedure. This
* function should be called on @ref IEEE802154_RADIO_CONFIRM_CCA,
* If no interrupt is available, this function can be polled.
*
* @pre call to @ref ieee802154_radio_ops::request_cca was successful.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return positive number if the channel is clear
* @return 0 if the channel is busy
* @return -EAGAIN if the CCA procedure hasn't finished.
* @return negative errno on error
*/
int (*confirm_cca)(ieee802154_dev_t *dev);
/**
* @brief Get a cap from the radio
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param cap cap to be checked
*
* @return true if the radio supports the cap
* @return false otherwise
*/
bool (*get_cap)(ieee802154_dev_t *dev, ieee802154_rf_caps_t cap);
/**
* @brief Set the threshold for the Energy Detection (first mode of CCA)
*
* @pre the device is on
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] threshold the threshold in dBm.
*
* @return 0 on success
* @return negative errno on error
*/
int (*set_cca_threshold)(ieee802154_dev_t *dev, int8_t threshold);
/**
* @brief Set CCA mode
*
* All radios MUST at least implement the first CCA mode (ED Threshold).
*
* @pre the device is on
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] mode the CCA mode
*
* @return 0 on success
* @return -ENOTSUP if the mode is not supported
* @return negative errno on error
*/
int (*set_cca_mode)(ieee802154_dev_t *dev, ieee802154_cca_mode_t mode);
/**
* @brief Set IEEE802.15.4 PHY configuration (channel, TX power)
*
* This function SHOULD NOT validate the PHY configurations unless
* it's specific to the device. The upper layer is responsible of all kind
* of validations.
* In case a configuration is not valid (e.g parameters out of range), this
* function should return -EINVAL
*
* @pre the device is on
* @pre the transceiver state is @ref IEEE802154_TRX_STATE_TRX_OFF
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] conf the PHY configuration
*
* @return 0 on success
* @return -EINVAL if the configuration is not valid for the device.
* @return <0 error, return value is negative errno indicating the cause.
*/
int (*config_phy)(ieee802154_dev_t *dev, const ieee802154_phy_conf_t *conf);
/**
* @brief Set IEEE802.15.4 addresses in hardware address filter
*
* @pre the device is on
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] short_addr the IEEE802.15.4 short address. If NULL, the short
* address is not altered..
* @param[in] ext_addr the IEEE802.15.4 extended address (Network Byte Order).
* If NULL, the extended address is not altered.
* @param[in] pan_id the IEEE802.15.4 PAN ID. If NULL, the PAN ID is not altered.
*
* @return 0 on success
* @return negative errno on error
*/
int (*set_hw_addr_filter)(ieee802154_dev_t *dev,
const network_uint16_t *short_addr,
const eui64_t *ext_addr,
const uint16_t *pan_id);
/**
* @brief Set number of frame retransmissions
*
* @pre the device is on
*
* @note this function pointer can be NULL if the device doesn't support
* frame retransmissions
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] retrans the number of retransmissions attempts.
*
* @return 0 on success
* @return negative errno on error
*/
int (*set_frame_retrans)(ieee802154_dev_t *dev, uint8_t retrans);
/**
* @brief Set the CSMA-CA parameters.
*
* @pre the device is on
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] bd parameters of the exponential backoff. If NULL, the
* parameters are not altered.
* @param[in] retries number of CSMA-CA retries. If @p retries < 0,
* retransmissions with CSMA-CA MUST be disabled.
* If @p retries == 0, the @ref
* ieee802154_radio_ops::request_transmit function is
* equivalent to CCA send.
*
* @return 0 on success
* @return -EINVAL if the settings are not supported.
* @return negative errno on error
*/
int (*set_csma_params)(ieee802154_dev_t *dev, const ieee802154_csma_be_t *bd,
int8_t retries);
/**
* @brief Set the RX mode.
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] mode RX mode
*
* @return 0 on success
* @return negative errno on error
*/
int (*set_rx_mode)(ieee802154_dev_t *dev, ieee802154_rx_mode_t mode);
};
/**
* @brief Forward declaration of the radio cipher ops structure
*/
typedef struct ieee802154_radio_cipher_ops ieee802154_radio_cipher_ops_t;
/**
* @brief Forward declaration of the IEEE802.15.4 security device descriptor
*/
typedef struct ieee802154_sec_dev ieee802154_sec_dev_t;
/**
* @brief IEEE802.15.4 security device descriptor
*/
struct ieee802154_sec_dev {
/**
* @brief Pointer to the operations of the device
*/
const struct ieee802154_radio_cipher_ops *cipher_ops;
/**
* @brief pointer to the context of the device
*/
void *ctx;
};
struct ieee802154_radio_cipher_ops {
/**
* @brief Function to set the encryption key for the
* next cipher operation
*
* @param[in] dev Security device descriptor
* @param[in] key Key to be used for the next cipher operation
* @param[in] key_size key size in bytes
*/
void (*set_key)(ieee802154_sec_dev_t *dev,
const uint8_t *key, uint8_t key_size);
/**
* @brief Function to perform ECB encryption
*
* @param[in] dev Security device descriptor
* @param[out] cipher Output cipher blocks
* @param[in] plain Input plain blocks
* @param[in] nblocks Number of blocks
*/
void (*ecb)(const ieee802154_sec_dev_t *dev, uint8_t *cipher,
const uint8_t *plain, uint8_t nblocks);
/**
* @brief Function to compute CBC-MAC
*
* @param[in] dev Security device descriptor
* @param[in] cipher Output cipher blocks
* @param[in, out] iv in: IV; out: computed MIC
* @param[in] plain Input plain blocks
* @param[in] nblocks Number of blocks
*/
void (*cbc)(const ieee802154_sec_dev_t *dev, uint8_t *cipher,
uint8_t *iv, const uint8_t *plain, uint8_t nblocks);
};
/**
* @brief Shortcut to @ref ieee802154_radio_ops::write
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] psdu PSDU frame to be sent
*
* @return result of @ref ieee802154_radio_ops::write
*/
static inline int ieee802154_radio_write(ieee802154_dev_t *dev, const iolist_t *psdu)
{
return dev->driver->write(dev, psdu);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::request_transmit
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return result of @ref ieee802154_radio_ops::request_transmit
*/
static inline int ieee802154_radio_request_transmit(ieee802154_dev_t *dev)
{
return dev->driver->request_transmit(dev);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::confirm_transmit
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[out] info the TX information
*
* @return result of @ref ieee802154_radio_ops::confirm_transmit
*/
static inline int ieee802154_radio_confirm_transmit(ieee802154_dev_t *dev,
ieee802154_tx_info_t *info)
{
return dev->driver->confirm_transmit(dev, info);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::len
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return result of @ref ieee802154_radio_ops::len
*/
static inline int ieee802154_radio_len(ieee802154_dev_t *dev)
{
return dev->driver->len(dev);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::read
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[out] buf buffer to write the received frame into.
* @param[in] size size of @p buf
* @param[in] info information of the received frame (LQI, RSSI). Can be
* NULL if this information is not needed.
*
* @return result of @ref ieee802154_radio_ops::read
*/
static inline int ieee802154_radio_read(ieee802154_dev_t *dev,
void *buf,
size_t size,
ieee802154_rx_info_t *info)
{
return dev->driver->read(dev, buf, size, info);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::set_cca_threshold
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] threshold the threshold in dBm
*
* @return result of @ref ieee802154_radio_ops::set_cca_threshold
*/
static inline int ieee802154_radio_set_cca_threshold(ieee802154_dev_t *dev,
int8_t threshold)
{
return dev->driver->set_cca_threshold(dev, threshold);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::set_cca_mode
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] mode the CCA mode
*
* @return result of @ref ieee802154_radio_ops::set_cca_mode
*/
static inline int ieee802154_radio_set_cca_mode(ieee802154_dev_t *dev,
ieee802154_cca_mode_t mode)
{
return dev->driver->set_cca_mode(dev, mode);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::config_phy
*
* @pre the transceiver state is @ref IEEE802154_TRX_STATE_TRX_OFF
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] conf the PHY configuration
*
* @return result of @ref ieee802154_radio_ops::config_phy
*/
static inline int ieee802154_radio_config_phy(ieee802154_dev_t *dev,
const ieee802154_phy_conf_t *conf)
{
return dev->driver->config_phy(dev, conf);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::off
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @post the transceiver state is @ref IEEE802154_TRX_STATE_TRX_OFF
*
* @return result of @ref ieee802154_radio_ops::off
*/
static inline int ieee802154_radio_off(ieee802154_dev_t *dev)
{
return dev->driver->off(dev);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::set_hw_addr_filter
*
* @pre the device is on
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] short_addr the IEEE802.15.4 short address. If NULL, the short
* address is not altered..
* @param[in] ext_addr the IEEE802.15.4 extended address (Network Byte Order).
* If NULL, the extended address is not altered.
* @param[in] pan_id the IEEE802.15.4 PAN ID. If NULL, the PAN ID is not altered.
*
* @return result of @ref ieee802154_radio_ops::set_hw_addr_filter
*/
static inline int ieee802154_radio_set_hw_addr_filter(ieee802154_dev_t *dev,
const network_uint16_t *short_addr,
const eui64_t *ext_addr,
const uint16_t *pan_id)
{
return dev->driver->set_hw_addr_filter(dev, short_addr, ext_addr, pan_id);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::set_frame_retrans
*
* @pre the device is on
* @pre the device supports frame retransmissions
* (@ref ieee802154_radio_has_frame_retrans() == true)
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] retrans the number of retransmissions
*
* @return result of @ref ieee802154_radio_ops::set_frame_retrans
*/
static inline int ieee802154_radio_set_frame_retrans(ieee802154_dev_t *dev,
uint8_t retrans)
{
return dev->driver->set_frame_retrans(dev, retrans);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::set_csma_params
*
* @pre the device is on
* @pre the device supports frame retransmissions
* (@ref ieee802154_radio_has_frame_retrans() == true)
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] bd parameters of the exponential backoff
* @param[in] retries number of CSMA-CA retries. If @p restries < 0,
* retransmissions with CSMA-CA are disabled
*
* @return result of @ref ieee802154_radio_ops::set_csma_params
*/
static inline int ieee802154_radio_set_csma_params(ieee802154_dev_t *dev,
const ieee802154_csma_be_t *bd,
int8_t retries)
{
return dev->driver->set_csma_params(dev, bd, retries);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::request_on
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return result of @ref ieee802154_radio_ops::request_on
*/
static inline int ieee802154_radio_request_on(ieee802154_dev_t *dev)
{
return dev->driver->request_on(dev);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::confirm_on
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return result of @ref ieee802154_radio_ops::confirm_on
*/
static inline int ieee802154_radio_confirm_on(ieee802154_dev_t *dev)
{
return dev->driver->confirm_on(dev);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::request_set_trx_state
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] state the new state
*
* @return result of @ref ieee802154_radio_ops::request_set_trx_state
*/
static inline int ieee802154_radio_request_set_trx_state(ieee802154_dev_t *dev,
ieee802154_trx_state_t state)
{
return dev->driver->request_set_trx_state(dev, state);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::confirm_set_trx_state
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return result of @ref ieee802154_radio_ops::confirm_set_trx_state
*/
static inline int ieee802154_radio_confirm_set_trx_state(ieee802154_dev_t *dev)
{
return dev->driver->confirm_set_trx_state(dev);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::request_cca
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return result of @ref ieee802154_radio_ops::request_cca
*/
static inline int ieee802154_radio_request_cca(ieee802154_dev_t *dev)
{
return dev->driver->request_cca(dev);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::confirm_cca
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return result of @ref ieee802154_radio_ops::confirm_cca
*/
static inline int ieee802154_radio_confirm_cca(ieee802154_dev_t *dev)
{
return dev->driver->confirm_cca(dev);
}
/**
* @brief Check if the device supports ACK timeout
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_IRQ_ACK_TIMEOUT.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_irq_ack_timeout(ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_IRQ_ACK_TIMEOUT);
}
/**
* @brief Check if the device supports frame retransmissions (with CSMA-CA).
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_FRAME_RETRANS.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_frame_retrans(ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_FRAME_RETRANS);
}
/**
* @brief Check if the device supports Auto CSMA-CA for transmissions.
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_AUTO_CSMA.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_auto_csma(ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_AUTO_CSMA);
}
/**
* @brief Check if the device supports the IEEE802.15.4 Sub-GHz band
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_SUB_GHZ.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_sub_ghz(ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_SUB_GHZ);
}
/**
* @brief Check if the device supports the IEEE802.15.4 2.4 GHz band
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_24_GHZ.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_24_ghz(ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_24_GHZ);
}
/**
* @brief Check if the device supports TX done interrupt
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_IRQ_TX_DONE.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_irq_tx_done(ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_IRQ_TX_DONE);
}
/**
* @brief Check if the device supports RX start interrupt
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_IRQ_RX_START.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_irq_rx_start(ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_IRQ_RX_START);
}
/**
* @brief Check if the device supports TX start interrupt
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_IRQ_TX_START.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_irq_tx_start(ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_IRQ_TX_START);
}
/**
* @brief Check if the device supports CCA done interrupt
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_IRQ_CCA_DONE.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_irq_cca_done(ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_IRQ_CCA_DONE);
}
/**
* @brief Check if the device reports the number of retransmissions of the last
* TX procedure.
*
* Internally this function calls ieee802154_radio_ops::get_cap with @ref
* IEEE802154_CAP_FRAME_RETRANS_INFO.
*
* @param[in] dev IEEE802.15.4 device descriptor
*
* @return true if the device has support
* @return false otherwise
*/
static inline bool ieee802154_radio_has_frame_retrans_info(
ieee802154_dev_t *dev)
{
return dev->driver->get_cap(dev, IEEE802154_CAP_FRAME_RETRANS_INFO);
}
/**
* @brief Shortcut to @ref ieee802154_radio_ops::set_rx_mode
*
* @param[in] dev IEEE802.15.4 device descriptor
* @param[in] mode RX mode
*
* @return result of @ref ieee802154_radio_ops::set_rx_mode
*/
static inline int ieee802154_radio_set_rx_mode(ieee802154_dev_t *dev,
ieee802154_rx_mode_t mode)
{
return dev->driver->set_rx_mode(dev, mode);
}
/**
* @brief Shortcut to ieee802154_sec_dev_t::ieee802154_radio_cipher_ops_t::set_key
*
* @param[in] dev IEEE802.15.4 security device descriptor
* @param[in] key Encryption key
* @param[in] key_size Size of the key in bytes
*/
static inline void ieee802154_radio_cipher_set_key(ieee802154_sec_dev_t *dev,
const uint8_t *key, uint8_t key_size)
{
dev->cipher_ops->set_key(dev->ctx, key, key_size);
}
/**
* @brief Shortcut to ieee802154_sec_dev_t::ieee802154_radio_cipher_ops_t::ecb
*
* @param[in] dev IEEE802.15.4 security device descriptor
* @param[out] cipher Output cipher blocks
* @param[in] plain Input plain blocks
* @param[in] nblocks Number of blocks
*/
static inline void ieee802154_radio_cipher_ecb(const ieee802154_sec_dev_t *dev, uint8_t *cipher,
const uint8_t *plain, uint8_t nblocks)
{
dev->cipher_ops->ecb(dev->ctx, cipher, plain, nblocks);
}
/**
* @brief Shortcut to ieee802154_sec_dev_t::ieee802154_radio_cipher_ops_t::cbc
*
* @param[in] dev IEEE802.15.4 security device descriptor
* @param[out] cipher Output cipher blocks
* @param[in] iv Initial vector to be XOR´ed to the first plain block
* @param[in] plain Input plain blocks
* @param[in] nblocks Number of blocks
*/
static inline void ieee802154_radio_cipher_cbc(const ieee802154_sec_dev_t *dev, uint8_t *cipher,
uint8_t *iv, const uint8_t *plain, uint8_t nblocks)
{
dev->cipher_ops->cbc(dev->ctx, cipher, iv, plain, nblocks);
}
#ifdef __cplusplus
}
#endif
#endif /* NET_IEEE802154_RADIO_H */
/** @} */