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!
- Todo
- Provide a user-defined callback scheme in order to implement the ieee802154_dev_t:cb function here, rather than adding it redundantly to each upper-layer implementation.
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 | |
| +----------->| |<-------+
| +--------+
| +--------+ ^
| | | |
+--->| TX ACK |-----+
| |
+--------+
- 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 that requests an acknowledgement and the radio does not send ACKs by itself, the SubMAC goes to TX ACK. Otherwise it calls ieee802154_submac_cb_t::rx_done and immediately goes 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.
- TX ACK: The last received frame required an acknowledgement. Sending further frames in this state is not permitted. After ACK transmission is completed, the SubMAC calls ieee802154_submac_cb_t::rx_done and immediately goes to IDLE.
The events that trigger state machine changes are defined in ieee802154_fsm_ev_t
The following events are valid for each state:
| Event/State | RX | IDLE | PREPARE | TX | WAIT FOR ACK | TX ACK |
| ENTRY** | (X) | (X) | X | (X) | (X) | (X) |
| EXIT** | (X) | (X) | (X) | (X) | (X) | (X) |
| TX_DONE | - | - | - | X | - | 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
**: ENTRY and EXIT events are generated on every state transition. Only PREPARE acts on ENTRY, all other states ignore them.
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_ev_t {
IEEE802154_FSM_EV_ENTRY
, IEEE802154_FSM_EV_EXIT
, IEEE802154_FSM_EV_TX_DONE
, IEEE802154_FSM_EV_RX_DONE
,
IEEE802154_FSM_EV_CRC_ERROR
, IEEE802154_FSM_EV_ACK_TIMEOUT
, 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...
|
| |
| enum | ieee802154_submac_fsm_return_t { IEEE802154_SUBMAC_FSM_RETURN_HANDLED
, IEEE802154_SUBMAC_FSM_RETURN_TRANSITION
, IEEE802154_SUBMAC_FSM_RETURN_IGNORED
} |
| | Internal SubMAC FSM process Event return status. 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, const ieee802154_phy_conf_t *conf) |
| | 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_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.
|
| |
| bool | ieee802154_submac_state_is_rx (ieee802154_submac_t *submac) |
| | Check whether the SubMAC is in RX state.
|
| |
| 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) |
| | Set the ACK timeout timer.
|
| |
| void | ieee802154_submac_ack_timer_cancel (ieee802154_submac_t *submac) |
| | Cancel the ACK timeout timer.
|
| |
|
int | 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_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.
|
| |
| static int | ieee802154_set_idle (ieee802154_submac_t *submac) |
| | Set the SubMAC to IDLE state.
|
| |
| static int | ieee802154_set_rx (ieee802154_submac_t *submac) |
| | Set the SubMAC to RX state.
|
| |
◆ ieee802154_fsm_state_cb_t
Internal SubMAC FSM state.
Definition at line 204 of file submac.h.
◆ ieee802154_submac_t
IEEE 802.15.4 SubMAC forward declaration.
Definition at line 140 of file submac.h.
◆ ieee802154_fsm_ev_t
Internal SubMAC FSM state machine events.
| Enumerator |
|---|
| IEEE802154_FSM_EV_ENTRY | FSM calls entry function of a state.
|
| IEEE802154_FSM_EV_EXIT | FSM calls exit function of a state.
|
| 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_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 179 of file submac.h.
◆ ieee802154_submac_fsm_return_t
Internal SubMAC FSM process Event return status.
| Enumerator |
|---|
| IEEE802154_SUBMAC_FSM_RETURN_HANDLED | Event was handled.
|
| IEEE802154_SUBMAC_FSM_RETURN_TRANSITION | Event has caused a transition.
|
| IEEE802154_SUBMAC_FSM_RETURN_IGNORED | Event was ignored, no action was performed.
|
Definition at line 195 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 422 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 337 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 443 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_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 294 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 |
| -EALREADY | if the SubMAC is already in IDLE state |
| -EBUSY | if the SubMAC is currently busy |
Definition at line 575 of file submac.h.
◆ 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 316 of file submac.h.
◆ ieee802154_set_phy_conf()
Set IEEE 802.15.4 PHY configuration (channel, TX power)
- Parameters
-
| [in] | submac | pointer to the SubMAC descriptor |
| [in] | conf | pointer to the PHY configuration |
- 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 |
| -EALREADY | if the SubMAC is already in RX state |
| -EBUSY | if the SubMAC is currently busy |
Definition at line 592 of file submac.h.
◆ 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 271 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 527 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 |
◆ 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 547 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 537 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 |
◆ 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 |
◆ 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 557 of file submac.h.