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