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 > 127) {
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 		struct net_buf *frag;
132 
133 		pkt = net_pkt_rx_alloc(K_NO_WAIT);
134 		if (!pkt) {
135 			LOG_DBG("No pkt available");
136 			goto flush;
137 		}
138 
139 		frag = net_pkt_get_frag(pkt, upipe->rx_len, K_NO_WAIT);
140 		if (!frag) {
141 			LOG_DBG("No fragment available");
142 			goto out;
143 		}
144 
145 		net_pkt_frag_insert(pkt, frag);
146 
147 		memcpy(frag->data, upipe->rx_buf, upipe->rx_len);
148 		net_buf_add(frag, upipe->rx_len);
149 
150 #if defined(CONFIG_IEEE802154_UPIPE_HW_FILTER)
151 		if (received_dest_addr_matched(frag->data) == false) {
152 			LOG_DBG("Packet received is not addressed to me");
153 			goto out;
154 		}
155 #endif
156 
157 		if (ieee802154_handle_ack(upipe->iface, pkt) == NET_OK) {
158 			LOG_DBG("ACK packet handled");
159 			goto out;
160 		}
161 
162 		LOG_DBG("Caught a packet (%u)", upipe->rx_len);
163 		if (net_recv_data(upipe->iface, pkt) < 0) {
164 			LOG_DBG("Packet dropped by NET stack");
165 			goto out;
166 		}
167 
168 		goto flush;
169 out:
170 		net_pkt_unref(pkt);
171 flush:
172 		upipe->rx = false;
173 		upipe->rx_len = 0U;
174 		upipe->rx_off = 0U;
175 	}
176 done:
177 	*off = 0;
178 
179 	return buf;
180 }
181 
upipe_get_capabilities(const struct device * dev)182 static enum ieee802154_hw_caps upipe_get_capabilities(const struct device *dev)
183 {
184 	return IEEE802154_HW_FCS | IEEE802154_HW_FILTER;
185 }
186 
upipe_cca(const struct device * dev)187 static int upipe_cca(const struct device *dev)
188 {
189 	struct upipe_context *upipe = dev->data;
190 
191 	if (upipe->stopped) {
192 		return -EIO;
193 	}
194 
195 	return 0;
196 }
197 
upipe_set_channel(const struct device * dev,uint16_t channel)198 static int upipe_set_channel(const struct device *dev, uint16_t channel)
199 {
200 	ARG_UNUSED(dev);
201 	ARG_UNUSED(channel);
202 
203 	return 0;
204 }
205 
upipe_set_pan_id(const struct device * dev,uint16_t pan_id)206 static int upipe_set_pan_id(const struct device *dev, uint16_t pan_id)
207 {
208 	uint8_t pan_id_le[2];
209 
210 	ARG_UNUSED(dev);
211 
212 	sys_put_le16(pan_id, pan_id_le);
213 	memcpy(dev_pan_id, pan_id_le, PAN_ID_SIZE);
214 
215 	return 0;
216 }
217 
upipe_set_short_addr(const struct device * dev,uint16_t short_addr)218 static int upipe_set_short_addr(const struct device *dev, uint16_t short_addr)
219 {
220 	uint8_t short_addr_le[2];
221 
222 	ARG_UNUSED(dev);
223 
224 	sys_put_le16(short_addr, short_addr_le);
225 	memcpy(dev_short_addr, short_addr_le, SHORT_ADDRESS_SIZE);
226 
227 	return 0;
228 }
229 
upipe_set_ieee_addr(const struct device * dev,const uint8_t * ieee_addr)230 static int upipe_set_ieee_addr(const struct device *dev,
231 			       const uint8_t *ieee_addr)
232 {
233 	ARG_UNUSED(dev);
234 
235 	memcpy(dev_ext_addr, ieee_addr, EXTENDED_ADDRESS_SIZE);
236 
237 	return 0;
238 }
239 
upipe_filter(const struct device * dev,bool set,enum ieee802154_filter_type type,const struct ieee802154_filter * filter)240 static int upipe_filter(const struct device *dev,
241 			bool set,
242 			enum ieee802154_filter_type type,
243 			const struct ieee802154_filter *filter)
244 {
245 	LOG_DBG("Applying filter %u", type);
246 
247 	if (!set) {
248 		return -ENOTSUP;
249 	}
250 
251 	if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
252 		return upipe_set_ieee_addr(dev, filter->ieee_addr);
253 	} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
254 		return upipe_set_short_addr(dev, filter->short_addr);
255 	} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
256 		return upipe_set_pan_id(dev, filter->pan_id);
257 	}
258 
259 	return -ENOTSUP;
260 }
261 
upipe_set_txpower(const struct device * dev,int16_t dbm)262 static int upipe_set_txpower(const struct device *dev, int16_t dbm)
263 {
264 	ARG_UNUSED(dev);
265 	ARG_UNUSED(dbm);
266 
267 	return 0;
268 }
269 
upipe_tx(const struct device * dev,enum ieee802154_tx_mode mode,struct net_pkt * pkt,struct net_buf * frag)270 static int upipe_tx(const struct device *dev,
271 		    enum ieee802154_tx_mode mode,
272 		    struct net_pkt *pkt,
273 		    struct net_buf *frag)
274 {
275 	struct upipe_context *upipe = dev->data;
276 	uint8_t *pkt_buf = frag->data;
277 	uint8_t len = frag->len;
278 	uint8_t i, data;
279 
280 	if (mode != IEEE802154_TX_MODE_DIRECT) {
281 		NET_ERR("TX mode %d not supported", mode);
282 		return -ENOTSUP;
283 	}
284 
285 	LOG_DBG("%p (%u)", frag, len);
286 
287 	if (upipe->stopped) {
288 		return -EIO;
289 	}
290 
291 	data = UART_PIPE_RADIO_15_4_FRAME_TYPE;
292 	uart_pipe_send(&data, 1);
293 
294 	data = len;
295 	uart_pipe_send(&data, 1);
296 
297 	for (i = 0U; i < len; i++) {
298 		uart_pipe_send(pkt_buf+i, 1);
299 	}
300 
301 	return 0;
302 }
303 
upipe_start(const struct device * dev)304 static int upipe_start(const struct device *dev)
305 {
306 	struct upipe_context *upipe = dev->data;
307 
308 	if (!upipe->stopped) {
309 		return -EALREADY;
310 	}
311 
312 	upipe->stopped = false;
313 
314 	return 0;
315 }
316 
upipe_stop(const struct device * dev)317 static int upipe_stop(const struct device *dev)
318 {
319 	struct upipe_context *upipe = dev->data;
320 
321 	if (upipe->stopped) {
322 		return -EALREADY;
323 	}
324 
325 	upipe->stopped = true;
326 
327 	return 0;
328 }
329 
330 /* driver-allocated attribute memory - constant across all driver instances */
331 IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26);
332 
333 /* API implementation: attr_get */
upipe_attr_get(const struct device * dev,enum ieee802154_attr attr,struct ieee802154_attr_value * value)334 static int upipe_attr_get(const struct device *dev, enum ieee802154_attr attr,
335 			  struct ieee802154_attr_value *value)
336 {
337 	ARG_UNUSED(dev);
338 
339 	return ieee802154_attr_get_channel_page_and_range(
340 		attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915,
341 		&drv_attr.phy_supported_channels, value);
342 }
343 
upipe_init(const struct device * dev)344 static int upipe_init(const struct device *dev)
345 {
346 	struct upipe_context *upipe = dev->data;
347 
348 	(void)memset(upipe, 0, sizeof(struct upipe_context));
349 
350 	uart_pipe_register(upipe->uart_pipe_buf, 1, upipe_rx);
351 
352 	upipe_stop(dev);
353 
354 	return 0;
355 }
356 
get_mac(const struct device * dev)357 static inline uint8_t *get_mac(const struct device *dev)
358 {
359 	struct upipe_context *upipe = dev->data;
360 
361 	upipe->mac_addr[0] = 0x00;
362 	upipe->mac_addr[1] = 0x10;
363 	upipe->mac_addr[2] = 0x20;
364 	upipe->mac_addr[3] = 0x30;
365 
366 #if defined(CONFIG_IEEE802154_UPIPE_RANDOM_MAC)
367 	UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()),
368 		      (uint32_t *) ((uint8_t *)upipe->mac_addr+4));
369 #else
370 	upipe->mac_addr[4] = CONFIG_IEEE802154_UPIPE_MAC4;
371 	upipe->mac_addr[5] = CONFIG_IEEE802154_UPIPE_MAC5;
372 	upipe->mac_addr[6] = CONFIG_IEEE802154_UPIPE_MAC6;
373 	upipe->mac_addr[7] = CONFIG_IEEE802154_UPIPE_MAC7;
374 #endif
375 
376 	return upipe->mac_addr;
377 }
378 
upipe_iface_init(struct net_if * iface)379 static void upipe_iface_init(struct net_if *iface)
380 {
381 	const struct device *dev = net_if_get_device(iface);
382 	struct upipe_context *upipe = dev->data;
383 	uint8_t *mac = get_mac(dev);
384 
385 	net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);
386 
387 	upipe_dev = dev;
388 	upipe->iface = iface;
389 
390 	ieee802154_init(iface);
391 }
392 
393 static struct upipe_context upipe_context_data;
394 
395 static struct ieee802154_radio_api upipe_radio_api = {
396 	.iface_api.init		= upipe_iface_init,
397 
398 	.get_capabilities	= upipe_get_capabilities,
399 	.cca			= upipe_cca,
400 	.set_channel		= upipe_set_channel,
401 	.filter			= upipe_filter,
402 	.set_txpower		= upipe_set_txpower,
403 	.tx			= upipe_tx,
404 	.start			= upipe_start,
405 	.stop			= upipe_stop,
406 	.attr_get		= upipe_attr_get,
407 };
408 
409 NET_DEVICE_DT_INST_DEFINE(0, upipe_init, NULL, &upipe_context_data, NULL,
410 			  CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &upipe_radio_api,
411 			  IEEE802154_L2, NET_L2_GET_CTX_TYPE(IEEE802154_L2),
412 			  125);
413