1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <ztest.h>
8
9 #include <zephyr.h>
10 #include <errno.h>
11 #include <stdio.h>
12
13 #include <net/ieee802154_radio.h>
14 #include <net/net_pkt.h>
15
16 #include <openthread/platform/radio.h>
17 #include <openthread/message.h>
18 #include <platform-zephyr.h>
19
20 /**
21 * @brief Tests for the radio.c - OpenThread radio api
22 * @defgroup openthread_tests radio
23 * @ingroup all_tests
24 * @{
25 */
26
27 #define ACK_PKT_LENGTH 3
28 #define FRAME_TYPE_MASK 0x07
29 #define FRAME_TYPE_ACK 0x02
30
31 K_SEM_DEFINE(ot_sem, 0, 1);
32
33 energy_scan_done_cb_t scan_done_cb;
34
35 /**
36 * Fake pointer as it should not be accessed by the code.
37 * Should not be null to be sure it was properly passed.
38 */
39 otInstance *ot = (otInstance *)0xAAAA;
40 otMessage *ip_msg = (otMessage *)0xBBBB;
41
42 /* forward declarations */
43 static int scan_mock(const struct device *dev, uint16_t duration,
44 energy_scan_done_cb_t done_cb);
45 static enum ieee802154_hw_caps get_capabilities(const struct device *dev);
46 static int cca_mock(const struct device *dev);
47 static int set_channel_mock(const struct device *dev, uint16_t channel);
48 static int filter_mock(const struct device *dev, bool set,
49 enum ieee802154_filter_type type,
50 const struct ieee802154_filter *filter);
51 static int set_txpower_mock(const struct device *dev, int16_t dbm);
52 static int tx_mock(const struct device *dev, enum ieee802154_tx_mode mode,
53 struct net_pkt *pkt, struct net_buf *frag);
54 static int start_mock(const struct device *dev);
55 static int stop_mock(const struct device *dev);
56 static int configure_mock(const struct device *dev,
57 enum ieee802154_config_type type,
58 const struct ieee802154_config *config);
59
60 /* mocks */
61 static struct ieee802154_radio_api rapi = {
62 .get_capabilities = get_capabilities,
63 .cca = cca_mock,
64 .set_channel = set_channel_mock,
65 .filter = filter_mock,
66 .set_txpower = set_txpower_mock,
67 .tx = tx_mock,
68 .start = start_mock,
69 .stop = stop_mock,
70 .configure = configure_mock,
71 #ifdef CONFIG_NET_L2_IEEE802154_SUB_GHZ
72 .get_subg_channel_count = NULL,
73 #endif /* CONFIG_NET_L2_IEEE802154_SUB_GHZ */
74 .ed_scan = scan_mock
75 };
76
77 static struct device radio = { .api = &rapi };
78
scan_mock(const struct device * dev,uint16_t duration,energy_scan_done_cb_t done_cb)79 static int scan_mock(const struct device *dev, uint16_t duration,
80 energy_scan_done_cb_t done_cb)
81 {
82 zassert_equal(dev, &radio, "Device handle incorrect.");
83 ztest_check_expected_value(duration);
84 scan_done_cb = done_cb;
85 return ztest_get_return_value();
86 }
87
rssi_scan_mock(const struct device * dev,uint16_t duration,energy_scan_done_cb_t done_cb)88 static int rssi_scan_mock(const struct device *dev, uint16_t duration,
89 energy_scan_done_cb_t done_cb)
90 {
91 zassert_equal(dev, &radio, "Device handle incorrect.");
92 zassert_equal(duration, 1,
93 "otPlatRadioGetRssi shall pass minimal allowed value.");
94
95 /* use return value as callback param */
96 done_cb(&radio, ztest_get_return_value());
97
98 return 0;
99 }
100
set_channel_mock(const struct device * dev,uint16_t channel)101 static int set_channel_mock(const struct device *dev, uint16_t channel)
102 {
103 zassert_equal(dev, &radio, "Device handle incorrect.");
104 ztest_check_expected_value(channel);
105 return ztest_get_return_value();
106 }
107
otPlatRadioEnergyScanDone(otInstance * aInstance,int8_t aEnergyScanMaxRssi)108 void otPlatRadioEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi)
109 {
110 zassert_equal(aInstance, ot, "Incorrect instance.");
111 ztest_check_expected_value(aEnergyScanMaxRssi);
112 }
113
otSysEventSignalPending(void)114 void otSysEventSignalPending(void)
115 {
116 k_sem_give(&ot_sem);
117 }
118
otTaskletsSignalPending(otInstance * aInstance)119 void otTaskletsSignalPending(otInstance *aInstance)
120 {
121 zassert_equal(aInstance, ot, "Incorrect instance.");
122 k_sem_give(&ot_sem);
123 }
124
make_sure_sem_set(k_timeout_t timeout)125 static void make_sure_sem_set(k_timeout_t timeout)
126 {
127 zassert_equal(k_sem_take(&ot_sem, timeout), 0, "Sem not released.");
128 }
129
otPlatRadioReceiveDone(otInstance * aInstance,otRadioFrame * aFrame,otError aError)130 void otPlatRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame,
131 otError aError)
132 {
133 zassert_equal(aInstance, ot, "Incorrect instance.");
134 ztest_check_expected_value(aFrame->mChannel);
135 ztest_check_expected_value(aFrame->mLength);
136 ztest_check_expected_data(aFrame->mPsdu, aFrame->mLength);
137 ztest_check_expected_value(aError);
138 }
139
otPlatRadioTxDone(otInstance * aInstance,otRadioFrame * aFrame,otRadioFrame * aAckFrame,otError aError)140 void otPlatRadioTxDone(otInstance *aInstance, otRadioFrame *aFrame,
141 otRadioFrame *aAckFrame, otError aError)
142 {
143 zassert_equal(aInstance, ot, "Incorrect instance.");
144 ztest_check_expected_value(aError);
145 }
146
get_capabilities(const struct device * dev)147 static enum ieee802154_hw_caps get_capabilities(const struct device *dev)
148 {
149 zassert_equal(dev, &radio, "Device handle incorrect.");
150
151 return IEEE802154_HW_FCS | IEEE802154_HW_2_4_GHZ |
152 IEEE802154_HW_TX_RX_ACK | IEEE802154_HW_FILTER |
153 IEEE802154_HW_ENERGY_SCAN | IEEE802154_HW_SLEEP_TO_TX;
154 }
155
get_capabilities_caps_mock(const struct device * dev)156 static enum ieee802154_hw_caps get_capabilities_caps_mock(const struct device *dev)
157 {
158 zassert_equal(dev, &radio, "Device handle incorrect.");
159
160 return ztest_get_return_value();
161 }
162
configure_mock(const struct device * dev,enum ieee802154_config_type type,const struct ieee802154_config * config)163 static int configure_mock(const struct device *dev,
164 enum ieee802154_config_type type,
165 const struct ieee802154_config *config)
166 {
167 zassert_equal(dev, &radio, "Device handle incorrect.");
168
169 zassert_equal(type, IEEE802154_CONFIG_EVENT_HANDLER,
170 "Only event handler configuration was expected.");
171
172 return 0;
173 }
174
configure_match_mock(const struct device * dev,enum ieee802154_config_type type,const struct ieee802154_config * config)175 static int configure_match_mock(const struct device *dev,
176 enum ieee802154_config_type type,
177 const struct ieee802154_config *config)
178 {
179 zassert_equal(dev, &radio, "Device handle incorrect.");
180 ztest_check_expected_value(type);
181
182 switch (type) {
183 case IEEE802154_CONFIG_AUTO_ACK_FPB:
184 ztest_check_expected_value(config->auto_ack_fpb.mode);
185 ztest_check_expected_value(config->auto_ack_fpb.enabled);
186 break;
187 case IEEE802154_CONFIG_ACK_FPB:
188 ztest_check_expected_value(config->ack_fpb.extended);
189 ztest_check_expected_value(config->ack_fpb.enabled);
190 ztest_check_expected_data(
191 config->ack_fpb.addr,
192 (config->ack_fpb.extended) ? sizeof(otExtAddress) : 2);
193 break;
194 default:
195 zassert_unreachable("Unexpected config type %d.", type);
196 break;
197 }
198
199 return 0;
200 }
201
configure_promiscuous_mock(const struct device * dev,enum ieee802154_config_type type,const struct ieee802154_config * config)202 static int configure_promiscuous_mock(const struct device *dev,
203 enum ieee802154_config_type type,
204 const struct ieee802154_config *config)
205 {
206 zassert_equal(dev, &radio, "Device handle incorrect.");
207 zassert_equal(type, IEEE802154_CONFIG_PROMISCUOUS,
208 "Config type incorrect.");
209 ztest_check_expected_value(config->promiscuous);
210
211 return 0;
212 }
213
cca_mock(const struct device * dev)214 static int cca_mock(const struct device *dev)
215 {
216 /* not using assert to verify function called */
217 ztest_check_expected_value(dev);
218 return 0;
219 }
220
filter_mock(const struct device * dev,bool set,enum ieee802154_filter_type type,const struct ieee802154_filter * filter)221 static int filter_mock(const struct device *dev, bool set,
222 enum ieee802154_filter_type type,
223 const struct ieee802154_filter *filter)
224 {
225 zassert_equal(dev, &radio, "Device handle incorrect.");
226 ztest_check_expected_value(set);
227 ztest_check_expected_value(type);
228 switch (type) {
229 case IEEE802154_FILTER_TYPE_IEEE_ADDR:
230 ztest_check_expected_data(filter->ieee_addr,
231 OT_EXT_ADDRESS_SIZE);
232 break;
233 case IEEE802154_FILTER_TYPE_SHORT_ADDR:
234 ztest_check_expected_value(filter->short_addr);
235 break;
236 case IEEE802154_FILTER_TYPE_PAN_ID:
237 ztest_check_expected_value(filter->pan_id);
238 break;
239 default:
240 zassert_false(true, "Type not supported in mock: %d.", type);
241 break;
242 }
243 return 0;
244 }
245
set_txpower_mock(const struct device * dev,int16_t dbm)246 static int set_txpower_mock(const struct device *dev, int16_t dbm)
247 {
248 zassert_equal(dev, &radio, "Device handle incorrect.");
249 ztest_check_expected_value(dbm);
250
251 return 0;
252 }
253
tx_mock(const struct device * dev,enum ieee802154_tx_mode mode,struct net_pkt * pkt,struct net_buf * frag)254 static int tx_mock(const struct device *dev, enum ieee802154_tx_mode mode,
255 struct net_pkt *pkt, struct net_buf *frag)
256 {
257 zassert_equal(dev, &radio, "Device handle incorrect.");
258 ztest_check_expected_value(frag->data);
259
260 return 0;
261 }
262
start_mock(const struct device * dev)263 static int start_mock(const struct device *dev)
264 {
265 ztest_check_expected_value(dev);
266 return 0;
267 }
268
stop_mock(const struct device * dev)269 static int stop_mock(const struct device *dev)
270 {
271 ztest_check_expected_value(dev);
272 return 0;
273 }
274
device_get_binding_stub(const char * name)275 const struct device *device_get_binding_stub(const char *name)
276 {
277 return &radio;
278 }
279
otIp6Send(otInstance * aInstance,otMessage * aMessage)280 otError otIp6Send(otInstance *aInstance, otMessage *aMessage)
281 {
282 zassert_equal(aInstance, ot, "Incorrect instance.");
283 ztest_check_expected_value(aMessage);
284 return ztest_get_return_value();
285 }
286
otIp6NewMessage(otInstance * aInstance,const otMessageSettings * aSettings)287 otMessage *otIp6NewMessage(otInstance *aInstance,
288 const otMessageSettings *aSettings)
289 {
290 zassert_equal(aInstance, ot, "Incorrect instance.");
291 return ip_msg;
292 }
293
otMessageAppend(otMessage * aMessage,const void * aBuf,uint16_t aLength)294 otError otMessageAppend(otMessage *aMessage, const void *aBuf, uint16_t aLength)
295 {
296 void *buf = (void *)aBuf;
297
298 ztest_check_expected_value(aMessage);
299 ztest_check_expected_value(aLength);
300 ztest_check_expected_data(buf, aLength);
301 return ztest_get_return_value();
302 }
303
otMessageFree(otMessage * aMessage)304 void otMessageFree(otMessage *aMessage)
305 {
306 ztest_check_expected_value(aMessage);
307 }
308
otPlatRadioTxStarted(otInstance * aInstance,otRadioFrame * aFrame)309 void otPlatRadioTxStarted(otInstance *aInstance, otRadioFrame *aFrame)
310 {
311 zassert_equal(aInstance, ot, "Incorrect instance.");
312 }
313
314 /**
315 * @brief Test for immediate energy scan
316 * Tests for case when radio energy scan returns success at the first call.
317 *
318 */
test_energy_scan_immediate_test(void)319 static void test_energy_scan_immediate_test(void)
320 {
321 const uint8_t chan = 10;
322 const uint8_t dur = 100;
323 const int16_t energy = -94;
324
325 scan_done_cb = NULL;
326
327 ztest_returns_value(set_channel_mock, 0);
328 ztest_expect_value(set_channel_mock, channel, chan);
329
330 ztest_returns_value(scan_mock, 0);
331 ztest_expect_value(scan_mock, duration, dur);
332
333 zassert_equal(otPlatRadioEnergyScan(ot, chan, dur), OT_ERROR_NONE,
334 "Energy scan returned error.");
335 zassert_not_null(scan_done_cb, "Scan callback not specified.");
336
337 scan_done_cb(&radio, energy);
338 make_sure_sem_set(K_NO_WAIT);
339
340 ztest_expect_value(otPlatRadioEnergyScanDone, aEnergyScanMaxRssi,
341 energy);
342 platformRadioProcess(ot);
343 }
344
345 /**
346 * @brief Test for delayed energy scan
347 * Tests for case when radio returns not being able to start energy scan and
348 * the scan should be sheduled for later.
349 *
350 */
test_energy_scan_delayed_test(void)351 static void test_energy_scan_delayed_test(void)
352 {
353 const uint8_t chan = 10;
354 const uint8_t dur = 100;
355 const int16_t energy = -94;
356
357 scan_done_cb = NULL;
358
359 /* request scan */
360 ztest_returns_value(set_channel_mock, 0);
361 ztest_expect_value(set_channel_mock, channel, chan);
362
363 ztest_returns_value(scan_mock, -EBUSY);
364 ztest_expect_value(scan_mock, duration, dur);
365
366 zassert_equal(otPlatRadioEnergyScan(ot, chan, dur), OT_ERROR_NONE,
367 "Energy scan returned error.");
368 zassert_not_null(scan_done_cb, "Scan callback not specified.");
369 make_sure_sem_set(K_NO_WAIT);
370
371 /* process reported event */
372 ztest_returns_value(scan_mock, 0);
373 ztest_expect_value(scan_mock, duration, dur);
374
375 ztest_returns_value(set_channel_mock, 0);
376 ztest_expect_value(set_channel_mock, channel, chan);
377 platformRadioProcess(ot);
378 zassert_not_null(scan_done_cb, "Scan callback not specified.");
379
380 /* invoke scan done */
381 scan_done_cb(&radio, energy);
382 make_sure_sem_set(K_NO_WAIT);
383
384 ztest_expect_value(otPlatRadioEnergyScanDone, aEnergyScanMaxRssi,
385 energy);
386 platformRadioProcess(ot);
387 }
388
create_ack_frame(void)389 static void create_ack_frame(void)
390 {
391 struct net_pkt *packet;
392 struct net_buf *buf;
393 const uint8_t lqi = 230;
394 const int8_t rssi = -80;
395
396 packet = net_pkt_alloc(K_NO_WAIT);
397 buf = net_pkt_get_reserve_tx_data(K_NO_WAIT);
398 net_pkt_append_buffer(packet, buf);
399
400 buf->len = ACK_PKT_LENGTH;
401 buf->data[0] = FRAME_TYPE_ACK;
402
403 net_pkt_set_ieee802154_rssi(packet, rssi);
404 net_pkt_set_ieee802154_lqi(packet, lqi);
405 zassert_equal(ieee802154_radio_handle_ack(NULL, packet), NET_OK,
406 "Handling ack failed.");
407 net_pkt_unref(packet);
408 }
409
410 /**
411 * @brief Test for tx data handling
412 * Tests if OT frame is correctly passed to the radio driver.
413 * Additionally verifies ACK frame passing back to the OT.
414 *
415 */
test_tx_test(void)416 static void test_tx_test(void)
417 {
418 const uint8_t chan = 20;
419 uint8_t chan2 = chan - 1;
420 const int8_t power = -3;
421
422 otRadioFrame *frm = otPlatRadioGetTransmitBuffer(ot);
423
424 zassert_not_null(frm, "Transmit buffer is null.");
425
426 zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE,
427 "Failed to set TX power.");
428
429 ztest_returns_value(set_channel_mock, 0);
430 ztest_expect_value(set_channel_mock, channel, chan);
431 ztest_expect_value(set_txpower_mock, dbm, power);
432 ztest_expect_value(start_mock, dev, &radio);
433 zassert_equal(otPlatRadioReceive(ot, chan), OT_ERROR_NONE,
434 "Failed to receive.");
435
436 /* ACKed frame */
437 frm->mChannel = chan2;
438 frm->mInfo.mTxInfo.mCsmaCaEnabled = true;
439 frm->mPsdu[0] = IEEE802154_AR_FLAG_SET;
440 ztest_returns_value(set_channel_mock, 0);
441 ztest_expect_value(set_channel_mock, channel, chan2);
442 ztest_expect_value(cca_mock, dev, &radio);
443 ztest_expect_value(tx_mock, frag->data, frm->mPsdu);
444 ztest_expect_value(set_txpower_mock, dbm, power);
445 zassert_equal(otPlatRadioTransmit(ot, frm), OT_ERROR_NONE,
446 "Transmit failed.");
447
448 create_ack_frame();
449 make_sure_sem_set(Z_TIMEOUT_MS(100));
450
451 ztest_expect_value(otPlatRadioTxDone, aError, OT_ERROR_NONE);
452 platformRadioProcess(ot);
453
454 /* Non-ACKed frame */
455 frm->mChannel = --chan2;
456 frm->mInfo.mTxInfo.mCsmaCaEnabled = false;
457 frm->mPsdu[0] = 0;
458
459 ztest_returns_value(set_channel_mock, 0);
460 ztest_expect_value(set_channel_mock, channel, chan2);
461 ztest_expect_value(tx_mock, frag->data, frm->mPsdu);
462 ztest_expect_value(set_txpower_mock, dbm, power);
463 zassert_equal(otPlatRadioTransmit(ot, frm), OT_ERROR_NONE,
464 "Transmit failed.");
465 make_sure_sem_set(Z_TIMEOUT_MS(100));
466 ztest_expect_value(otPlatRadioTxDone, aError, OT_ERROR_NONE);
467 platformRadioProcess(ot);
468
469 /* ACKed frame, no ACK */
470 frm->mChannel = --chan2;
471 frm->mInfo.mTxInfo.mCsmaCaEnabled = false;
472 frm->mPsdu[0] = IEEE802154_AR_FLAG_SET;
473
474 ztest_returns_value(set_channel_mock, 0);
475 ztest_expect_value(set_channel_mock, channel, chan2);
476 ztest_expect_value(tx_mock, frag->data, frm->mPsdu);
477 ztest_expect_value(set_txpower_mock, dbm, power);
478 zassert_equal(otPlatRadioTransmit(ot, frm), OT_ERROR_NONE,
479 "Transmit failed.");
480 make_sure_sem_set(Z_TIMEOUT_MS(100));
481
482 ztest_expect_value(otPlatRadioTxDone, aError, OT_ERROR_NO_ACK);
483 platformRadioProcess(ot);
484 }
485
486 /**
487 * @brief Test for tx power setting
488 * Tests if tx power requested by the OT is correctly passed to the radio.
489 *
490 */
test_tx_power_test(void)491 static void test_tx_power_test(void)
492 {
493 int8_t out_power = 0;
494
495 zassert_equal(otPlatRadioSetTransmitPower(ot, -3), OT_ERROR_NONE,
496 "Failed to set TX power.");
497 zassert_equal(otPlatRadioGetTransmitPower(ot, &out_power),
498 OT_ERROR_NONE, "Failed to obtain TX power.");
499 zassert_equal(out_power, -3, "Got different power than set.");
500 zassert_equal(otPlatRadioSetTransmitPower(ot, -6), OT_ERROR_NONE,
501 "Failed to set TX power.");
502 zassert_equal(otPlatRadioGetTransmitPower(ot, &out_power),
503 OT_ERROR_NONE, "Failed to obtain TX power.");
504 zassert_equal(out_power, -6,
505 "Second call to otPlatRadioSetTransmitPower failed.");
506 }
507
508 /**
509 * @brief Test for getting radio sensitivity
510 * There is no api to get radio sensitivity from the radio so the value is
511 * hardcoded in radio.c. Test only verifies if the value returned makes any
512 * sense.
513 *
514 */
test_sensitivity_test(void)515 static void test_sensitivity_test(void)
516 {
517 /*
518 * Nothing to test actually as this is constant 100.
519 * When radio interface will be extended to get sensitivity this test
520 * can be extended with the radio api call. For now just verify if the
521 * value is reasonable.
522 */
523 zassert_true(-80 > otPlatRadioGetReceiveSensitivity(ot),
524 "Radio sensitivity not in range.");
525 }
526
set_expected_match_values(enum ieee802154_config_type type,uint8_t * addr,bool extended,bool enabled)527 static void set_expected_match_values(enum ieee802154_config_type type,
528 uint8_t *addr, bool extended, bool enabled)
529 {
530 ztest_expect_value(configure_match_mock, type, type);
531 switch (type) {
532 case IEEE802154_CONFIG_AUTO_ACK_FPB:
533 ztest_expect_value(configure_match_mock,
534 config->auto_ack_fpb.enabled, enabled);
535 ztest_expect_value(configure_match_mock,
536 config->auto_ack_fpb.mode,
537 IEEE802154_FPB_ADDR_MATCH_THREAD);
538 break;
539 case IEEE802154_CONFIG_ACK_FPB:
540 ztest_expect_value(configure_match_mock,
541 config->ack_fpb.extended, extended);
542 ztest_expect_value(configure_match_mock,
543 config->ack_fpb.enabled, enabled);
544 ztest_expect_data(configure_match_mock, config->ack_fpb.addr,
545 addr);
546 break;
547 default:
548 break;
549 }
550 }
551
552 /**
553 * @brief Test different types of OT source match.
554 * Tests if Enable, Disable, Add and Clear Source Match calls are passed to the
555 * radio driver correctly.
556 *
557 */
test_source_match_test(void)558 static void test_source_match_test(void)
559 {
560 otExtAddress ext_addr;
561
562 rapi.configure = configure_match_mock;
563 /* Enable/Disable */
564 set_expected_match_values(IEEE802154_CONFIG_AUTO_ACK_FPB, NULL, false,
565 true);
566 otPlatRadioEnableSrcMatch(ot, true);
567 set_expected_match_values(IEEE802154_CONFIG_AUTO_ACK_FPB, NULL, false,
568 false);
569 otPlatRadioEnableSrcMatch(ot, false);
570
571 set_expected_match_values(IEEE802154_CONFIG_AUTO_ACK_FPB, NULL, false,
572 true);
573 otPlatRadioEnableSrcMatch(ot, true);
574
575 /* Add */
576 sys_put_le16(12345, ext_addr.m8);
577 set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, ext_addr.m8, false,
578 true);
579 zassert_equal(otPlatRadioAddSrcMatchShortEntry(ot, 12345),
580 OT_ERROR_NONE, "Failed to add short src entry.");
581
582
583 for (int i = 0; i < sizeof(ext_addr.m8); i++) {
584 ext_addr.m8[i] = i;
585 }
586 set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, ext_addr.m8, true,
587 true);
588 zassert_equal(otPlatRadioAddSrcMatchExtEntry(ot, &ext_addr),
589 OT_ERROR_NONE, "Failed to add ext src entry.");
590
591 /* Clear */
592 sys_put_le16(12345, ext_addr.m8);
593 set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, ext_addr.m8, false,
594 false);
595 zassert_equal(otPlatRadioClearSrcMatchShortEntry(ot, 12345),
596 OT_ERROR_NONE, "Failed to clear short src entry.");
597
598 set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, ext_addr.m8, true,
599 false);
600 zassert_equal(otPlatRadioClearSrcMatchExtEntry(ot, &ext_addr),
601 OT_ERROR_NONE, "Failed to clear ext src entry.");
602
603 set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, NULL, false,
604 false);
605 otPlatRadioClearSrcMatchShortEntries(ot);
606
607 set_expected_match_values(IEEE802154_CONFIG_ACK_FPB, NULL, true, false);
608 otPlatRadioClearSrcMatchExtEntries(ot);
609
610 rapi.configure = configure_mock;
611 }
612
613 /**
614 * @brief Test for enabling or disabling promiscuous mode
615 * Tests if OT can successfully enable or disable promiscuous mode.
616 *
617 */
test_promiscuous_mode_set_test(void)618 static void test_promiscuous_mode_set_test(void)
619 {
620 rapi.configure = configure_promiscuous_mock;
621
622 zassert_false(otPlatRadioGetPromiscuous(ot),
623 "By default promiscuous mode shall be disabled.");
624
625 ztest_expect_value(configure_promiscuous_mock, config->promiscuous,
626 true);
627 otPlatRadioSetPromiscuous(ot, true);
628 zassert_true(otPlatRadioGetPromiscuous(ot), "Mode not enabled.");
629
630 ztest_expect_value(configure_promiscuous_mock, config->promiscuous,
631 false);
632 otPlatRadioSetPromiscuous(ot, false);
633 zassert_false(otPlatRadioGetPromiscuous(ot), "Mode still enabled.");
634
635 rapi.configure = configure_mock;
636 }
637
638 /**
639 * @brief Test of proper radio to OT capabilities mapping
640 * Tests if different radio capabilities map for their corresponding OpenThread
641 * capability
642 *
643 */
test_get_caps_test(void)644 static void test_get_caps_test(void)
645 {
646 rapi.get_capabilities = get_capabilities_caps_mock;
647
648 /* no caps */
649 ztest_returns_value(get_capabilities_caps_mock, 0);
650 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
651 "Incorrect capabilities returned.");
652
653 /* not used by OT */
654 ztest_returns_value(get_capabilities_caps_mock, IEEE802154_HW_FCS);
655 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
656 "Incorrect capabilities returned.");
657 ztest_returns_value(get_capabilities_caps_mock, IEEE802154_HW_2_4_GHZ);
658 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
659 "Incorrect capabilities returned.");
660 ztest_returns_value(get_capabilities_caps_mock, IEEE802154_HW_SUB_GHZ);
661 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
662 "Incorrect capabilities returned.");
663
664 /* not implemented or not fully supported */
665 ztest_returns_value(get_capabilities_caps_mock, IEEE802154_HW_TXTIME);
666 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
667 "Incorrect capabilities returned.");
668
669 ztest_returns_value(get_capabilities_caps_mock, IEEE802154_HW_PROMISC);
670 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_NONE,
671 "Incorrect capabilities returned.");
672
673 /* proper mapping */
674 ztest_returns_value(get_capabilities_caps_mock, IEEE802154_HW_CSMA);
675 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_CSMA_BACKOFF,
676 "Incorrect capabilities returned.");
677
678 ztest_returns_value(get_capabilities_caps_mock,
679 IEEE802154_HW_ENERGY_SCAN);
680 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_ENERGY_SCAN,
681 "Incorrect capabilities returned.");
682
683 ztest_returns_value(get_capabilities_caps_mock,
684 IEEE802154_HW_TX_RX_ACK);
685 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_ACK_TIMEOUT,
686 "Incorrect capabilities returned.");
687
688 ztest_returns_value(get_capabilities_caps_mock,
689 IEEE802154_HW_SLEEP_TO_TX);
690 zassert_equal(otPlatRadioGetCaps(ot), OT_RADIO_CAPS_SLEEP_TO_TX,
691 "Incorrect capabilities returned.");
692
693 /* all at once */
694 ztest_returns_value(
695 get_capabilities_caps_mock,
696 IEEE802154_HW_FCS | IEEE802154_HW_PROMISC |
697 IEEE802154_HW_FILTER | IEEE802154_HW_CSMA |
698 IEEE802154_HW_2_4_GHZ | IEEE802154_HW_TX_RX_ACK |
699 IEEE802154_HW_SUB_GHZ | IEEE802154_HW_ENERGY_SCAN |
700 IEEE802154_HW_TXTIME | IEEE802154_HW_SLEEP_TO_TX);
701 zassert_equal(
702 otPlatRadioGetCaps(ot),
703 OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_ENERGY_SCAN |
704 OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_SLEEP_TO_TX,
705 "Incorrect capabilities returned.");
706
707 rapi.get_capabilities = get_capabilities;
708 }
709
710 /**
711 * @brief Test for getting the rssi value from the radio
712 * Tests if correct value is returned from the otPlatRadioGetRssi function.
713 *
714 */
test_get_rssi_test(void)715 static void test_get_rssi_test(void)
716 {
717 const int8_t rssi = -103;
718
719 rapi.ed_scan = rssi_scan_mock;
720
721 ztest_returns_value(rssi_scan_mock, rssi);
722 zassert_equal(otPlatRadioGetRssi(ot), rssi,
723 "Invalid RSSI value reveiced.");
724
725 rapi.ed_scan = scan_mock;
726 }
727
728 /**
729 * @brief Test switching between radio states
730 * Tests if radio is correctly switched between states.
731 *
732 */
test_radio_state_test(void)733 static void test_radio_state_test(void)
734 {
735 const uint8_t channel = 12;
736 const uint8_t power = 10;
737
738 zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE,
739 "Failed to set TX power.");
740 zassert_equal(otPlatRadioDisable(ot), OT_ERROR_NONE,
741 "Failed to disable radio.");
742
743 zassert_false(otPlatRadioIsEnabled(ot), "Radio reports as enabled.");
744
745 zassert_equal(otPlatRadioSleep(ot), OT_ERROR_INVALID_STATE,
746 "Changed to sleep regardles being disabled.");
747
748 zassert_equal(otPlatRadioEnable(ot), OT_ERROR_NONE,
749 "Enabling radio failed.");
750
751 zassert_true(otPlatRadioIsEnabled(ot), "Radio reports disabled.");
752
753 ztest_expect_value(stop_mock, dev, &radio);
754 zassert_equal(otPlatRadioSleep(ot), OT_ERROR_NONE,
755 "Failed to switch to sleep mode.");
756
757 zassert_true(otPlatRadioIsEnabled(ot), "Radio reports as disabled.");
758
759 ztest_returns_value(set_channel_mock, 0);
760 ztest_expect_value(set_channel_mock, channel, channel);
761 ztest_expect_value(set_txpower_mock, dbm, power);
762 ztest_expect_value(start_mock, dev, &radio);
763 zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE,
764 "Failed to receive.");
765 zassert_equal(platformRadioChannelGet(ot), channel,
766 "Channel number not remembered.");
767
768 zassert_true(otPlatRadioIsEnabled(ot), "Radio reports as disabled.");
769 }
770
771 /**
772 * @brief Test address filtering
773 * Tests if short, extended address and PanID are correctly passed to the radio
774 * driver.
775 *
776 */
test_address_test(void)777 static void test_address_test(void)
778 {
779 const uint16_t pan_id = 0xDEAD;
780 const uint16_t short_add = 0xCAFE;
781 otExtAddress ieee_addr;
782
783 for (int i = 0; i < sizeof(ieee_addr.m8); i++) {
784 ieee_addr.m8[i] = 'a' + i;
785 }
786
787 ztest_expect_value(filter_mock, set, true);
788 ztest_expect_value(filter_mock, type, IEEE802154_FILTER_TYPE_PAN_ID);
789 ztest_expect_value(filter_mock, filter->pan_id, pan_id);
790 otPlatRadioSetPanId(ot, pan_id);
791
792 ztest_expect_value(filter_mock, set, true);
793 ztest_expect_value(filter_mock, type,
794 IEEE802154_FILTER_TYPE_SHORT_ADDR);
795 ztest_expect_value(filter_mock, filter->short_addr, short_add);
796 otPlatRadioSetShortAddress(ot, short_add);
797
798 ztest_expect_value(filter_mock, set, true);
799 ztest_expect_value(filter_mock, type, IEEE802154_FILTER_TYPE_IEEE_ADDR);
800 ztest_expect_data(filter_mock, filter->ieee_addr, ieee_addr.m8);
801 otPlatRadioSetExtendedAddress(ot, &ieee_addr);
802 }
803
804
alloc_pkt(struct net_pkt ** out_packet,uint8_t buf_ct,uint8_t offset)805 uint8_t alloc_pkt(struct net_pkt **out_packet, uint8_t buf_ct, uint8_t offset)
806 {
807 struct net_pkt *packet;
808 struct net_buf *buf;
809 uint8_t len = 0;
810 uint8_t buf_num;
811
812 packet = net_pkt_alloc(K_NO_WAIT);
813 for (buf_num = 0; buf_num < buf_ct; buf_num++) {
814 buf = net_pkt_get_reserve_tx_data(K_NO_WAIT);
815 net_pkt_append_buffer(packet, buf);
816
817 for (int i = 0; i < buf->size; i++) {
818 buf->data[i] = (offset + i + buf_num) & 0xFF;
819 }
820
821 len = buf->size - 3;
822 buf->len = len;
823 }
824
825 *out_packet = packet;
826 return len;
827 }
828
829 /**
830 * @brief Test received messages handling.
831 * Tests if received frames are properly passed to the OpenThread
832 *
833 */
test_receive_test(void)834 static void test_receive_test(void)
835 {
836 struct net_pkt *packet;
837 struct net_buf *buf;
838 const uint8_t channel = 21;
839 const int8_t power = -5;
840 const uint8_t lqi = 240;
841 const int8_t rssi = -90;
842 uint8_t len;
843
844 len = alloc_pkt(&packet, 1, 'a');
845 buf = packet->buffer;
846
847 net_pkt_set_ieee802154_lqi(packet, lqi);
848 net_pkt_set_ieee802154_rssi(packet, rssi);
849
850 zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE,
851 "Failed to set TX power.");
852
853 ztest_returns_value(set_channel_mock, 0);
854 ztest_expect_value(set_channel_mock, channel, channel);
855 ztest_expect_value(set_txpower_mock, dbm, power);
856 ztest_expect_value(start_mock, dev, &radio);
857 zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE,
858 "Failed to receive.");
859
860 /*
861 * Not setting any expect values as nothing shall be called from
862 * notify_new_rx_frame calling thread. OT functions can be called only
863 * after semaphore for main thread is released.
864 */
865 notify_new_rx_frame(packet);
866
867 make_sure_sem_set(Z_TIMEOUT_MS(100));
868 ztest_expect_value(otPlatRadioReceiveDone, aError, OT_ERROR_NONE);
869 ztest_expect_value(otPlatRadioReceiveDone, aFrame->mChannel, channel);
870 ztest_expect_value(otPlatRadioReceiveDone, aFrame->mLength, len);
871 ztest_expect_data(otPlatRadioReceiveDone, aFrame->mPsdu, buf->data);
872 platformRadioProcess(ot);
873 }
874
875 /**
876 * @brief Test received messages handling.
877 * Tests if received frames are properly passed to the OpenThread
878 *
879 */
test_net_pkt_transmit(void)880 static void test_net_pkt_transmit(void)
881 {
882 struct net_pkt *packet;
883 struct net_buf *buf;
884 const uint8_t channel = 21;
885 const int8_t power = -5;
886 uint8_t len;
887
888 /* success */
889 len = alloc_pkt(&packet, 2, 'a');
890 buf = packet->buffer;
891 zassert_equal(otPlatRadioSetTransmitPower(ot, power), OT_ERROR_NONE,
892 "Failed to set TX power.");
893
894 ztest_returns_value(set_channel_mock, 0);
895 ztest_expect_value(set_channel_mock, channel, channel);
896 ztest_expect_value(set_txpower_mock, dbm, power);
897 ztest_expect_value(start_mock, dev, &radio);
898 zassert_equal(otPlatRadioReceive(ot, channel), OT_ERROR_NONE,
899 "Failed to receive.");
900
901 notify_new_tx_frame(packet);
902
903 make_sure_sem_set(Z_TIMEOUT_MS(100));
904
905 ztest_expect_value(otMessageAppend, aMessage, ip_msg);
906 ztest_expect_value(otMessageAppend, aLength, len);
907 ztest_expect_data(otMessageAppend, buf, buf->data);
908 ztest_returns_value(otMessageAppend, OT_ERROR_NONE);
909
910 buf = buf->frags;
911 ztest_expect_value(otMessageAppend, aMessage, ip_msg);
912 ztest_expect_value(otMessageAppend, aLength, len);
913 ztest_expect_data(otMessageAppend, buf, buf->data);
914 ztest_returns_value(otMessageAppend, OT_ERROR_NONE);
915
916 ztest_expect_value(otIp6Send, aMessage, ip_msg);
917 ztest_returns_value(otIp6Send, OT_ERROR_NONE);
918
919 /* Do not expect free in case of success */
920
921 platformRadioProcess(ot);
922
923 /* fail on append */
924 len = alloc_pkt(&packet, 2, 'b');
925 buf = packet->buffer;
926
927 notify_new_tx_frame(packet);
928
929 make_sure_sem_set(Z_TIMEOUT_MS(100));
930
931 ztest_expect_value(otMessageAppend, aMessage, ip_msg);
932 ztest_expect_value(otMessageAppend, aLength, len);
933 ztest_expect_data(otMessageAppend, buf, buf->data);
934 ztest_returns_value(otMessageAppend, OT_ERROR_NO_BUFS);
935
936 /* Expect free in case of failure in appending buffer*/
937 ztest_expect_value(otMessageFree, aMessage, ip_msg);
938
939 platformRadioProcess(ot);
940
941 /* fail on send */
942 len = alloc_pkt(&packet, 1, 'c');
943 buf = packet->buffer;
944
945 notify_new_tx_frame(packet);
946
947 make_sure_sem_set(Z_TIMEOUT_MS(100));
948
949 ztest_expect_value(otMessageAppend, aMessage, ip_msg);
950 ztest_expect_value(otMessageAppend, aLength, len);
951 ztest_expect_data(otMessageAppend, buf, buf->data);
952 ztest_returns_value(otMessageAppend, OT_ERROR_NONE);
953
954 ztest_expect_value(otIp6Send, aMessage, ip_msg);
955 ztest_returns_value(otIp6Send, OT_ERROR_BUSY);
956
957 /* Do not expect free in case of failure in send */
958
959 platformRadioProcess(ot);
960
961 }
962
test_main(void)963 void test_main(void)
964 {
965 platformRadioInit();
966
967 ztest_test_suite(openthread_radio,
968 ztest_unit_test(test_energy_scan_immediate_test),
969 ztest_unit_test(test_energy_scan_delayed_test),
970 ztest_unit_test(test_tx_test),
971 ztest_unit_test(test_tx_power_test),
972 ztest_unit_test(test_sensitivity_test),
973 ztest_unit_test(test_source_match_test),
974 ztest_unit_test(test_promiscuous_mode_set_test),
975 ztest_unit_test(test_get_caps_test),
976 ztest_unit_test(test_get_rssi_test),
977 ztest_unit_test(test_radio_state_test),
978 ztest_unit_test(test_address_test),
979 ztest_unit_test(test_receive_test),
980 ztest_unit_test(test_net_pkt_transmit));
981
982
983 ztest_run_test_suite(openthread_radio);
984 }
985