net: openthread: radio: Fix platform radio state machine

Fix platform radio state machine to be compliant with one shown in
OpenThread's `include/openthread/platform/radio.h`

Align twister tests to verify proper behavior of the
state machine.

Signed-off-by: Maciej Baczmanski <maciej.baczmanski@nordicsemi.no>
This commit is contained in:
Maciej Baczmanski 2025-01-07 14:45:35 +01:00 committed by Benjamin Cabé
parent 48ac31c7a2
commit b46f72009a
2 changed files with 34 additions and 15 deletions

View file

@ -756,19 +756,25 @@ bool otPlatRadioIsEnabled(otInstance *aInstance)
otError otPlatRadioEnable(otInstance *aInstance) otError otPlatRadioEnable(otInstance *aInstance)
{ {
if (!otPlatRadioIsEnabled(aInstance)) { ARG_UNUSED(aInstance);
sState = OT_RADIO_STATE_SLEEP;
if (sState != OT_RADIO_STATE_DISABLED && sState != OT_RADIO_STATE_SLEEP) {
return OT_ERROR_INVALID_STATE;
} }
sState = OT_RADIO_STATE_SLEEP;
return OT_ERROR_NONE; return OT_ERROR_NONE;
} }
otError otPlatRadioDisable(otInstance *aInstance) otError otPlatRadioDisable(otInstance *aInstance)
{ {
if (otPlatRadioIsEnabled(aInstance)) { ARG_UNUSED(aInstance);
sState = OT_RADIO_STATE_DISABLED;
if (sState != OT_RADIO_STATE_DISABLED && sState != OT_RADIO_STATE_SLEEP) {
return OT_ERROR_INVALID_STATE;
} }
sState = OT_RADIO_STATE_DISABLED;
return OT_ERROR_NONE; return OT_ERROR_NONE;
} }
@ -776,23 +782,24 @@ otError otPlatRadioSleep(otInstance *aInstance)
{ {
ARG_UNUSED(aInstance); ARG_UNUSED(aInstance);
otError error = OT_ERROR_INVALID_STATE; if (sState != OT_RADIO_STATE_SLEEP && sState != OT_RADIO_STATE_RECEIVE) {
return OT_ERROR_INVALID_STATE;
if (sState == OT_RADIO_STATE_SLEEP ||
sState == OT_RADIO_STATE_RECEIVE ||
sState == OT_RADIO_STATE_TRANSMIT) {
error = OT_ERROR_NONE;
radio_api->stop(radio_dev);
sState = OT_RADIO_STATE_SLEEP;
} }
return error; radio_api->stop(radio_dev);
sState = OT_RADIO_STATE_SLEEP;
return OT_ERROR_NONE;
} }
otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{ {
ARG_UNUSED(aInstance); ARG_UNUSED(aInstance);
if (sState == OT_RADIO_STATE_DISABLED) {
return OT_ERROR_INVALID_STATE;
}
channel = aChannel; channel = aChannel;
radio_api->set_channel(radio_dev, aChannel); radio_api->set_channel(radio_dev, aChannel);
@ -897,7 +904,9 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aPacket)
radio_caps = radio_api->get_capabilities(radio_dev); radio_caps = radio_api->get_capabilities(radio_dev);
if ((sState == OT_RADIO_STATE_RECEIVE) || (radio_caps & IEEE802154_HW_SLEEP_TO_TX)) { if (sState == OT_RADIO_STATE_RECEIVE ||
(sState == OT_RADIO_STATE_SLEEP &&
radio_caps & IEEE802154_HW_SLEEP_TO_TX)) {
if (run_tx_task(aInstance) == 0) { if (run_tx_task(aInstance) == 0) {
error = OT_ERROR_NONE; error = OT_ERROR_NONE;
} }

View file

@ -625,6 +625,9 @@ ZTEST(openthread_radio, test_radio_state_test)
zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE, zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE,
"Failed to set TX power."); "Failed to set TX power.");
zassert_equal(otPlatRadioSleep(ot), OT_ERROR_NONE, "Failed to switch to sleep mode.");
zassert_equal(otPlatRadioDisable(ot), OT_ERROR_NONE, "Failed to disable radio."); zassert_equal(otPlatRadioDisable(ot), OT_ERROR_NONE, "Failed to disable radio.");
zassert_false(otPlatRadioIsEnabled(ot), "Radio reports as enabled."); zassert_false(otPlatRadioIsEnabled(ot), "Radio reports as enabled.");
@ -632,6 +635,9 @@ ZTEST(openthread_radio, test_radio_state_test)
zassert_equal(otPlatRadioSleep(ot), OT_ERROR_INVALID_STATE, zassert_equal(otPlatRadioSleep(ot), OT_ERROR_INVALID_STATE,
"Changed to sleep regardless being disabled."); "Changed to sleep regardless being disabled.");
zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_INVALID_STATE,
"Changed to receive regardless being disabled.");
zassert_equal(otPlatRadioEnable(ot), OT_ERROR_NONE, "Enabling radio failed."); zassert_equal(otPlatRadioEnable(ot), OT_ERROR_NONE, "Enabling radio failed.");
zassert_true(otPlatRadioIsEnabled(ot), "Radio reports disabled."); zassert_true(otPlatRadioIsEnabled(ot), "Radio reports disabled.");
@ -644,6 +650,9 @@ ZTEST(openthread_radio, test_radio_state_test)
zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE, "Failed to receive."); zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE, "Failed to receive.");
zassert_equal(platformRadioChannelGet(ot), channel, "Channel number not remembered."); zassert_equal(platformRadioChannelGet(ot), channel, "Channel number not remembered.");
zassert_equal(otPlatRadioDisable(ot), OT_ERROR_INVALID_STATE,
"Changed to disabled regardless being in receive state.");
zassert_true(otPlatRadioIsEnabled(ot), "Radio reports as disabled."); zassert_true(otPlatRadioIsEnabled(ot), "Radio reports as disabled.");
zassert_equal(1, set_channel_mock_fake.call_count); zassert_equal(1, set_channel_mock_fake.call_count);
zassert_equal(channel, set_channel_mock_fake.arg1_val); zassert_equal(channel, set_channel_mock_fake.arg1_val);
@ -651,7 +660,7 @@ ZTEST(openthread_radio, test_radio_state_test)
zassert_equal(power, set_txpower_mock_fake.arg1_val); zassert_equal(power, set_txpower_mock_fake.arg1_val);
zassert_equal(1, start_mock_fake.call_count); zassert_equal(1, start_mock_fake.call_count);
zassert_equal_ptr(radio, start_mock_fake.arg0_val, NULL); zassert_equal_ptr(radio, start_mock_fake.arg0_val, NULL);
zassert_equal(1, stop_mock_fake.call_count); zassert_equal(2, stop_mock_fake.call_count);
zassert_equal_ptr(radio, stop_mock_fake.arg0_val, NULL); zassert_equal_ptr(radio, stop_mock_fake.arg0_val, NULL);
} }
@ -814,6 +823,7 @@ ZTEST(openthread_radio, test_net_pkt_transmit)
"Failed to set TX power."); "Failed to set TX power.");
set_channel_mock_fake.return_val = 0; set_channel_mock_fake.return_val = 0;
zassert_equal(otPlatRadioEnable(ot), OT_ERROR_NONE, "Failed to enable.");
zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE, "Failed to receive."); zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE, "Failed to receive.");
zassert_equal(1, set_channel_mock_fake.call_count); zassert_equal(1, set_channel_mock_fake.call_count);
zassert_equal(channel, set_channel_mock_fake.arg1_val); zassert_equal(channel, set_channel_mock_fake.arg1_val);