983 lines
33 KiB
C
983 lines
33 KiB
C
/*
|
|
* Copyright (c) 2020 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
|
|
#include <zephyr/fff.h>
|
|
#include <zephyr/net/ieee802154_radio.h>
|
|
#include <zephyr/net/net_pkt.h>
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/ztest.h>
|
|
|
|
#include <openthread/message.h>
|
|
#include <openthread/platform/radio.h>
|
|
#include <platform-zephyr.h>
|
|
|
|
DEFINE_FFF_GLOBALS;
|
|
|
|
/**
|
|
* @brief Tests for the radio.c - OpenThread radio api
|
|
* @defgroup openthread_tests radio
|
|
* @ingroup all_tests
|
|
* @{
|
|
*/
|
|
|
|
#define ACK_PKT_LENGTH 3
|
|
#define FRAME_TYPE_MASK 0x07
|
|
#define FRAME_TYPE_ACK 0x02
|
|
|
|
K_SEM_DEFINE(ot_sem, 0, 1);
|
|
|
|
/**
|
|
* Fake pointer as it should not be accessed by the code.
|
|
* Should not be null to be sure it was properly passed.
|
|
*/
|
|
otInstance *ot = (otInstance *)0xAAAA;
|
|
otMessage *ip_msg = (otMessage *)0xBBBB;
|
|
|
|
/* forward declarations */
|
|
FAKE_VALUE_FUNC(int, scan_mock, const struct device *, uint16_t, energy_scan_done_cb_t);
|
|
FAKE_VALUE_FUNC(int, cca_mock, const struct device *);
|
|
FAKE_VALUE_FUNC(int, set_channel_mock, const struct device *, uint16_t);
|
|
FAKE_VALUE_FUNC(int, filter_mock, const struct device *, bool, enum ieee802154_filter_type,
|
|
const struct ieee802154_filter *);
|
|
FAKE_VALUE_FUNC(int, set_txpower_mock, const struct device *, int16_t);
|
|
FAKE_VALUE_FUNC(int, tx_mock, const struct device *, enum ieee802154_tx_mode, struct net_pkt *,
|
|
struct net_buf *);
|
|
FAKE_VALUE_FUNC(int, start_mock, const struct device *);
|
|
FAKE_VALUE_FUNC(int, stop_mock, const struct device *);
|
|
FAKE_VALUE_FUNC(int, configure_mock, const struct device *, enum ieee802154_config_type,
|
|
const struct ieee802154_config *);
|
|
FAKE_VALUE_FUNC(enum ieee802154_hw_caps, get_capabilities_caps_mock, const struct device *);
|
|
|
|
static enum ieee802154_hw_caps get_capabilities(const struct device *dev);
|
|
|
|
/* mocks */
|
|
static struct ieee802154_radio_api rapi = {.get_capabilities = get_capabilities,
|
|
.cca = cca_mock,
|
|
.set_channel = set_channel_mock,
|
|
.filter = filter_mock,
|
|
.set_txpower = set_txpower_mock,
|
|
.tx = tx_mock,
|
|
.start = start_mock,
|
|
.stop = stop_mock,
|
|
.configure = configure_mock,
|
|
#ifdef CONFIG_NET_L2_IEEE802154_SUB_GHZ
|
|
.get_subg_channel_count = NULL,
|
|
#endif /* CONFIG_NET_L2_IEEE802154_SUB_GHZ */
|
|
.ed_scan = scan_mock};
|
|
|
|
#define DT_DRV_COMPAT vnd_ieee802154
|
|
DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, POST_KERNEL, 0, &rapi);
|
|
|
|
static const struct device *const radio = DEVICE_DT_INST_GET(0);
|
|
|
|
static int16_t rssi_scan_mock_max_ed;
|
|
static int rssi_scan_mock(const struct device *dev, uint16_t duration,
|
|
energy_scan_done_cb_t done_cb)
|
|
{
|
|
zassert_equal(dev, radio, "Device handle incorrect.");
|
|
zassert_equal(duration, 1, "otPlatRadioGetRssi shall pass minimal allowed value.");
|
|
|
|
/* use return value as callback param */
|
|
done_cb(radio, rssi_scan_mock_max_ed);
|
|
|
|
return 0;
|
|
}
|
|
|
|
FAKE_VOID_FUNC(otPlatRadioEnergyScanDone, otInstance *, int8_t);
|
|
|
|
void otSysEventSignalPending(void) { k_sem_give(&ot_sem); }
|
|
|
|
void otTaskletsSignalPending(otInstance *aInstance)
|
|
{
|
|
zassert_equal(aInstance, ot, "Incorrect instance.");
|
|
k_sem_give(&ot_sem);
|
|
}
|
|
|
|
static void make_sure_sem_set(k_timeout_t timeout)
|
|
{
|
|
zassert_equal(k_sem_take(&ot_sem, timeout), 0, "Sem not released.");
|
|
}
|
|
|
|
static otRadioFrame otPlatRadioReceiveDone_expected_aframe;
|
|
static otError otPlatRadioReceiveDone_expected_error;
|
|
void otPlatRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
|
|
{
|
|
zassert_equal(aInstance, ot, "Incorrect instance.");
|
|
zassert_equal(otPlatRadioReceiveDone_expected_aframe.mChannel, aFrame->mChannel);
|
|
zassert_equal(otPlatRadioReceiveDone_expected_aframe.mLength, aFrame->mLength);
|
|
zassert_mem_equal(otPlatRadioReceiveDone_expected_aframe.mPsdu, aFrame->mPsdu,
|
|
aFrame->mLength, NULL);
|
|
zassert_equal(otPlatRadioReceiveDone_expected_error, aError);
|
|
}
|
|
|
|
FAKE_VOID_FUNC(otPlatRadioTxDone, otInstance *, otRadioFrame *, otRadioFrame *, otError);
|
|
|
|
static enum ieee802154_hw_caps get_capabilities(const struct device *dev)
|
|
{
|
|
enum ieee802154_hw_caps caps;
|
|
|
|
zassert_equal(dev, radio, "Device handle incorrect.");
|
|
|
|
caps = IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK |
|
|
IEEE802154_HW_FILTER | IEEE802154_HW_ENERGY_SCAN | IEEE802154_HW_SLEEP_TO_TX;
|
|
if (IS_ENABLED(CONFIG_NET_PKT_TXTIME)) {
|
|
caps |= IEEE802154_HW_TXTIME;
|
|
}
|
|
return caps;
|
|
}
|
|
|
|
FAKE_VALUE_FUNC(otError, otIp6Send, otInstance *, otMessage *);
|
|
|
|
otMessage *otIp6NewMessage(otInstance *aInstance, const otMessageSettings *aSettings)
|
|
{
|
|
zassert_equal(aInstance, ot, "Incorrect instance.");
|
|
return ip_msg;
|
|
}
|
|
|
|
FAKE_VALUE_FUNC(otError, otMessageAppend, otMessage *, const void *, uint16_t);
|
|
|
|
FAKE_VOID_FUNC(otMessageFree, otMessage *);
|
|
|
|
void otPlatRadioTxStarted(otInstance *aInstance, otRadioFrame *aFrame)
|
|
{
|
|
zassert_equal(aInstance, ot, "Incorrect instance.");
|
|
}
|
|
|
|
/**
|
|
* @brief Test for immediate energy scan
|
|
* Tests for case when radio energy scan returns success at the first call.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_energy_scan_immediate_test)
|
|
{
|
|
const uint8_t chan = 10;
|
|
const uint8_t dur = 100;
|
|
const int16_t energy = -94;
|
|
|
|
set_channel_mock_fake.return_val = 0;
|
|
|
|
scan_mock_fake.return_val = 0;
|
|
zassert_equal(otPlatRadioEnergyScan(ot, chan, dur), OT_ERROR_NONE,
|
|
"Energy scan returned error.");
|
|
zassert_equal(1, scan_mock_fake.call_count);
|
|
zassert_equal(dur, scan_mock_fake.arg1_val);
|
|
zassert_not_null(scan_mock_fake.arg2_val, "Scan callback not specified.");
|
|
zassert_equal(1, set_channel_mock_fake.call_count);
|
|
zassert_equal(chan, set_channel_mock_fake.arg1_val);
|
|
|
|
scan_mock_fake.arg2_val(radio, energy);
|
|
make_sure_sem_set(K_NO_WAIT);
|
|
|
|
platformRadioProcess(ot);
|
|
zassert_equal(1, otPlatRadioEnergyScanDone_fake.call_count);
|
|
zassert_equal_ptr(ot, otPlatRadioEnergyScanDone_fake.arg0_val, NULL);
|
|
zassert_equal(energy, otPlatRadioEnergyScanDone_fake.arg1_val);
|
|
}
|
|
|
|
/**
|
|
* @brief Test for delayed energy scan
|
|
* Tests for case when radio returns not being able to start energy scan and
|
|
* the scan should be scheduled for later.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_energy_scan_delayed_test)
|
|
{
|
|
const uint8_t chan = 10;
|
|
const uint8_t dur = 100;
|
|
const int16_t energy = -94;
|
|
|
|
/* request scan */
|
|
set_channel_mock_fake.return_val = 0;
|
|
scan_mock_fake.return_val = -EBUSY;
|
|
|
|
zassert_equal(otPlatRadioEnergyScan(ot, chan, dur), OT_ERROR_NONE,
|
|
"Energy scan returned error.");
|
|
zassert_equal(1, scan_mock_fake.call_count);
|
|
zassert_equal(dur, scan_mock_fake.arg1_val);
|
|
zassert_not_null(scan_mock_fake.arg2_val, "Scan callback not specified.");
|
|
zassert_equal(1, set_channel_mock_fake.call_count);
|
|
zassert_equal(chan, set_channel_mock_fake.arg1_val);
|
|
make_sure_sem_set(K_NO_WAIT);
|
|
|
|
/* process reported event */
|
|
RESET_FAKE(scan_mock);
|
|
RESET_FAKE(set_channel_mock);
|
|
FFF_RESET_HISTORY();
|
|
|
|
scan_mock_fake.return_val = 0;
|
|
set_channel_mock_fake.return_val = 0;
|
|
|
|
platformRadioProcess(ot);
|
|
zassert_equal(1, scan_mock_fake.call_count);
|
|
zassert_equal(dur, scan_mock_fake.arg1_val);
|
|
zassert_not_null(scan_mock_fake.arg2_val, "Scan callback not specified.");
|
|
zassert_equal(1, set_channel_mock_fake.call_count);
|
|
zassert_equal(chan, set_channel_mock_fake.arg1_val);
|
|
|
|
/* invoke scan done */
|
|
scan_mock_fake.arg2_val(radio, energy);
|
|
make_sure_sem_set(K_NO_WAIT);
|
|
|
|
platformRadioProcess(ot);
|
|
zassert_equal(1, otPlatRadioEnergyScanDone_fake.call_count);
|
|
zassert_equal_ptr(ot, otPlatRadioEnergyScanDone_fake.arg0_val, NULL);
|
|
zassert_equal(energy, otPlatRadioEnergyScanDone_fake.arg1_val);
|
|
}
|
|
|
|
static void create_ack_frame(void)
|
|
{
|
|
struct net_pkt *packet;
|
|
struct net_buf *buf;
|
|
const uint8_t lqi = 230;
|
|
const int8_t rssi = -80;
|
|
|
|
packet = net_pkt_alloc(K_NO_WAIT);
|
|
buf = net_pkt_get_reserve_tx_data(ACK_PKT_LENGTH, K_NO_WAIT);
|
|
net_pkt_append_buffer(packet, buf);
|
|
|
|
buf->len = ACK_PKT_LENGTH;
|
|
buf->data[0] = FRAME_TYPE_ACK;
|
|
|
|
net_pkt_set_ieee802154_rssi_dbm(packet, rssi);
|
|
net_pkt_set_ieee802154_lqi(packet, lqi);
|
|
zassert_equal(ieee802154_handle_ack(NULL, packet), NET_OK, "Handling ack failed.");
|
|
net_pkt_unref(packet);
|
|
}
|
|
|
|
/**
|
|
* @brief Test for tx data handling
|
|
* Tests if OT frame is correctly passed to the radio driver.
|
|
* Additionally verifies ACK frame passing back to the OT.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_tx_test)
|
|
{
|
|
const uint8_t chan = 20;
|
|
uint8_t chan2 = chan - 1;
|
|
const int8_t power = -3;
|
|
net_time_t expected_target_time = 0;
|
|
|
|
otRadioFrame *frm = otPlatRadioGetTransmitBuffer(ot);
|
|
|
|
zassert_not_null(frm, "Transmit buffer is null.");
|
|
|
|
zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE,
|
|
"Failed to set TX power.");
|
|
|
|
set_channel_mock_fake.return_val = 0;
|
|
zassert_equal(otPlatRadioReceive(ot, chan), OT_ERROR_NONE, "Failed to receive.");
|
|
zassert_equal(1, set_channel_mock_fake.call_count);
|
|
zassert_equal(chan, set_channel_mock_fake.arg1_val);
|
|
zassert_equal(1, set_txpower_mock_fake.call_count);
|
|
zassert_equal(power, set_txpower_mock_fake.arg1_val);
|
|
zassert_equal(1, start_mock_fake.call_count);
|
|
zassert_equal_ptr(radio, start_mock_fake.arg0_val, NULL);
|
|
RESET_FAKE(set_channel_mock);
|
|
RESET_FAKE(set_txpower_mock);
|
|
RESET_FAKE(start_mock);
|
|
FFF_RESET_HISTORY();
|
|
|
|
if (IS_ENABLED(CONFIG_NET_PKT_TXTIME)) {
|
|
frm->mInfo.mTxInfo.mTxDelayBaseTime = 3U;
|
|
frm->mInfo.mTxInfo.mTxDelay = 5U;
|
|
expected_target_time =
|
|
(frm->mInfo.mTxInfo.mTxDelayBaseTime + frm->mInfo.mTxInfo.mTxDelay) *
|
|
NSEC_PER_USEC;
|
|
}
|
|
|
|
/* ACKed frame */
|
|
frm->mChannel = chan2;
|
|
frm->mInfo.mTxInfo.mCsmaCaEnabled = true;
|
|
frm->mPsdu[0] = IEEE802154_AR_FLAG_SET;
|
|
set_channel_mock_fake.return_val = 0;
|
|
zassert_equal(otPlatRadioTransmit(ot, frm), OT_ERROR_NONE, "Transmit failed.");
|
|
k_yield();
|
|
|
|
create_ack_frame();
|
|
make_sure_sem_set(Z_TIMEOUT_MS(100));
|
|
|
|
platformRadioProcess(ot);
|
|
zassert_equal(1, set_channel_mock_fake.call_count);
|
|
zassert_equal(chan2, set_channel_mock_fake.arg1_val);
|
|
if (IS_ENABLED(CONFIG_NET_PKT_TXTIME)) {
|
|
zassert_equal(0, cca_mock_fake.call_count);
|
|
} else {
|
|
zassert_equal(1, cca_mock_fake.call_count);
|
|
zassert_equal_ptr(radio, cca_mock_fake.arg0_val, NULL);
|
|
}
|
|
zassert_equal(1, set_txpower_mock_fake.call_count);
|
|
zassert_equal(power, set_txpower_mock_fake.arg1_val);
|
|
zassert_equal(1, tx_mock_fake.call_count);
|
|
zassert_equal_ptr(frm->mPsdu, tx_mock_fake.arg3_val->data, NULL);
|
|
zassert_equal(expected_target_time,
|
|
net_ptp_time_to_ns(net_pkt_timestamp(tx_mock_fake.arg2_val)));
|
|
zassert_equal(IS_ENABLED(CONFIG_NET_PKT_TXTIME) ? IEEE802154_TX_MODE_TXTIME_CCA
|
|
: IEEE802154_TX_MODE_DIRECT,
|
|
tx_mock_fake.arg1_val);
|
|
zassert_equal(1, otPlatRadioTxDone_fake.call_count);
|
|
zassert_equal_ptr(ot, otPlatRadioTxDone_fake.arg0_val, NULL);
|
|
zassert_equal(OT_ERROR_NONE, otPlatRadioTxDone_fake.arg3_val);
|
|
RESET_FAKE(set_channel_mock);
|
|
RESET_FAKE(set_txpower_mock);
|
|
RESET_FAKE(tx_mock);
|
|
RESET_FAKE(otPlatRadioTxDone);
|
|
FFF_RESET_HISTORY();
|
|
|
|
/* Non-ACKed frame */
|
|
frm->mChannel = --chan2;
|
|
frm->mInfo.mTxInfo.mCsmaCaEnabled = false;
|
|
frm->mPsdu[0] = 0;
|
|
|
|
set_channel_mock_fake.return_val = 0;
|
|
zassert_equal(otPlatRadioTransmit(ot, frm), OT_ERROR_NONE, "Transmit failed.");
|
|
make_sure_sem_set(Z_TIMEOUT_MS(100));
|
|
platformRadioProcess(ot);
|
|
zassert_equal(1, set_channel_mock_fake.call_count);
|
|
zassert_equal(chan2, set_channel_mock_fake.arg1_val);
|
|
zassert_equal(1, set_txpower_mock_fake.call_count);
|
|
zassert_equal(power, set_txpower_mock_fake.arg1_val);
|
|
zassert_equal(1, tx_mock_fake.call_count);
|
|
zassert_equal_ptr(frm->mPsdu, tx_mock_fake.arg3_val->data, NULL);
|
|
zassert_equal(1, otPlatRadioTxDone_fake.call_count);
|
|
zassert_equal_ptr(ot, otPlatRadioTxDone_fake.arg0_val, NULL);
|
|
zassert_equal(OT_ERROR_NONE, otPlatRadioTxDone_fake.arg3_val);
|
|
}
|
|
|
|
/**
|
|
* @brief Test for tx power setting
|
|
* Tests if tx power requested by the OT is correctly passed to the radio.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_tx_power_test)
|
|
{
|
|
int8_t out_power = 0;
|
|
|
|
zassert_equal(otPlatRadioSetTransmitPower(ot, -3), OT_ERROR_NONE,
|
|
"Failed to set TX power.");
|
|
zassert_equal(otPlatRadioGetTransmitPower(ot, &out_power), OT_ERROR_NONE,
|
|
"Failed to obtain TX power.");
|
|
zassert_equal(out_power, -3, "Got different power than set.");
|
|
zassert_equal(otPlatRadioSetTransmitPower(ot, -6), OT_ERROR_NONE,
|
|
"Failed to set TX power.");
|
|
zassert_equal(otPlatRadioGetTransmitPower(ot, &out_power), OT_ERROR_NONE,
|
|
"Failed to obtain TX power.");
|
|
zassert_equal(out_power, -6, "Second call to otPlatRadioSetTransmitPower failed.");
|
|
}
|
|
|
|
/**
|
|
* @brief Test for getting radio sensitivity
|
|
* There is no api to get radio sensitivity from the radio so the value is
|
|
* hardcoded in radio.c. Test only verifies if the value returned makes any
|
|
* sense.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_sensitivity_test)
|
|
{
|
|
/*
|
|
* Nothing to test actually as this is constant 100.
|
|
* When radio interface will be extended to get sensitivity this test
|
|
* can be extended with the radio api call. For now just verify if the
|
|
* value is reasonable.
|
|
*/
|
|
zassert_true(-80 > otPlatRadioGetReceiveSensitivity(ot), "Radio sensitivity not in range.");
|
|
}
|
|
|
|
static enum ieee802154_config_type custom_configure_match_mock_expected_type;
|
|
static struct ieee802154_config custom_configure_match_mock_expected_config;
|
|
static int custom_configure_match_mock(const struct device *dev, enum ieee802154_config_type type,
|
|
const struct ieee802154_config *config)
|
|
{
|
|
zassert_equal_ptr(dev, radio, "Device handle incorrect.");
|
|
zassert_equal(custom_configure_match_mock_expected_type, type);
|
|
switch (type) {
|
|
case IEEE802154_CONFIG_AUTO_ACK_FPB:
|
|
zassert_equal(custom_configure_match_mock_expected_config.auto_ack_fpb.mode,
|
|
config->auto_ack_fpb.mode, NULL);
|
|
zassert_equal(custom_configure_match_mock_expected_config.auto_ack_fpb.enabled,
|
|
config->auto_ack_fpb.enabled, NULL);
|
|
break;
|
|
case IEEE802154_CONFIG_ACK_FPB:
|
|
zassert_equal(custom_configure_match_mock_expected_config.ack_fpb.extended,
|
|
config->ack_fpb.extended, NULL);
|
|
zassert_equal(custom_configure_match_mock_expected_config.ack_fpb.enabled,
|
|
config->ack_fpb.enabled, NULL);
|
|
if (custom_configure_match_mock_expected_config.ack_fpb.addr == NULL) {
|
|
zassert_is_null(config->ack_fpb.addr, NULL);
|
|
} else {
|
|
zassert_mem_equal(custom_configure_match_mock_expected_config.ack_fpb.addr,
|
|
config->ack_fpb.addr,
|
|
(config->ack_fpb.extended) ? sizeof(otExtAddress) : 2,
|
|
NULL);
|
|
}
|
|
break;
|
|
default:
|
|
zassert_unreachable("Unexpected config type %d.", type);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
static void set_expected_match_values(enum ieee802154_config_type type, uint8_t *addr,
|
|
bool extended, bool enabled)
|
|
{
|
|
custom_configure_match_mock_expected_type = type;
|
|
switch (type) {
|
|
case IEEE802154_CONFIG_AUTO_ACK_FPB:
|
|
custom_configure_match_mock_expected_config.auto_ack_fpb.enabled = enabled;
|
|
custom_configure_match_mock_expected_config.auto_ack_fpb.mode =
|
|
IEEE802154_FPB_ADDR_MATCH_THREAD;
|
|
break;
|
|
case IEEE802154_CONFIG_ACK_FPB:
|
|
custom_configure_match_mock_expected_config.ack_fpb.extended = extended;
|
|
custom_configure_match_mock_expected_config.ack_fpb.enabled = enabled;
|
|
custom_configure_match_mock_expected_config.ack_fpb.addr = addr;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Test different types of OT source match.
|
|
* Tests if Enable, Disable, Add and Clear Source Match calls are passed to the
|
|
* radio driver correctly.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_source_match_test)
|
|
{
|
|
otExtAddress ext_addr;
|
|
configure_mock_fake.custom_fake = custom_configure_match_mock;
|
|
|
|
/* Enable/Disable */
|
|
set_expected_match_values(IEEE802154_CONFIG_AUTO_ACK_FPB, NULL, false, true);
|
|
otPlatRadioEnableSrcMatch(ot, true);
|
|
|
|
set_expected_match_values(IEEE802154_CONFIG_AUTO_ACK_FPB, NULL, false, false);
|
|
otPlatRadioEnableSrcMatch(ot, false);
|
|
|
|
set_expected_match_values(IEEE802154_CONFIG_AUTO_ACK_FPB, NULL, false, true);
|
|
otPlatRadioEnableSrcMatch(ot, true);
|
|
|
|
/* Add */
|
|
sys_put_le16(12345, ext_addr.m8);
|
|
set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, ext_addr.m8, false, true);
|
|
zassert_equal(otPlatRadioAddSrcMatchShortEntry(ot, 12345), OT_ERROR_NONE,
|
|
"Failed to add short src entry.");
|
|
|
|
for (int i = 0; i < sizeof(ext_addr.m8); i++) {
|
|
ext_addr.m8[i] = i;
|
|
}
|
|
set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, ext_addr.m8, true, true);
|
|
zassert_equal(otPlatRadioAddSrcMatchExtEntry(ot, &ext_addr), OT_ERROR_NONE,
|
|
"Failed to add ext src entry.");
|
|
|
|
/* Clear */
|
|
sys_put_le16(12345, ext_addr.m8);
|
|
set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, ext_addr.m8, false, false);
|
|
zassert_equal(otPlatRadioClearSrcMatchShortEntry(ot, 12345), OT_ERROR_NONE,
|
|
"Failed to clear short src entry.");
|
|
|
|
set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, ext_addr.m8, true, false);
|
|
zassert_equal(otPlatRadioClearSrcMatchExtEntry(ot, &ext_addr), OT_ERROR_NONE,
|
|
"Failed to clear ext src entry.");
|
|
|
|
set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, NULL, false, false);
|
|
otPlatRadioClearSrcMatchShortEntries(ot);
|
|
|
|
set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, NULL, true, false);
|
|
otPlatRadioClearSrcMatchExtEntries(ot);
|
|
}
|
|
|
|
static bool custom_configure_promiscuous_mock_promiscuous;
|
|
static int custom_configure_promiscuous_mock(const struct device *dev,
|
|
enum ieee802154_config_type type,
|
|
const struct ieee802154_config *config)
|
|
{
|
|
zassert_equal(dev, radio, "Device handle incorrect.");
|
|
zassert_equal(type, IEEE802154_CONFIG_PROMISCUOUS, "Config type incorrect.");
|
|
custom_configure_promiscuous_mock_promiscuous = config->promiscuous;
|
|
|
|
return 0;
|
|
}
|
|
/**
|
|
* @brief Test for enabling or disabling promiscuous mode
|
|
* Tests if OT can successfully enable or disable promiscuous mode.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_promiscuous_mode_set_test)
|
|
{
|
|
zassert_false(otPlatRadioGetPromiscuous(ot),
|
|
"By default promiscuous mode shall be disabled.");
|
|
|
|
configure_mock_fake.custom_fake = custom_configure_promiscuous_mock;
|
|
otPlatRadioSetPromiscuous(ot, true);
|
|
zassert_true(otPlatRadioGetPromiscuous(ot), "Mode not enabled.");
|
|
zassert_equal(1, configure_mock_fake.call_count);
|
|
zassert_true(custom_configure_promiscuous_mock_promiscuous);
|
|
|
|
RESET_FAKE(configure_mock);
|
|
|
|
configure_mock_fake.custom_fake = custom_configure_promiscuous_mock;
|
|
otPlatRadioSetPromiscuous(ot, false);
|
|
zassert_false(otPlatRadioGetPromiscuous(ot), "Mode still enabled.");
|
|
zassert_equal(1, configure_mock_fake.call_count);
|
|
zassert_false(custom_configure_promiscuous_mock_promiscuous);
|
|
}
|
|
|
|
/**
|
|
* @brief Test of proper radio to OT capabilities mapping
|
|
* Tests if different radio capabilities map for their corresponding OpenThread
|
|
* capability
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_get_caps_test)
|
|
{
|
|
rapi.get_capabilities = get_capabilities_caps_mock;
|
|
|
|
/* no caps */
|
|
get_capabilities_caps_mock_fake.return_val = 0;
|
|
zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
|
|
"Incorrect capabilities returned.");
|
|
|
|
/* not used by OT */
|
|
get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_FCS;
|
|
zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
|
|
"Incorrect capabilities returned.");
|
|
get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_2_4_GHZ;
|
|
zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
|
|
"Incorrect capabilities returned.");
|
|
get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_SUB_GHZ;
|
|
zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
|
|
"Incorrect capabilities returned.");
|
|
|
|
/* not implemented or not fully supported */
|
|
get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_PROMISC;
|
|
zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
|
|
"Incorrect capabilities returned.");
|
|
|
|
/* proper mapping */
|
|
get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_CSMA;
|
|
zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_CSMA_BACKOFF,
|
|
"Incorrect capabilities returned.");
|
|
|
|
get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_ENERGY_SCAN;
|
|
zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_ENERGY_SCAN,
|
|
"Incorrect capabilities returned.");
|
|
|
|
get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_TX_RX_ACK;
|
|
zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_ACK_TIMEOUT,
|
|
"Incorrect capabilities returned.");
|
|
|
|
get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_TXTIME;
|
|
zassert_equal(otPlatRadioGetCaps(ot),
|
|
IS_ENABLED(CONFIG_NET_PKT_TXTIME) ? OT_RADIO_CAPS_TRANSMIT_TIMING
|
|
: OT_RADIO_CAPS_NONE,
|
|
"Incorrect capabilities returned.");
|
|
|
|
get_capabilities_caps_mock_fake.return_val = IEEE802154_HW_SLEEP_TO_TX;
|
|
zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_SLEEP_TO_TX,
|
|
"Incorrect capabilities returned.");
|
|
|
|
/* all at once */
|
|
get_capabilities_caps_mock_fake.return_val =
|
|
IEEE802154_HW_FCS | IEEE802154_HW_PROMISC | IEEE802154_HW_FILTER |
|
|
IEEE802154_HW_CSMA | IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK |
|
|
IEEE802154_HW_SUB_GHZ | IEEE802154_HW_ENERGY_SCAN | IEEE802154_HW_TXTIME |
|
|
IEEE802154_HW_SLEEP_TO_TX;
|
|
zassert_equal(
|
|
otPlatRadioGetCaps(ot),
|
|
OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_ACK_TIMEOUT |
|
|
OT_RADIO_CAPS_SLEEP_TO_TX |
|
|
(IS_ENABLED(CONFIG_NET_PKT_TXTIME) ? OT_RADIO_CAPS_TRANSMIT_TIMING : 0),
|
|
"Incorrect capabilities returned.");
|
|
|
|
rapi.get_capabilities = get_capabilities;
|
|
}
|
|
|
|
/**
|
|
* @brief Test for getting the rssi value from the radio
|
|
* Tests if correct value is returned from the otPlatRadioGetRssi function.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_get_rssi_test)
|
|
{
|
|
const int8_t rssi = -103;
|
|
|
|
rapi.ed_scan = rssi_scan_mock;
|
|
|
|
rssi_scan_mock_max_ed = rssi;
|
|
zassert_equal(otPlatRadioGetRssi(ot), rssi, "Invalid RSSI value received.");
|
|
|
|
rapi.ed_scan = scan_mock;
|
|
}
|
|
|
|
/**
|
|
* @brief Test switching between radio states
|
|
* Tests if radio is correctly switched between states.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_radio_state_test)
|
|
{
|
|
const uint8_t channel = 12;
|
|
const uint8_t power = 10;
|
|
|
|
zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE,
|
|
"Failed to set TX power.");
|
|
zassert_equal(otPlatRadioDisable(ot), OT_ERROR_NONE, "Failed to disable radio.");
|
|
|
|
zassert_false(otPlatRadioIsEnabled(ot), "Radio reports as enabled.");
|
|
|
|
zassert_equal(otPlatRadioSleep(ot), OT_ERROR_INVALID_STATE,
|
|
"Changed to sleep regardless being disabled.");
|
|
|
|
zassert_equal(otPlatRadioEnable(ot), OT_ERROR_NONE, "Enabling radio failed.");
|
|
|
|
zassert_true(otPlatRadioIsEnabled(ot), "Radio reports disabled.");
|
|
|
|
zassert_equal(otPlatRadioSleep(ot), OT_ERROR_NONE, "Failed to switch to sleep mode.");
|
|
|
|
zassert_true(otPlatRadioIsEnabled(ot), "Radio reports as disabled.");
|
|
|
|
set_channel_mock_fake.return_val = 0;
|
|
zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE, "Failed to receive.");
|
|
zassert_equal(platformRadioChannelGet(ot), channel, "Channel number not remembered.");
|
|
|
|
zassert_true(otPlatRadioIsEnabled(ot), "Radio reports as disabled.");
|
|
zassert_equal(1, set_channel_mock_fake.call_count);
|
|
zassert_equal(channel, set_channel_mock_fake.arg1_val);
|
|
zassert_equal(1, set_txpower_mock_fake.call_count);
|
|
zassert_equal(power, set_txpower_mock_fake.arg1_val);
|
|
zassert_equal(1, start_mock_fake.call_count);
|
|
zassert_equal_ptr(radio, start_mock_fake.arg0_val, NULL);
|
|
zassert_equal(1, stop_mock_fake.call_count);
|
|
zassert_equal_ptr(radio, stop_mock_fake.arg0_val, NULL);
|
|
}
|
|
|
|
static uint16_t custom_filter_mock_pan_id;
|
|
static uint16_t custom_filter_mock_short_addr;
|
|
static uint8_t *custom_filter_mock_ieee_addr;
|
|
static int custom_filter_mock(const struct device *dev, bool set, enum ieee802154_filter_type type,
|
|
const struct ieee802154_filter *filter)
|
|
{
|
|
switch (type) {
|
|
case IEEE802154_FILTER_TYPE_IEEE_ADDR:
|
|
custom_filter_mock_ieee_addr = filter->ieee_addr;
|
|
break;
|
|
case IEEE802154_FILTER_TYPE_SHORT_ADDR:
|
|
custom_filter_mock_short_addr = filter->short_addr;
|
|
break;
|
|
case IEEE802154_FILTER_TYPE_PAN_ID:
|
|
custom_filter_mock_pan_id = filter->pan_id;
|
|
break;
|
|
default:
|
|
zassert_false(true, "Type not supported in mock: %d.", type);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Test address filtering
|
|
* Tests if short, extended address and PanID are correctly passed to the radio
|
|
* driver.
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_address_test)
|
|
{
|
|
const uint16_t pan_id = 0xDEAD;
|
|
const uint16_t short_add = 0xCAFE;
|
|
otExtAddress ieee_addr;
|
|
|
|
for (int i = 0; i < sizeof(ieee_addr.m8); i++) {
|
|
ieee_addr.m8[i] = 'a' + i;
|
|
}
|
|
|
|
filter_mock_fake.custom_fake = custom_filter_mock;
|
|
otPlatRadioSetPanId(ot, pan_id);
|
|
zassert_equal(1, filter_mock_fake.call_count);
|
|
zassert_true(filter_mock_fake.arg1_val);
|
|
zassert_equal(IEEE802154_FILTER_TYPE_PAN_ID, filter_mock_fake.arg2_val);
|
|
zassert_equal(pan_id, custom_filter_mock_pan_id);
|
|
RESET_FAKE(filter_mock);
|
|
FFF_RESET_HISTORY();
|
|
|
|
filter_mock_fake.custom_fake = custom_filter_mock;
|
|
otPlatRadioSetShortAddress(ot, short_add);
|
|
zassert_equal(1, filter_mock_fake.call_count);
|
|
zassert_true(filter_mock_fake.arg1_val);
|
|
zassert_equal(IEEE802154_FILTER_TYPE_SHORT_ADDR, filter_mock_fake.arg2_val);
|
|
zassert_equal(short_add, custom_filter_mock_short_addr);
|
|
RESET_FAKE(filter_mock);
|
|
FFF_RESET_HISTORY();
|
|
|
|
filter_mock_fake.custom_fake = custom_filter_mock;
|
|
otPlatRadioSetExtendedAddress(ot, &ieee_addr);
|
|
zassert_equal(1, filter_mock_fake.call_count);
|
|
zassert_true(filter_mock_fake.arg1_val);
|
|
zassert_equal(IEEE802154_FILTER_TYPE_IEEE_ADDR, filter_mock_fake.arg2_val);
|
|
zassert_mem_equal(ieee_addr.m8, custom_filter_mock_ieee_addr, OT_EXT_ADDRESS_SIZE, NULL);
|
|
}
|
|
|
|
uint8_t alloc_pkt(struct net_pkt **out_packet, uint8_t buf_ct, uint8_t offset)
|
|
{
|
|
struct net_pkt *packet;
|
|
struct net_buf *buf;
|
|
uint8_t len = 0;
|
|
uint8_t buf_num;
|
|
|
|
packet = net_pkt_alloc(K_NO_WAIT);
|
|
for (buf_num = 0; buf_num < buf_ct; buf_num++) {
|
|
buf = net_pkt_get_reserve_tx_data(IEEE802154_MAX_PHY_PACKET_SIZE,
|
|
K_NO_WAIT);
|
|
net_pkt_append_buffer(packet, buf);
|
|
|
|
for (int i = 0; i < buf->size; i++) {
|
|
buf->data[i] = (offset + i + buf_num) & 0xFF;
|
|
}
|
|
|
|
len = buf->size - 3;
|
|
buf->len = len;
|
|
}
|
|
|
|
*out_packet = packet;
|
|
return len;
|
|
}
|
|
|
|
/**
|
|
* @brief Test received messages handling.
|
|
* Tests if received frames are properly passed to the OpenThread
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_receive_test)
|
|
{
|
|
struct net_pkt *packet;
|
|
struct net_buf *buf;
|
|
const uint8_t channel = 21;
|
|
const int8_t power = -5;
|
|
const uint8_t lqi = 240;
|
|
const int8_t rssi = -90;
|
|
uint8_t len;
|
|
|
|
len = alloc_pkt(&packet, 1, 'a');
|
|
buf = packet->buffer;
|
|
|
|
net_pkt_set_ieee802154_lqi(packet, lqi);
|
|
net_pkt_set_ieee802154_rssi_dbm(packet, rssi);
|
|
|
|
zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE,
|
|
"Failed to set TX power.");
|
|
|
|
set_channel_mock_fake.return_val = 0;
|
|
zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE, "Failed to receive.");
|
|
zassert_equal(1, set_channel_mock_fake.call_count);
|
|
zassert_equal(channel, set_channel_mock_fake.arg1_val);
|
|
zassert_equal(1, set_txpower_mock_fake.call_count);
|
|
zassert_equal(power, set_txpower_mock_fake.arg1_val);
|
|
zassert_equal(1, start_mock_fake.call_count);
|
|
zassert_equal_ptr(radio, start_mock_fake.arg0_val, NULL);
|
|
|
|
/*
|
|
* Not setting any expect values as nothing shall be called from
|
|
* notify_new_rx_frame calling thread. OT functions can be called only
|
|
* after semaphore for main thread is released.
|
|
*/
|
|
notify_new_rx_frame(packet);
|
|
|
|
make_sure_sem_set(Z_TIMEOUT_MS(100));
|
|
otPlatRadioReceiveDone_expected_error = OT_ERROR_NONE;
|
|
otPlatRadioReceiveDone_expected_aframe.mChannel = channel;
|
|
otPlatRadioReceiveDone_expected_aframe.mLength = len;
|
|
otPlatRadioReceiveDone_expected_aframe.mPsdu = buf->data;
|
|
platformRadioProcess(ot);
|
|
}
|
|
|
|
/**
|
|
* @brief Test received messages handling.
|
|
* Tests if received frames are properly passed to the OpenThread
|
|
*
|
|
*/
|
|
ZTEST(openthread_radio, test_net_pkt_transmit)
|
|
{
|
|
void *expected_data_ptrs[2];
|
|
struct net_pkt *packet;
|
|
struct net_buf *buf;
|
|
const uint8_t channel = 21;
|
|
const int8_t power = -5;
|
|
uint8_t len;
|
|
|
|
/* success */
|
|
len = alloc_pkt(&packet, 2, 'a');
|
|
buf = packet->buffer;
|
|
zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE,
|
|
"Failed to set TX power.");
|
|
|
|
set_channel_mock_fake.return_val = 0;
|
|
zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE, "Failed to receive.");
|
|
zassert_equal(1, set_channel_mock_fake.call_count);
|
|
zassert_equal(channel, set_channel_mock_fake.arg1_val);
|
|
zassert_equal(1, set_txpower_mock_fake.call_count);
|
|
zassert_equal(power, set_txpower_mock_fake.arg1_val);
|
|
zassert_equal(1, start_mock_fake.call_count);
|
|
zassert_equal_ptr(radio, start_mock_fake.arg0_val, NULL);
|
|
|
|
notify_new_tx_frame(packet);
|
|
|
|
make_sure_sem_set(Z_TIMEOUT_MS(100));
|
|
|
|
otMessageAppend_fake.return_val = OT_ERROR_NONE;
|
|
otIp6Send_fake.return_val = OT_ERROR_NONE;
|
|
|
|
/* Do not expect free in case of success */
|
|
|
|
expected_data_ptrs[0] = buf->data;
|
|
expected_data_ptrs[1] = buf->frags->data;
|
|
platformRadioProcess(ot);
|
|
zassert_equal(2, otMessageAppend_fake.call_count);
|
|
zassert_equal_ptr(ip_msg, otMessageAppend_fake.arg0_history[0], NULL);
|
|
zassert_equal_ptr(ip_msg, otMessageAppend_fake.arg0_history[1], NULL);
|
|
zassert_equal_ptr(expected_data_ptrs[0], otMessageAppend_fake.arg1_history[0], NULL);
|
|
zassert_equal_ptr(expected_data_ptrs[1], otMessageAppend_fake.arg1_history[1], NULL);
|
|
zassert_equal(len, otMessageAppend_fake.arg2_history[0]);
|
|
zassert_equal(len, otMessageAppend_fake.arg2_history[1]);
|
|
zassert_equal(1, otIp6Send_fake.call_count);
|
|
zassert_equal_ptr(ot, otIp6Send_fake.arg0_val, NULL);
|
|
zassert_equal_ptr(ip_msg, otIp6Send_fake.arg1_val, NULL);
|
|
|
|
RESET_FAKE(otMessageAppend);
|
|
RESET_FAKE(otIp6Send);
|
|
FFF_RESET_HISTORY();
|
|
|
|
/* fail on append */
|
|
len = alloc_pkt(&packet, 2, 'b');
|
|
buf = packet->buffer;
|
|
|
|
notify_new_tx_frame(packet);
|
|
|
|
make_sure_sem_set(Z_TIMEOUT_MS(100));
|
|
|
|
otMessageAppend_fake.return_val = OT_ERROR_NO_BUFS;
|
|
expected_data_ptrs[0] = buf->data;
|
|
|
|
platformRadioProcess(ot);
|
|
zassert_equal(1, otMessageAppend_fake.call_count);
|
|
zassert_equal_ptr(ip_msg, otMessageAppend_fake.arg0_val, NULL);
|
|
zassert_equal_ptr(expected_data_ptrs[0], otMessageAppend_fake.arg1_val, NULL);
|
|
zassert_equal(len, otMessageAppend_fake.arg2_val);
|
|
zassert_equal_ptr(ip_msg, otMessageFree_fake.arg0_val, NULL);
|
|
|
|
RESET_FAKE(otMessageAppend);
|
|
FFF_RESET_HISTORY();
|
|
|
|
/* fail on send */
|
|
len = alloc_pkt(&packet, 1, 'c');
|
|
buf = packet->buffer;
|
|
|
|
notify_new_tx_frame(packet);
|
|
|
|
make_sure_sem_set(Z_TIMEOUT_MS(100));
|
|
|
|
otMessageAppend_fake.return_val = OT_ERROR_NONE;
|
|
otIp6Send_fake.return_val = OT_ERROR_BUSY;
|
|
expected_data_ptrs[0] = buf->data;
|
|
|
|
/* Do not expect free in case of failure in send */
|
|
|
|
platformRadioProcess(ot);
|
|
zassert_equal(1, otMessageAppend_fake.call_count);
|
|
zassert_equal_ptr(ip_msg, otMessageAppend_fake.arg0_val, NULL);
|
|
zassert_equal_ptr(expected_data_ptrs[0], otMessageAppend_fake.arg1_val, NULL);
|
|
zassert_equal(len, otMessageAppend_fake.arg2_val);
|
|
zassert_equal(1, otIp6Send_fake.call_count);
|
|
zassert_equal_ptr(ot, otIp6Send_fake.arg0_val, NULL);
|
|
zassert_equal_ptr(ip_msg, otIp6Send_fake.arg1_val, NULL);
|
|
}
|
|
|
|
#ifdef CONFIG_OPENTHREAD_CSL_RECEIVER
|
|
static int64_t custom_configure_csl_rx_time_mock_csl_rx_time;
|
|
static int custom_configure_csl_rx_time(const struct device *dev,
|
|
enum ieee802154_config_type type,
|
|
const struct ieee802154_config *config)
|
|
{
|
|
zassert_equal(dev, radio, "Device handle incorrect.");
|
|
zassert_equal(type, IEEE802154_CONFIG_CSL_RX_TIME, "Config type incorrect.");
|
|
custom_configure_csl_rx_time_mock_csl_rx_time = config->csl_rx_time;
|
|
|
|
return 0;
|
|
}
|
|
|
|
ZTEST(openthread_radio, test_csl_receiver_sample_time)
|
|
{
|
|
uint32_t sample_time = 50U;
|
|
|
|
configure_mock_fake.custom_fake = custom_configure_csl_rx_time;
|
|
otPlatRadioUpdateCslSampleTime(NULL, sample_time);
|
|
zassert_equal(1, configure_mock_fake.call_count);
|
|
zassert_equal(sample_time * NSEC_PER_USEC, custom_configure_csl_rx_time_mock_csl_rx_time);
|
|
}
|
|
|
|
|
|
static struct ieee802154_config custom_configure_rx_slot_mock_config;
|
|
static int custom_configure_csl_rx_slot(const struct device *dev,
|
|
enum ieee802154_config_type type,
|
|
const struct ieee802154_config *config)
|
|
{
|
|
zassert_equal(dev, radio, "Device handle incorrect.");
|
|
zassert_equal(type, IEEE802154_CONFIG_RX_SLOT, "Config type incorrect.");
|
|
custom_configure_rx_slot_mock_config.rx_slot.channel = config->rx_slot.channel;
|
|
custom_configure_rx_slot_mock_config.rx_slot.start = config->rx_slot.start;
|
|
custom_configure_rx_slot_mock_config.rx_slot.duration = config->rx_slot.duration;
|
|
|
|
return 0;
|
|
}
|
|
|
|
ZTEST(openthread_radio, test_csl_receiver_receive_at)
|
|
{
|
|
uint8_t channel = 11U;
|
|
uint32_t start = 1000U;
|
|
uint32_t duration = 100U;
|
|
int res;
|
|
|
|
configure_mock_fake.custom_fake = custom_configure_csl_rx_slot;
|
|
res = otPlatRadioReceiveAt(NULL, channel, start, duration);
|
|
zassert_ok(res);
|
|
zassert_equal(1, configure_mock_fake.call_count);
|
|
zassert_equal(channel, custom_configure_rx_slot_mock_config.rx_slot.channel);
|
|
zassert_equal(start * NSEC_PER_USEC, custom_configure_rx_slot_mock_config.rx_slot.start);
|
|
zassert_equal(duration * NSEC_PER_USEC,
|
|
custom_configure_rx_slot_mock_config.rx_slot.duration);
|
|
}
|
|
#endif
|
|
|
|
static void *openthread_radio_setup(void)
|
|
{
|
|
platformRadioInit();
|
|
return NULL;
|
|
}
|
|
|
|
static void openthread_radio_before(void *f)
|
|
{
|
|
ARG_UNUSED(f);
|
|
RESET_FAKE(scan_mock);
|
|
RESET_FAKE(cca_mock);
|
|
RESET_FAKE(set_channel_mock);
|
|
RESET_FAKE(filter_mock);
|
|
RESET_FAKE(set_txpower_mock);
|
|
RESET_FAKE(tx_mock);
|
|
RESET_FAKE(start_mock);
|
|
RESET_FAKE(stop_mock);
|
|
RESET_FAKE(configure_mock);
|
|
RESET_FAKE(get_capabilities_caps_mock);
|
|
RESET_FAKE(otPlatRadioEnergyScanDone);
|
|
RESET_FAKE(otPlatRadioTxDone);
|
|
RESET_FAKE(otMessageFree);
|
|
FFF_RESET_HISTORY();
|
|
}
|
|
|
|
ZTEST_SUITE(openthread_radio, NULL, openthread_radio_setup, openthread_radio_before, NULL, NULL);
|