This module defines a common layer for handling the lower part of the IEEE 802.15.4 MAC layer.
More...
This module defines a common layer for handling the lower part of the IEEE 802.15.4 MAC layer.
- Warning
- This feature is experimental!
This API is experimental and in an early state - expect changes!
This layer is responsible for:
- Handling CSMA-CA and retransmissions.
- Maintaining part of the MAC Information Base, e.g IEEE 802.15.4 addresses, channel settings, CSMA-CA params, etc.
The SubMAC defines the following state machine:
+--------+ +--------+ +--------+
| |------->| | | |
| RX | |PREPARE |<--->| TX |
| | +--->| | | |
+--------+ | +--------+ +--------+
^ | ^ |
| | | |
| | | |
| | +--------+ |
| | | | v
| | |WAIT FOR|<--------+
| | | ACK | |
| | +--------+ |
| | | |
| | | |
| | v |
| | +--------+ |
| +-----| | |
| | IDLE | |
+------------->| |<-------+
+--------+
- IDLE: The transceiver is off and therefore cannot receive frames. Sending frames might be triggered using ieee802154_send. The next SubMAC state would be PREPARE.
- RX: The device is ready to receive frames. In case the SubMAC receives a frame it will call ieee802154_submac_cb_t::rx_done and immediately go to IDLE. Same as the IDLE state, it's possible to trigger frames using ieee802154_send.
- PREPARE: The frame is already in the framebuffer and waiting to be transmitted. This state might handle CSMA-CA backoff timer in case the device doesn't support it. The SubMAC will then request the transmission and go immediately to the TX state.
- TX: The frame was already sent and it's waiting for the TX DONE event from the radio. The SubMAC might call ieee802154_submac_cb_t::tx_done if any of the following criteria are meet:
- The transmitted frame didn't request ACK
- The radio already handles retransmissions
- WAIT FOR ACK: The SubMAC is waiting for an ACK frame. In case a valid ACK frame is received, the SubMAC will either to IDLE. In case the ACK frame is invalid or there's an ACK timeout event (either triggered by the radio or a timer), the SubMAC goes to either IDLE if there are no more retransmissions left or no more CSMA-CA retries or PREPARE otherwise.
The events that trigger state machine changes are defined in ieee802154_fsm_state_t
The following events are valid for each state:
Event/State | RX | IDLE | PREPARE | TX | WAIT FOR ACK |
TX_DONE | - | - | - | X | - |
RX_DONE | X | X* | X* | X* | X |
CRC_ERROR | X | X* | X* | X* | X |
ACK_TIMEOUT | - | - | - | - | X |
BH | - | - | X | - | - |
REQ_TX | X | X | - | - | - |
REQ_SET_RX_ON | - | X | - | - | - |
REQ_SET_IDLE | X | - | - | - | - |
*: RX_DONE and CRC_ERROR during these events might be a race condition between the ACK Timer and the radios RX_DONE event. If this happens, the SubMAC will react accordingly
Unexpected events will be reported and asserted.
The upper layer needs to implement the following callbacks:
- Author
- José I. Alamos jose..nosp@m.alam.nosp@m.os@ha.nosp@m.w-ha.nosp@m.mburg.nosp@m..de
|
enum | ieee802154_fsm_state_t {
IEEE802154_FSM_STATE_INVALID
, IEEE802154_FSM_STATE_RX
, IEEE802154_FSM_STATE_IDLE
, IEEE802154_FSM_STATE_PREPARE
,
IEEE802154_FSM_STATE_TX
, IEEE802154_FSM_STATE_WAIT_FOR_ACK
, IEEE802154_FSM_STATE_NUMOF
} |
| Internal SubMAC FSM state machine states. More...
|
|
enum | ieee802154_fsm_ev_t {
IEEE802154_FSM_EV_TX_DONE
, IEEE802154_FSM_EV_RX_DONE
, IEEE802154_FSM_EV_CRC_ERROR
, IEEE802154_FSM_EV_ACK_TIMEOUT
,
IEEE802154_FSM_EV_BH
, IEEE802154_FSM_EV_REQUEST_TX
, IEEE802154_FSM_EV_REQUEST_SET_RX_ON
, IEEE802154_FSM_EV_REQUEST_SET_IDLE
,
IEEE802154_FSM_EV_NUMOF
} |
| Internal SubMAC FSM state machine events. More...
|
|
|
int | ieee802154_send (ieee802154_submac_t *submac, const iolist_t *iolist) |
| Transmit an IEEE 802.15.4 PSDU.
|
|
static int | ieee802154_set_short_addr (ieee802154_submac_t *submac, const network_uint16_t *short_addr) |
| Set the IEEE 802.15.4 short address.
|
|
static int | ieee802154_set_ext_addr (ieee802154_submac_t *submac, const eui64_t *ext_addr) |
| Set the IEEE 802.15.4 extended address.
|
|
static int | ieee802154_set_panid (ieee802154_submac_t *submac, const uint16_t *panid) |
| Set the IEEE 802.15.4 PAN ID.
|
|
static ieee802154_phy_mode_t | ieee802154_get_phy_mode (ieee802154_submac_t *submac) |
| Get IEEE 802.15.4 PHY mode.
|
|
int | ieee802154_set_phy_conf (ieee802154_submac_t *submac, uint16_t channel_num, uint8_t channel_page, int8_t tx_pow) |
| Set IEEE 802.15.4 PHY configuration (channel, TX power)
|
|
static int | ieee802154_set_channel_number (ieee802154_submac_t *submac, uint16_t channel_num) |
| Set IEEE 802.15.4 channel number.
|
|
static int | ieee802154_set_channel_page (ieee802154_submac_t *submac, uint16_t channel_page) |
| Set IEEE 802.15.4 channel page.
|
|
static int | ieee802154_set_tx_power (ieee802154_submac_t *submac, int8_t tx_pow) |
| Set IEEE 802.15.4 transmission power.
|
|
static int | ieee802154_get_frame_length (ieee802154_submac_t *submac) |
| Get the received frame length.
|
|
static int | ieee802154_read_frame (ieee802154_submac_t *submac, void *buf, size_t len, ieee802154_rx_info_t *info) |
| Read the received frame.
|
|
int | ieee802154_set_idle (ieee802154_submac_t *submac) |
| Set the SubMAC to IDLE state.
|
|
int | ieee802154_set_rx (ieee802154_submac_t *submac) |
| Set the SubMAC to RX state.
|
|
static bool | ieee802154_submac_state_is_rx (ieee802154_submac_t *submac) |
| Check whether the SubMAC is in RX state.
|
|
static bool | ieee802154_submac_state_is_idle (ieee802154_submac_t *submac) |
| Check whether the SubMAC is in IDLE state.
|
|
int | ieee802154_submac_init (ieee802154_submac_t *submac, const network_uint16_t *short_addr, const eui64_t *ext_addr) |
| Init the IEEE 802.15.4 SubMAC.
|
|
void | ieee802154_submac_ack_timer_set (ieee802154_submac_t *submac, uint16_t us) |
| Set the ACK timeout timer.
|
|
void | ieee802154_submac_ack_timer_cancel (ieee802154_submac_t *submac) |
| Cancel the ACK timeout timer.
|
|
void | ieee802154_submac_bh_request (ieee802154_submac_t *submac) |
| ieee802154_submac_bh_process should be called as soon as possible.
|
|
ieee802154_fsm_state_t | ieee802154_submac_process_ev (ieee802154_submac_t *submac, ieee802154_fsm_ev_t ev) |
| Process an FSM event.
|
|
static void | ieee802154_submac_ack_timeout_fired (ieee802154_submac_t *submac) |
| Indicate the SubMAC that the ACK timeout fired.
|
|
static void | ieee802154_submac_bh_process (ieee802154_submac_t *submac) |
| Indicate the SubMAC that the BH should process an internal event.
|
|
static void | ieee802154_submac_rx_done_cb (ieee802154_submac_t *submac) |
| Indicate the SubMAC that the device received a frame.
|
|
static void | ieee802154_submac_crc_error_cb (ieee802154_submac_t *submac) |
| Indicate the SubMAC that a frame with invalid CRC was received.
|
|
static void | ieee802154_submac_tx_done_cb (ieee802154_submac_t *submac) |
| Indicate the SubMAC that the device finished the transmission procedure.
|
|
◆ ieee802154_submac_t
IEEE 802.15.4 SubMAC forward declaration.
Definition at line 124 of file submac.h.
◆ ieee802154_fsm_ev_t
Internal SubMAC FSM state machine events.
Enumerator |
---|
IEEE802154_FSM_EV_TX_DONE | Radio reports frame was sent.
|
IEEE802154_FSM_EV_RX_DONE | Radio reports frame was received.
|
IEEE802154_FSM_EV_CRC_ERROR | Radio reports frame was received but CRC failed.
|
IEEE802154_FSM_EV_ACK_TIMEOUT | ACK timer fired.
|
IEEE802154_FSM_EV_BH | The Bottom Half should process an event.
|
IEEE802154_FSM_EV_REQUEST_TX | The upper layer requested to transmit a frame.
|
IEEE802154_FSM_EV_REQUEST_SET_RX_ON | The upper layer requested to go to RX.
|
IEEE802154_FSM_EV_REQUEST_SET_IDLE | The upper layer requested to go to IDLE.
|
IEEE802154_FSM_EV_NUMOF | Number of SubMAC FSM events.
|
Definition at line 176 of file submac.h.
◆ ieee802154_fsm_state_t
Internal SubMAC FSM state machine states.
Enumerator |
---|
IEEE802154_FSM_STATE_INVALID | Invalid state.
|
IEEE802154_FSM_STATE_RX | SubMAC is ready to receive frames.
|
IEEE802154_FSM_STATE_IDLE | The transceiver is off.
|
IEEE802154_FSM_STATE_PREPARE | The SubMAC is preparing the next transmission.
|
IEEE802154_FSM_STATE_TX | The SubMAC is currently transmitting a frame.
|
IEEE802154_FSM_STATE_WAIT_FOR_ACK | The SubMAC is waiting for an ACK frame.
|
IEEE802154_FSM_STATE_NUMOF | Number of SubMAC FSM states.
|
Definition at line 163 of file submac.h.
◆ ieee802154_get_frame_length()
Get the received frame length.
- Precondition
- this function MUST be called either inside ieee802154_submac_cb_t::rx_done or in SLEEP state.
- Parameters
-
[in] | submac | pointer to the SubMAC |
- Returns
- length of the PSDU (excluding FCS length)
Definition at line 403 of file submac.h.
◆ ieee802154_get_phy_mode()
Get IEEE 802.15.4 PHY mode.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
- Returns
- PHY mode.
Definition at line 303 of file submac.h.
◆ ieee802154_read_frame()
Read the received frame.
This functions reads the received PSDU from the device (excluding FCS)
- Precondition
- this function MUST be called either inside ieee802154_submac_cb_t::rx_done or in SLEEP state.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
[out] | buf | buffer to write into. If NULL, the packet is discarded |
[in] | len | length of the buffer |
[out] | info | RX information of the packet. If NULL, the information is not fetched. |
- Returns
- the number of bytes written to
buf
-
negative errno on error
Definition at line 424 of file submac.h.
◆ ieee802154_send()
Transmit an IEEE 802.15.4 PSDU.
This function performs an IEEE 802.15.4 transmission, including CSMA-CA and retransmissions (if ACK Request bit is set). When the transmission finishes an ieee802154_submac_cb_t::tx_done event is issued.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
[in] | iolist | pointer to the PSDU frame (without FCS) |
- Returns
- 0 on success
-
-EBUSY if the SubMAC is not in RX or IDLE state or if called inside ieee802154_submac_cb_t::rx_done or ieee802154_submac_cb_t::tx_done
◆ ieee802154_set_channel_number()
static int ieee802154_set_channel_number |
( |
ieee802154_submac_t * |
submac, |
|
|
uint16_t |
channel_num |
|
) |
| |
|
inlinestatic |
◆ ieee802154_set_channel_page()
◆ ieee802154_set_ext_addr()
Set the IEEE 802.15.4 extended address.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
[in] | ext_addr | IEEE 802.15.4 extended address |
- Returns
- 0 on success
-
negative errno on error
Definition at line 260 of file submac.h.
◆ ieee802154_set_idle()
Set the SubMAC to IDLE state.
Frames won't be received in this state. However, it's still possible to send frames.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
- Returns
- success or error code.
- Return values
-
0 | on success |
-EBUSY | if the SubMAC is currently busy |
◆ ieee802154_set_panid()
Set the IEEE 802.15.4 PAN ID.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
[in] | panid | IEEE 802.15.4 PAN ID |
- Returns
- 0 on success
-
negative errno on error
Definition at line 282 of file submac.h.
◆ ieee802154_set_phy_conf()
int ieee802154_set_phy_conf |
( |
ieee802154_submac_t * |
submac, |
|
|
uint16_t |
channel_num, |
|
|
uint8_t |
channel_page, |
|
|
int8_t |
tx_pow |
|
) |
| |
Set IEEE 802.15.4 PHY configuration (channel, TX power)
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
[in] | channel_num | channel number |
[in] | channel_page | channel page |
[in] | tx_pow | transmission power (in dBm) |
- Returns
- 0 on success
-
-ENOTSUP if the PHY settings are not supported
-
-EBUSY if the SubMAC is not in RX or IDLE state or if called inside ieee802154_submac_cb_t::rx_done or ieee802154_submac_cb_t::tx_done
-
negative errno on error
◆ ieee802154_set_rx()
Set the SubMAC to RX state.
During this state the SubMAC accepts incoming frames.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
- Returns
- success or error code.
- Return values
-
0 | on success |
-EBUSY | if the SubMAC is currently busy |
◆ ieee802154_set_short_addr()
Set the IEEE 802.15.4 short address.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
[in] | short_addr | IEEE 802.15.4 short address |
- Returns
- 0 on success
-
negative errno on error
Definition at line 237 of file submac.h.
◆ ieee802154_set_tx_power()
◆ ieee802154_submac_ack_timeout_fired()
Indicate the SubMAC that the ACK timeout fired.
This function must be called when the ACK timeout timer fires.
- Note
- this function should not be called inside ISR context and MUST NOT be invoked if ieee802154_submac_ack_timer_cancel was already called.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
Definition at line 551 of file submac.h.
◆ ieee802154_submac_ack_timer_cancel()
Cancel the ACK timeout timer.
- Note
- This function should be implemented by the user of the SubMAC.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
◆ ieee802154_submac_ack_timer_set()
Set the ACK timeout timer.
- Note
- This function should be implemented by the user of the SubMAC.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
[in] | us | microseconds until the ACK timeout timer is fired |
◆ ieee802154_submac_bh_process()
Indicate the SubMAC that the BH should process an internal event.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
Definition at line 561 of file submac.h.
◆ ieee802154_submac_bh_request()
ieee802154_submac_bh_process should be called as soon as possible.
- Note
- This function should be implemented by the user of the SubMAC.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
◆ ieee802154_submac_crc_error_cb()
Indicate the SubMAC that a frame with invalid CRC was received.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
Definition at line 581 of file submac.h.
◆ ieee802154_submac_init()
Init the IEEE 802.15.4 SubMAC.
The SubMAC state machine starts in RX state.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
[in] | short_addr | pointer to the IEEE 802.15.4 short address |
[in] | ext_addr | pointer to the IEEE 802.15.4 extended address |
- Returns
- 0 on success
-
negative errno on error
◆ ieee802154_submac_rx_done_cb()
Indicate the SubMAC that the device received a frame.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
Definition at line 571 of file submac.h.
◆ ieee802154_submac_state_is_idle()
Check whether the SubMAC is in IDLE state.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
- Return values
-
true | if the SubMAC is in IDLE state |
false | otherwise |
Definition at line 478 of file submac.h.
◆ ieee802154_submac_state_is_rx()
Check whether the SubMAC is in RX state.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
- Return values
-
true | if the SubMAC is in RX state |
false | otherwise |
Definition at line 465 of file submac.h.
◆ ieee802154_submac_tx_done_cb()
Indicate the SubMAC that the device finished the transmission procedure.
- Parameters
-
[in] | submac | pointer to the SubMAC descriptor |
Definition at line 591 of file submac.h.