1 /*
2  * Copyright (c) 2016 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT zephyr_ieee802154_uart_pipe
8 
9 #define LOG_MODULE_NAME ieee802154_uart_pipe
10 #define LOG_LEVEL CONFIG_IEEE802154_DRIVER_LOG_LEVEL
11 
12 #include <zephyr/logging/log.h>
13 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
14 
15 #include <errno.h>
16 
17 #include <zephyr/kernel.h>
18 #include <zephyr/arch/cpu.h>
19 
20 #include <zephyr/device.h>
21 #include <zephyr/init.h>
22 #include <zephyr/net/net_if.h>
23 #include <zephyr/net/net_pkt.h>
24 #include <zephyr/random/random.h>
25 
26 #include <zephyr/drivers/uart_pipe.h>
27 #include <zephyr/net/ieee802154_radio.h>
28 
29 #include "ieee802154_uart_pipe.h"
30 
31 #define PAN_ID_OFFSET           3 /* Pan Id offset */
32 #define DEST_ADDR_OFFSET        5 /* Destination offset address*/
33 #define DEST_ADDR_TYPE_OFFSET   1 /* Destination address type */
34 
35 #define DEST_ADDR_TYPE_MASK     0x0c /* Mask for destination address type */
36 
37 #define DEST_ADDR_TYPE_SHORT    0x08 /* Short destination address type */
38 #define DEST_ADDR_TYPE_EXTENDED 0x0c /* Extended destination address type */
39 
40 #define PAN_ID_SIZE           2    /* Size of Pan Id */
41 #define SHORT_ADDRESS_SIZE    2    /* Size of Short Mac Address */
42 #define EXTENDED_ADDRESS_SIZE 8    /* Size of Extended Mac Address */
43 
44 /* Broadcast Short Address */
45 #define BROADCAST_ADDRESS    ((uint8_t [SHORT_ADDRESS_SIZE]) {0xff, 0xff})
46 
47 static uint8_t dev_pan_id[PAN_ID_SIZE];             /* Device Pan Id */
48 static uint8_t dev_short_addr[SHORT_ADDRESS_SIZE];  /* Device Short Address */
49 static uint8_t dev_ext_addr[EXTENDED_ADDRESS_SIZE]; /* Device Extended Address */
50 
51 /** Singleton device used in uart pipe callback */
52 static const struct device *upipe_dev;
53 
54 #if defined(CONFIG_IEEE802154_UPIPE_HW_FILTER)
55 
received_dest_addr_matched(uint8_t * rx_buffer)56 static bool received_dest_addr_matched(uint8_t *rx_buffer)
57 {
58 	struct upipe_context *upipe = upipe_dev->data;
59 
60 	/* Check destination PAN Id */
61 	if (memcmp(&rx_buffer[PAN_ID_OFFSET],
62 		   dev_pan_id, PAN_ID_SIZE) != 0 &&
63 	    memcmp(&rx_buffer[PAN_ID_OFFSET],
64 		   BROADCAST_ADDRESS, PAN_ID_SIZE) != 0) {
65 		return false;
66 	}
67 
68 	/* Check destination address */
69 	switch (rx_buffer[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK) {
70 	case DEST_ADDR_TYPE_SHORT:
71 		/* First check if the destination is broadcast */
72 		/* If not broadcast, check if length and address matches */
73 		if (memcmp(&rx_buffer[DEST_ADDR_OFFSET],
74 			   BROADCAST_ADDRESS,
75 			   SHORT_ADDRESS_SIZE) != 0 &&
76 		    (net_if_get_link_addr(upipe->iface)->len !=
77 		     SHORT_ADDRESS_SIZE ||
78 		     memcmp(&rx_buffer[DEST_ADDR_OFFSET],
79 			    dev_short_addr,
80 			    SHORT_ADDRESS_SIZE) != 0)) {
81 			return false;
82 		}
83 	break;
84 
85 	case DEST_ADDR_TYPE_EXTENDED:
86 		/* If not broadcast, check if length and address matches */
87 		if (net_if_get_link_addr(upipe->iface)->len !=
88 		    EXTENDED_ADDRESS_SIZE ||
89 		    memcmp(&rx_buffer[DEST_ADDR_OFFSET],
90 			   dev_ext_addr, EXTENDED_ADDRESS_SIZE) != 0) {
91 			return false;
92 		}
93 		break;
94 
95 	default:
96 		return false;
97 	}
98 
99 	return true;
100 }
101 
102 #endif
103 
upipe_rx(uint8_t * buf,size_t * off)104 static uint8_t *upipe_rx(uint8_t *buf, size_t *off)
105 {
106 	struct net_pkt *pkt = NULL;
107 	struct upipe_context *upipe;
108 
109 	if (!upipe_dev) {
110 		goto done;
111 	}
112 
113 	upipe = upipe_dev->data;
114 	if (!upipe->rx && *buf == UART_PIPE_RADIO_15_4_FRAME_TYPE) {
115 		upipe->rx = true;
116 		goto done;
117 	}
118 
119 	if (!upipe->rx_len) {
120 		if (*buf > IEEE802154_MAX_PHY_PACKET_SIZE) {
121 			goto flush;
122 		}
123 
124 		upipe->rx_len = *buf;
125 		goto done;
126 	}
127 
128 	upipe->rx_buf[upipe->rx_off++] = *buf;
129 
130 	if (upipe->rx_len == upipe->rx_off) {
131 		pkt = net_pkt_rx_alloc_with_buffer(upipe->iface, upipe->rx_len,
132 						   AF_UNSPEC, 0, K_NO_WAIT);
133 		if (!pkt) {
134 			LOG_DBG("No pkt available");
135 			goto flush;
136 		}
137 
138 		if (net_pkt_write(pkt, upipe->rx_buf, upipe->rx_len)) {
139 			LOG_DBG("No content read?");
140 			goto out;
141 		}
142 
143 #if defined(CONFIG_IEEE802154_UPIPE_HW_FILTER)
144 		if (received_dest_addr_matched(pkt->buffer->data) == false) {
145 			LOG_DBG("Packet received is not addressed to me");
146 			goto out;
147 		}
148 #endif
149 
150 		if (ieee802154_handle_ack(upipe->iface, pkt) == NET_OK) {
151 			LOG_DBG("ACK packet handled");
152 			goto out;
153 		}
154 
155 		LOG_DBG("Caught a packet (%u)", upipe->rx_len);
156 		if (net_recv_data(upipe->iface, pkt) < 0) {
157 			LOG_DBG("Packet dropped by NET stack");
158 			goto out;
159 		}
160 
161 		goto flush;
162 out:
163 		net_pkt_unref(pkt);
164 flush:
165 		upipe->rx = false;
166 		upipe->rx_len = 0U;
167 		upipe->rx_off = 0U;
168 	}
169 done:
170 	*off = 0;
171 
172 	return buf;
173 }
174 
upipe_get_capabilities(const struct device * dev)175 static enum ieee802154_hw_caps upipe_get_capabilities(const struct device *dev)
176 {
177 	return IEEE802154_HW_FCS | IEEE802154_HW_FILTER;
178 }
179 
upipe_cca(const struct device * dev)180 static int upipe_cca(const struct device *dev)
181 {
182 	struct upipe_context *upipe = dev->data;
183 
184 	if (upipe->stopped) {
185 		return -EIO;
186 	}
187 
188 	return 0;
189 }
190 
upipe_set_channel(const struct device * dev,uint16_t channel)191 static int upipe_set_channel(const struct device *dev, uint16_t channel)
192 {
193 	ARG_UNUSED(dev);
194 	ARG_UNUSED(channel);
195 
196 	return 0;
197 }
198 
upipe_set_pan_id(const struct device * dev,uint16_t pan_id)199 static int upipe_set_pan_id(const struct device *dev, uint16_t pan_id)
200 {
201 	uint8_t pan_id_le[2];
202 
203 	ARG_UNUSED(dev);
204 
205 	sys_put_le16(pan_id, pan_id_le);
206 	memcpy(dev_pan_id, pan_id_le, PAN_ID_SIZE);
207 
208 	return 0;
209 }
210 
upipe_set_short_addr(const struct device * dev,uint16_t short_addr)211 static int upipe_set_short_addr(const struct device *dev, uint16_t short_addr)
212 {
213 	uint8_t short_addr_le[2];
214 
215 	ARG_UNUSED(dev);
216 
217 	sys_put_le16(short_addr, short_addr_le);
218 	memcpy(dev_short_addr, short_addr_le, SHORT_ADDRESS_SIZE);
219 
220 	return 0;
221 }
222 
upipe_set_ieee_addr(const struct device * dev,const uint8_t * ieee_addr)223 static int upipe_set_ieee_addr(const struct device *dev,
224 			       const uint8_t *ieee_addr)
225 {
226 	ARG_UNUSED(dev);
227 
228 	memcpy(dev_ext_addr, ieee_addr, EXTENDED_ADDRESS_SIZE);
229 
230 	return 0;
231 }
232 
upipe_filter(const struct device * dev,bool set,enum ieee802154_filter_type type,const struct ieee802154_filter * filter)233 static int upipe_filter(const struct device *dev,
234 			bool set,
235 			enum ieee802154_filter_type type,
236 			const struct ieee802154_filter *filter)
237 {
238 	LOG_DBG("Applying filter %u", type);
239 
240 	if (!set) {
241 		return -ENOTSUP;
242 	}
243 
244 	if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
245 		return upipe_set_ieee_addr(dev, filter->ieee_addr);
246 	} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
247 		return upipe_set_short_addr(dev, filter->short_addr);
248 	} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
249 		return upipe_set_pan_id(dev, filter->pan_id);
250 	}
251 
252 	return -ENOTSUP;
253 }
254 
upipe_set_txpower(const struct device * dev,int16_t dbm)255 static int upipe_set_txpower(const struct device *dev, int16_t dbm)
256 {
257 	ARG_UNUSED(dev);
258 	ARG_UNUSED(dbm);
259 
260 	return 0;
261 }
262 
upipe_tx(const struct device * dev,enum ieee802154_tx_mode mode,struct net_pkt * pkt,struct net_buf * frag)263 static int upipe_tx(const struct device *dev,
264 		    enum ieee802154_tx_mode mode,
265 		    struct net_pkt *pkt,
266 		    struct net_buf *frag)
267 {
268 	struct upipe_context *upipe = dev->data;
269 	uint8_t *pkt_buf = frag->data;
270 	uint8_t len = frag->len;
271 	uint8_t i, data;
272 
273 	if (mode != IEEE802154_TX_MODE_DIRECT) {
274 		NET_ERR("TX mode %d not supported", mode);
275 		return -ENOTSUP;
276 	}
277 
278 	LOG_DBG("%p (%u)", frag, len);
279 
280 	if (upipe->stopped) {
281 		return -EIO;
282 	}
283 
284 	data = UART_PIPE_RADIO_15_4_FRAME_TYPE;
285 	uart_pipe_send(&data, 1);
286 
287 	data = len;
288 	uart_pipe_send(&data, 1);
289 
290 	for (i = 0U; i < len; i++) {
291 		uart_pipe_send(pkt_buf+i, 1);
292 	}
293 
294 	return 0;
295 }
296 
upipe_start(const struct device * dev)297 static int upipe_start(const struct device *dev)
298 {
299 	struct upipe_context *upipe = dev->data;
300 
301 	if (!upipe->stopped) {
302 		return -EALREADY;
303 	}
304 
305 	upipe->stopped = false;
306 
307 	return 0;
308 }
309 
upipe_stop(const struct device * dev)310 static int upipe_stop(const struct device *dev)
311 {
312 	struct upipe_context *upipe = dev->data;
313 
314 	if (upipe->stopped) {
315 		return -EALREADY;
316 	}
317 
318 	upipe->stopped = true;
319 
320 	return 0;
321 }
322 
323 /* driver-allocated attribute memory - constant across all driver instances */
324 IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26);
325 
326 /* API implementation: attr_get */
upipe_attr_get(const struct device * dev,enum ieee802154_attr attr,struct ieee802154_attr_value * value)327 static int upipe_attr_get(const struct device *dev, enum ieee802154_attr attr,
328 			  struct ieee802154_attr_value *value)
329 {
330 	ARG_UNUSED(dev);
331 
332 	return ieee802154_attr_get_channel_page_and_range(
333 		attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915,
334 		&drv_attr.phy_supported_channels, value);
335 }
336 
upipe_init(const struct device * dev)337 static int upipe_init(const struct device *dev)
338 {
339 	struct upipe_context *upipe = dev->data;
340 
341 	(void)memset(upipe, 0, sizeof(struct upipe_context));
342 
343 	uart_pipe_register(upipe->uart_pipe_buf, 1, upipe_rx);
344 
345 	upipe_stop(dev);
346 
347 	return 0;
348 }
349 
get_mac(const struct device * dev)350 static inline uint8_t *get_mac(const struct device *dev)
351 {
352 	struct upipe_context *upipe = dev->data;
353 
354 	upipe->mac_addr[0] = 0x00;
355 	upipe->mac_addr[1] = 0x10;
356 	upipe->mac_addr[2] = 0x20;
357 	upipe->mac_addr[3] = 0x30;
358 
359 #if defined(CONFIG_IEEE802154_UPIPE_RANDOM_MAC)
360 	sys_rand_get(&upipe->mac_addr[4], 4U);
361 #else
362 	upipe->mac_addr[4] = CONFIG_IEEE802154_UPIPE_MAC4;
363 	upipe->mac_addr[5] = CONFIG_IEEE802154_UPIPE_MAC5;
364 	upipe->mac_addr[6] = CONFIG_IEEE802154_UPIPE_MAC6;
365 	upipe->mac_addr[7] = CONFIG_IEEE802154_UPIPE_MAC7;
366 #endif
367 
368 	return upipe->mac_addr;
369 }
370 
upipe_iface_init(struct net_if * iface)371 static void upipe_iface_init(struct net_if *iface)
372 {
373 	const struct device *dev = net_if_get_device(iface);
374 	struct upipe_context *upipe = dev->data;
375 	uint8_t *mac = get_mac(dev);
376 
377 	net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);
378 
379 	upipe_dev = dev;
380 	upipe->iface = iface;
381 
382 	ieee802154_init(iface);
383 }
384 
385 static struct upipe_context upipe_context_data;
386 
387 static const struct ieee802154_radio_api upipe_radio_api = {
388 	.iface_api.init		= upipe_iface_init,
389 
390 	.get_capabilities	= upipe_get_capabilities,
391 	.cca			= upipe_cca,
392 	.set_channel		= upipe_set_channel,
393 	.filter			= upipe_filter,
394 	.set_txpower		= upipe_set_txpower,
395 	.tx			= upipe_tx,
396 	.start			= upipe_start,
397 	.stop			= upipe_stop,
398 	.attr_get		= upipe_attr_get,
399 };
400 
401 NET_DEVICE_DT_INST_DEFINE(0, upipe_init, NULL, &upipe_context_data, NULL,
402 			  CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &upipe_radio_api,
403 			  IEEE802154_L2, NET_L2_GET_CTX_TYPE(IEEE802154_L2),
404 			  IEEE802154_MTU);
405