1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/ztest.h>
11 #include <zephyr/net/net_if.h>
12 #include <zephyr/net/ieee802154_radio.h>
13 
14 #define TEST_FLAG_SET (NET_L2_MULTICAST | NET_L2_PROMISC_MODE)
15 #define TEST_PAYLOAD "TEST PAYLOAD"
16 
17 static struct test_data {
18 	bool state;
19 	struct net_pkt *tx_pkt;
20 	struct net_pkt *rx_pkt;
21 } test_data;
22 
custom_l2_recv(struct net_if * iface,struct net_pkt * pkt)23 static inline enum net_verdict custom_l2_recv(struct net_if *iface,
24 					      struct net_pkt *pkt)
25 {
26 	test_data.rx_pkt = pkt;
27 
28 	return NET_OK;
29 }
30 
custom_l2_send(struct net_if * iface,struct net_pkt * pkt)31 static inline int custom_l2_send(struct net_if *iface, struct net_pkt *pkt)
32 {
33 	test_data.tx_pkt = pkt;
34 
35 	return net_pkt_get_len(pkt);
36 }
37 
custom_l2_enable(struct net_if * iface,bool state)38 static int custom_l2_enable(struct net_if *iface, bool state)
39 {
40 	test_data.state = state;
41 
42 	return 0;
43 }
44 
custom_l2_flags(struct net_if * iface)45 static enum net_l2_flags custom_l2_flags(struct net_if *iface)
46 {
47 	return TEST_FLAG_SET;
48 }
49 
50 NET_L2_INIT(CUSTOM_IEEE802154_L2, custom_l2_recv, custom_l2_send,
51 	    custom_l2_enable, custom_l2_flags);
52 
dummy_iface_init(struct net_if * iface)53 static void dummy_iface_init(struct net_if *iface)
54 {
55 	static uint8_t mac[8] = { 0x00, 0x11, 0x22, 0x33,
56 				  0x44, 0x55, 0x66, 0x77 };
57 
58 	net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);
59 }
60 
61 static struct ieee802154_radio_api dummy_radio_api = {
62 	.iface_api.init	= dummy_iface_init,
63 };
64 
65 NET_DEVICE_INIT(dummy, "dummy_ieee802154", NULL, NULL, NULL, NULL,
66 		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
67 		&dummy_radio_api, CUSTOM_IEEE802154_L2,
68 		NET_L2_GET_CTX_TYPE(CUSTOM_IEEE802154_L2),
69 		CONFIG_NET_L2_CUSTOM_IEEE802154_MTU);
70 
ZTEST(ieee802154_custom_l2,test_send)71 ZTEST(ieee802154_custom_l2, test_send)
72 {
73 	int ret;
74 	struct net_pkt *tx_pkt;
75 	struct net_if *iface = net_if_get_first_by_type(
76 					&NET_L2_GET_NAME(CUSTOM_IEEE802154));
77 
78 	zassert_not_null(net_if_l2(iface), "No L2 found");
79 	zassert_not_null(net_if_l2(iface)->send, "No send() found");
80 
81 	tx_pkt = net_pkt_alloc_with_buffer(iface, sizeof(TEST_PAYLOAD),
82 					   AF_UNSPEC, 0, K_NO_WAIT);
83 	zassert_not_null(tx_pkt, "Failed to allocate packet");
84 
85 	ret = net_pkt_write(tx_pkt, TEST_PAYLOAD, sizeof(TEST_PAYLOAD));
86 	zassert_equal(0, ret, "Failed to write payload");
87 
88 	ret = net_send_data(tx_pkt);
89 	zassert_equal(0, ret, "Failed to process TX packet");
90 	zassert_equal(tx_pkt, test_data.tx_pkt, "TX packet did not reach L2");
91 
92 	net_pkt_unref(tx_pkt);
93 }
94 
ZTEST(ieee802154_custom_l2,test_recv)95 ZTEST(ieee802154_custom_l2, test_recv)
96 {
97 	int ret;
98 	struct net_pkt *rx_pkt;
99 	struct net_if *iface = net_if_get_first_by_type(
100 					&NET_L2_GET_NAME(CUSTOM_IEEE802154));
101 
102 	zassert_not_null(net_if_l2(iface), "No L2 found");
103 	zassert_not_null(net_if_l2(iface)->recv, "No recv () found");
104 
105 	rx_pkt = net_pkt_rx_alloc_with_buffer(iface, sizeof(TEST_PAYLOAD),
106 					      AF_UNSPEC, 0, K_NO_WAIT);
107 	zassert_not_null(rx_pkt, "Failed to allocate packet");
108 
109 	ret = net_pkt_write(rx_pkt, TEST_PAYLOAD, sizeof(TEST_PAYLOAD));
110 	zassert_equal(0, ret, "Failed to write payload");
111 
112 	ret = net_recv_data(iface, rx_pkt);
113 	zassert_equal(0, ret, "Failed to process RX packet");
114 	zassert_equal(rx_pkt, test_data.rx_pkt, "RX packet did not reach L2");
115 
116 	net_pkt_unref(rx_pkt);
117 }
118 
ZTEST(ieee802154_custom_l2,test_enable)119 ZTEST(ieee802154_custom_l2, test_enable)
120 {
121 	int ret;
122 	struct net_if *iface = net_if_get_first_by_type(
123 					&NET_L2_GET_NAME(CUSTOM_IEEE802154));
124 
125 	zassert_not_null(net_if_l2(iface), "No L2 found");
126 	zassert_not_null(net_if_l2(iface)->enable, "No enable() found");
127 
128 	ret = net_if_down(iface);
129 	zassert_equal(0, ret, "Failed to set iface down");
130 	zassert_false(test_data.state, "L2 up");
131 
132 	ret = net_if_up(iface);
133 	zassert_equal(0, ret, "Failed to set iface up");
134 	zassert_true(test_data.state, "L2 down");
135 }
136 
ZTEST(ieee802154_custom_l2,test_flags)137 ZTEST(ieee802154_custom_l2, test_flags)
138 {
139 	enum net_l2_flags flags;
140 	struct net_if *iface = net_if_get_first_by_type(
141 					&NET_L2_GET_NAME(CUSTOM_IEEE802154));
142 	zassert_not_null(net_if_l2(iface), "No L2 found");
143 	zassert_not_null(net_if_l2(iface)->get_flags, "No get_flags() found");
144 
145 	flags = net_if_l2(iface)->get_flags(iface);
146 	zassert_equal(TEST_FLAG_SET, flags, "Invalid flags");
147 }
148 
149 ZTEST_SUITE(ieee802154_custom_l2, NULL, NULL, NULL, NULL, NULL);
150