diff --git a/nrf_802154/common/include/nrf_802154_types.h b/nrf_802154/common/include/nrf_802154_types.h index dfabc05061..9fb34aaf59 100644 --- a/nrf_802154/common/include/nrf_802154_types.h +++ b/nrf_802154/common/include/nrf_802154_types.h @@ -497,7 +497,6 @@ typedef struct * @brief Function pointer used for notifying about transmission failure. */ typedef void (* nrf_802154_transmit_failed_notification_t)( - uint8_t * p_frame, nrf_802154_tx_error_t error, const nrf_802154_transmit_done_metadata_t * p_meta); diff --git a/nrf_802154/driver/CMakeLists.txt b/nrf_802154/driver/CMakeLists.txt index a33c9cd3b5..0e1f71ed43 100644 --- a/nrf_802154/driver/CMakeLists.txt +++ b/nrf_802154/driver/CMakeLists.txt @@ -75,6 +75,7 @@ target_sources(nrf-802154-driver src/mac_features/nrf_802154_frame_parser.c src/mac_features/nrf_802154_ie_writer.c src/mac_features/nrf_802154_ifs.c + src/mac_features/nrf_802154_imm_tx.c src/mac_features/nrf_802154_security_pib_ram.c src/mac_features/nrf_802154_security_writer.c src/mac_features/nrf_802154_precise_ack_timeout.c diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_ack_timeout.h b/nrf_802154/driver/src/mac_features/nrf_802154_ack_timeout.h index bec6cbfb0f..cd01bb4050 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_ack_timeout.h +++ b/nrf_802154/driver/src/mac_features/nrf_802154_ack_timeout.h @@ -91,23 +91,15 @@ void nrf_802154_ack_timeout_transmitted_hook(const nrf_802154_frame_t * p_frame) * * @param[in] p_frame Pointer to the buffer that contains a frame that was not transmitted. * @param[in] error Cause of failed transmission. - * - * @retval true TX failed event is to be propagated to the MAC layer. - * @retval false TX failed event is not to be propagated to the MAC layer. It is handled - * internally in the ACK timeout module. */ -bool nrf_802154_ack_timeout_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error); +void nrf_802154_ack_timeout_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error); /** * @brief Handles a TX started event. * * @param[in] p_frame Pointer to the buffer that contains a frame being transmitted. - * - * @retval true TX started event is to be propagated to the MAC layer. - * @retval false TX started event is not to be propagated to the MAC layer. It is handled - * internally in the ACK timeout module. */ -bool nrf_802154_ack_timeout_tx_started_hook(uint8_t * p_frame); +void nrf_802154_ack_timeout_tx_started_hook(uint8_t * p_frame); /** * @brief Handles a RX ACK started event. diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c b/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c index 864d884dc9..6ced7484eb 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c +++ b/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c @@ -69,8 +69,8 @@ typedef enum { CSMA_CA_STATE_IDLE, ///< The CSMA-CA procedure is inactive. CSMA_CA_STATE_BACKOFF, ///< The CSMA-CA procedure is in backoff stage. - CSMA_CA_STATE_ONGOING, ///< The frame is being sent. - CSMA_CA_STATE_ABORTED ///< The CSMA-CA procedure is being aborted. + CSMA_CA_STATE_ATTEMPTING_CCATX, ///< The frame transmit attempt is in progress. + CSMA_CA_STATE_TRANSMITTING, ///< The frame has begun transmission. } csma_ca_state_t; static uint8_t m_nb; ///< The number of times the CSMA-CA algorithm was required to back off while attempting the current transmission. @@ -85,17 +85,29 @@ static bool m_tx_timestamp_encode; ///< Tx timestamp requ #endif static csma_ca_state_t m_state; ///< The current state of the CSMA-CA procedure. -/** - * @brief Perform appropriate actions for busy channel conditions. - * - * According to CSMA-CA description in 802.15.4 specification, when channel is busy NB and BE shall - * be incremented and the device shall wait random delay before next CCA procedure. If NB reaches - * macMaxCsmaBackoffs procedure fails. - * - * @retval true Procedure failed and TX failure should be notified to the next higher layer. - * @retval false Procedure is still ongoing and TX failure should be handled internally. - */ -static bool channel_busy(void); +static bool csma_ca_can_abort(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + const nrf_802154_tx_client_t * p_client); +static void csma_ca_failed(uint8_t * p_frame, + nrf_802154_tx_error_t error, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client); +static void csma_ca_tx_started(const nrf_802154_tx_client_t * p_client); + +static void csma_ca_tx_done(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client); + +static const nrf_802154_tx_client_interface_t m_csma_ca_tx_client_iface = { + .can_abort = csma_ca_can_abort, + .failed = csma_ca_failed, + .started = csma_ca_tx_started, + .done = csma_ca_tx_done, +}; + +static nrf_802154_tx_client_t m_csma_ca_tx_client = { + .p_iface = &m_csma_ca_tx_client_iface, +}; static bool csma_ca_state_set(csma_ca_state_t expected, csma_ca_state_t desired) { @@ -137,44 +149,6 @@ static void priority_leverage(void) nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } -/** - * @brief Notify MAC layer that CSMA-CA failed - * - * @param[in] error The error that caused the failure - */ -static void notify_failed(nrf_802154_tx_error_t error) -{ - // core rejected attempt, use my current frame_props - nrf_802154_transmit_done_metadata_t metadata = {}; - - metadata.frame_props = m_data_props; - - nrf_802154_notify_transmit_failed(m_frame.p_frame, error, &metadata); -} - -/** - * @brief Notify MAC layer that channel is busy if tx request failed and there are no retries left. - * - * @param[in] result Result of TX request. - */ -static void notify_busy_channel(bool result) -{ - nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); - - nrf_802154_rsch_delayed_timeslot_cancel(NRF_802154_RESERVED_CSMACA_ID, true); - - // The 802.15.4 specification requires CSMA-CA to continue until m_nb is strictly greater - // than nrf_802154_pib_csmaca_max_backoffs_get(), but at the moment this function is executed - // the value of m_nb has not yet been incremented to reflect the latest attempt. Therefore - // the comparison uses `greater or equal` instead of `greater than`. - if (!result && (m_nb >= nrf_802154_pib_csmaca_max_backoffs_get())) - { - notify_failed(NRF_802154_TX_ERROR_BUSY_CHANNEL); - } - - nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); -} - /** * @brief Perform CCA procedure followed by frame transmission. * @@ -190,7 +164,9 @@ static void frame_transmit(rsch_dly_ts_id_t dly_ts_id) nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - if (csma_ca_state_set(CSMA_CA_STATE_BACKOFF, CSMA_CA_STATE_ONGOING)) + nrf_802154_tx_error_t result = NRF_802154_TX_ERROR_NONE; + + if (csma_ca_state_set(CSMA_CA_STATE_BACKOFF, CSMA_CA_STATE_ATTEMPTING_CCATX)) { priority_leverage(); @@ -208,19 +184,28 @@ static void frame_transmit(rsch_dly_ts_id_t dly_ts_id) #else .tx_timestamp_encode = false, #endif + .p_client = &m_csma_ca_tx_client, + .rsch_timeslot_id = dly_ts_id, }; - if (!nrf_802154_request_transmit(NRF_802154_TERM_NONE, - REQ_ORIG_CSMA_CA, - ¶ms, - notify_busy_channel)) - { - (void)channel_busy(); - } + result = nrf_802154_request_transmit(NRF_802154_TERM_NONE, + REQ_ORIG_CSMA_CA, + ¶ms); } else { - nrf_802154_rsch_delayed_timeslot_cancel(dly_ts_id, true); + bool cancel_status = nrf_802154_rsch_delayed_timeslot_cancel(dly_ts_id, true); + + NRF_802154_ASSERT(cancel_status); + (void)cancel_status; + } + + if (result != NRF_802154_TX_ERROR_NONE) + { + nrf_802154_transmit_done_metadata_t metadata = {}; + + metadata.frame_props = m_data_props; + csma_ca_failed(m_frame.p_frame, result, &metadata, &m_csma_ca_tx_client); } nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); @@ -322,13 +307,23 @@ static void random_backoff_start(void) nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } +/** + * @brief Perform appropriate actions for busy channel conditions. + * + * According to CSMA-CA description in 802.15.4 specification, when channel is busy NB and BE shall + * be incremented and the device shall wait random delay before next CCA procedure. If NB reaches + * macMaxCsmaBackoffs procedure fails. + * + * @retval true Procedure failed and TX failure should be notified to the next higher layer. + * @retval false Procedure is still ongoing and TX failure should be handled internally. + */ static bool channel_busy(void) { bool result = true; nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - if (csma_ca_state_set(CSMA_CA_STATE_ONGOING, CSMA_CA_STATE_BACKOFF)) + if (csma_ca_state_set(CSMA_CA_STATE_ATTEMPTING_CCATX, CSMA_CA_STATE_BACKOFF)) { m_nb++; @@ -339,7 +334,6 @@ static bool channel_busy(void) if (m_nb > nrf_802154_pib_csmaca_max_backoffs_get()) { - nrf_802154_frame_parser_data_clear(&m_frame); bool ret = csma_ca_state_set(CSMA_CA_STATE_BACKOFF, CSMA_CA_STATE_IDLE); NRF_802154_ASSERT(ret); @@ -395,14 +389,17 @@ bool nrf_802154_csma_ca_start(const nrf_802154_frame_t * p_f return true; } -bool nrf_802154_csma_ca_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig) +static bool csma_ca_can_abort(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + const nrf_802154_tx_client_t * p_client) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + (void)p_client; + bool result = true; - if (((req_orig != REQ_ORIG_CORE) && (req_orig != REQ_ORIG_HIGHER_LAYER)) || - (CSMA_CA_STATE_IDLE == nrf_802154_sl_atomic_load_u8((uint8_t *)&m_state))) + if ((req_orig != REQ_ORIG_CORE) && (req_orig != REQ_ORIG_HIGHER_LAYER)) { // The request does not originate from core or the higher layer or the procedure // is stopped already. Ignore the abort request and return success, no matter @@ -411,10 +408,7 @@ bool nrf_802154_csma_ca_abort(nrf_802154_term_t term_lvl, req_originator_t req_o else if (term_lvl >= NRF_802154_TERM_802154) { // The procedure is active and the termination level allows the abort - // request to be executed. Force aborted state. Don't clear the frame - // pointer - it might be needed to notify failure. - nrf_802154_sl_atomic_store_u8((uint8_t *)&m_state, CSMA_CA_STATE_ABORTED); - nrf_802154_rsch_delayed_timeslot_cancel(NRF_802154_RESERVED_CSMACA_ID, false); + // request to be executed. } else { @@ -428,70 +422,69 @@ bool nrf_802154_csma_ca_abort(nrf_802154_term_t term_lvl, req_originator_t req_o return result; } -bool nrf_802154_csma_ca_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error) +static void csma_ca_failed(uint8_t * p_frame, + nrf_802154_tx_error_t error, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client) { - bool result = true; - nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + (void)p_client; + switch (error) { - // Below errors mean a failure occurred during the frame processing and the frame cannot be - // transmitted unless a higher layer takes appropriate actions, hence the CSMA-CA procedure - // shall be stopped. - case NRF_802154_TX_ERROR_TIMESTAMP_ENCODING_ERROR: - case NRF_802154_TX_ERROR_KEY_ID_INVALID: - /* Fallthrough. */ - case NRF_802154_TX_ERROR_FRAME_COUNTER_ERROR: - if (m_frame.p_frame == p_frame) + case NRF_802154_TX_ERROR_TIMESLOT_DENIED: + case NRF_802154_TX_ERROR_BUSY_CHANNEL: + case NRF_802154_TX_ERROR_TIMESLOT_ENDED: + if (channel_busy()) { - nrf_802154_frame_parser_data_clear(&m_frame); nrf_802154_sl_atomic_store_u8((uint8_t *)&m_state, CSMA_CA_STATE_IDLE); + nrf_802154_frame_parser_data_clear(&m_frame); + nrf_802154_notify_transmit_failed(p_frame, + NRF_802154_TX_ERROR_BUSY_CHANNEL, + p_metadata); } break; default: - if (csma_ca_state_set(CSMA_CA_STATE_ABORTED, CSMA_CA_STATE_IDLE)) - { - // The procedure was successfully aborted. - - if (p_frame != m_frame.p_frame) - { - // The procedure was aborted while another operation was holding - // frame pointer in the core - hence p_frame points to a different - // frame than mp_data. CSMA-CA failure must be notified directly. - notify_failed(error); - } - } - else if (p_frame == m_frame.p_frame) - { - // The procedure is active and transmission attempt failed. Try again - result = channel_busy(); - } - else - { - // Intentionally empty. - } + nrf_802154_sl_atomic_store_u8((uint8_t *)&m_state, CSMA_CA_STATE_IDLE); + nrf_802154_frame_parser_data_clear(&m_frame); + nrf_802154_notify_transmit_failed(p_frame, error, p_metadata); break; } nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} - return result; +static void csma_ca_tx_started(const nrf_802154_tx_client_t * p_client) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + (void)p_client; + + bool result = csma_ca_state_set(CSMA_CA_STATE_ATTEMPTING_CCATX, CSMA_CA_STATE_TRANSMITTING); + + NRF_802154_ASSERT(result); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } -bool nrf_802154_csma_ca_tx_started_hook(uint8_t * p_frame) +static void csma_ca_tx_done(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - if (m_frame.p_frame == p_frame) - { - nrf_802154_frame_parser_data_clear(&m_frame); - nrf_802154_sl_atomic_store_u8((uint8_t *)&m_state, CSMA_CA_STATE_IDLE); - } + (void)p_client; + + bool result = csma_ca_state_set(CSMA_CA_STATE_TRANSMITTING, CSMA_CA_STATE_IDLE); + + NRF_802154_ASSERT(result); + + nrf_802154_frame_parser_data_clear(&m_frame); + nrf_802154_notify_transmitted(p_frame, p_metadata); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); - return true; } #endif // NRF_802154_CSMA_CA_ENABLED diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.h b/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.h index d2f5107b2c..71c92fe107 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.h +++ b/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.h @@ -66,47 +66,6 @@ bool nrf_802154_csma_ca_start(const nrf_802154_frame_t * p_frame, const nrf_802154_transmit_csma_ca_metadata_t * p_metadata); -/** - * @brief Aborts the ongoing CSMA-CA procedure. - * - * @note Do not call this function during the execution of @ref nrf_802154_csma_ca_start - * (from ISR with higher priority), as it will result in an unrecoverable runtime error. - * - * If CSMA-CA is not running during the call, this function does nothing and returns true. - * - * @param[in] term_lvl Termination level of this request. Selects procedures to abort. - * @param[in] req_orig Module that originates this request. - - * @retval true CSMA-CA procedure is not running anymore. - * @retval false CSMA-CA cannot be stopped because of a too low termination level. - */ -bool nrf_802154_csma_ca_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig); - -/** - * @brief Handles a TX failed event. - * - * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame - * that was not transmitted. - * @param[in] error Cause of failed transmission. - * - * @retval true TX failed event is to be propagated to the MAC layer. - * @retval false TX failed event is not to be propagated to the MAC layer. It is handled - * internally in the CSMA-CA module. - */ -bool nrf_802154_csma_ca_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error); - -/** - * @brief Handles a TX started event. - * - * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame - * that is being transmitted. - * - * @retval true TX started event is to be propagated to the MAC layer. - * @retval false TX started event is not to be propagated to the MAC layer. It is handled - * internally in the CSMA-CA module. - */ -bool nrf_802154_csma_ca_tx_started_hook(uint8_t * p_frame); - /** *@} **/ diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c b/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c index 54d78d6afd..5ee015f4b1 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c +++ b/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c @@ -126,10 +126,11 @@ typedef struct */ typedef struct { - nrf_802154_transmit_params_t params; ///< Transmission parameters. + nrf_802154_transmit_params_t params; ///< Transmission parameters. + nrf_802154_tx_client_t tx_client; ///< Client instance. #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) - uint64_t time; ///< Target time of the first bit of the frame. + uint64_t time; ///< Target time of the first bit of the frame. #endif } dly_tx_data_t; @@ -150,6 +151,25 @@ typedef struct }; } dly_op_data_t; +static bool delayed_tx_can_abort(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + const nrf_802154_tx_client_t * p_client); +static void delayed_tx_failed(uint8_t * p_frame, + nrf_802154_tx_error_t error, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client); +static void delayed_tx_started(const nrf_802154_tx_client_t * p_client); +static void delayed_tx_done(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client); + +static const nrf_802154_tx_client_interface_t m_delayed_trx_tx_client_iface = { + .can_abort = delayed_tx_can_abort, + .started = delayed_tx_started, + .failed = delayed_tx_failed, + .done = delayed_tx_done, +}; + /** * @brief Array of slots for RX delayed operations. */ @@ -271,6 +291,13 @@ static dly_op_data_t * dly_tx_data_by_id_search(rsch_dly_ts_id_t id) return NULL; } +static dly_op_data_t * dly_tx_data_by_client_get(const nrf_802154_tx_client_t * p_client) +{ + dly_tx_data_t * dly_tx = CONTAINER_OF(p_client, dly_tx_data_t, tx_client); + + return CONTAINER_OF(dly_tx, dly_op_data_t, tx); +} + /** * @brief Retrieve an available slot from a pool. * @@ -339,18 +366,13 @@ static dly_op_data_t * ongoing_dly_rx_slot_get(void) return p_dly_op_data; } -static bool dly_ts_slot_release(dly_op_data_t * p_dly_op_data, bool handler) +static bool dly_ts_slot_release(dly_op_data_t * p_dly_op_data) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); bool result; - result = nrf_802154_rsch_delayed_timeslot_cancel(p_dly_op_data->id, handler); - - if (result) - { - p_dly_op_data->id = NRF_802154_RESERVED_INVALID_ID; - } + result = nrf_802154_rsch_delayed_timeslot_cancel(p_dly_op_data->id, false); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); @@ -366,7 +388,7 @@ static void dly_rx_data_atomically_push(dly_op_data_t * p_dly_op_data) { nrf_802154_mcu_critical_state_t mcu_cs; - nrf_802154_mcu_critical_enter(mcu_cs); + mcu_cs = nrf_802154_mcu_critical_enter(); NRF_802154_ASSERT(!nrf_802154_queue_is_full(&m_dly_rx_id_q)); @@ -388,7 +410,7 @@ static dly_op_data_t * dly_rx_data_atomically_pop(void) { nrf_802154_mcu_critical_state_t mcu_cs; - nrf_802154_mcu_critical_enter(mcu_cs); + mcu_cs = nrf_802154_mcu_critical_enter(); dly_op_data_t ** pp_op = (dly_op_data_t **)nrf_802154_queue_pop_begin(&m_dly_rx_id_q); @@ -487,32 +509,72 @@ static void notify_rx_timeout(nrf_802154_sl_timer_t * p_timer) nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } -/** - * Transmit request result callback. - * - * @param[in] result Result of TX request. - */ -static void dly_tx_result_notify(bool result) +static bool delayed_tx_can_abort(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + const nrf_802154_tx_client_t * p_client) { - nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + + return true; +} + +static void delayed_tx_started(const nrf_802154_tx_client_t * p_client) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + // Intentionally empty. + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void delayed_tx_failed(uint8_t * p_frame, + nrf_802154_tx_error_t error, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + bool result = false; // Currently there's only a single delayed transmission possible at a time - dly_op_data_t * p_dly_op_data = dly_tx_data_by_id_search(NRF_802154_RESERVED_DTX_ID); + dly_op_data_t * p_dly_op_data = dly_tx_data_by_client_get(p_client); NRF_802154_ASSERT(p_dly_op_data != NULL); + p_dly_op_data->id = NRF_802154_RESERVED_INVALID_ID; - if (!result) - { - // core rejected attempt, use my current frame_props - nrf_802154_transmit_done_metadata_t metadata = {}; + result = dly_op_state_set(p_dly_op_data, + DELAYED_TRX_OP_STATE_ONGOING, + DELAYED_TRX_OP_STATE_STOPPED); + NRF_802154_ASSERT(result); + (void)result; - metadata.frame_props = p_dly_op_data->tx.params.frame_props; - nrf_802154_notify_transmit_failed(p_dly_op_data->tx.params.frame.p_frame, - NRF_802154_TX_ERROR_TIMESLOT_DENIED, - &metadata); - } + nrf_802154_notify_transmit_failed(p_frame, error, p_metadata); - nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void delayed_tx_done(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + bool result = false; + + dly_op_data_t * p_dly_op_data = dly_tx_data_by_client_get(p_client); + + NRF_802154_ASSERT(p_dly_op_data != NULL); + + p_dly_op_data->id = NRF_802154_RESERVED_INVALID_ID; + + result = dly_op_state_set(p_dly_op_data, + DELAYED_TRX_OP_STATE_ONGOING, + DELAYED_TRX_OP_STATE_STOPPED); + NRF_802154_ASSERT(result); + (void)result; + + nrf_802154_notify_transmitted(p_frame, p_metadata); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } static void dly_rx_all_ongoing_abort(void) @@ -608,17 +670,18 @@ static void dly_rx_result_notify(bool result) nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } -static void transmit_attempt(dly_op_data_t * p_dly_op_data) +static nrf_802154_tx_error_t transmit_attempt(dly_op_data_t * p_dly_op_data) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); // No need to enqueue transmit attempts. Proceed to transmission immediately - (void)nrf_802154_request_transmit(NRF_802154_TERM_802154, - REQ_ORIG_DELAYED_TRX, - &p_dly_op_data->tx.params, - dly_tx_result_notify); + nrf_802154_tx_error_t result = nrf_802154_request_transmit(NRF_802154_TERM_802154, + REQ_ORIG_DELAYED_TRX, + &p_dly_op_data->tx.params); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + + return result; } static bool receive_attempt(dly_op_data_t * p_dly_op_data) @@ -675,17 +738,21 @@ static void tx_timeslot_started_callback(rsch_dly_ts_id_t dly_ts_id) DELAYED_TRX_OP_STATE_ONGOING); NRF_802154_ASSERT(result); + (void)result; - transmit_attempt(p_dly_op_data); + nrf_802154_tx_error_t tx_result = transmit_attempt(p_dly_op_data); - result = dly_ts_slot_release(p_dly_op_data, true); - NRF_802154_ASSERT(result); + if (tx_result != NRF_802154_TX_ERROR_NONE) + { + nrf_802154_transmit_done_metadata_t metadata = {0}; - result = dly_op_state_set(p_dly_op_data, - DELAYED_TRX_OP_STATE_ONGOING, - DELAYED_TRX_OP_STATE_STOPPED); - NRF_802154_ASSERT(result); - (void)result; + metadata.frame_props = p_dly_op_data->tx.params.frame_props; + + delayed_tx_failed(p_dly_op_data->tx.params.frame.p_frame, + tx_result, + &metadata, + &p_dly_op_data->tx.tx_client); + } nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } @@ -720,6 +787,7 @@ static void rx_timeslot_started_callback(rsch_dly_ts_id_t dly_ts_id) result = nrf_802154_rsch_delayed_timeslot_cancel(dly_ts_id, true); NRF_802154_ASSERT(result); + (void)result; if (!attempt_success) { @@ -729,6 +797,7 @@ static void rx_timeslot_started_callback(rsch_dly_ts_id_t dly_ts_id) DELAYED_TRX_OP_STATE_ONGOING, DELAYED_TRX_OP_STATE_STOPPED); NRF_802154_ASSERT(result); + (void)result; } nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); @@ -762,8 +831,9 @@ void nrf_802154_delayed_trx_init(void) for (uint32_t i = 0; i < sizeof(m_dly_tx_data) / sizeof(m_dly_tx_data[0]); i++) { - m_dly_tx_data[i].state = DELAYED_TRX_OP_STATE_STOPPED; - m_dly_tx_data[i].id = NRF_802154_RESERVED_INVALID_ID; + m_dly_tx_data[i].state = DELAYED_TRX_OP_STATE_STOPPED; + m_dly_tx_data[i].id = NRF_802154_RESERVED_INVALID_ID; + m_dly_tx_data[i].tx.tx_client.p_iface = &m_delayed_trx_tx_client_iface; } } @@ -805,6 +875,8 @@ bool nrf_802154_delayed_trx_transmit(const nrf_802154_frame_t * p p_dly_tx_data->tx.params.extra_cca_attempts = p_metadata->extra_cca_attempts; p_dly_tx_data->tx.params.channel = p_metadata->channel; p_dly_tx_data->tx.params.tx_timestamp_encode = p_metadata->tx_timestamp_encode; + p_dly_tx_data->tx.params.p_client = &p_dly_tx_data->tx.tx_client; + p_dly_tx_data->tx.params.rsch_timeslot_id = NRF_802154_RESERVED_DTX_ID; p_dly_tx_data->id = NRF_802154_RESERVED_DTX_ID; rsch_dly_ts_param_t dly_ts_param = @@ -879,8 +951,10 @@ bool nrf_802154_delayed_trx_transmit_cancel(void) dly_op_data_t * p_dly_op_data = &m_dly_tx_data[0]; bool result = false; - if (dly_ts_slot_release(p_dly_op_data, false)) + if (dly_ts_slot_release(p_dly_op_data)) { + p_dly_op_data->id = NRF_802154_RESERVED_INVALID_ID; + result = dly_op_state_set(p_dly_op_data, DELAYED_TRX_OP_STATE_PENDING, DELAYED_TRX_OP_STATE_STOPPED); diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_frame.h b/nrf_802154/driver/src/mac_features/nrf_802154_frame.h index ac0d32de46..2a654ef8bb 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_frame.h +++ b/nrf_802154/driver/src/mac_features/nrf_802154_frame.h @@ -40,12 +40,23 @@ #ifndef NRF_802154_FRAME_H #define NRF_802154_FRAME_H +#include "nrfx.h" #include "nrf_802154_const.h" #include "nrf_802154_utils_byteorder.h" #include #include #include +#ifdef __STATIC_INLINE__ +#undef __STATIC_INLINE__ +#endif + +#ifdef NRF_802154_FRAME_DECLARE_ONLY +#define __STATIC_INLINE__ +#else +#define __STATIC_INLINE__ __STATIC_INLINE +#endif + #define NRF_802154_FRAME_INVALID_OFFSET 0xff typedef enum @@ -180,11 +191,8 @@ typedef struct * * @returns Current parse level of @p p_parser_data. */ -static inline nrf_802154_frame_parser_level_t nrf_802154_frame_parse_level_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->parse_level; -} +__STATIC_INLINE__ nrf_802154_frame_parser_level_t nrf_802154_frame_parse_level_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the PSDU length of the frame. @@ -195,11 +203,8 @@ static inline nrf_802154_frame_parser_level_t nrf_802154_frame_parse_level_get( * * @note This function assumes that the PHR is correct. */ -static inline uint8_t nrf_802154_frame_length_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->p_frame[PHR_OFFSET]; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_length_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the PSDU start offset of the frame. @@ -208,11 +213,8 @@ static inline uint8_t nrf_802154_frame_length_get( * * @returns PSDU start offset of the frame. */ -static inline uint8_t nrf_802154_frame_psdu_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return PSDU_OFFSET; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_psdu_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the PSDU start address of the frame. @@ -221,11 +223,8 @@ static inline uint8_t nrf_802154_frame_psdu_offset_get( * * @returns PSDU start address of the frame. */ -static inline const uint8_t * nrf_802154_frame_psdu_get( - const nrf_802154_frame_t * p_parser_data) -{ - return &p_parser_data->p_frame[PSDU_OFFSET]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_psdu_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the MAC frame version value from the Frame Control Field. @@ -234,11 +233,8 @@ static inline const uint8_t * nrf_802154_frame_psdu_get( * * @returns Masked MAC frame version value. */ -static inline uint8_t nrf_802154_frame_version_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->p_frame[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_version_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the DSN suppress bit from the Frame Control Field. @@ -248,11 +244,8 @@ static inline uint8_t nrf_802154_frame_version_get( * @retval true DSN suppress bit is set. * @retval false DSN suppress bit is not set. */ -static inline bool nrf_802154_frame_dsn_suppress_bit_is_set( - const nrf_802154_frame_t * p_parser_data) -{ - return (p_parser_data->p_frame[DSN_SUPPRESS_OFFSET] & DSN_SUPPRESS_BIT) ? true : false; -} +__STATIC_INLINE__ bool nrf_802154_frame_dsn_suppress_bit_is_set( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the MAC frame destination address type from the Frame Control Field. @@ -261,11 +254,8 @@ static inline bool nrf_802154_frame_dsn_suppress_bit_is_set( * * @returns Masked MAC frame destination address type. */ -static inline uint8_t nrf_802154_frame_dst_addr_type_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->p_frame[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_addr_type_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Determines if the destination address is extended. @@ -275,12 +265,8 @@ static inline uint8_t nrf_802154_frame_dst_addr_type_get( * @retval true The destination address is extended. * @retval false The destination address is not extended. */ -static inline bool nrf_802154_frame_dst_addr_is_extended( - const nrf_802154_frame_t * p_parser_data) -{ - return (p_parser_data->p_frame[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK) == - DEST_ADDR_TYPE_EXTENDED; -} +__STATIC_INLINE__ bool nrf_802154_frame_dst_addr_is_extended( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the MAC frame source address type from the Frame Control Field. @@ -289,11 +275,8 @@ static inline bool nrf_802154_frame_dst_addr_is_extended( * * @returns Masked MAC frame source address type. */ -static inline uint8_t nrf_802154_frame_src_addr_type_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_src_addr_type_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Determines if the source address is extended. @@ -303,12 +286,8 @@ static inline uint8_t nrf_802154_frame_src_addr_type_get( * @retval true The destination address is extended. * @retval false The destination address is not extended. */ -static inline bool nrf_802154_frame_src_addr_is_extended( - const nrf_802154_frame_t * p_parser_data) -{ - return (p_parser_data->p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK) == - SRC_ADDR_TYPE_EXTENDED; -} +__STATIC_INLINE__ bool nrf_802154_frame_src_addr_is_extended( + const nrf_802154_frame_t * p_parser_data); /** * @brief Determines if the source address is short. @@ -318,12 +297,8 @@ static inline bool nrf_802154_frame_src_addr_is_extended( * @retval true The destination address is short. * @retval false The destination address is not short. */ -static inline bool nrf_802154_frame_src_addr_is_short( - const nrf_802154_frame_t * p_parser_data) -{ - return (p_parser_data->p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK) == - SRC_ADDR_TYPE_SHORT; -} +__STATIC_INLINE__ bool nrf_802154_frame_src_addr_is_short( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the Security Enabled bit from the Frame Control Field. @@ -333,11 +308,8 @@ static inline bool nrf_802154_frame_src_addr_is_short( * @retval true The security is enabled. * @retval false The security is not enabled. */ -static inline bool nrf_802154_frame_security_enabled_bit_is_set( - const nrf_802154_frame_t * p_parser_data) -{ - return (p_parser_data->p_frame[SECURITY_ENABLED_OFFSET] & SECURITY_ENABLED_BIT) ? true : false; -} +__STATIC_INLINE__ bool nrf_802154_frame_security_enabled_bit_is_set( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the IE present bit from the Frame Control Field. @@ -347,17 +319,11 @@ static inline bool nrf_802154_frame_security_enabled_bit_is_set( * @retval true The Information Elements are present. * @retval false The Information Elements are not present. */ -static inline bool nrf_802154_frame_ie_present_bit_is_set( - const nrf_802154_frame_t * p_parser_data) -{ - return (p_parser_data->p_frame[IE_PRESENT_OFFSET] & IE_PRESENT_BIT) ? true : false; -} +__STATIC_INLINE__ bool nrf_802154_frame_ie_present_bit_is_set( + const nrf_802154_frame_t * p_parser_data); -static inline bool nrf_802154_frame_pending_bit_is_set( - const nrf_802154_frame_t * p_parser_data) -{ - return (p_parser_data->p_frame[FRAME_PENDING_OFFSET] & FRAME_PENDING_BIT) != 0; -} +__STATIC_INLINE__ bool nrf_802154_frame_pending_bit_is_set( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the frame type field from the Frame Control Field. @@ -366,11 +332,8 @@ static inline bool nrf_802154_frame_pending_bit_is_set( * * @returns Masked value of the frame type. */ -static inline uint8_t nrf_802154_frame_type_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->p_frame[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_type_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the PAN ID compressions bit from the Frame Control Field. @@ -380,11 +343,8 @@ static inline uint8_t nrf_802154_frame_type_get( * @retval true PAN ID compressions is set. * @retval false PAN ID compressions is not set. */ -static inline bool nrf_802154_frame_panid_compression_is_set( - const nrf_802154_frame_t * p_parser_data) -{ - return (p_parser_data->p_frame[PAN_ID_COMPR_OFFSET] & PAN_ID_COMPR_MASK) ? true : false; -} +__STATIC_INLINE__ bool nrf_802154_frame_panid_compression_is_set( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the AR bit from the Frame Control Field. @@ -394,18 +354,8 @@ static inline bool nrf_802154_frame_panid_compression_is_set( * @retval true AR bit is set. * @retval false AR bit is not set. */ -static inline bool nrf_802154_frame_ar_bit_is_set( - const nrf_802154_frame_t * p_parser_data) -{ - if ((p_parser_data->p_frame[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) == FRAME_TYPE_MULTIPURPOSE) - { - return false; - } - else - { - return (p_parser_data->p_frame[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT) ? true : false; - } -} +__STATIC_INLINE__ bool nrf_802154_frame_ar_bit_is_set( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the DSN field. @@ -414,16 +364,8 @@ static inline bool nrf_802154_frame_ar_bit_is_set( * * @returns The value of the DSN field. */ -static inline const uint8_t * nrf_802154_frame_dsn_get( - const nrf_802154_frame_t * p_parser_data) -{ - if (nrf_802154_frame_dsn_suppress_bit_is_set(p_parser_data)) - { - return NULL; - } - - return &p_parser_data->p_frame[DSN_OFFSET]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_dsn_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the Destination PAN ID field. @@ -432,11 +374,8 @@ static inline const uint8_t * nrf_802154_frame_dsn_get( * * @returns Offset of the Destination PAN ID field. */ -static inline uint8_t nrf_802154_frame_dst_panid_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.dst.panid_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_panid_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the Destination PAN field. @@ -445,18 +384,8 @@ static inline uint8_t nrf_802154_frame_dst_panid_offset_get( * * @returns Address of the Destination PAN field. */ -static inline const uint8_t * nrf_802154_frame_dst_panid_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_dst_panid_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_dst_panid_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of frame Destination Address. @@ -465,11 +394,8 @@ static inline const uint8_t * nrf_802154_frame_dst_panid_get( * * @returns Offset of the frame Destination Address field. */ -static inline uint8_t nrf_802154_frame_dst_addr_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.dst.addr_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_addr_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the Destination Address field. @@ -478,18 +404,8 @@ static inline uint8_t nrf_802154_frame_dst_addr_offset_get( * * @returns Address of the Destination Address field. */ -static inline const uint8_t * nrf_802154_frame_dst_addr_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_dst_addr_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_dst_addr_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of frame Source PAN ID. @@ -498,11 +414,8 @@ static inline const uint8_t * nrf_802154_frame_dst_addr_get( * * @returns Offset of the frame Source PAN ID field. */ -static inline uint8_t nrf_802154_frame_src_panid_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.src.panid_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_src_panid_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the Source PAN ID field. @@ -511,18 +424,8 @@ static inline uint8_t nrf_802154_frame_src_panid_offset_get( * * @returns Address of the Source PAN ID field. */ -static inline const uint8_t * nrf_802154_frame_src_panid_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_src_panid_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_src_panid_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of frame Source Address. @@ -531,11 +434,8 @@ static inline const uint8_t * nrf_802154_frame_src_panid_get( * * @returns Offset of the frame Source Address field. */ -static inline uint8_t nrf_802154_frame_src_addr_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.src.addr_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_src_addr_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the Source Address field. @@ -544,18 +444,8 @@ static inline uint8_t nrf_802154_frame_src_addr_offset_get( * * @returns Address of the Source Address field. */ -static inline const uint8_t * nrf_802154_frame_src_addr_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_src_addr_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_src_addr_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the size of the source address. @@ -564,11 +454,8 @@ static inline const uint8_t * nrf_802154_frame_src_addr_get( * * @returns Source address size in bytes. */ -static inline uint8_t nrf_802154_frame_src_addr_size_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->helper.src_addr_size; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_src_addr_size_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the size of the destination address. @@ -577,11 +464,8 @@ static inline uint8_t nrf_802154_frame_src_addr_size_get( * * @returns Destination address size in bytes. */ -static inline uint8_t nrf_802154_frame_dst_addr_size_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->helper.dst_addr_size; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_addr_size_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the Security Control Field. @@ -590,11 +474,8 @@ static inline uint8_t nrf_802154_frame_dst_addr_size_get( * * @returns Offset of the Security Control Field. */ -static inline uint8_t nrf_802154_frame_sec_ctrl_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.aux_sec_hdr.sec_ctrl_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_sec_ctrl_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the Security Level field from the Security Control Field. @@ -603,18 +484,8 @@ static inline uint8_t nrf_802154_frame_sec_ctrl_offset_get( * * @returns Masked Security Level field value. */ -static inline uint8_t nrf_802154_frame_sec_ctrl_sec_lvl_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return 0; - } - - return p_parser_data->p_frame[offset] & SECURITY_LEVEL_MASK; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_sec_ctrl_sec_lvl_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the Frame Counter Suppress bit from the Security Control Field. @@ -624,18 +495,8 @@ static inline uint8_t nrf_802154_frame_sec_ctrl_sec_lvl_get( * @retval true FC suppress bit is set. * @retval false FC suppress bit is not set. */ -static inline bool nrf_802154_frame_sec_ctrl_fc_suppress_bit_is_set( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return false; - } - - return p_parser_data->p_frame[offset] & FRAME_COUNTER_SUPPRESS_BIT; -} +__STATIC_INLINE__ bool nrf_802154_frame_sec_ctrl_fc_suppress_bit_is_set( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the Key ID Mode field from the Security Control Field. @@ -644,18 +505,8 @@ static inline bool nrf_802154_frame_sec_ctrl_fc_suppress_bit_is_set( * * @returns Masked Key ID Mode field value. */ -static inline uint8_t nrf_802154_frame_sec_ctrl_key_id_mode_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return 0; - } - - return (p_parser_data->p_frame[offset] & KEY_ID_MODE_MASK) >> KEY_ID_MODE_BIT_OFFSET; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_sec_ctrl_key_id_mode_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the value of the ASN in Nonce bit from the Security Control Field. @@ -665,18 +516,8 @@ static inline uint8_t nrf_802154_frame_sec_ctrl_key_id_mode_get( * @retval true ASN in Nonce bit is set. * @retval false ASN in Nonce bit is not set. */ -static inline bool nrf_802154_frame_sec_ctrl_asn_in_nonce_bit_is_set( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return false; - } - - return p_parser_data->p_frame[offset] & ASN_IN_NONCE_BIT; -} +__STATIC_INLINE__ bool nrf_802154_frame_sec_ctrl_asn_in_nonce_bit_is_set( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the Security Control Field. @@ -685,18 +526,8 @@ static inline bool nrf_802154_frame_sec_ctrl_asn_in_nonce_bit_is_set( * * @returns Address of the Security Control Field. */ -static inline const uint8_t * nrf_802154_frame_sec_ctrl_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_sec_ctrl_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the Frame Counter field. @@ -705,11 +536,8 @@ static inline const uint8_t * nrf_802154_frame_sec_ctrl_get( * * @returns Offset of the Frame Counter field. */ -static inline uint8_t nrf_802154_frame_counter_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.aux_sec_hdr.frame_counter_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_counter_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the Frame Counter field. @@ -718,18 +546,8 @@ static inline uint8_t nrf_802154_frame_counter_offset_get( * * @returns Address of the Frame Counter field. */ -static inline const uint8_t * nrf_802154_frame_counter_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_counter_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_counter_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the Key ID field. @@ -738,11 +556,8 @@ static inline const uint8_t * nrf_802154_frame_counter_get( * * @returns Offset of the Key ID field. */ -static inline uint8_t nrf_802154_frame_key_id_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.aux_sec_hdr.key_id_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_id_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the Key ID field. @@ -751,18 +566,8 @@ static inline uint8_t nrf_802154_frame_key_id_offset_get( * * @returns Address of the Key ID field. */ -static inline const uint8_t * nrf_802154_frame_key_id_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_key_id_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_key_id_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the Key Source field. @@ -771,11 +576,8 @@ static inline const uint8_t * nrf_802154_frame_key_id_get( * * @returns Offset of the Key Source field. */ -static inline uint8_t nrf_802154_frame_key_source_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.aux_sec_hdr.key_src_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_source_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the Key Source field. @@ -784,18 +586,8 @@ static inline uint8_t nrf_802154_frame_key_source_offset_get( * * @returns Address of the Key Source field. */ -static inline const uint8_t * nrf_802154_frame_key_source_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_key_source_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_key_source_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the length of the Key Source field. @@ -804,11 +596,8 @@ static inline const uint8_t * nrf_802154_frame_key_source_get( * * @returns Length of the Key Source field. */ -static inline uint8_t nrf_802154_frame_key_source_length_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->helper.key_src_size; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_source_length_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the Key Index field. @@ -817,11 +606,8 @@ static inline uint8_t nrf_802154_frame_key_source_length_get( * * @returns Offset of the Key Index field. */ -static inline uint8_t nrf_802154_frame_key_index_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.aux_sec_hdr.key_idx_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_index_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the Key Index field. @@ -830,18 +616,8 @@ static inline uint8_t nrf_802154_frame_key_index_offset_get( * * @returns Address of the Key Index field. */ -static inline uint8_t nrf_802154_frame_key_index_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_key_index_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return 0; - } - - return p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_index_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the IE header. @@ -850,11 +626,8 @@ static inline uint8_t nrf_802154_frame_key_index_get( * * @returns Offset of the IE header. */ -static inline uint8_t nrf_802154_frame_ie_header_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mhr.header_ie_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_ie_header_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the IE header. @@ -863,18 +636,8 @@ static inline uint8_t nrf_802154_frame_ie_header_offset_get( * * @returns Address of the IE header. */ -static inline const uint8_t * nrf_802154_frame_ie_header_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_ie_header_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_ie_header_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the MAC payload. @@ -883,11 +646,8 @@ static inline const uint8_t * nrf_802154_frame_ie_header_get( * * @returns Offset of the MAC payload. */ -static inline uint8_t nrf_802154_frame_mac_payload_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->mac_payload.mac_payload_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_mac_payload_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the MAC payload. @@ -896,18 +656,8 @@ static inline uint8_t nrf_802154_frame_mac_payload_offset_get( * * @returns Address of the MAC payload. */ -static inline const uint8_t * nrf_802154_frame_mac_payload_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_mac_payload_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_mac_payload_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the MAC Command ID field. @@ -916,17 +666,8 @@ static inline const uint8_t * nrf_802154_frame_mac_payload_get( * * @returns Offset of the MAC Command ID field. */ -static inline uint8_t nrf_802154_frame_mac_command_id_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - if (nrf_802154_frame_type_get(p_parser_data) != FRAME_TYPE_COMMAND) - { - return NRF_802154_FRAME_INVALID_OFFSET; - } - - // MAC command frames containing Payload Information Elements are not supported. - return nrf_802154_frame_mac_payload_offset_get(p_parser_data); -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_mac_command_id_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the MAC Command ID field. @@ -935,18 +676,8 @@ static inline uint8_t nrf_802154_frame_mac_command_id_offset_get( * * @returns Address of the MAC Command ID field. */ -static inline const uint8_t * nrf_802154_frame_mac_command_id_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_mac_command_id_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_mac_command_id_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the offset of the MFR field. @@ -955,11 +686,8 @@ static inline const uint8_t * nrf_802154_frame_mac_command_id_get( * * @returns Offset of the MFR field. */ -static inline uint8_t nrf_802154_frame_mfr_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return nrf_802154_frame_length_get(p_parser_data) - FCS_SIZE + PHR_SIZE; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_mfr_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the address of the MFR field. @@ -968,18 +696,8 @@ static inline uint8_t nrf_802154_frame_mfr_offset_get( * * @returns Address of the MFR field. */ -static inline const uint8_t * nrf_802154_frame_mfr_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_mfr_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_mfr_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the length of the MIC field. @@ -988,11 +706,8 @@ static inline const uint8_t * nrf_802154_frame_mfr_get( * * @returns Length of the MIC field. */ -static inline uint8_t nrf_802154_frame_mic_size_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->helper.mic_size; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_mic_size_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the length of the MAC payload. @@ -1001,15 +716,8 @@ static inline uint8_t nrf_802154_frame_mic_size_get( * * @returns Length of the MAC payload. */ -static inline uint8_t nrf_802154_frame_mac_payload_length_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t mic_len = nrf_802154_frame_mic_size_get(p_parser_data); - uint8_t payload_start = nrf_802154_frame_mac_payload_offset_get(p_parser_data); - uint8_t payload_end = nrf_802154_frame_mfr_offset_get(p_parser_data) - mic_len; - - return payload_end - payload_start; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_mac_payload_length_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the length of the MAC header. @@ -1018,19 +726,8 @@ static inline uint8_t nrf_802154_frame_mac_payload_length_get( * * @returns Length of the MAC header. */ -static inline uint8_t nrf_802154_frame_mac_header_length_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t mhr_start = nrf_802154_frame_psdu_offset_get(p_parser_data); - uint8_t mhr_end = nrf_802154_frame_mac_payload_offset_get(p_parser_data); - - if (mhr_end == NRF_802154_FRAME_INVALID_OFFSET) - { - mhr_end = nrf_802154_frame_mfr_offset_get(p_parser_data); - } - - return mhr_end - mhr_start; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_mac_header_length_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the end offset of the destination addressing section. @@ -1039,11 +736,8 @@ static inline uint8_t nrf_802154_frame_mac_header_length_get( * * @returns End offset of the destination addressing section. */ -static inline uint8_t nrf_802154_frame_dst_addressing_end_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->helper.dst_addressing_end_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_addressing_end_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the end address of the destination addressing section. @@ -1052,18 +746,8 @@ static inline uint8_t nrf_802154_frame_dst_addressing_end_offset_get( * * @returns End address of the destination addressing section. */ -static inline const uint8_t * nrf_802154_frame_dst_addressing_end_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_dst_addressing_end_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_dst_addressing_end_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the end offset of the addressing section. @@ -1072,11 +756,8 @@ static inline const uint8_t * nrf_802154_frame_dst_addressing_end_get( * * @returns End offset of the addressing section. */ -static inline uint8_t nrf_802154_frame_addressing_end_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->helper.addressing_end_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_addressing_end_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the end address of the addressing section. @@ -1085,18 +766,8 @@ static inline uint8_t nrf_802154_frame_addressing_end_offset_get( * * @returns End address of the addressing section. */ -static inline const uint8_t * nrf_802154_frame_addressing_end_get( - const nrf_802154_frame_t * p_parser_data) -{ - uint8_t offset = nrf_802154_frame_addressing_end_offset_get(p_parser_data); - - if (offset == NRF_802154_FRAME_INVALID_OFFSET) - { - return NULL; - } - - return &p_parser_data->p_frame[offset]; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_addressing_end_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Gets the end offset of the security header section. @@ -1105,11 +776,8 @@ static inline const uint8_t * nrf_802154_frame_addressing_end_get( * * @returns End offset of the security header section. */ -static inline uint8_t nrf_802154_frame_aux_sec_hdr_end_offset_get( - const nrf_802154_frame_t * p_parser_data) -{ - return p_parser_data->helper.aux_sec_hdr_end_offset; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_aux_sec_hdr_end_offset_get( + const nrf_802154_frame_t * p_parser_data); /** * @brief Initializes the IE iterator with given IE header address. @@ -1119,11 +787,8 @@ static inline uint8_t nrf_802154_frame_aux_sec_hdr_end_offset_get( * @returns Information element iterator. * */ -static inline const uint8_t * nrf_802154_frame_header_ie_iterator_begin( - const uint8_t * p_ie_header) -{ - return p_ie_header; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_header_ie_iterator_begin( + const uint8_t * p_ie_header); /** * @brief Gets payload address of currently iterated IE. @@ -1135,11 +800,8 @@ static inline const uint8_t * nrf_802154_frame_header_ie_iterator_begin( * @note The user must ensure that the payload is properly bounded. * */ -static inline const uint8_t * nrf_802154_frame_ie_content_address_get( - const uint8_t * p_ie_iterator) -{ - return p_ie_iterator + IE_DATA_OFFSET; -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_ie_content_address_get( + const uint8_t * p_ie_iterator); /** * @brief Gets length of currently iterated IE. @@ -1149,10 +811,7 @@ static inline const uint8_t * nrf_802154_frame_ie_content_address_get( * @returns Length of currently iterated information element. * */ -static inline uint8_t nrf_802154_frame_ie_length_get(const uint8_t * p_ie_iterator) -{ - return p_ie_iterator[IE_LENGTH_OFFSET] & IE_LENGTH_MASK; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_ie_length_get(const uint8_t * p_ie_iterator); /** * @brief Gets next information element iterator. @@ -1162,12 +821,8 @@ static inline uint8_t nrf_802154_frame_ie_length_get(const uint8_t * p_ie_iterat * @returns Next information element iterator. * */ -static inline const uint8_t * nrf_802154_frame_ie_iterator_next( - const uint8_t * p_ie_iterator) -{ - return nrf_802154_frame_ie_content_address_get(p_ie_iterator) - + nrf_802154_frame_ie_length_get(p_ie_iterator); -} +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_ie_iterator_next( + const uint8_t * p_ie_iterator); /** * @brief Gets identifier of currently iterated IE. @@ -1177,10 +832,7 @@ static inline const uint8_t * nrf_802154_frame_ie_iterator_next( * @returns Identifier of currently iterated information element. * */ -static inline uint8_t nrf_802154_frame_ie_id_get(const uint8_t * p_ie_iterator) -{ - return (p_ie_iterator[IE_ID_OFFSET_0] >> 7) | (p_ie_iterator[IE_ID_OFFSET_1] << 1); -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_ie_id_get(const uint8_t * p_ie_iterator); /** * @brief Checks if the current IE is a terminator. @@ -1192,15 +844,8 @@ static inline uint8_t nrf_802154_frame_ie_id_get(const uint8_t * p_ie_iterator) * @retval false The IE is not a terminator and iteration has not passed the end address. * */ -static inline bool nrf_802154_frame_ie_iterator_end(const uint8_t * p_ie_iterator, - const uint8_t * p_end_addr) -{ - uint8_t ie_id = nrf_802154_frame_ie_id_get(p_ie_iterator); - - return ((nrf_802154_frame_ie_length_get(p_ie_iterator) == 0) && - ((ie_id == IE_HT1) || (ie_id == IE_HT2))) - || (p_ie_iterator >= p_end_addr); -} +__STATIC_INLINE__ bool nrf_802154_frame_ie_iterator_end(const uint8_t * p_ie_iterator, + const uint8_t * p_end_addr); /** * @brief Gets vendor-specific OUI (organizationally unique identifier) of currently iterated IE. @@ -1212,14 +857,11 @@ static inline bool nrf_802154_frame_ie_iterator_end(const uint8_t * p_ie_iterato * - ID: @ref IE_VENDOR_ID ID. * - IE length: at least @ref IE_VENDOR_SIZE_MIN * Otherwise, returned value is not OUI. - * See @ref nrf_802154_frame_parser_ie_id_get. + * See @ref nrf_802154_frame_ie_id_get. * * @returns Vendor-specific OUI. */ -static inline uint32_t nrf_802154_frame_ie_vendor_oui_get(const uint8_t * p_ie_iterator) -{ - return little_24_to_host((uint8_t *)&p_ie_iterator[IE_DATA_OFFSET + IE_VENDOR_OUI_OFFSET]); -} +__STATIC_INLINE__ uint32_t nrf_802154_frame_ie_vendor_oui_get(const uint8_t * p_ie_iterator); /** * @brief Gets subtype of Thread vendor-specific IE. @@ -1232,16 +874,13 @@ static inline uint32_t nrf_802154_frame_ie_vendor_oui_get(const uint8_t * p_ie_i * - OUI: @ref IE_VENDOR_THREAD_OUI. * - IE length: at least @ref IE_VENDOR_THREAD_SIZE_MIN * Otherwise, returned value is not Thread IE subtype. - * - @ref nrf_802154_frame_parser_ie_id_get, - * - @ref nrf_802154_frame_parser_ie_vendor_oui_get. + * - @ref nrf_802154_frame_ie_id_get, + * - @ref nrf_802154_frame_ie_vendor_oui_get. * * @returns subtype of Thread vendor-specific IE. */ -static inline uint8_t nrf_802154_frame_ie_vendor_thread_subtype_get( - const uint8_t * p_ie_iterator) -{ - return p_ie_iterator[IE_DATA_OFFSET + IE_VENDOR_THREAD_SUBTYPE_OFFSET]; -} +__STATIC_INLINE__ uint8_t nrf_802154_frame_ie_vendor_thread_subtype_get( + const uint8_t * p_ie_iterator); /** * @brief Gets vendor-specific IE thread data address of currently iterated IE. @@ -1256,124 +895,594 @@ static inline uint8_t nrf_802154_frame_ie_vendor_thread_subtype_get( * - IE length: at least @ref IE_VENDOR_THREAD_ACK_SIZE_MIN * Otherwise, returned pointer does not point to thread vendor-specific IE data. * See also: - * - @ref nrf_802154_frame_parser_ie_id_get, - * - @ref nrf_802154_frame_parser_ie_vendor_oui_get, - * - @ref nrf_802154_frame_parser_ie_vendor_thread_subtype_get. + * - @ref nrf_802154_frame_ie_id_get, + * - @ref nrf_802154_frame_ie_vendor_oui_get, + * - @ref nrf_802154_frame_ie_vendor_thread_subtype_get. * * @returns Current vendor-specific IE thread data address. */ -static inline const uint8_t * nrf_802154_frame_ie_vendor_thread_data_addr_get( +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_ie_vendor_thread_data_addr_get( + const uint8_t * p_ie_iterator); + +#ifndef NRF_802154_FRAME_DECLARE_ONLY + +__STATIC_INLINE__ nrf_802154_frame_parser_level_t nrf_802154_frame_parse_level_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->parse_level; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_length_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->p_frame[PHR_OFFSET]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_psdu_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return PSDU_OFFSET; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_psdu_get( + const nrf_802154_frame_t * p_parser_data) +{ + return &p_parser_data->p_frame[PSDU_OFFSET]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_version_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->p_frame[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK; +} + +__STATIC_INLINE__ bool nrf_802154_frame_dsn_suppress_bit_is_set( + const nrf_802154_frame_t * p_parser_data) +{ + return (p_parser_data->p_frame[DSN_SUPPRESS_OFFSET] & DSN_SUPPRESS_BIT) ? true : false; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_addr_type_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->p_frame[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK; +} + +__STATIC_INLINE__ bool nrf_802154_frame_dst_addr_is_extended( + const nrf_802154_frame_t * p_parser_data) +{ + return (p_parser_data->p_frame[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK) == + DEST_ADDR_TYPE_EXTENDED; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_src_addr_type_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK; +} + +__STATIC_INLINE__ bool nrf_802154_frame_src_addr_is_extended( + const nrf_802154_frame_t * p_parser_data) +{ + return (p_parser_data->p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK) == + SRC_ADDR_TYPE_EXTENDED; +} + +__STATIC_INLINE__ bool nrf_802154_frame_src_addr_is_short( + const nrf_802154_frame_t * p_parser_data) +{ + return (p_parser_data->p_frame[SRC_ADDR_TYPE_OFFSET] & SRC_ADDR_TYPE_MASK) == + SRC_ADDR_TYPE_SHORT; +} + +__STATIC_INLINE__ bool nrf_802154_frame_security_enabled_bit_is_set( + const nrf_802154_frame_t * p_parser_data) +{ + return (p_parser_data->p_frame[SECURITY_ENABLED_OFFSET] & SECURITY_ENABLED_BIT) ? true : false; +} + +__STATIC_INLINE__ bool nrf_802154_frame_ie_present_bit_is_set( + const nrf_802154_frame_t * p_parser_data) +{ + return (p_parser_data->p_frame[IE_PRESENT_OFFSET] & IE_PRESENT_BIT) ? true : false; +} + +__STATIC_INLINE__ bool nrf_802154_frame_pending_bit_is_set( + const nrf_802154_frame_t * p_parser_data) +{ + return (p_parser_data->p_frame[FRAME_PENDING_OFFSET] & FRAME_PENDING_BIT) != 0; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_type_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->p_frame[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK; +} + +__STATIC_INLINE__ bool nrf_802154_frame_panid_compression_is_set( + const nrf_802154_frame_t * p_parser_data) +{ + return (p_parser_data->p_frame[PAN_ID_COMPR_OFFSET] & PAN_ID_COMPR_MASK) ? true : false; +} + +__STATIC_INLINE__ bool nrf_802154_frame_ar_bit_is_set( + const nrf_802154_frame_t * p_parser_data) +{ + if ((p_parser_data->p_frame[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) == FRAME_TYPE_MULTIPURPOSE) + { + return false; + } + else + { + return (p_parser_data->p_frame[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT) ? true : false; + } +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_dsn_get( + const nrf_802154_frame_t * p_parser_data) +{ + if (nrf_802154_frame_dsn_suppress_bit_is_set(p_parser_data)) + { + return NULL; + } + + return &p_parser_data->p_frame[DSN_OFFSET]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_panid_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.dst.panid_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_dst_panid_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_dst_panid_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_addr_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.dst.addr_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_dst_addr_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_dst_addr_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_src_panid_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.src.panid_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_src_panid_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_src_panid_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_src_addr_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.src.addr_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_src_addr_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_src_addr_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_src_addr_size_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->helper.src_addr_size; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_addr_size_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->helper.dst_addr_size; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_sec_ctrl_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.aux_sec_hdr.sec_ctrl_offset; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_sec_ctrl_sec_lvl_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return 0; + } + + return p_parser_data->p_frame[offset] & SECURITY_LEVEL_MASK; +} + +__STATIC_INLINE__ bool nrf_802154_frame_sec_ctrl_fc_suppress_bit_is_set( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return false; + } + + return p_parser_data->p_frame[offset] & FRAME_COUNTER_SUPPRESS_BIT; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_sec_ctrl_key_id_mode_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return 0; + } + + return (p_parser_data->p_frame[offset] & KEY_ID_MODE_MASK) >> KEY_ID_MODE_BIT_OFFSET; +} + +__STATIC_INLINE__ bool nrf_802154_frame_sec_ctrl_asn_in_nonce_bit_is_set( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return false; + } + + return p_parser_data->p_frame[offset] & ASN_IN_NONCE_BIT; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_sec_ctrl_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_sec_ctrl_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_counter_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.aux_sec_hdr.frame_counter_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_counter_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_counter_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_id_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.aux_sec_hdr.key_id_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_key_id_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_key_id_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_source_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.aux_sec_hdr.key_src_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_key_source_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_key_source_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_source_length_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->helper.key_src_size; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_index_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.aux_sec_hdr.key_idx_offset; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_key_index_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_key_index_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return 0; + } + + return p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_ie_header_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mhr.header_ie_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_ie_header_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_ie_header_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_mac_payload_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->mac_payload.mac_payload_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_mac_payload_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_mac_payload_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_mac_command_id_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + if (nrf_802154_frame_type_get(p_parser_data) != FRAME_TYPE_COMMAND) + { + return NRF_802154_FRAME_INVALID_OFFSET; + } + + // MAC command frames containing Payload Information Elements are not supported. + return nrf_802154_frame_mac_payload_offset_get(p_parser_data); +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_mac_command_id_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_mac_command_id_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_mfr_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return nrf_802154_frame_length_get(p_parser_data) - FCS_SIZE + PHR_SIZE; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_mfr_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_mfr_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_mic_size_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->helper.mic_size; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_mac_payload_length_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t mic_len = nrf_802154_frame_mic_size_get(p_parser_data); + uint8_t payload_start = nrf_802154_frame_mac_payload_offset_get(p_parser_data); + uint8_t payload_end = nrf_802154_frame_mfr_offset_get(p_parser_data) - mic_len; + + return payload_end - payload_start; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_mac_header_length_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t mhr_start = nrf_802154_frame_psdu_offset_get(p_parser_data); + uint8_t mhr_end = nrf_802154_frame_mac_payload_offset_get(p_parser_data); + + if (mhr_end == NRF_802154_FRAME_INVALID_OFFSET) + { + mhr_end = nrf_802154_frame_mfr_offset_get(p_parser_data); + } + + return mhr_end - mhr_start; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_dst_addressing_end_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->helper.dst_addressing_end_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_dst_addressing_end_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_dst_addressing_end_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_addressing_end_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->helper.addressing_end_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_addressing_end_get( + const nrf_802154_frame_t * p_parser_data) +{ + uint8_t offset = nrf_802154_frame_addressing_end_offset_get(p_parser_data); + + if (offset == NRF_802154_FRAME_INVALID_OFFSET) + { + return NULL; + } + + return &p_parser_data->p_frame[offset]; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_aux_sec_hdr_end_offset_get( + const nrf_802154_frame_t * p_parser_data) +{ + return p_parser_data->helper.aux_sec_hdr_end_offset; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_header_ie_iterator_begin( + const uint8_t * p_ie_header) +{ + return p_ie_header; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_ie_content_address_get( + const uint8_t * p_ie_iterator) +{ + return p_ie_iterator + IE_DATA_OFFSET; +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_ie_length_get(const uint8_t * p_ie_iterator) +{ + return p_ie_iterator[IE_LENGTH_OFFSET] & IE_LENGTH_MASK; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_ie_iterator_next( + const uint8_t * p_ie_iterator) +{ + return nrf_802154_frame_ie_content_address_get(p_ie_iterator) + + nrf_802154_frame_ie_length_get(p_ie_iterator); +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_ie_id_get(const uint8_t * p_ie_iterator) +{ + return (p_ie_iterator[IE_ID_OFFSET_0] >> 7) | (p_ie_iterator[IE_ID_OFFSET_1] << 1); +} + +__STATIC_INLINE__ bool nrf_802154_frame_ie_iterator_end(const uint8_t * p_ie_iterator, + const uint8_t * p_end_addr) +{ + uint8_t ie_id = nrf_802154_frame_ie_id_get(p_ie_iterator); + + return ((nrf_802154_frame_ie_length_get(p_ie_iterator) == 0) && + ((ie_id == IE_HT1) || (ie_id == IE_HT2))) + || (p_ie_iterator >= p_end_addr); +} + +__STATIC_INLINE__ uint32_t nrf_802154_frame_ie_vendor_oui_get(const uint8_t * p_ie_iterator) +{ + return little_24_to_host((uint8_t *)&p_ie_iterator[IE_DATA_OFFSET + IE_VENDOR_OUI_OFFSET]); +} + +__STATIC_INLINE__ uint8_t nrf_802154_frame_ie_vendor_thread_subtype_get( + const uint8_t * p_ie_iterator) +{ + return p_ie_iterator[IE_DATA_OFFSET + IE_VENDOR_THREAD_SUBTYPE_OFFSET]; +} + +__STATIC_INLINE__ const uint8_t * nrf_802154_frame_ie_vendor_thread_data_addr_get( const uint8_t * p_ie_iterator) { return nrf_802154_frame_ie_content_address_get(p_ie_iterator) + IE_VENDOR_THREAD_DATA_OFFSET; } -/* Old function names kept for compatibility. */ - -#define nrf_802154_frame_parser_parse_level_get nrf_802154_frame_parse_level_get -#define nrf_802154_frame_parser_frame_length_get nrf_802154_frame_length_get -#define nrf_802154_frame_parser_psdu_offset_get nrf_802154_frame_psdu_offset_get -#define nrf_802154_frame_parser_psdu_get nrf_802154_frame_psdu_get -#define nrf_802154_frame_parser_frame_version_get nrf_802154_frame_version_get -#define nrf_802154_frame_parser_dsn_suppress_bit_is_set \ - nrf_802154_frame_dsn_suppress_bit_is_set -#define nrf_802154_frame_parser_dst_addr_type_get nrf_802154_frame_dst_addr_type_get -#define nrf_802154_frame_parser_dst_addr_is_extended \ - nrf_802154_frame_dst_addr_is_extended -#define nrf_802154_frame_parser_src_addr_type_get nrf_802154_frame_src_addr_type_get -#define nrf_802154_frame_parser_src_addr_is_extended \ - nrf_802154_frame_src_addr_is_extended -#define nrf_802154_frame_parser_src_addr_is_short nrf_802154_frame_src_addr_is_short -#define nrf_802154_frame_parser_security_enabled_bit_is_set \ - nrf_802154_frame_security_enabled_bit_is_set -#define nrf_802154_frame_parser_ie_present_bit_is_set \ - nrf_802154_frame_ie_present_bit_is_set -#define nrf_802154_frame_parser_frame_pending_bit_is_set \ - nrf_802154_frame_pending_bit_is_set -#define nrf_802154_frame_parser_frame_type_get nrf_802154_frame_type_get -#define nrf_802154_frame_parser_panid_compression_is_set \ - nrf_802154_frame_panid_compression_is_set -#define nrf_802154_frame_parser_ar_bit_is_set nrf_802154_frame_ar_bit_is_set -#define nrf_802154_frame_parser_dsn_get nrf_802154_frame_dsn_get -#define nrf_802154_frame_parser_dst_panid_offset_get \ - nrf_802154_frame_dst_panid_offset_get -#define nrf_802154_frame_parser_dst_panid_get nrf_802154_frame_dst_panid_get -#define nrf_802154_frame_parser_dst_addr_offset_get \ - nrf_802154_frame_dst_addr_offset_get -#define nrf_802154_frame_parser_dst_addr_get nrf_802154_frame_dst_addr_get -#define nrf_802154_frame_parser_src_panid_offset_get \ - nrf_802154_frame_src_panid_offset_get -#define nrf_802154_frame_parser_src_panid_get nrf_802154_frame_src_panid_get -#define nrf_802154_frame_parser_src_addr_offset_get \ - nrf_802154_frame_src_addr_offset_get -#define nrf_802154_frame_parser_src_addr_get nrf_802154_frame_src_addr_get -#define nrf_802154_frame_parser_src_addr_size_get nrf_802154_frame_src_addr_size_get -#define nrf_802154_frame_parser_dst_addr_size_get nrf_802154_frame_dst_addr_size_get -#define nrf_802154_frame_parser_sec_ctrl_offset_get \ - nrf_802154_frame_sec_ctrl_offset_get -#define nrf_802154_frame_parser_sec_ctrl_sec_lvl_get \ - nrf_802154_frame_sec_ctrl_sec_lvl_get -#define nrf_802154_frame_parser_sec_ctrl_fc_suppress_bit_is_set \ - nrf_802154_frame_sec_ctrl_fc_suppress_bit_is_set -#define nrf_802154_frame_parser_sec_ctrl_key_id_mode_get \ - nrf_802154_frame_sec_ctrl_key_id_mode_get -#define nrf_802154_frame_parser_sec_ctrl_asn_in_nonce_bit_is_set \ - nrf_802154_frame_sec_ctrl_asn_in_nonce_bit_is_set -#define nrf_802154_frame_parser_sec_ctrl_get nrf_802154_frame_sec_ctrl_get -#define nrf_802154_frame_parser_frame_counter_offset_get \ - nrf_802154_frame_counter_offset_get -#define nrf_802154_frame_parser_frame_counter_get nrf_802154_frame_counter_get -#define nrf_802154_frame_parser_key_id_offset_get nrf_802154_frame_key_id_offset_get -#define nrf_802154_frame_parser_key_id_get nrf_802154_frame_key_id_get -#define nrf_802154_frame_parser_key_source_offset_get \ - nrf_802154_frame_key_source_offset_get -#define nrf_802154_frame_parser_key_source_get nrf_802154_frame_key_source_get -#define nrf_802154_frame_parser_key_source_length_get \ - nrf_802154_frame_key_source_length_get -#define nrf_802154_frame_parser_key_index_offset_get \ - nrf_802154_frame_key_index_offset_get -#define nrf_802154_frame_parser_key_index_get nrf_802154_frame_key_index_get -#define nrf_802154_frame_parser_ie_header_offset_get \ - nrf_802154_frame_ie_header_offset_get -#define nrf_802154_frame_parser_ie_header_get nrf_802154_frame_ie_header_get -#define nrf_802154_frame_parser_mac_payload_offset_get \ - nrf_802154_frame_mac_payload_offset_get -#define nrf_802154_frame_parser_mac_payload_get nrf_802154_frame_mac_payload_get -#define nrf_802154_frame_parser_mac_command_id_offset_get \ - nrf_802154_frame_mac_command_id_offset_get -#define nrf_802154_frame_parser_mac_command_id_get nrf_802154_frame_mac_command_id_get -#define nrf_802154_frame_parser_mfr_offset_get nrf_802154_frame_mfr_offset_get -#define nrf_802154_frame_parser_mfr_get nrf_802154_frame_mfr_get -#define nrf_802154_frame_parser_mic_size_get nrf_802154_frame_mic_size_get -#define nrf_802154_frame_parser_mac_payload_length_get \ - nrf_802154_frame_mac_payload_length_get -#define nrf_802154_frame_parser_mac_header_length_get \ - nrf_802154_frame_mac_header_length_get -#define nrf_802154_frame_parser_dst_addressing_end_offset_get \ - nrf_802154_frame_dst_addressing_end_offset_get -#define nrf_802154_frame_parser_dst_addressing_end_get \ - nrf_802154_frame_dst_addressing_end_get -#define nrf_802154_frame_parser_addressing_end_offset_get \ - nrf_802154_frame_addressing_end_offset_get -#define nrf_802154_frame_parser_addressing_end_get nrf_802154_frame_addressing_end_get -#define nrf_802154_frame_parser_aux_sec_hdr_end_offset_get \ - nrf_802154_frame_aux_sec_hdr_end_offset_get -#define nrf_802154_frame_parser_header_ie_iterator_begin \ - nrf_802154_frame_header_ie_iterator_begin -#define nrf_802154_frame_parser_ie_content_address_get \ - nrf_802154_frame_ie_content_address_get -#define nrf_802154_frame_parser_ie_length_get nrf_802154_frame_ie_length_get -#define nrf_802154_frame_parser_ie_iterator_next nrf_802154_frame_ie_iterator_next -#define nrf_802154_frame_parser_ie_id_get nrf_802154_frame_ie_id_get -#define nrf_802154_frame_parser_ie_iterator_end nrf_802154_frame_ie_iterator_end -#define nrf_802154_frame_parser_ie_vendor_oui_get nrf_802154_frame_ie_vendor_oui_get -#define nrf_802154_frame_parser_ie_vendor_thread_subtype_get \ - nrf_802154_frame_ie_vendor_thread_subtype_get -#define nrf_802154_frame_parser_ie_vendor_thread_data_addr_get \ - nrf_802154_frame_ie_vendor_thread_data_addr_get - -/* Old type name kept for compatibility. */ -typedef nrf_802154_frame_t nrf_802154_frame_parser_data_t; +#endif /* NRF_802154_FRAME_DECLARE_ONLY */ #endif // NRF_802154_FRAME_H diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c b/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c index 93650abe6c..3ab6936311 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c +++ b/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c @@ -623,9 +623,8 @@ void nrf_802154_ie_writer_prepare(uint8_t * p_ie_header, const uint8_t * p_end_a ie_writer_prepare(p_ie_header, p_end_addr); } -bool nrf_802154_ie_writer_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function) +nrf_802154_tx_error_t nrf_802154_ie_writer_tx_setup( + nrf_802154_transmit_params_t * p_params) { NRF_802154_ASSERT(nrf_802154_frame_parse_level_get(&p_params->frame) >= PARSE_LEVEL_FULL); @@ -641,13 +640,13 @@ bool nrf_802154_ie_writer_tx_setup( if (p_params->frame_props.dynamic_data_is_set) { // The dynamic data in the frame is already set. Pass. - return true; + return NRF_802154_TX_ERROR_NONE; } if (nrf_802154_frame_type_get(&p_params->frame) == FRAME_TYPE_MULTIPURPOSE) { // Multipurpose frame parsing is not implemented, so skip IE writer. - return true; + return NRF_802154_TX_ERROR_NONE; } const uint8_t * p_mfr_addr; @@ -658,21 +657,21 @@ bool nrf_802154_ie_writer_tx_setup( if (p_ie_header == NULL) { - return true; + return NRF_802154_TX_ERROR_NONE; } nrf_802154_ie_writer_prepare(p_ie_header, p_mfr_addr); - return true; + return NRF_802154_TX_ERROR_NONE; } -bool nrf_802154_ie_writer_tx_started_hook(uint8_t * p_frame) +void nrf_802154_ie_writer_tx_started_hook(uint8_t * p_frame) { (void)p_frame; if (m_writer_state != IE_WRITER_PREPARE) { - return true; + return; } bool written = false; @@ -692,8 +691,6 @@ bool nrf_802154_ie_writer_tx_started_hook(uint8_t * p_frame) { nrf_802154_tx_work_buffer_is_dynamic_data_updated_set(); } - - return true; } void nrf_802154_ie_writer_tx_ack_started_hook(uint8_t * p_ack) diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.h b/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.h index 6c3c0286c2..ddfd40bc96 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.h +++ b/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.h @@ -87,13 +87,11 @@ void nrf_802154_ie_writer_prepare(uint8_t * p_ie_header, const uint8_t * p_end_a * unarmed state. There is no guarantee that all malformed frames will be detected. * * @param[in] p_params Pointer to the transmission parameters. - * @param[in] notify_function Function to be called to notify transmission failure. * - * @retval true Always succeeds. + * @retval NRF_802154_TX_ERROR_NONE Always succeeds. */ -bool nrf_802154_ie_writer_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function); +nrf_802154_tx_error_t nrf_802154_ie_writer_tx_setup( + nrf_802154_transmit_params_t * p_params); /** * @brief ACK TX started hook for the IE writer module. @@ -125,10 +123,8 @@ void nrf_802154_ie_writer_tx_ack_started_hook(uint8_t * p_ack); * that this hook must not exceed. * * @param[in] p_frame Pointer to the buffer that contains the PHR and PSDU of the transmitted frame. - * - * @retval true Always succeeds. */ -bool nrf_802154_ie_writer_tx_started_hook(uint8_t * p_frame); +void nrf_802154_ie_writer_tx_started_hook(uint8_t * p_frame); /** * @brief Sets the value of CSL period to inject into the CSL information element. diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_imm_tx.c b/nrf_802154/driver/src/mac_features/nrf_802154_imm_tx.c new file mode 100644 index 0000000000..013cb7783e --- /dev/null +++ b/nrf_802154/driver/src/mac_features/nrf_802154_imm_tx.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2025, Nordic Semiconductor ASA + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_IMM_TX + +#include "nrf_802154_imm_tx.h" + +#include "nrf_802154_request.h" +#include "nrf_802154_pib.h" +#include "nrf_802154_tx_power.h" +#include "rsch/nrf_802154_rsch.h" +#include "nrf_802154_debug_log.h" + +static void imm_tx_done(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client) +{ + nrf_802154_sl_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + nrf_802154_notify_transmitted(p_frame, p_metadata); + + nrf_802154_sl_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static bool imm_tx_can_abort(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + const nrf_802154_tx_client_t * p_client) +{ + nrf_802154_sl_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + nrf_802154_sl_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + + return true; +} + +static void imm_tx_started(const nrf_802154_tx_client_t * p_client) +{ + nrf_802154_sl_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + // Intentionally empty. + + nrf_802154_sl_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void imm_tx_failed(uint8_t * p_frame, + nrf_802154_tx_error_t error, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client) +{ + nrf_802154_sl_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + nrf_802154_notify_transmit_failed(p_frame, error, p_metadata); + + nrf_802154_sl_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static const nrf_802154_tx_client_interface_t m_imm_tx_tx_client_iface = { + .can_abort = imm_tx_can_abort, + .started = imm_tx_started, + .failed = imm_tx_failed, + .done = imm_tx_done, +}; + +static nrf_802154_tx_client_t m_imm_tx_tx_client = { + .p_iface = &m_imm_tx_tx_client_iface, +}; + +bool nrf_802154_imm_tx_transmit(const nrf_802154_frame_t * p_frame, + const nrf_802154_transmit_metadata_t * p_metadata) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + nrf_802154_tx_error_t result; + uint8_t channel; + + channel = + p_metadata->tx_channel.use_metadata_value ? p_metadata->tx_channel.channel : + nrf_802154_pib_channel_get(); + + nrf_802154_transmit_params_t params = + { + .frame_props = p_metadata->frame_props, + .tx_power = {0}, + .channel = channel, + .cca = p_metadata->cca, + .immediate = false, + .extra_cca_attempts = 0U, + .tx_timestamp_encode = p_metadata->tx_timestamp_encode, + .frame = *p_frame, + .p_client = &m_imm_tx_tx_client, + .rsch_timeslot_id = NRF_802154_RSCH_DLY_TS_ID_INVALID, + }; + + (void)nrf_802154_tx_power_convert_metadata_to_tx_power_split(channel, + p_metadata->tx_power, + ¶ms.tx_power); + + result = nrf_802154_request_transmit(NRF_802154_TERM_NONE, + REQ_ORIG_HIGHER_LAYER, + ¶ms); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + + return result == NRF_802154_TX_ERROR_NONE; +} diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_imm_tx.h b/nrf_802154/driver/src/mac_features/nrf_802154_imm_tx.h new file mode 100644 index 0000000000..dfe693050c --- /dev/null +++ b/nrf_802154/driver/src/mac_features/nrf_802154_imm_tx.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025, Nordic Semiconductor ASA + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NRF_802154_IMM_TX_H__ +#define NRF_802154_IMM_TX_H__ + +#include +#include + +#include "nrf_802154_const.h" +#include "nrf_802154_config.h" +#include "nrf_802154_types.h" +#include "mac_features/nrf_802154_frame.h" + +/** + * @brief Immediately transmit the frame. + * + * The function transmits the immediately, if the radio is sleeping or idle receiving. + * + * @param[in] p_frame Pointer to a frame data structure. + * @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data + * to transmit and additional parameters for the procedure. + * + * @retval true The transmission procedure was scheduled. + * @retval false The driver could not schedule the transmission procedure. + */ +bool nrf_802154_imm_tx_transmit(const nrf_802154_frame_t * p_frame, + const nrf_802154_transmit_metadata_t * p_metadata); + +#endif /* NRF_802154_IMM_TX_H__ */ diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_precise_ack_timeout.c b/nrf_802154/driver/src/mac_features/nrf_802154_precise_ack_timeout.c index 860e90768d..86ba427f82 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_precise_ack_timeout.c +++ b/nrf_802154/driver/src/mac_features/nrf_802154_precise_ack_timeout.c @@ -169,12 +169,10 @@ void nrf_802154_ack_timeout_time_set(uint32_t time) m_timeout = time; } -bool nrf_802154_ack_timeout_tx_started_hook(uint8_t * p_frame) +void nrf_802154_ack_timeout_tx_started_hook(uint8_t * p_frame) { mp_frame = p_frame; timeout_timer_start(); - - return true; } bool nrf_802154_ack_timeout_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig) @@ -215,14 +213,12 @@ void nrf_802154_ack_timeout_rx_ack_started_hook(void) timeout_timer_stop(); } -bool nrf_802154_ack_timeout_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error) +void nrf_802154_ack_timeout_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error) { (void)error; NRF_802154_ASSERT((p_frame == mp_frame) || (!m_procedure_is_active)); timeout_timer_stop(); - - return true; } #endif // NRF_802154_ACK_TIMEOUT_ENABLED diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.c b/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.c index 665486f998..aa48abbf06 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.c +++ b/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.c @@ -150,15 +150,15 @@ static bool security_is_enabled(const nrf_802154_frame_t * p_frame_data) (SECURITY_LEVEL_NONE != nrf_802154_frame_sec_ctrl_sec_lvl_get(p_frame_data)); } -bool nrf_802154_security_writer_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function) +nrf_802154_tx_error_t nrf_802154_security_writer_tx_setup( + nrf_802154_transmit_params_t * p_params) { NRF_802154_ASSERT(nrf_802154_frame_parse_level_get(&p_params->frame) >= PARSE_LEVEL_AUX_SEC_HDR_END); - nrf_802154_key_id_t key_id; - bool result = false; + nrf_802154_key_id_t key_id; + bool result = false; + nrf_802154_tx_error_t error = NRF_802154_TX_ERROR_FRAME_COUNTER_ERROR; key_id.p_key_id = NULL; m_frame_counter_injected = false; @@ -166,13 +166,13 @@ bool nrf_802154_security_writer_tx_setup( if (p_params->frame_props.dynamic_data_is_set) { // The frame has a frame counter field already set. Pass. - return true; + return NRF_802154_TX_ERROR_NONE; } if (nrf_802154_frame_type_get(&p_params->frame) == FRAME_TYPE_MULTIPURPOSE) { // Multipurpose frame parsing is not implemented, so skip security. - return true; + return NRF_802154_TX_ERROR_NONE; } do @@ -181,6 +181,7 @@ bool nrf_802154_security_writer_tx_setup( { /* Security is not enabled. Pass. */ result = true; + error = NRF_802154_TX_ERROR_NONE; break; } @@ -194,29 +195,20 @@ bool nrf_802154_security_writer_tx_setup( case NRF_802154_SECURITY_ERROR_NONE: result = true; m_frame_counter_injected = true; + error = NRF_802154_TX_ERROR_NONE; break; case NRF_802154_SECURITY_ERROR_KEY_NOT_FOUND: { - nrf_802154_transmit_done_metadata_t metadata = {}; - - metadata.frame_props = p_params->frame_props; - notify_function(p_params->frame.p_frame, - NRF_802154_TX_ERROR_KEY_ID_INVALID, - &metadata); result = false; + error = NRF_802154_TX_ERROR_KEY_ID_INVALID; } break; case NRF_802154_SECURITY_ERROR_FRAME_COUNTER_OVERFLOW: { - nrf_802154_transmit_done_metadata_t metadata = {}; - - metadata.frame_props = p_params->frame_props; - notify_function(p_params->frame.p_frame, - NRF_802154_TX_ERROR_FRAME_COUNTER_ERROR, - &metadata); result = false; + error = NRF_802154_TX_ERROR_FRAME_COUNTER_ERROR; } break; @@ -226,22 +218,21 @@ bool nrf_802154_security_writer_tx_setup( */ NRF_802154_ASSERT(false); result = false; + error = NRF_802154_TX_ERROR_FRAME_COUNTER_ERROR; } } while (0); - return result; + return error; } -bool nrf_802154_security_writer_tx_started_hook(uint8_t * p_frame) +void nrf_802154_security_writer_tx_started_hook(uint8_t * p_frame) { if (m_frame_counter_injected) { /* Mark dynamic data updated in the work buffer. */ nrf_802154_tx_work_buffer_is_dynamic_data_updated_set(); } - - return true; } #endif // NRF_802154_SECURITY_WRITER_ENABLED diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.h b/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.h index 19b7232055..d08bd502d5 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.h +++ b/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.h @@ -43,22 +43,20 @@ /** * @brief Transmission setup hook for the security writer module. * - * This hook parses the frame to check availability of the key identified by the frame's security + * This hook checks availability of the key identified by the frame's security * header and injects a frame counter associated with the key. If the frame's security level is * zero, then no processing occurs. * - * If this function detects a malformed frame, the higher layer is notified of transmission - * failure. A frame is considered malformed if requested key is invalid. + * If the key requested in the frame is not found, the procedure returns an error. * * @param[in] p_params Pointer to the transmission parameters. - * @param[in] notify_function Function to be called to notify transmission failure. * - * @retval false Frame security header was not processed successfully. - * @retval true Frame security header was processed successfully. + * @retval NRF_802154_TX_ERROR_NONE The procedure was succesful. + * @retval NRF_802154_TX_ERROR_KEY_ID_INVALID The requested key was not found. + * @retval NRF_802154_TX_ERROR_FRAME_COUNTER_ERROR The frame counter overflowed. */ -bool nrf_802154_security_writer_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function); +nrf_802154_tx_error_t nrf_802154_security_writer_tx_setup( + nrf_802154_transmit_params_t * p_params); /** * @brief TX started hook for the security writer module. @@ -67,9 +65,7 @@ bool nrf_802154_security_writer_tx_setup( * into the transmitted frame, this hook marks the frame counter as updated. * * @param[in] p_frame Pointer to the buffer that contains the PHR and PSDU of the transmitted frame. - * - * @retval true Always succeeds. */ -bool nrf_802154_security_writer_tx_started_hook(uint8_t * p_frame); +void nrf_802154_security_writer_tx_started_hook(uint8_t * p_frame); #endif // NRF_802154_SECURITY_WRITER_H__ diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_tx_timestamp_provider.c b/nrf_802154/driver/src/mac_features/nrf_802154_tx_timestamp_provider.c index 62ec17f414..4d26453e1a 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_tx_timestamp_provider.c +++ b/nrf_802154/driver/src/mac_features/nrf_802154_tx_timestamp_provider.c @@ -49,9 +49,8 @@ static uint64_t m_tx_timestamp_us; ///< Cached transmit timestamp. static uint8_t * mp_tx_timestamp_addr; ///< Cached tx timestamp placeholder address. -bool nrf_802154_tx_timestamp_provider_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function) +nrf_802154_tx_error_t nrf_802154_tx_timestamp_provider_tx_setup( + nrf_802154_transmit_params_t * p_params) { NRF_802154_ASSERT(nrf_802154_frame_parse_level_get(&p_params->frame) >= PARSE_LEVEL_FULL); @@ -64,7 +63,7 @@ bool nrf_802154_tx_timestamp_provider_tx_setup( if (p_params->tx_timestamp_encode == false) { // There is nothing to do. - return true; + return NRF_802154_TX_ERROR_NONE; } do @@ -104,25 +103,20 @@ bool nrf_802154_tx_timestamp_provider_tx_setup( if (result == false) { - nrf_802154_transmit_done_metadata_t metadata = {}; - - metadata.frame_props = p_params->frame_props; - notify_function(p_params->frame.p_frame, - NRF_802154_TX_ERROR_TIMESTAMP_ENCODING_ERROR, - &metadata); + return NRF_802154_TX_ERROR_TIMESTAMP_ENCODING_ERROR; } - return result; + return NRF_802154_TX_ERROR_NONE; } -bool nrf_802154_tx_timestamp_provider_tx_started_hook(uint8_t * p_frame) +void nrf_802154_tx_timestamp_provider_tx_started_hook(uint8_t * p_frame) { NRF_802154_ASSERT(m_tx_timestamp_us == 0); // Verify that the setup phase has been completed. if (mp_tx_timestamp_addr == NULL) { - return true; + return; } /* This function is executed in the handler of RADIO.ADDRESS event. According to the IPS, * in 802.15.4 transmit sequence RADIO.FRAMESTART event is triggered after the SHR is @@ -137,8 +131,6 @@ bool nrf_802154_tx_timestamp_provider_tx_started_hook(uint8_t * p_frame) host_64_to_big(m_tx_timestamp_us, mp_tx_timestamp_addr); mp_tx_timestamp_addr = NULL; - - return true; } #endif // NRF_802154_TX_TIMESTAMP_PROVIDER_ENABLED diff --git a/nrf_802154/driver/src/mac_features/nrf_802154_tx_timestamp_provider.h b/nrf_802154/driver/src/mac_features/nrf_802154_tx_timestamp_provider.h index 191c551543..dc15004d15 100644 --- a/nrf_802154/driver/src/mac_features/nrf_802154_tx_timestamp_provider.h +++ b/nrf_802154/driver/src/mac_features/nrf_802154_tx_timestamp_provider.h @@ -51,15 +51,13 @@ * If the transmission parameters do not request transmit timestamp encoding, this hook exits * without performing any actions. * - * @param[in] p_params Pointer to the transmission parameters. - * @param[in] notify_function Function to be called to notify transmission failure. + * @param[in] p_params Pointer to the transmission parameters. * - * @retval false Transmission parameters were not processed successfully. - * @retval true Transmission parameters were processed successfully. + * @retval NRF_802154_TX_ERROR_NONE The procedure was successful. + * @retval NRF_802154_TX_ERROR_TIMESTAMP_ENCODING_ERROR The timestamp cannot be inserted into the frame. */ -bool nrf_802154_tx_timestamp_provider_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function); +nrf_802154_tx_error_t nrf_802154_tx_timestamp_provider_tx_setup( + nrf_802154_transmit_params_t * p_params); /** * @brief TX started hook for the tx timestamp provider module. @@ -70,9 +68,7 @@ bool nrf_802154_tx_timestamp_provider_tx_setup( * time (in microseconds) to that address. * * @param[in] p_frame Pointer to the buffer that contains the PHR and PSDU of the transmitted frame. - * - * @retval true Always succeeds. */ -bool nrf_802154_tx_timestamp_provider_tx_started_hook(uint8_t * p_frame); +void nrf_802154_tx_timestamp_provider_tx_started_hook(uint8_t * p_frame); #endif // NRF_802154_TX_TIMESTAMP_PROVIDER_H__ diff --git a/nrf_802154/driver/src/nrf_802154.c b/nrf_802154/driver/src/nrf_802154.c index 96d5ccae87..08bb20a0c1 100644 --- a/nrf_802154/driver/src/nrf_802154.c +++ b/nrf_802154/driver/src/nrf_802154.c @@ -76,6 +76,7 @@ #include "mac_features/nrf_802154_security_pib.h" #include "mac_features/ack_generator/nrf_802154_ack_data.h" #include "mac_features/nrf_802154_frame_parser.h" +#include "mac_features/nrf_802154_imm_tx.h" #include "nrf_802154_sl_ant_div.h" #include "nrf_802154_sl_crit_sect_if.h" @@ -401,8 +402,8 @@ bool nrf_802154_receive(void) bool nrf_802154_transmit_raw(uint8_t * p_data, const nrf_802154_transmit_metadata_t * p_metadata) { - bool result; - uint8_t channel; + bool result; + nrf_802154_frame_t frame; nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); @@ -420,25 +421,10 @@ bool nrf_802154_transmit_raw(uint8_t * p_data, p_metadata = &metadata_default; } - channel = - p_metadata->tx_channel.use_metadata_value ? p_metadata->tx_channel.channel : - nrf_802154_pib_channel_get(); - - nrf_802154_transmit_params_t params = - { - .frame_props = p_metadata->frame_props, - .tx_power = {0}, - .channel = channel, - .cca = p_metadata->cca, - .immediate = false, - .extra_cca_attempts = 0U, - .tx_timestamp_encode = p_metadata->tx_timestamp_encode, - }; - result = nrf_802154_frame_parser_data_init(p_data, p_data[PHR_OFFSET] + PHR_SIZE, PARSE_LEVEL_FULL, - ¶ms.frame); + &frame); if (!result) { @@ -446,18 +432,12 @@ bool nrf_802154_transmit_raw(uint8_t * p_data, return result; } - (void)nrf_802154_tx_power_convert_metadata_to_tx_power_split(channel, - p_metadata->tx_power, - ¶ms.tx_power); - - result = are_frame_properties_valid(¶ms.frame_props) && + result = are_frame_properties_valid(&p_metadata->frame_props) && is_tx_timestamp_request_valid(p_metadata->tx_timestamp_encode); if (result) { - result = nrf_802154_request_transmit(NRF_802154_TERM_NONE, - REQ_ORIG_HIGHER_LAYER, - ¶ms, - NULL); + result = nrf_802154_imm_tx_transmit(&frame, + p_metadata); } nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); diff --git a/nrf_802154/driver/src/nrf_802154_core.c b/nrf_802154/driver/src/nrf_802154_core.c index 46d21c3682..f6b8640343 100644 --- a/nrf_802154/driver/src/nrf_802154_core.c +++ b/nrf_802154/driver/src/nrf_802154_core.c @@ -110,20 +110,19 @@ */ #define PRESTARTED_TIMER_TIMEOUT_US (160U) -static rx_buffer_t * mp_current_rx_buffer; /// Pointer to currently used receive buffer. -static uint8_t * mp_ack; ///< Pointer to Ack frame buffer. -static nrf_802154_frame_t m_tx_data; ///< Data structure of the frame to be transmitted. -static uint32_t m_ed_time_left; ///< Remaining time of the current energy detection procedure [us]. -static int8_t m_ed_result; ///< Result of the current energy detection procedure. -static uint8_t m_last_lqi; ///< LQI of the last received non-ACK frame, corrected for the temperature. -static nrf_802154_fal_tx_power_split_t m_tx_power; ///< Power to be used to transmit the current frame split into components. -static uint8_t m_tx_channel; ///< Channel to be used to transmit the current frame. -static int8_t m_last_rssi; ///< RSSI of the last received non-ACK frame, corrected for the temperature. -static uint8_t m_no_rx_buffer_notified; ///< Set when NRF_802154_RX_ERROR_NO_BUFFER has been notified. +static rx_buffer_t * mp_current_rx_buffer; /// Pointer to currently used receive buffer. +static uint8_t * mp_ack; ///< Pointer to Ack frame buffer. +static uint32_t m_ed_time_left; ///< Remaining time of the current energy detection procedure [us]. +static int8_t m_ed_result; ///< Result of the current energy detection procedure. +static uint8_t m_last_lqi; ///< LQI of the last received non-ACK frame, corrected for the temperature. +static int8_t m_last_rssi; ///< RSSI of the last received non-ACK frame, corrected for the temperature. +static uint8_t m_no_rx_buffer_notified; ///< Set when NRF_802154_RX_ERROR_NO_BUFFER has been notified. -static nrf_802154_frame_t m_current_rx_frame_data; ///< RX frame parser data. +static nrf_802154_frame_t m_current_rx_frame_data; ///< RX frame parser data. -static volatile radio_state_t m_state; ///< State of the radio driver. +static nrf_802154_transmit_params_t m_tx; + +static volatile radio_state_t m_state; ///< State of the radio driver. typedef struct { @@ -317,18 +316,6 @@ static void receive_failed_notify(nrf_802154_rx_error_t error) nrf_802154_critical_section_nesting_deny(); } -/** Notify MAC layer that transmission of requested frame has started. */ -static void transmit_started_notify(void) -{ -#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) - /** - * TX started hooks were executed before transmission started. Use latched result - */ -#else - (void)nrf_802154_core_hooks_tx_started(m_tx_data.p_frame); -#endif -} - /** Notify MAC layer that transmission of ACK frame has started. */ static void transmit_ack_started_notify() { @@ -348,9 +335,80 @@ static void receive_started_notify(void) nrf_802154_core_hooks_rx_started(&m_current_rx_frame_data); } +static bool tx_client_can_abort(nrf_802154_term_t term_lvl, + req_originator_t req_orig) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + bool result = true; + + if (m_tx.p_client != NULL) + { + result = m_tx.p_client->p_iface->can_abort(term_lvl, req_orig, m_tx.p_client); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + + return result; +} + +static void tx_client_failed_notify(uint8_t * p_frame, + nrf_802154_tx_error_t error, + const nrf_802154_transmit_done_metadata_t * p_meta) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + NRF_802154_ASSERT(m_tx.p_client != NULL); + m_tx.p_client->p_iface->failed(p_frame, error, p_meta, m_tx.p_client); + m_tx.p_client = NULL; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void tx_client_started_notify(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + NRF_802154_ASSERT(m_tx.p_client != NULL); + m_tx.p_client->p_iface->started(m_tx.p_client); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void tx_client_transmitted_notify(nrf_802154_frame_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_meta) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + NRF_802154_ASSERT(m_tx.p_client != NULL); + m_tx.p_client->p_iface->done(p_frame->p_frame, p_meta, m_tx.p_client); + m_tx.p_client = NULL; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +/** Notify MAC layer that transmission of requested frame has started. */ +static void transmit_started_notify(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + +#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) + /** + * TX started hooks were executed before transmission started. Use latched result + */ +#else + nrf_802154_core_hooks_tx_started(m_tx.frame.p_frame); + tx_client_started_notify(); +#endif + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + /** Notify MAC layer that a frame was transmitted. */ static void transmitted_frame_notify(uint8_t * p_ack, int8_t power, uint8_t lqi) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + nrf_802154_transmit_done_metadata_t metadata = {0}; metadata.data.transmitted.p_ack = p_ack; @@ -367,24 +425,31 @@ static void transmitted_frame_notify(uint8_t * p_ack, int8_t power, uint8_t lqi) nrf_802154_stat_timestamp_read(&metadata.data.transmitted.time, last_ack_end_timestamp); } + // Update the transmitted frame contents and update frame status flags + nrf_802154_tx_work_buffer_original_frame_update(m_tx.frame.p_frame, + &metadata.frame_props); + nrf_802154_critical_section_nesting_allow(); - nrf_802154_core_hooks_transmitted(&m_tx_data); + nrf_802154_core_hooks_transmitted(&m_tx.frame); - nrf_802154_notify_transmitted(m_tx_data.p_frame, &metadata); + tx_client_transmitted_notify(&m_tx.frame, &metadata); nrf_802154_critical_section_nesting_deny(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } /** Notify MAC layer that transmission procedure failed. */ -static void transmit_failed_notify(uint8_t * p_frame, - nrf_802154_tx_error_t error, +static void transmit_failed_notify(nrf_802154_tx_error_t error, const nrf_802154_transmit_done_metadata_t * p_meta) { - if (nrf_802154_core_hooks_tx_failed(p_frame, error)) - { - nrf_802154_notify_transmit_failed(p_frame, error, p_meta); - } + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + nrf_802154_core_hooks_tx_failed(m_tx.frame.p_frame, error); + tx_client_failed_notify(m_tx.frame.p_frame, error, p_meta); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } /** Allow nesting critical sections and notify MAC layer that transmission procedure failed. */ @@ -394,7 +459,7 @@ static void transmit_failed_notify_and_nesting_allow( { nrf_802154_critical_section_nesting_allow(); - transmit_failed_notify(m_tx_data.p_frame, error, p_meta); + transmit_failed_notify(error, p_meta); nrf_802154_critical_section_nesting_deny(); } @@ -726,9 +791,9 @@ static void operation_terminated_notify(radio_state_t state, bool receiving_psdu { nrf_802154_transmit_done_metadata_t metadata = {}; - nrf_802154_tx_work_buffer_original_frame_update(m_tx_data.p_frame, + nrf_802154_tx_work_buffer_original_frame_update(m_tx.frame.p_frame, &metadata.frame_props); - transmit_failed_notify(m_tx_data.p_frame, NRF_802154_TX_ERROR_ABORTED, &metadata); + transmit_failed_notify(NRF_802154_TX_ERROR_ABORTED, &metadata); } break; @@ -736,9 +801,9 @@ static void operation_terminated_notify(radio_state_t state, bool receiving_psdu { nrf_802154_transmit_done_metadata_t metadata = {}; - nrf_802154_tx_work_buffer_original_frame_update(m_tx_data.p_frame, + nrf_802154_tx_work_buffer_original_frame_update(m_tx.frame.p_frame, &metadata.frame_props); - transmit_failed_notify(m_tx_data.p_frame, NRF_802154_TX_ERROR_NO_ACK, &metadata); + transmit_failed_notify(NRF_802154_TX_ERROR_NO_ACK, &metadata); } break; @@ -773,7 +838,12 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl, req_originator_t req_orig, bool notify) { - bool result = nrf_802154_core_hooks_terminate(term_lvl, req_orig); + bool result = tx_client_can_abort(term_lvl, req_orig); + + if (result) + { + result = nrf_802154_core_hooks_terminate(term_lvl, req_orig); + } if (result) { @@ -1054,12 +1124,12 @@ static bool tx_init(const nrf_802154_frame_t * p_frame, } #endif - nrf_802154_trx_channel_set(m_tx_channel); + nrf_802154_trx_channel_set(m_tx.channel); m_flags.tx_with_cca = cca; nrf_802154_trx_transmit_frame(nrf_802154_tx_work_buffer_get(p_frame->p_frame), rampup_trigg_mode, cca_attempts, - &m_tx_power, + &m_tx.tx_power, m_trx_transmit_frame_notifications_mask); #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) /** @@ -1094,7 +1164,9 @@ static bool tx_init(const nrf_802154_frame_t * p_frame, nrf_802154_bsim_utils_core_hooks_adjustments_set(&adjustments); - m_flags.tx_started_notify = nrf_802154_core_hooks_tx_started(m_tx_data.p_frame); + nrf_802154_core_hooks_tx_started(m_tx.frame.p_frame); + tx_client_started_notify(); + m_flags.tx_started_notify = true; nrf_802154_bsim_utils_core_hooks_adjustments_t zeroes = {0}; @@ -1264,7 +1336,6 @@ static void on_timeslot_ended(void) result = nrf_802154_core_hooks_terminate(NRF_802154_TERM_802154, REQ_ORIG_RSCH); NRF_802154_ASSERT(result); - (void)result; switch (m_state) { @@ -1293,7 +1364,7 @@ static void on_timeslot_ended(void) state_set(RADIO_STATE_RX); nrf_802154_transmit_done_metadata_t metadata = {}; - nrf_802154_tx_work_buffer_original_frame_update(m_tx_data.p_frame, + nrf_802154_tx_work_buffer_original_frame_update(m_tx.frame.p_frame, &metadata.frame_props); transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_TIMESLOT_ENDED, &metadata); @@ -1305,7 +1376,7 @@ static void on_timeslot_ended(void) state_set(RADIO_STATE_RX); nrf_802154_transmit_done_metadata_t metadata = {}; - nrf_802154_tx_work_buffer_original_frame_update(m_tx_data.p_frame, + nrf_802154_tx_work_buffer_original_frame_update(m_tx.frame.p_frame, &metadata.frame_props); transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_NO_ACK, &metadata); @@ -1412,11 +1483,11 @@ static void on_preconditions_approved(radio_state_t state) break; case RADIO_STATE_CCA_TX: - (void)tx_init(&m_tx_data, TRX_RAMP_UP_SW_TRIGGER, true); + (void)tx_init(&m_tx.frame, TRX_RAMP_UP_SW_TRIGGER, true); break; case RADIO_STATE_TX: - (void)tx_init(&m_tx_data, TRX_RAMP_UP_SW_TRIGGER, false); + (void)tx_init(&m_tx.frame, TRX_RAMP_UP_SW_TRIGGER, false); break; case RADIO_STATE_ED: @@ -1433,7 +1504,7 @@ static void on_preconditions_approved(radio_state_t state) break; case RADIO_STATE_MODULATED_CARRIER: - modulated_carrier_init(m_tx_data.p_frame); + modulated_carrier_init(m_tx.frame.p_frame); break; #endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED @@ -2155,7 +2226,7 @@ void nrf_802154_trx_transmit_frame_started(void) nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); NRF_802154_ASSERT((m_state == RADIO_STATE_TX) || (m_state == RADIO_STATE_CCA_TX)); - if (tx_started_core_hooks_will_fit_within_timeslot(m_tx_data.p_frame)) + if (tx_started_core_hooks_will_fit_within_timeslot(m_tx.frame.p_frame)) { transmit_started_notify(); } @@ -2166,9 +2237,9 @@ void nrf_802154_trx_transmit_frame_started(void) nrf_802154_transmit_done_metadata_t metadata = {}; - nrf_802154_tx_work_buffer_original_frame_update(m_tx_data.p_frame, &metadata.frame_props); + nrf_802154_tx_work_buffer_original_frame_update(m_tx.frame.p_frame, &metadata.frame_props); - transmit_failed_notify(m_tx_data.p_frame, NRF_802154_TX_ERROR_TIMESLOT_ENDED, &metadata); + transmit_failed_notify(NRF_802154_TX_ERROR_TIMESLOT_ENDED, &metadata); } nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); @@ -2231,7 +2302,7 @@ void nrf_802154_trx_transmit_frame_transmitted(void) m_flags.tx_diminished_prio = false; // We calculate the timestamp when ccaidle must happened. - ts -= nrf_802154_frame_duration_get(m_tx_data.p_frame[0], + ts -= nrf_802154_frame_duration_get(m_tx.frame.p_frame[0], true, true) + RX_TX_TURNAROUND_TIME; @@ -2240,7 +2311,7 @@ void nrf_802154_trx_transmit_frame_transmitted(void) #endif - if (tx_frame_ack_is_requested(&m_tx_data)) + if (tx_frame_ack_is_requested(&m_tx.frame)) { state_set(RADIO_STATE_RX_ACK); @@ -2366,7 +2437,7 @@ static void on_bad_ack(void) nrf_802154_transmit_done_metadata_t metadata = {}; - nrf_802154_tx_work_buffer_original_frame_update(m_tx_data.p_frame, &metadata.frame_props); + nrf_802154_tx_work_buffer_original_frame_update(m_tx.frame.p_frame, &metadata.frame_props); transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_INVALID_ACK, &metadata); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); @@ -2384,7 +2455,7 @@ void nrf_802154_trx_receive_ack_received(void) PARSE_LEVEL_ADDRESSING_END, &m_current_rx_frame_data); - if (result && ack_match_check(&m_tx_data, &m_current_rx_frame_data)) + if (result && ack_match_check(&m_tx.frame, &m_current_rx_frame_data)) { #if (NRF_802154_FRAME_TIMESTAMP_ENABLED) uint64_t ts = timer_coord_timestamp_get(); @@ -2399,9 +2470,9 @@ void nrf_802154_trx_receive_ack_received(void) // Detect Frame Pending field set to one on Ack frame received after a Data Request Command bool should_receive = false; - if (nrf_802154_frame_type_get(&m_tx_data) == FRAME_TYPE_COMMAND) + if (nrf_802154_frame_type_get(&m_tx.frame) == FRAME_TYPE_COMMAND) { - const uint8_t * p_cmd = nrf_802154_frame_mac_command_id_get(&m_tx_data); + const uint8_t * p_cmd = nrf_802154_frame_mac_command_id_get(&m_tx.frame); if ((p_cmd != NULL) && (*p_cmd == MAC_CMD_DATA_REQ)) { @@ -2488,7 +2559,7 @@ void nrf_802154_trx_transmit_frame_ccabusy(void) nrf_802154_transmit_done_metadata_t metadata = {}; - nrf_802154_tx_work_buffer_original_frame_update(m_tx_data.p_frame, &metadata.frame_props); + nrf_802154_tx_work_buffer_original_frame_update(m_tx.frame.p_frame, &metadata.frame_props); transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_BUSY_CHANNEL, &metadata); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); @@ -2693,84 +2764,81 @@ bool nrf_802154_core_receive(nrf_802154_term_t term_lvl, return result; } -bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl, - req_originator_t req_orig, - nrf_802154_transmit_params_t * p_params, - nrf_802154_notification_func_t notify_function) +nrf_802154_tx_error_t nrf_802154_core_transmit(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + nrf_802154_transmit_params_t * p_params) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - bool result = critical_section_enter_and_verify_timeslot_length(); + bool result = critical_section_enter_and_verify_timeslot_length(); + bool crit_sect_entered = result; + nrf_802154_tx_error_t error = NRF_802154_TX_ERROR_TIMESLOT_DENIED; if (result) { - if (nrf_802154_core_hooks_pre_transmission(p_params, &transmit_failed_notify)) - { - result = current_operation_terminate(term_lvl, req_orig, true); + result = nrf_802154_core_hooks_pre_transmission(p_params, &transmit_failed_notify); + } - if (result) - { - nrf_802154_tx_work_buffer_reset(&p_params->frame_props); - result = nrf_802154_core_hooks_tx_setup(p_params, &transmit_failed_notify); + if (result) + { + result = current_operation_terminate(term_lvl, req_orig, true); + } - if (!result) - { - switch_to_idle(); - } - } + if (result) + { + nrf_802154_tx_work_buffer_reset(&p_params->frame_props); + error = nrf_802154_core_hooks_tx_setup(p_params); + result = error == NRF_802154_TX_ERROR_NONE; - if (result) - { - m_coex_tx_request_mode = nrf_802154_pib_coex_tx_request_mode_get(); - m_trx_transmit_frame_notifications_mask = - make_trx_frame_transmit_notification_mask(p_params->cca); - m_flags.tx_diminished_prio = - m_coex_tx_request_mode == NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE; + if (!result) + { + switch_to_idle(); + } + } - state_set(p_params->cca ? RADIO_STATE_CCA_TX : RADIO_STATE_TX); - m_tx_data = p_params->frame; - m_tx_power = p_params->tx_power; - m_tx_channel = p_params->channel; + if (result) + { + m_coex_tx_request_mode = nrf_802154_pib_coex_tx_request_mode_get(); + m_trx_transmit_frame_notifications_mask = + make_trx_frame_transmit_notification_mask(p_params->cca); + m_flags.tx_diminished_prio = + m_coex_tx_request_mode == NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE; - uint8_t cca_attempts = p_params->cca ? (1 + p_params->extra_cca_attempts) : 0; + state_set(p_params->cca ? RADIO_STATE_CCA_TX : RADIO_STATE_TX); + m_tx = *p_params; - // coverity[check_return] - result = tx_init(&p_params->frame, - ramp_up_mode_choose(req_orig), - cca_attempts); + uint8_t cca_attempts = p_params->cca ? (1 + p_params->extra_cca_attempts) : 0; - if (p_params->immediate) - { - if (!result) - { - switch_to_idle(); - } - } - else - { - result = true; - } - } - } + // coverity[check_return] + result = tx_init(&p_params->frame, + ramp_up_mode_choose(req_orig), + cca_attempts); - if (notify_function != NULL) + if (p_params->immediate && !result) { - notify_function(result); + error = NRF_802154_TX_ERROR_TIMESLOT_DENIED; + m_tx.p_client = NULL; + switch_to_idle(); + } + else + { + result = true; } + } - nrf_802154_critical_section_exit(); + if (p_params->rsch_timeslot_id != NRF_802154_RSCH_DLY_TS_ID_INVALID) + { + nrf_802154_rsch_delayed_timeslot_cancel(p_params->rsch_timeslot_id, true); } - else + + if (crit_sect_entered) { - if (notify_function != NULL) - { - notify_function(false); - } + nrf_802154_critical_section_exit(); } nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); - return result; + return error; } bool nrf_802154_core_ack_timeout_handle(const nrf_802154_ack_timeout_handle_params_t * p_param) @@ -2781,7 +2849,7 @@ bool nrf_802154_core_ack_timeout_handle(const nrf_802154_ack_timeout_handle_para if (result) { - if ((m_state == RADIO_STATE_RX_ACK) && (p_param->p_frame == m_tx_data.p_frame)) + if ((m_state == RADIO_STATE_RX_ACK) && (p_param->p_frame == m_tx.frame.p_frame)) { bool r; @@ -2804,9 +2872,8 @@ bool nrf_802154_core_ack_timeout_handle(const nrf_802154_ack_timeout_handle_para nrf_802154_tx_work_buffer_original_frame_update(p_param->p_frame, &metadata.frame_props); - nrf_802154_notify_transmit_failed(p_param->p_frame, - NRF_802154_TX_ERROR_NO_ACK, - &metadata); + + tx_client_failed_notify(p_param->p_frame, NRF_802154_TX_ERROR_NO_ACK, &metadata); } nrf_802154_critical_section_exit(); @@ -2913,7 +2980,7 @@ bool nrf_802154_core_modulated_carrier(nrf_802154_term_t term_lvl, if (result) { state_set(RADIO_STATE_MODULATED_CARRIER); - m_tx_data.p_frame = (uint8_t *)p_data; + m_tx.frame.p_frame = (uint8_t *)p_data; modulated_carrier_init(p_data); } diff --git a/nrf_802154/driver/src/nrf_802154_core.h b/nrf_802154/driver/src/nrf_802154_core.h index 060be897c6..6f50bc814c 100644 --- a/nrf_802154/driver/src/nrf_802154_core.h +++ b/nrf_802154/driver/src/nrf_802154_core.h @@ -141,15 +141,14 @@ bool nrf_802154_core_receive(nrf_802154_term_t term_lvl, * @param[in] term_lvl Termination level of this request. Selects procedures to abort. * @param[in] req_orig Module that originates this request. * @param[in] p_params Pointer to transmission parameters. - * @param[in] notify_function Function called to notify the status of this procedure. May be NULL. * - * @retval true Entering the transmit state succeeded. - * @retval false Entering the transmit state failed (the driver is performing other procedure). + * @retval NRF_802154_TX_ERROR_NONE The request was succesful. + * + * @returns The request error that prevented the frame from being transmitted. */ -bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl, - req_originator_t req_orig, - nrf_802154_transmit_params_t * p_params, - nrf_802154_notification_func_t notify_function); +nrf_802154_tx_error_t nrf_802154_core_transmit(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + nrf_802154_transmit_params_t * p_params); /** * @brief Requests end of waiting for an ACK by the core. diff --git a/nrf_802154/driver/src/nrf_802154_core_hooks.c b/nrf_802154/driver/src/nrf_802154_core_hooks.c index 6d2ba2e51e..39fbb3a683 100644 --- a/nrf_802154/driver/src/nrf_802154_core_hooks.c +++ b/nrf_802154/driver/src/nrf_802154_core_hooks.c @@ -46,7 +46,6 @@ #include #include "mac_features/nrf_802154_ack_timeout.h" -#include "mac_features/nrf_802154_csma_ca.h" #include "mac_features/nrf_802154_delayed_trx.h" #include "mac_features/nrf_802154_ie_writer.h" #include "mac_features/nrf_802154_security_writer.h" @@ -58,12 +57,11 @@ typedef bool (* abort_hook)(nrf_802154_term_t term_lvl, req_originator_t req_orig); typedef bool (* pre_transmission_hook)(nrf_802154_transmit_params_t * p_params, nrf_802154_transmit_failed_notification_t notify_function); -typedef bool (* tx_setup_hook)(nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function); +typedef nrf_802154_tx_error_t (* tx_setup_hook)(nrf_802154_transmit_params_t * p_params); typedef void (* transmitted_hook)(const nrf_802154_frame_t * p_frame); -typedef bool (* tx_failed_hook)(uint8_t * p_frame, nrf_802154_tx_error_t error); +typedef void (* tx_failed_hook)(uint8_t * p_frame, nrf_802154_tx_error_t error); typedef void (* tx_ack_failed_hook)(uint8_t * p_ack, nrf_802154_tx_error_t error); -typedef bool (* tx_started_hook)(uint8_t * p_frame); +typedef void (* tx_started_hook)(uint8_t * p_frame); typedef void (* rx_started_hook)(const nrf_802154_frame_t * p_frame); typedef void (* rx_ack_started_hook)(void); typedef void (* tx_ack_started_hook)(uint8_t * p_ack); @@ -75,10 +73,6 @@ typedef void (* tx_ack_started_hook)(uint8_t * p_ack); static const abort_hook m_abort_hooks[] = { -#if NRF_802154_CSMA_CA_ENABLED - nrf_802154_csma_ca_abort, -#endif - #if NRF_802154_ACK_TIMEOUT_ENABLED nrf_802154_ack_timeout_abort, #endif @@ -132,10 +126,6 @@ static const transmitted_hook m_transmitted_hooks[] = static const tx_failed_hook m_tx_failed_hooks[] = { -#if NRF_802154_CSMA_CA_ENABLED - nrf_802154_csma_ca_tx_failed_hook, -#endif - #if NRF_802154_ACK_TIMEOUT_ENABLED nrf_802154_ack_timeout_tx_failed_hook, #endif @@ -158,10 +148,6 @@ static const tx_ack_failed_hook m_tx_ack_failed_hooks[] = static const tx_started_hook m_tx_started_hooks[] = { -#if NRF_802154_CSMA_CA_ENABLED - nrf_802154_csma_ca_tx_started_hook, -#endif - #if NRF_802154_ACK_TIMEOUT_ENABLED nrf_802154_ack_timeout_tx_started_hook, #endif @@ -263,11 +249,10 @@ bool nrf_802154_core_hooks_pre_transmission( return result; } -bool nrf_802154_core_hooks_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function) +nrf_802154_tx_error_t nrf_802154_core_hooks_tx_setup( + nrf_802154_transmit_params_t * p_params) { - bool result = true; + nrf_802154_tx_error_t result = NRF_802154_TX_ERROR_NONE; for (uint32_t i = 0; i < sizeof(m_tx_setup_hooks) / sizeof(m_tx_setup_hooks[0]); i++) @@ -277,9 +262,9 @@ bool nrf_802154_core_hooks_tx_setup( break; } - result = m_tx_setup_hooks[i](p_params, notify_function); + result = m_tx_setup_hooks[i](p_params); - if (!result) + if (result != NRF_802154_TX_ERROR_NONE) { break; } @@ -301,10 +286,8 @@ void nrf_802154_core_hooks_transmitted(const nrf_802154_frame_t * p_frame) } } -bool nrf_802154_core_hooks_tx_failed(uint8_t * p_frame, nrf_802154_tx_error_t error) +void nrf_802154_core_hooks_tx_failed(uint8_t * p_frame, nrf_802154_tx_error_t error) { - bool result = true; - for (uint32_t i = 0; i < sizeof(m_tx_failed_hooks) / sizeof(m_tx_failed_hooks[0]); i++) { if (m_tx_failed_hooks[i] == NULL) @@ -312,15 +295,8 @@ bool nrf_802154_core_hooks_tx_failed(uint8_t * p_frame, nrf_802154_tx_error_t er break; } - result = m_tx_failed_hooks[i](p_frame, error); - - if (!result) - { - break; - } + m_tx_failed_hooks[i](p_frame, error); } - - return result; } void nrf_802154_core_hooks_tx_ack_failed(uint8_t * p_ack, nrf_802154_tx_error_t error) @@ -336,10 +312,8 @@ void nrf_802154_core_hooks_tx_ack_failed(uint8_t * p_ack, nrf_802154_tx_error_t } } -bool nrf_802154_core_hooks_tx_started(uint8_t * p_frame) +void nrf_802154_core_hooks_tx_started(uint8_t * p_frame) { - bool result = true; - for (uint32_t i = 0; i < sizeof(m_tx_started_hooks) / sizeof(m_tx_started_hooks[0]); i++) { if (m_tx_started_hooks[i] == NULL) @@ -347,15 +321,8 @@ bool nrf_802154_core_hooks_tx_started(uint8_t * p_frame) break; } - result = m_tx_started_hooks[i](p_frame); - - if (!result) - { - break; - } + m_tx_started_hooks[i](p_frame); } - - return result; } void nrf_802154_core_hooks_rx_started(const nrf_802154_frame_t * p_frame) diff --git a/nrf_802154/driver/src/nrf_802154_core_hooks.h b/nrf_802154/driver/src/nrf_802154_core_hooks.h index b325c8c0b0..5764492cb8 100644 --- a/nrf_802154/driver/src/nrf_802154_core_hooks.h +++ b/nrf_802154/driver/src/nrf_802154_core_hooks.h @@ -47,8 +47,7 @@ * @ingroup nrf_802154 * @brief Hooks for the 802.15.4 driver core module. * - * Hooks are used by the optional driver features to modify the way in which notifications - * are propagated through the driver. + * The core hooks extend the core with additional functionalities. */ /** @@ -80,15 +79,11 @@ bool nrf_802154_core_hooks_pre_transmission( * @brief Processes hooks which are to fire before the transmission but after previous operation * has been already terminated. * - * @param[in] p_params Pointer to the transmission parameters. - * @param[in] notify_function Function to be called to notify transmission failure. + * @param[in] p_params Pointer to the transmission parameters. * - * @retval true Frame can be sent immediately. - * @retval false Hooks have handled the frame - upper layer should not worry about it anymore. + * @returns Error reported by a hook implementation. */ -bool nrf_802154_core_hooks_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function); +nrf_802154_tx_error_t nrf_802154_core_hooks_tx_setup(nrf_802154_transmit_params_t * p_params); /** * @brief Processes hooks for the transmitted event. @@ -103,12 +98,8 @@ void nrf_802154_core_hooks_transmitted(const nrf_802154_frame_t * p_frame); * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame * that was not transmitted. * @param[in] error Cause of the failed transmission. - * - * @retval true TX failed event is to be propagated to the MAC layer. - * @retval false TX failed event is not to be propagated to the MAC layer. It is handled - * internally. */ -bool nrf_802154_core_hooks_tx_failed(uint8_t * p_frame, nrf_802154_tx_error_t error); +void nrf_802154_core_hooks_tx_failed(uint8_t * p_frame, nrf_802154_tx_error_t error); /** * @brief Processes hooks for the ACK TX failed event. @@ -124,12 +115,8 @@ void nrf_802154_core_hooks_tx_ack_failed(uint8_t * p_ack, nrf_802154_tx_error_t * * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame * that is being transmitted. - * - * @retval true TX started event is to be propagated to the MAC layer. - * @retval false TX started event is not to be propagated to the MAC layer. It is handled - * internally. */ -bool nrf_802154_core_hooks_tx_started(uint8_t * p_frame); +void nrf_802154_core_hooks_tx_started(uint8_t * p_frame); /** * @brief Processes hooks for the RX started event. diff --git a/nrf_802154/driver/src/nrf_802154_critical_section.c b/nrf_802154/driver/src/nrf_802154_critical_section.c index bf61006896..6f28b12a67 100644 --- a/nrf_802154/driver/src/nrf_802154_critical_section.c +++ b/nrf_802154/driver/src/nrf_802154_critical_section.c @@ -119,7 +119,7 @@ static bool critical_section_enter(bool forced) */ active_vector_priority = active_vector_priority_get(); - nrf_802154_mcu_critical_enter(mcu_cs); + mcu_cs = nrf_802154_mcu_critical_enter(); if (forced || (m_nested_critical_section_counter == 0) || @@ -153,7 +153,7 @@ static void critical_section_exit(void) uint8_t cnt; nrf_802154_mcu_critical_state_t mcu_cs; - nrf_802154_mcu_critical_enter(mcu_cs); + mcu_cs = nrf_802154_mcu_critical_enter(); cnt = m_nested_critical_section_counter; diff --git a/nrf_802154/driver/src/nrf_802154_debug_log_codes.h b/nrf_802154/driver/src/nrf_802154_debug_log_codes.h index ec5b16103b..27e6f1db84 100644 --- a/nrf_802154/driver/src/nrf_802154_debug_log_codes.h +++ b/nrf_802154/driver/src/nrf_802154_debug_log_codes.h @@ -63,7 +63,8 @@ typedef enum NRF_802154_DRV_MODULE_ID_ACK_TIMEOUT = 7U, NRF_802154_DRV_MODULE_ID_TRX_PPI = 8U, NRF_802154_DRV_MODULE_ID_NOTIFICATION = 9U, - NRF_802154_DRV_MODULE_ID_CO = 10U + NRF_802154_DRV_MODULE_ID_CO = 10U, + NRF_802154_DRV_MODULE_ID_IMM_TX = 11U, } nrf_802154_drv_modules_list_t; /** diff --git a/nrf_802154/driver/src/nrf_802154_encrypt.c b/nrf_802154/driver/src/nrf_802154_encrypt.c index 9131d02215..f1a67c3344 100644 --- a/nrf_802154/driver/src/nrf_802154_encrypt.c +++ b/nrf_802154/driver/src/nrf_802154_encrypt.c @@ -323,9 +323,8 @@ void nrf_802154_encrypt_ack_reset(void) nrf_802154_aes_ccm_transform_reset(); } -bool nrf_802154_encrypt_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function) +nrf_802154_tx_error_t nrf_802154_encrypt_tx_setup( + nrf_802154_transmit_params_t * p_params) { NRF_802154_ASSERT(nrf_802154_frame_parse_level_get(&p_params->frame) >= PARSE_LEVEL_FULL); @@ -335,13 +334,13 @@ bool nrf_802154_encrypt_tx_setup( if (p_params->frame_props.is_secured) { // The frame is already secured. Pass. - return true; + return NRF_802154_TX_ERROR_NONE; } if (nrf_802154_frame_type_get(&p_params->frame) == FRAME_TYPE_MULTIPURPOSE) { // Multipurpose frame parsing is not implemented, so skip encryption. - return true; + return NRF_802154_TX_ERROR_NONE; } nrf_802154_aes_ccm_data_t aes_ccm_data; @@ -362,24 +361,14 @@ bool nrf_802154_encrypt_tx_setup( success = false; } - if (!success) - { - nrf_802154_transmit_done_metadata_t metadata = {}; - - metadata.frame_props = p_params->frame_props; - notify_function(p_params->frame.p_frame, NRF_802154_TX_ERROR_KEY_ID_INVALID, &metadata); - } - - return success; + return success ? NRF_802154_TX_ERROR_NONE : NRF_802154_TX_ERROR_KEY_ID_INVALID; } -bool nrf_802154_encrypt_tx_started_hook(uint8_t * p_frame) +void nrf_802154_encrypt_tx_started_hook(uint8_t * p_frame) { // The provided pointer is the original buffer. It doesn't need to be changed, // because the AES-CCM* module is aware of two separate buffers (original vs work buffer) nrf_802154_aes_ccm_transform_start(p_frame); - - return true; } void nrf_802154_encrypt_tx_ack_started_hook(uint8_t * p_ack) @@ -387,13 +376,11 @@ void nrf_802154_encrypt_tx_ack_started_hook(uint8_t * p_ack) nrf_802154_aes_ccm_transform_start(p_ack); } -bool nrf_802154_encrypt_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error) +void nrf_802154_encrypt_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error) { (void)error; nrf_802154_aes_ccm_transform_abort(p_frame); - - return true; } void nrf_802154_encrypt_tx_ack_failed_hook(uint8_t * p_ack, nrf_802154_tx_error_t error) diff --git a/nrf_802154/driver/src/nrf_802154_encrypt.h b/nrf_802154/driver/src/nrf_802154_encrypt.h index b79ce716fd..20b45139d0 100644 --- a/nrf_802154/driver/src/nrf_802154_encrypt.h +++ b/nrf_802154/driver/src/nrf_802154_encrypt.h @@ -63,14 +63,13 @@ void nrf_802154_encrypt_ack_reset(void); * This hook prepares encryption data for provided frame. * * @param[in] p_params Pointer to the transmission parameters. - * @param[in] notify_function Function to be called to notify transmission failure. * - * @retval true Encryption was prepared successfully. - * @retval false Encryption prepare failed. + * @retval NRF_802154_TX_ERROR_NONE The procedure was successful. + * @retval NRF_802154_TX_ERROR_KEY_ID_INVALID The frame cannot be encrypted with the requested + * parameters. */ -bool nrf_802154_encrypt_tx_setup( - nrf_802154_transmit_params_t * p_params, - nrf_802154_transmit_failed_notification_t notify_function); +nrf_802154_tx_error_t nrf_802154_encrypt_tx_setup( + nrf_802154_transmit_params_t * p_params); /** * @brief TX started hook for the encryption module. @@ -78,10 +77,8 @@ bool nrf_802154_encrypt_tx_setup( * This function triggers the transformation procedure of the provided frame. * * @param[in] p_frame Pointer to the buffer that contains a frame being transmitted. - * - * @retval true Always succeeds. */ -bool nrf_802154_encrypt_tx_started_hook(uint8_t * p_frame); +void nrf_802154_encrypt_tx_started_hook(uint8_t * p_frame); /** * @brief ACK TX started hook for the encryption module. @@ -99,10 +96,8 @@ void nrf_802154_encrypt_tx_ack_started_hook(uint8_t * p_ack); * * @param[in] p_frame Pointer to the buffer that contains a frame being transmitted. * @param[in] error Cause of the failed transmission. - * - * @retval true Always succeeds. */ -bool nrf_802154_encrypt_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error); +void nrf_802154_encrypt_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error); /** * @brief ACK TX failed hook for the encryption module. diff --git a/nrf_802154/driver/src/nrf_802154_notification.h b/nrf_802154/driver/src/nrf_802154_notification.h index 46a718c4e0..acd70c047f 100644 --- a/nrf_802154/driver/src/nrf_802154_notification.h +++ b/nrf_802154/driver/src/nrf_802154_notification.h @@ -101,8 +101,8 @@ bool nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id, * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the transmitted frame. * @param[in] p_metadata Pointer to a metadata structure describing frame passed in @p p_frame. */ -void nrf_802154_notify_transmitted(uint8_t * p_frame, - nrf_802154_transmit_done_metadata_t * p_metadata); +void nrf_802154_notify_transmitted(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata); /** * @brief Notifies the next higher layer that a frame was not transmitted. diff --git a/nrf_802154/driver/src/nrf_802154_notification_direct.c b/nrf_802154/driver/src/nrf_802154_notification_direct.c index 3ca646f2dc..23ae8b379e 100644 --- a/nrf_802154/driver/src/nrf_802154_notification_direct.c +++ b/nrf_802154/driver/src/nrf_802154_notification_direct.c @@ -52,7 +52,6 @@ #include "nrf_802154_co.h" #include "nrf_802154_critical_section.h" #include "nrf_802154_debug.h" -#include "nrf_802154_tx_work_buffer.h" #define RAW_LENGTH_OFFSET 0 #define RAW_PAYLOAD_OFFSET 1 @@ -84,14 +83,11 @@ bool nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id, return true; } -void nrf_802154_notify_transmitted(uint8_t * p_frame, - nrf_802154_transmit_done_metadata_t * p_metadata) +void nrf_802154_notify_transmitted(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - // Update the transmitted frame contents and update frame status flags - nrf_802154_tx_work_buffer_original_frame_update(p_frame, - &p_metadata->frame_props); // Notify nrf_802154_co_transmitted_raw(p_frame, p_metadata); diff --git a/nrf_802154/driver/src/nrf_802154_notification_swi.c b/nrf_802154/driver/src/nrf_802154_notification_swi.c index 99a8c207a8..057210a032 100644 --- a/nrf_802154/driver/src/nrf_802154_notification_swi.c +++ b/nrf_802154/driver/src/nrf_802154_notification_swi.c @@ -55,7 +55,6 @@ #include "nrf_802154_debug.h" #include "nrf_802154_queue.h" #include "nrf_802154_swi.h" -#include "nrf_802154_tx_work_buffer.h" #include "nrf_802154_peripherals.h" #include "nrf_802154_utils.h" #include "hal/nrf_egu.h" @@ -268,7 +267,7 @@ static void ntf_slot_free(nrf_802154_ntf_data_t * p_slot) */ static nrf_802154_queue_entry_t * ntf_enter(void) { - nrf_802154_mcu_critical_enter(m_mcu_cs); + m_mcu_cs = nrf_802154_mcu_critical_enter(); NRF_802154_ASSERT(!nrf_802154_queue_is_full(&m_notifications_queue)); @@ -395,8 +394,8 @@ bool swi_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id, bool al * @retval true Notification enqueued successfully. * @retval false Notification could not be performed. */ -bool swi_notify_transmitted(uint8_t * p_frame, - nrf_802154_transmit_done_metadata_t * p_metadata) +bool swi_notify_transmitted(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata) { uint8_t slot_id = ntf_slot_alloc(m_primary_ntf_pool, NTF_PRIMARY_POOL_SIZE); @@ -605,15 +604,11 @@ bool nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id, return notified; } -void nrf_802154_notify_transmitted(uint8_t * p_frame, - nrf_802154_transmit_done_metadata_t * p_metadata) +void nrf_802154_notify_transmitted(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - // Update the transmitted frame contents and update frame status flags - nrf_802154_tx_work_buffer_original_frame_update(p_frame, - &p_metadata->frame_props); - bool notified = swi_notify_transmitted(p_frame, p_metadata); // It should always be possible to notify transmission result diff --git a/nrf_802154/driver/src/nrf_802154_procedures_duration.h b/nrf_802154/driver/src/nrf_802154_procedures_duration.h index 58e2833434..e58728670d 100644 --- a/nrf_802154/driver/src/nrf_802154_procedures_duration.h +++ b/nrf_802154/driver/src/nrf_802154_procedures_duration.h @@ -46,6 +46,16 @@ #include "nrf_802154_const.h" +#ifdef __STATIC_INLINE__ +#undef __STATIC_INLINE__ +#endif + +#ifdef NRF_802154_PROCEDURES_DURATION_DECLARE_ONLY +#define __STATIC_INLINE__ +#else +#define __STATIC_INLINE__ __STATIC_INLINE +#endif + #define TX_RAMP_UP_TIME 40 // us #define RX_RAMP_UP_TIME 40 // us #define RX_RAMP_DOWN_TIME 0 // us @@ -82,21 +92,25 @@ PHY_US_TIME_FROM_SYMBOLS( \ PHY_SHR_SYMBOLS + PHY_SYMBOLS_FROM_OCTETS(PHR_SIZE + MAX_PACKET_SIZE)) -__STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, - bool cca, - bool ack_requested); +__STATIC_INLINE__ uint16_t nrf_802154_frame_duration_get(uint8_t psdu_length, + bool shr, + bool phr); + +__STATIC_INLINE__ uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, + bool cca, + bool ack_requested); -__STATIC_INLINE uint16_t nrf_802154_cca_before_tx_duration_get(void); +__STATIC_INLINE__ uint16_t nrf_802154_cca_before_tx_duration_get(void); -__STATIC_INLINE uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ack_requested); +__STATIC_INLINE__ uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ack_requested); -__STATIC_INLINE uint16_t nrf_802154_cca_duration_get(void); +__STATIC_INLINE__ uint16_t nrf_802154_cca_duration_get(void); -#ifndef SUPPRESS_INLINE_IMPLEMENTATION +#ifndef NRF_802154_PROCEDURES_DURATION_DECLARE_ONLY -__STATIC_INLINE uint16_t nrf_802154_frame_duration_get(uint8_t psdu_length, - bool shr, - bool phr) +__STATIC_INLINE__ uint16_t nrf_802154_frame_duration_get(uint8_t psdu_length, + bool shr, + bool phr) { uint16_t us_time = PHY_US_TIME_FROM_SYMBOLS(PHY_SYMBOLS_FROM_OCTETS(psdu_length)); @@ -113,9 +127,9 @@ __STATIC_INLINE uint16_t nrf_802154_frame_duration_get(uint8_t psdu_length, return us_time; } -__STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, - bool cca, - bool ack_requested) +__STATIC_INLINE__ uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, + bool cca, + bool ack_requested) { // ramp down // if CCA: + RX ramp up + CCA + RX ramp down @@ -140,7 +154,7 @@ __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, return us_time; } -__STATIC_INLINE uint16_t nrf_802154_cca_before_tx_duration_get(void) +__STATIC_INLINE__ uint16_t nrf_802154_cca_before_tx_duration_get(void) { // CCA + turnaround time uint16_t us_time = PHY_US_TIME_FROM_SYMBOLS(A_CCA_DURATION_SYMBOLS) + RX_TX_TURNAROUND_TIME; @@ -149,7 +163,7 @@ __STATIC_INLINE uint16_t nrf_802154_cca_before_tx_duration_get(void) } /**@brief Get the duration of the Ack frame along with turnaround in microseconds. */ -__STATIC_INLINE uint16_t nrf_802154_ack_duration_with_turnaround_get(void) +__STATIC_INLINE__ uint16_t nrf_802154_ack_duration_with_turnaround_get(void) { // aTurnaroundTime + ACK frame duration return PHY_US_TIME_FROM_SYMBOLS(A_TURNAROUND_TIME_SYMBOLS + @@ -157,7 +171,7 @@ __STATIC_INLINE uint16_t nrf_802154_ack_duration_with_turnaround_get(void) PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE)); } -__STATIC_INLINE uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ack_requested) +__STATIC_INLINE__ uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ack_requested) { // SHR + PHR + PSDU // if ACK: + aTurnaroundTime + ACK frame duration @@ -171,7 +185,7 @@ __STATIC_INLINE uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ac return us_time; } -__STATIC_INLINE uint16_t nrf_802154_cca_duration_get(void) +__STATIC_INLINE__ uint16_t nrf_802154_cca_duration_get(void) { // ramp down + rx ramp up + CCA uint16_t us_time = MAX_RAMP_DOWN_TIME + @@ -181,6 +195,6 @@ __STATIC_INLINE uint16_t nrf_802154_cca_duration_get(void) return us_time; } -#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ +#endif /* NRF_802154_PROCEDURES_DURATION_DECLARE_ONLY */ #endif /* NRF_802154_PROCEDURES_DURATION_H_ */ diff --git a/nrf_802154/driver/src/nrf_802154_request.h b/nrf_802154/driver/src/nrf_802154_request.h index a1791f54d7..224d4b7593 100644 --- a/nrf_802154/driver/src/nrf_802154_request.h +++ b/nrf_802154/driver/src/nrf_802154_request.h @@ -92,15 +92,12 @@ bool nrf_802154_request_receive(nrf_802154_term_t term_lvl, * @param[in] term_lvl Termination level of this request. Selects procedures to abort. * @param[in] req_orig Module that originates this request. * @param[in] p_params Pointer to transmission parameters. - * @param[in] notify_function Function called to notify the status of this procedure. May be NULL. * - * @retval true The driver will enter the transmit state. - * @retval false The driver cannot enter the transmit state due to an ongoing operation. + * @returns The error status reported by the core. */ -bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl, - req_originator_t req_orig, - nrf_802154_transmit_params_t * p_params, - nrf_802154_notification_func_t notify_function); +nrf_802154_tx_error_t nrf_802154_request_transmit(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + nrf_802154_transmit_params_t * p_params); /** * @brief Request to handle Ack timeout by the core module. diff --git a/nrf_802154/driver/src/nrf_802154_request_direct.c b/nrf_802154/driver/src/nrf_802154_request_direct.c index 18da9e3970..936e445aed 100644 --- a/nrf_802154/driver/src/nrf_802154_request_direct.c +++ b/nrf_802154/driver/src/nrf_802154_request_direct.c @@ -88,16 +88,14 @@ bool nrf_802154_request_receive(nrf_802154_term_t term_lvl, id) } -bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl, - req_originator_t req_orig, - nrf_802154_transmit_params_t * p_params, - nrf_802154_notification_func_t notify_function) +nrf_802154_tx_error_t nrf_802154_request_transmit(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + nrf_802154_transmit_params_t * p_params) { REQUEST_FUNCTION_PARMS(nrf_802154_core_transmit, term_lvl, req_orig, - p_params, - notify_function) + p_params) } bool nrf_802154_request_ack_timeout_handle(const nrf_802154_ack_timeout_handle_params_t * p_param) diff --git a/nrf_802154/driver/src/nrf_802154_request_swi.c b/nrf_802154/driver/src/nrf_802154_request_swi.c index f00d30dc45..e98fcdb306 100644 --- a/nrf_802154/driver/src/nrf_802154_request_swi.c +++ b/nrf_802154/driver/src/nrf_802154_request_swi.c @@ -122,13 +122,12 @@ typedef struct struct { - nrf_802154_notification_func_t notif_func; ///< Error notified in case of success. - nrf_802154_term_t term_lvl; ///< Request priority. - req_originator_t req_orig; ///< Request originator. - uint8_t * p_data; ///< Pointer to a buffer containing PHR and PSDU of the frame to transmit. - nrf_802154_transmit_params_t * p_params; ///< Pointer to transmission parameters. - bool * p_result; ///< Transmit request result. - } transmit; ///< Transmit request details. + nrf_802154_term_t term_lvl; ///< Request priority. + req_originator_t req_orig; ///< Request originator. + uint8_t * p_data; ///< Pointer to a buffer containing PHR and PSDU of the frame to transmit. + nrf_802154_transmit_params_t * p_params; ///< Pointer to transmission parameters. + nrf_802154_tx_error_t * p_result; ///< Transmit request result. + } transmit; ///< Transmit request details. struct { @@ -257,7 +256,7 @@ static volatile nrf_802154_mcu_critical_state_t m_mcu_cs; */ static nrf_802154_req_data_t * req_enter(void) { - nrf_802154_mcu_critical_enter(m_mcu_cs); + m_mcu_cs = nrf_802154_mcu_critical_enter(); NRF_802154_ASSERT(!nrf_802154_queue_is_full(&m_requests_queue)); @@ -285,34 +284,34 @@ static inline void assert_interrupt_status(void) NRF_802154_ASSERT(nrf_802154_irq_is_enabled(nrfx_get_irq_number(NRF_802154_EGU_INSTANCE))); } -#define REQUEST_FUNCTION(func_core, func_swi, ...) \ - bool result = false; \ - \ - if (active_vector_priority_is_high()) \ - { \ - result = func_core(__VA_ARGS__); \ - } \ - else \ - { \ - assert_interrupt_status(); \ - func_swi(__VA_ARGS__, &result); \ - } \ - \ +#define REQUEST_FUNCTION(func_core, func_swi, result_type, ...)\ + result_type result; \ + \ + if (active_vector_priority_is_high()) \ + { \ + result = func_core(__VA_ARGS__); \ + } \ + else \ + { \ + assert_interrupt_status(); \ + func_swi(__VA_ARGS__, &result); \ + } \ + \ return result; -#define REQUEST_FUNCTION_NO_ARGS(func_core, func_swi) \ - bool result = false; \ - \ - if (active_vector_priority_is_high()) \ - { \ - result = func_core(); \ - } \ - else \ - { \ - assert_interrupt_status(); \ - func_swi(&result); \ - } \ - \ +#define REQUEST_FUNCTION_NO_ARGS(func_core, func_swi, result_type)\ + result_type result; \ + \ + if (active_vector_priority_is_high()) \ + { \ + result = func_core(); \ + } \ + else \ + { \ + assert_interrupt_status(); \ + func_swi(&result); \ + } \ + \ return result; /** Check if active vector priority is high enough to call requests directly. @@ -390,17 +389,15 @@ static void swi_receive(nrf_802154_term_t term_lvl, static void swi_transmit(nrf_802154_term_t term_lvl, req_originator_t req_orig, nrf_802154_transmit_params_t * p_params, - nrf_802154_notification_func_t notify_function, - bool * p_result) + nrf_802154_tx_error_t * p_result) { nrf_802154_req_data_t * p_slot = req_enter(); - p_slot->type = REQ_TYPE_TRANSMIT; - p_slot->data.transmit.term_lvl = term_lvl; - p_slot->data.transmit.req_orig = req_orig; - p_slot->data.transmit.p_params = p_params; - p_slot->data.transmit.notif_func = notify_function; - p_slot->data.transmit.p_result = p_result; + p_slot->type = REQ_TYPE_TRANSMIT; + p_slot->data.transmit.term_lvl = term_lvl; + p_slot->data.transmit.req_orig = req_orig; + p_slot->data.transmit.p_params = p_params; + p_slot->data.transmit.p_result = p_result; req_exit(); } @@ -692,7 +689,7 @@ void nrf_802154_request_init(void) bool nrf_802154_request_sleep(nrf_802154_term_t term_lvl) { - REQUEST_FUNCTION(nrf_802154_core_sleep, swi_sleep, term_lvl) + REQUEST_FUNCTION(nrf_802154_core_sleep, swi_sleep, bool, term_lvl) } bool nrf_802154_request_receive(nrf_802154_term_t term_lvl, @@ -703,6 +700,7 @@ bool nrf_802154_request_receive(nrf_802154_term_t term_lvl, { REQUEST_FUNCTION(nrf_802154_core_receive, swi_receive, + bool, term_lvl, req_orig, notify_function, @@ -710,22 +708,21 @@ bool nrf_802154_request_receive(nrf_802154_term_t term_lvl, id) } -bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl, - req_originator_t req_orig, - nrf_802154_transmit_params_t * p_params, - nrf_802154_notification_func_t notify_function) +nrf_802154_tx_error_t nrf_802154_request_transmit(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + nrf_802154_transmit_params_t * p_params) { REQUEST_FUNCTION(nrf_802154_core_transmit, swi_transmit, + nrf_802154_tx_error_t, term_lvl, req_orig, - p_params, - notify_function) + p_params) } bool nrf_802154_request_ack_timeout_handle(const nrf_802154_ack_timeout_handle_params_t * p_param) { - REQUEST_FUNCTION(nrf_802154_core_ack_timeout_handle, swi_ack_timeout_handle, p_param); + REQUEST_FUNCTION(nrf_802154_core_ack_timeout_handle, swi_ack_timeout_handle, bool, p_param); } bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl, @@ -733,13 +730,14 @@ bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl, { REQUEST_FUNCTION(nrf_802154_core_energy_detection, swi_energy_detection, + bool, term_lvl, time_us) } bool nrf_802154_request_cca(nrf_802154_term_t term_lvl) { - REQUEST_FUNCTION(nrf_802154_core_cca, swi_cca, term_lvl) + REQUEST_FUNCTION(nrf_802154_core_cca, swi_cca, bool, term_lvl) } #if NRF_802154_CARRIER_FUNCTIONS_ENABLED @@ -747,6 +745,7 @@ bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl) { REQUEST_FUNCTION(nrf_802154_core_continuous_carrier, swi_continuous_carrier, + bool, term_lvl) } @@ -755,6 +754,7 @@ bool nrf_802154_request_modulated_carrier(nrf_802154_term_t term_lvl, { REQUEST_FUNCTION(nrf_802154_core_modulated_carrier, swi_modulated_carrier, + bool, term_lvl, p_data) } @@ -763,33 +763,34 @@ bool nrf_802154_request_modulated_carrier(nrf_802154_term_t term_lvl, bool nrf_802154_request_buffer_free(uint8_t * p_data) { - REQUEST_FUNCTION(nrf_802154_core_notify_buffer_free, swi_buffer_free, p_data) + REQUEST_FUNCTION(nrf_802154_core_notify_buffer_free, swi_buffer_free, bool, p_data) } bool nrf_802154_request_antenna_update(void) { - REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_antenna_update, swi_antenna_update) + REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_antenna_update, swi_antenna_update, bool) } bool nrf_802154_request_channel_update(req_originator_t req_orig) { - REQUEST_FUNCTION(nrf_802154_core_channel_update, swi_channel_update, req_orig) + REQUEST_FUNCTION(nrf_802154_core_channel_update, swi_channel_update, bool, req_orig) } bool nrf_802154_request_cca_cfg_update(void) { - REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_cca_cfg_update, swi_cca_cfg_update) + REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_cca_cfg_update, swi_cca_cfg_update, bool) } bool nrf_802154_request_rssi_measure(void) { - REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_rssi_measure, swi_rssi_measure) + REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_rssi_measure, swi_rssi_measure, bool) } bool nrf_802154_request_rssi_measurement_get(int8_t * p_rssi) { REQUEST_FUNCTION(nrf_802154_core_last_rssi_measurement_get, swi_rssi_measurement_get, + bool, p_rssi) } @@ -800,6 +801,7 @@ bool nrf_802154_request_transmit_raw_at(const nrf_802154_frame_t { REQUEST_FUNCTION(nrf_802154_delayed_trx_transmit, swi_transmit_at, + bool, p_frame, tx_time, p_metadata); @@ -807,7 +809,7 @@ bool nrf_802154_request_transmit_raw_at(const nrf_802154_frame_t bool nrf_802154_request_transmit_at_cancel(void) { - REQUEST_FUNCTION_NO_ARGS(nrf_802154_delayed_trx_transmit_cancel, swi_transmit_at_cancel); + REQUEST_FUNCTION_NO_ARGS(nrf_802154_delayed_trx_transmit_cancel, swi_transmit_at_cancel, bool); } bool nrf_802154_request_receive_at(uint64_t rx_time, @@ -815,18 +817,25 @@ bool nrf_802154_request_receive_at(uint64_t rx_time, uint8_t channel, uint32_t id) { - REQUEST_FUNCTION(nrf_802154_delayed_trx_receive, swi_receive_at, rx_time, timeout, channel, id); + REQUEST_FUNCTION(nrf_802154_delayed_trx_receive, + swi_receive_at, + bool, + rx_time, + timeout, + channel, + id); } bool nrf_802154_request_receive_at_cancel(uint32_t id) { - REQUEST_FUNCTION(nrf_802154_delayed_trx_receive_cancel, swi_receive_at_cancel, id); + REQUEST_FUNCTION(nrf_802154_delayed_trx_receive_cancel, swi_receive_at_cancel, bool, id); } bool nrf_802154_request_receive_at_scheduled_cancel(uint32_t id) { REQUEST_FUNCTION(nrf_802154_delayed_trx_receive_scheduled_cancel, swi_receive_at_scheduled_cancel, + bool, id); } @@ -835,6 +844,7 @@ bool nrf_802154_request_csma_ca_start(const nrf_802154_frame_t { REQUEST_FUNCTION(nrf_802154_csma_ca_start, swi_csma_ca_start, + bool, p_frame, p_metadata); } @@ -869,8 +879,7 @@ static void irq_handler_req_event(void) *(p_slot->data.transmit.p_result) = nrf_802154_core_transmit(p_slot->data.transmit.term_lvl, p_slot->data.transmit.req_orig, - p_slot->data.transmit.p_params, - p_slot->data.transmit.notif_func); + p_slot->data.transmit.p_params); break; case REQ_TYPE_ACK_TIMEOUT_HANDLE: diff --git a/nrf_802154/driver/src/nrf_802154_stats.c b/nrf_802154/driver/src/nrf_802154_stats.c index 1a8cff075a..5ae5c10aa6 100644 --- a/nrf_802154/driver/src/nrf_802154_stats.c +++ b/nrf_802154/driver/src/nrf_802154_stats.c @@ -61,7 +61,7 @@ void nrf_802154_stat_counters_subtract(const nrf_802154_stat_counters_t * p_stat { nrf_802154_mcu_critical_state_t mcu_cs; - nrf_802154_mcu_critical_enter(mcu_cs); + mcu_cs = nrf_802154_mcu_critical_enter(); *p_dst -= *p_src; nrf_802154_mcu_critical_exit(mcu_cs); diff --git a/nrf_802154/driver/src/nrf_802154_stats.h b/nrf_802154/driver/src/nrf_802154_stats.h index 23b203f24e..f0e629d6ea 100644 --- a/nrf_802154/driver/src/nrf_802154_stats.h +++ b/nrf_802154/driver/src/nrf_802154_stats.h @@ -51,7 +51,7 @@ extern volatile nrf_802154_stats_t g_nrf_802154_stats; { \ nrf_802154_mcu_critical_state_t mcu_cs; \ \ - nrf_802154_mcu_critical_enter(mcu_cs); \ + mcu_cs = nrf_802154_mcu_critical_enter(); \ (g_nrf_802154_stats.counters.field_name)++; \ nrf_802154_mcu_critical_exit(mcu_cs); \ } \ @@ -67,7 +67,7 @@ extern volatile nrf_802154_stats_t g_nrf_802154_stats; { \ nrf_802154_mcu_critical_state_t mcu_cs; \ \ - nrf_802154_mcu_critical_enter(mcu_cs); \ + mcu_cs = nrf_802154_mcu_critical_enter(); \ (g_nrf_802154_stats.timestamps.field_name) = (value); \ nrf_802154_mcu_critical_exit(mcu_cs); \ } \ @@ -79,7 +79,7 @@ extern volatile nrf_802154_stats_t g_nrf_802154_stats; { \ nrf_802154_mcu_critical_state_t mcu_cs; \ \ - nrf_802154_mcu_critical_enter(mcu_cs); \ + mcu_cs = nrf_802154_mcu_critical_enter(); \ *(variable) = g_nrf_802154_stats.timestamps.field_name; \ nrf_802154_mcu_critical_exit(mcu_cs); \ } \ diff --git a/nrf_802154/driver/src/nrf_802154_trx.c b/nrf_802154/driver/src/nrf_802154_trx.c index c08abb33ea..5150647eee 100644 --- a/nrf_802154/driver/src/nrf_802154_trx.c +++ b/nrf_802154/driver/src/nrf_802154_trx.c @@ -3066,9 +3066,9 @@ void nrf_802154_trx_swi_irq_handler(void) // If this handler is preempted by MARGIN, RADIO IRQ might be set to pending // and executed after MARGIN processing is finished, i.e. after the end of a timeslot. // To prevent that from happening, the handler is executed with disabled interrupts. - nrf_802154_mcu_critical_state_t mcu_crit_state; + nrf_802154_mcu_critical_state_t mcu_cs; - nrf_802154_mcu_critical_enter(mcu_crit_state); + mcu_cs = nrf_802154_mcu_critical_enter(); if (nrf_egu_int_enable_check(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK) && nrf_egu_event_check(NRF_802154_EGU_INSTANCE, EGU_SYNC_EVENT)) @@ -3088,7 +3088,7 @@ void nrf_802154_trx_swi_irq_handler(void) nrf_802154_irq_set_pending(nrfx_get_irq_number(NRF_RADIO)); } - nrf_802154_mcu_critical_exit(mcu_crit_state); + nrf_802154_mcu_critical_exit(mcu_cs); } #endif diff --git a/nrf_802154/driver/src/nrf_802154_types_internal.h b/nrf_802154/driver/src/nrf_802154_types_internal.h index 2b0390e380..70a3dca7d1 100644 --- a/nrf_802154/driver/src/nrf_802154_types_internal.h +++ b/nrf_802154/driver/src/nrf_802154_types_internal.h @@ -39,8 +39,87 @@ #include "nrf_802154_fal.h" #include "mac_features/nrf_802154_frame.h" +struct nrf_802154_tx_client_s; + +typedef struct nrf_802154_tx_client_s nrf_802154_tx_client_t; + +/** + * @brief Query if client operation can be aborted. + * + * The query asks if the operation can be aborted. + * The implementation must not modify any state. + * + * @param[in] term_lvl Termination level. + * @param[in] req_orig Request originator. + * @param[in] p_client Pointer to the TX client instance. + * + * @retval true The operation can be aborted. + * @retval false The operation cannot be aborted. + */ +typedef bool (* nrf_802154_tx_client_can_abort_t)(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + const nrf_802154_tx_client_t * p_client); + +/** + * @brief Callback notifying that the frame transmission has started. + * + * @param[in] p_client Pointer to the TX client instance. + */ +typedef void (* nrf_802154_tx_client_started_t)(const nrf_802154_tx_client_t * p_client); + +/** + * @brief Callback notifying failed transmission. + * + * This callback notifies that the frame transmission has failed. + * The notification signals the end of the transmit operation. + * + * @param[in] p_frame The frame that was being transmitted. + * @param[in] error Error status of the operation. + * @param[in] p_metadata Transmit metadata. + * @param[in] p_client Pointer to the TX client instance. + */ +typedef void (* nrf_802154_tx_client_failed_t)(uint8_t * p_frame, + nrf_802154_tx_error_t error, + const nrf_802154_transmit_done_metadata_t * + p_metadata, + const nrf_802154_tx_client_t * p_client); + +/** + * @brief Callback notifying successful transmission. + * + * This callback notifies that the frame has been successfully transmitted. + * The notification signals the end of the transmit operation. + * + * @param[in] p_frame Pointer to the transmitted frame. + * @param[in] p_metadata Transmit metadata. + * @param[in] p_client Pointer to the TX client instance. + */ +typedef void (* nrf_802154_tx_client_done_t)(uint8_t * p_frame, + const nrf_802154_transmit_done_metadata_t * p_metadata, + const nrf_802154_tx_client_t * p_client); + +typedef struct +{ + nrf_802154_tx_client_can_abort_t can_abort; // !< Abort query. + nrf_802154_tx_client_started_t started; // !< Started notification. + nrf_802154_tx_client_failed_t failed; // !< Failed notification. + nrf_802154_tx_client_done_t done; // !< Done notification. +} nrf_802154_tx_client_interface_t; + +/** + * @brief TX client instance. + * + * The client instance uniquely identifies the core client that performs the TX operation. + * Each client has its own set of notification and query callbacks. + */ +struct nrf_802154_tx_client_s +{ + const nrf_802154_tx_client_interface_t * p_iface; // !< Client interface. +}; + typedef struct { + const nrf_802154_tx_client_t * p_client; nrf_802154_frame_t frame; // !< Frame to be transmitted. nrf_802154_transmitted_frame_props_t frame_props; // !< Properties of the frame to be transmitted. nrf_802154_fal_tx_power_split_t tx_power; // !< Power to be used when transmitting the frame, split into components to be applied on each stage on transmit path. @@ -50,6 +129,7 @@ typedef struct // until its preconditions are met. uint8_t extra_cca_attempts; // !< Maximum number of additional CCA attempts that can be performed if the first attempt returns busy channel. Ignored if @ref cca equals @c false. bool tx_timestamp_encode; // !< True if the transmit timestamp shall be encoded in the payload. + uint32_t rsch_timeslot_id; // !< Identifier of the delayed operation. The timeslot is consumed by the core. } nrf_802154_transmit_params_t; typedef struct diff --git a/nrf_802154/driver/src/nrf_802154_utils.h b/nrf_802154/driver/src/nrf_802154_utils.h index 234c2f307f..df93008df5 100644 --- a/nrf_802154/driver/src/nrf_802154_utils.h +++ b/nrf_802154/driver/src/nrf_802154_utils.h @@ -37,10 +37,19 @@ #include "nrf_802154_assert.h" #include -#include #include "nrfx.h" #include +#ifdef __STATIC_INLINE__ +#undef __STATIC_INLINE__ +#endif + +#ifdef NRF_802154_UTILS_DECLARE_ONLY +#define __STATIC_INLINE__ +#else +#define __STATIC_INLINE__ __STATIC_INLINE +#endif + /** * @defgroup nrf_802154_utils Utils definitions used in the 802.15.4 driver * @{ @@ -73,14 +82,7 @@ * * @param[in] X Array. */ -#define NUMELTS(X) (sizeof((X)) / sizeof(X[0])) - -/**@brief Active waiting for given number of microseconds. - * - * It is guaranteed that execution of this macro will take at least @c time_in_us - * number of microseconds. - */ -#define nrf_802154_delay_us(time_in_us) nrfx_coredep_delay_us(time_in_us) +#define NUMELTS(X) (sizeof((X)) / sizeof(X[0])) /**@brief Type holding MCU critical section state. * @@ -89,43 +91,66 @@ */ typedef uint32_t nrf_802154_mcu_critical_state_t; +/**@brief Active waiting for given number of microseconds. + * + * It is guaranteed that execution of this function will take at least @c time_in_us + * number of microseconds. + */ +__STATIC_INLINE__ void nrf_802154_delay_us(uint32_t time_in_us); + /**@brief Enters critical section on MCU level. * * Use @ref nrf_802154_mcu_critical_exit complementary. Consider following code: * @code * nrf_802154_mcu_critical_state_t mcu_cs; - * nrf_802154_mcu_critical_enter(mcu_cs); + * mcu_cs = nrf_802154_mcu_critical_enter(); * // do your critical stuff as fast as possible * nrf_802154_mcu_critical_exit(mcu_cs); * @endcode * - * @param mcu_critical_state Variable of @ref nrf_802154_mcu_critical_state_t where current - * state of MCU level critical section will be stored. + * @returns Value to be passed to complementary call to @ref nrf_802154_mcu_critical_exit. */ -#define nrf_802154_mcu_critical_enter(mcu_critical_state) \ - do \ - { \ - (mcu_critical_state) = __get_PRIMASK(); \ - __disable_irq(); \ - } \ - while (0) +__STATIC_INLINE__ nrf_802154_mcu_critical_state_t nrf_802154_mcu_critical_enter(void); /**@brief Exits critical section on MCU level. * * This shall be used complementary to @ref nrf_802154_mcu_critical_enter. * - * @param mcu_critical_state Variable of @ref nrf_802154_mcu_critical_state_t where - * state of MCU level critical section is stored by - * former call to @ref nrf_802154_mcu_critical_enter + * @param mcu_cs Value returned by @ref nrf_802154_mcu_critical_enter. + */ +__STATIC_INLINE__ void nrf_802154_mcu_critical_exit(nrf_802154_mcu_critical_state_t mcu_cs); + +/**@brief Convert microseconds to RTC ticks. + * + * @param[in] time Time in microseconds. + * + * @return Time in RTC ticks. */ -#define nrf_802154_mcu_critical_exit(mcu_critical_state) \ - do \ - { \ - __set_PRIMASK(mcu_critical_state); \ - } \ - while (0) - -static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time) +__STATIC_INLINE__ uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time); + +#ifndef NRF_802154_UTILS_DECLARE_ONLY + +__STATIC_INLINE__ void nrf_802154_delay_us(uint32_t time_in_us) +{ + nrfx_coredep_delay_us(time_in_us); +} + +__STATIC_INLINE__ nrf_802154_mcu_critical_state_t nrf_802154_mcu_critical_enter(void) +{ + nrf_802154_mcu_critical_state_t mcu_cs; + + mcu_cs = __get_PRIMASK(); + __disable_irq(); + + return mcu_cs; +} + +__STATIC_INLINE__ void nrf_802154_mcu_critical_exit(nrf_802154_mcu_critical_state_t mcu_cs) +{ + __set_PRIMASK(mcu_cs); +} + +__STATIC_INLINE__ uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time) { uint64_t t1, u1; uint64_t result; @@ -200,6 +225,8 @@ static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time) return result; } +#endif /* NRF_802154_UTILS_DECLARE_ONLY */ + /** *@} **/ diff --git a/nrf_802154/sl/include/nrf_802154_sl_utils.h b/nrf_802154/sl/include/nrf_802154_sl_utils.h index 752f394bf8..dcd708b350 100644 --- a/nrf_802154/sl/include/nrf_802154_sl_utils.h +++ b/nrf_802154/sl/include/nrf_802154_sl_utils.h @@ -72,6 +72,29 @@ /**@brief Minimum of two values. */ #define min(a, b) ((a) < (b) ? (a) : (b)) +#ifndef CONTAINER_OF +/**@brief Can be used to get a pointer to the structure which contains a given struct element. + * + * Example: + * + * struct foo { + * int bar; + * }; + * + * struct foo my_foo; + * int *ptr = &my_foo.bar; + * + * struct foo *container = CONTAINER_OF(ptr, struct foo, bar); + * + * @param ptr Pointer to a struct element whose parent is desired + * @param type type of the parent structure which contains ptr + * @param member The name of the struct element pointed to by ptr + * + * @return A pointer to the memory space which contains ptr + */ +#define CONTAINER_OF(ptr, type, member) ((type *)( (char *)(ptr) - offsetof(type, member) )) +#endif /* CONTAINER_OF */ + /**@brief Converts microseconds (us) to RTC ticks. * * @param time Time is us to be converted to RTC ticks. diff --git a/nrf_802154/sl/include/rsch/nrf_802154_rsch.h b/nrf_802154/sl/include/rsch/nrf_802154_rsch.h index 24090aa055..81ee3946ac 100644 --- a/nrf_802154/sl/include/rsch/nrf_802154_rsch.h +++ b/nrf_802154/sl/include/rsch/nrf_802154_rsch.h @@ -90,6 +90,11 @@ extern "C" { NRF_802154_RSCH_DLY_TS_OP_DRX_SLOTS + \ NRF_802154_RSCH_DLY_TS_OP_CSMACA_SLOTS +/** + * @brief Invalid timeslot ID. + */ +#define NRF_802154_RSCH_DLY_TS_ID_INVALID UINT32_MAX + /** * @brief List of the preconditions that have to be met before any radio activity. */