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