1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_l2_openthread, CONFIG_OPENTHREAD_L2_LOG_LEVEL);
9 
10 #include <zephyr/net/net_core.h>
11 #include <zephyr/net/net_pkt.h>
12 #include <zephyr/net/net_mgmt.h>
13 #include <zephyr/net/openthread.h>
14 
15 #include <net_private.h>
16 
17 #include <zephyr/init.h>
18 #include <zephyr/sys/check.h>
19 #include <zephyr/sys/slist.h>
20 #include <zephyr/sys/util.h>
21 #include <zephyr/sys/__assert.h>
22 #include <zephyr/version.h>
23 
24 #include <openthread/cli.h>
25 #include <openthread/ip6.h>
26 #include <openthread/link.h>
27 #include <openthread/link_raw.h>
28 #include <openthread/ncp.h>
29 #include <openthread/message.h>
30 #include <openthread/platform/diag.h>
31 #include <openthread/tasklet.h>
32 #include <openthread/thread.h>
33 #include <openthread/dataset.h>
34 #include <openthread/joiner.h>
35 #include <openthread-system.h>
36 #include <utils/uart.h>
37 
38 #include <platform-zephyr.h>
39 
40 #include "openthread_utils.h"
41 
42 #if defined(CONFIG_OPENTHREAD_NAT64_TRANSLATOR)
43 #include <openthread/nat64.h>
44 #endif  /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */
45 
46 #define PKT_IS_IPv4(_p) ((NET_IPV6_HDR(_p)->vtc & 0xf0) == 0x40)
47 
48 #define OT_STACK_SIZE (CONFIG_OPENTHREAD_THREAD_STACK_SIZE)
49 
50 #if defined(CONFIG_OPENTHREAD_THREAD_PREEMPTIVE)
51 #define OT_PRIORITY K_PRIO_PREEMPT(CONFIG_OPENTHREAD_THREAD_PRIORITY)
52 #else
53 #define OT_PRIORITY K_PRIO_COOP(CONFIG_OPENTHREAD_THREAD_PRIORITY)
54 #endif
55 
56 #if defined(CONFIG_OPENTHREAD_NETWORK_NAME)
57 #define OT_NETWORK_NAME CONFIG_OPENTHREAD_NETWORK_NAME
58 #else
59 #define OT_NETWORK_NAME ""
60 #endif
61 
62 #if defined(CONFIG_OPENTHREAD_CHANNEL)
63 #define OT_CHANNEL CONFIG_OPENTHREAD_CHANNEL
64 #else
65 #define OT_CHANNEL 0
66 #endif
67 
68 #if defined(CONFIG_OPENTHREAD_PANID)
69 #define OT_PANID CONFIG_OPENTHREAD_PANID
70 #else
71 #define OT_PANID 0
72 #endif
73 
74 #if defined(CONFIG_OPENTHREAD_XPANID)
75 #define OT_XPANID CONFIG_OPENTHREAD_XPANID
76 #else
77 #define OT_XPANID ""
78 #endif
79 
80 #if defined(CONFIG_OPENTHREAD_NETWORKKEY)
81 #define OT_NETWORKKEY CONFIG_OPENTHREAD_NETWORKKEY
82 #else
83 #define OT_NETWORKKEY ""
84 #endif
85 
86 #if defined(CONFIG_OPENTHREAD_JOINER_PSKD)
87 #define OT_JOINER_PSKD CONFIG_OPENTHREAD_JOINER_PSKD
88 #else
89 #define OT_JOINER_PSKD ""
90 #endif
91 
92 #if defined(CONFIG_OPENTHREAD_PLATFORM_INFO)
93 #define OT_PLATFORM_INFO CONFIG_OPENTHREAD_PLATFORM_INFO
94 #else
95 #define OT_PLATFORM_INFO ""
96 #endif
97 
98 #if defined(CONFIG_OPENTHREAD_POLL_PERIOD)
99 #define OT_POLL_PERIOD CONFIG_OPENTHREAD_POLL_PERIOD
100 #else
101 #define OT_POLL_PERIOD 0
102 #endif
103 
104 #define ZEPHYR_PACKAGE_NAME "Zephyr"
105 #define PACKAGE_VERSION KERNEL_VERSION_STRING
106 
107 extern void platformShellInit(otInstance *aInstance);
108 
109 K_KERNEL_STACK_DEFINE(ot_stack_area, OT_STACK_SIZE);
110 
111 static struct net_linkaddr *ll_addr;
112 static otStateChangedCallback state_changed_cb;
113 
openthread_thread_id_get(void)114 k_tid_t openthread_thread_id_get(void)
115 {
116 	struct openthread_context *ot_context = openthread_get_default_context();
117 
118 	return ot_context ? (k_tid_t)&ot_context->work_q.thread : 0;
119 }
120 
121 #ifdef CONFIG_NET_MGMT_EVENT
122 static struct net_mgmt_event_callback ip6_addr_cb;
123 
ipv6_addr_event_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)124 static void ipv6_addr_event_handler(struct net_mgmt_event_callback *cb,
125 				    uint32_t mgmt_event, struct net_if *iface)
126 {
127 	if (net_if_l2(iface) != &NET_L2_GET_NAME(OPENTHREAD)) {
128 		return;
129 	}
130 
131 #ifdef CONFIG_NET_MGMT_EVENT_INFO
132 	struct openthread_context *ot_context = net_if_l2_data(iface);
133 
134 	if (cb->info == NULL || cb->info_length != sizeof(struct in6_addr)) {
135 		return;
136 	}
137 
138 	if (mgmt_event == NET_EVENT_IPV6_ADDR_ADD) {
139 		add_ipv6_addr_to_ot(ot_context, (const struct in6_addr *)cb->info);
140 	} else if (mgmt_event == NET_EVENT_IPV6_MADDR_ADD) {
141 		add_ipv6_maddr_to_ot(ot_context, (const struct in6_addr *)cb->info);
142 	}
143 #else
144 	NET_WARN("No address info provided with event, "
145 		 "please enable CONFIG_NET_MGMT_EVENT_INFO");
146 #endif /* CONFIG_NET_MGMT_EVENT_INFO */
147 }
148 #endif /* CONFIG_NET_MGMT_EVENT */
149 
ncp_hdlc_send(const uint8_t * buf,uint16_t len)150 static int ncp_hdlc_send(const uint8_t *buf, uint16_t len)
151 {
152 	otError err;
153 
154 	err = otPlatUartSend(buf, len);
155 	if (err != OT_ERROR_NONE) {
156 		return 0;
157 	}
158 
159 	return len;
160 }
161 
162 #ifndef CONFIG_HDLC_RCP_IF
otPlatRadioGetIeeeEui64(otInstance * instance,uint8_t * ieee_eui64)163 void otPlatRadioGetIeeeEui64(otInstance *instance, uint8_t *ieee_eui64)
164 {
165 	ARG_UNUSED(instance);
166 
167 	memcpy(ieee_eui64, ll_addr->addr, ll_addr->len);
168 }
169 #endif /* CONFIG_HDLC_RCP_IF */
170 
otTaskletsSignalPending(otInstance * instance)171 void otTaskletsSignalPending(otInstance *instance)
172 {
173 	struct openthread_context *ot_context = openthread_get_default_context();
174 
175 	if (ot_context) {
176 		k_work_submit_to_queue(&ot_context->work_q, &ot_context->api_work);
177 	}
178 }
179 
otSysEventSignalPending(void)180 void otSysEventSignalPending(void)
181 {
182 	otTaskletsSignalPending(NULL);
183 }
184 
ot_state_changed_handler(uint32_t flags,void * context)185 static void ot_state_changed_handler(uint32_t flags, void *context)
186 {
187 	struct openthread_state_changed_cb *entry, *next;
188 	struct openthread_context *ot_context = context;
189 
190 	NET_INFO("State changed! Flags: 0x%08" PRIx32 " Current role: %s",
191 		flags,
192 		otThreadDeviceRoleToString(otThreadGetDeviceRole(ot_context->instance))
193 		);
194 
195 	if (flags & OT_CHANGED_THREAD_ROLE) {
196 		switch (otThreadGetDeviceRole(ot_context->instance)) {
197 		case OT_DEVICE_ROLE_CHILD:
198 		case OT_DEVICE_ROLE_ROUTER:
199 		case OT_DEVICE_ROLE_LEADER:
200 			net_if_dormant_off(ot_context->iface);
201 			break;
202 
203 		case OT_DEVICE_ROLE_DISABLED:
204 		case OT_DEVICE_ROLE_DETACHED:
205 		default:
206 			net_if_dormant_on(ot_context->iface);
207 			break;
208 		}
209 	}
210 
211 	if (flags & OT_CHANGED_IP6_ADDRESS_REMOVED) {
212 		NET_DBG("Ipv6 address removed");
213 		rm_ipv6_addr_from_zephyr(ot_context);
214 	}
215 
216 	if (flags & OT_CHANGED_IP6_ADDRESS_ADDED) {
217 		NET_DBG("Ipv6 address added");
218 		add_ipv6_addr_to_zephyr(ot_context);
219 	}
220 
221 	if (flags & OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED) {
222 		NET_DBG("Ipv6 multicast address removed");
223 		rm_ipv6_maddr_from_zephyr(ot_context);
224 	}
225 
226 	if (flags & OT_CHANGED_IP6_MULTICAST_SUBSCRIBED) {
227 		NET_DBG("Ipv6 multicast address added");
228 		add_ipv6_maddr_to_zephyr(ot_context);
229 	}
230 
231 #if defined(CONFIG_OPENTHREAD_NAT64_TRANSLATOR)
232 
233 	if (flags & OT_CHANGED_NAT64_TRANSLATOR_STATE) {
234 		NET_DBG("Nat64 translator state changed to %x",
235 			otNat64GetTranslatorState(ot_context->instance));
236 	}
237 
238 #endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */
239 
240 	if (state_changed_cb) {
241 		state_changed_cb(flags, context);
242 	}
243 
244 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&ot_context->state_change_cbs, entry, next, node) {
245 		if (entry->state_changed_cb != NULL) {
246 			entry->state_changed_cb(flags, ot_context, entry->user_data);
247 		}
248 	}
249 }
250 
ot_receive_handler(otMessage * aMessage,void * context)251 static void ot_receive_handler(otMessage *aMessage, void *context)
252 {
253 	struct openthread_context *ot_context = context;
254 
255 	uint16_t offset = 0U;
256 	uint16_t read_len;
257 	struct net_pkt *pkt;
258 	struct net_buf *pkt_buf;
259 
260 	pkt = net_pkt_rx_alloc_with_buffer(ot_context->iface,
261 					   otMessageGetLength(aMessage),
262 					   AF_UNSPEC, 0, K_NO_WAIT);
263 	if (!pkt) {
264 		NET_ERR("Failed to reserve net pkt");
265 		goto out;
266 	}
267 
268 	pkt_buf = pkt->buffer;
269 
270 	while (1) {
271 		read_len = otMessageRead(aMessage, offset, pkt_buf->data,
272 					 net_buf_tailroom(pkt_buf));
273 		if (!read_len) {
274 			break;
275 		}
276 
277 		net_buf_add(pkt_buf, read_len);
278 
279 		offset += read_len;
280 
281 		if (!net_buf_tailroom(pkt_buf)) {
282 			pkt_buf = pkt_buf->frags;
283 			if (!pkt_buf) {
284 				break;
285 			}
286 		}
287 	}
288 
289 	NET_DBG("Injecting %s packet to Zephyr net stack",
290 		PKT_IS_IPv4(pkt) ? "translated IPv4" : "Ip6");
291 
292 	if (IS_ENABLED(CONFIG_OPENTHREAD_L2_DEBUG_DUMP_IPV6)) {
293 		if (IS_ENABLED(CONFIG_OPENTHREAD_NAT64_TRANSLATOR) && PKT_IS_IPv4(pkt)) {
294 			net_pkt_hexdump(pkt, "Received NAT64 IPv4 packet");
295 		} else {
296 			net_pkt_hexdump(pkt, "Received IPv6 packet");
297 		}
298 	}
299 
300 	if (!pkt_list_is_full(ot_context)) {
301 		if (pkt_list_add(ot_context, pkt) != 0) {
302 			NET_ERR("pkt_list_add failed");
303 			goto out;
304 		}
305 
306 		if (net_recv_data(ot_context->iface, pkt) < 0) {
307 			NET_ERR("net_recv_data failed");
308 			pkt_list_remove_first(ot_context);
309 			goto out;
310 		}
311 
312 		pkt = NULL;
313 	} else {
314 		NET_INFO("Packet list is full");
315 	}
316 out:
317 	if (pkt) {
318 		net_pkt_unref(pkt);
319 	}
320 
321 	otMessageFree(aMessage);
322 }
323 
ot_joiner_start_handler(otError error,void * context)324 static void ot_joiner_start_handler(otError error, void *context)
325 {
326 	struct openthread_context *ot_context = context;
327 
328 	switch (error) {
329 	case OT_ERROR_NONE:
330 		NET_INFO("Join success");
331 		otThreadSetEnabled(ot_context->instance, true);
332 		break;
333 	default:
334 		NET_ERR("Join failed [%d]", error);
335 		break;
336 	}
337 }
338 
openthread_process(struct k_work * work)339 static void openthread_process(struct k_work *work)
340 {
341 	struct openthread_context *ot_context
342 		= CONTAINER_OF(work, struct openthread_context, api_work);
343 
344 	openthread_api_mutex_lock(ot_context);
345 
346 	while (otTaskletsArePending(ot_context->instance)) {
347 		otTaskletsProcess(ot_context->instance);
348 	}
349 
350 	otSysProcessDrivers(ot_context->instance);
351 
352 	openthread_api_mutex_unlock(ot_context);
353 }
354 
is_ipv6_frag(struct net_pkt * pkt)355 static bool is_ipv6_frag(struct net_pkt *pkt)
356 {
357 	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(ipv6_access, struct net_ipv6_hdr);
358 	struct net_ipv6_hdr *hdr;
359 
360 	hdr = (struct net_ipv6_hdr *)net_pkt_get_data(pkt, &ipv6_access);
361 	if (!hdr) {
362 		return false;
363 	}
364 
365 	return hdr->nexthdr == NET_IPV6_NEXTHDR_FRAG ? true : false;
366 }
367 
openthread_recv(struct net_if * iface,struct net_pkt * pkt)368 static enum net_verdict openthread_recv(struct net_if *iface, struct net_pkt *pkt)
369 {
370 	struct openthread_context *ot_context = net_if_l2_data(iface);
371 
372 	if (pkt_list_peek(ot_context) == pkt) {
373 		pkt_list_remove_last(ot_context);
374 		NET_DBG("Got injected Ip6 packet, sending to upper layers");
375 
376 		if (IS_ENABLED(CONFIG_OPENTHREAD_L2_DEBUG_DUMP_IPV6)) {
377 			net_pkt_hexdump(pkt, "Injected IPv6 packet");
378 		}
379 
380 		if (IS_ENABLED(CONFIG_OPENTHREAD_IP6_FRAGM) && is_ipv6_frag(pkt)) {
381 			return NET_DROP;
382 		}
383 
384 		return NET_CONTINUE;
385 	}
386 
387 	NET_DBG("Got 802.15.4 packet, sending to OT");
388 
389 	if (IS_ENABLED(CONFIG_OPENTHREAD_L2_DEBUG_DUMP_IPV6)) {
390 		net_pkt_hexdump(pkt, "Received 802.15.4 frame");
391 	}
392 
393 	if (notify_new_rx_frame(pkt) != 0) {
394 		NET_ERR("Failed to queue RX packet for OpenThread");
395 		return NET_DROP;
396 	}
397 
398 	return NET_OK;
399 }
400 
openthread_send(struct net_if * iface,struct net_pkt * pkt)401 int openthread_send(struct net_if *iface, struct net_pkt *pkt)
402 {
403 	int len = net_pkt_get_len(pkt);
404 
405 	if (IS_ENABLED(CONFIG_OPENTHREAD_L2_DEBUG_DUMP_IPV6)) {
406 		net_pkt_hexdump(pkt, "IPv6 packet to send");
407 	}
408 
409 	net_capture_pkt(iface, pkt);
410 
411 	if (notify_new_tx_frame(pkt) != 0) {
412 		net_pkt_unref(pkt);
413 	}
414 
415 	return len;
416 }
417 
openthread_start(struct openthread_context * ot_context)418 int openthread_start(struct openthread_context *ot_context)
419 {
420 	otInstance *ot_instance = ot_context->instance;
421 	otError error = OT_ERROR_NONE;
422 
423 	openthread_api_mutex_lock(ot_context);
424 
425 	NET_INFO("OpenThread version: %s", otGetVersionString());
426 
427 	if (IS_ENABLED(CONFIG_OPENTHREAD_COPROCESSOR)) {
428 		NET_DBG("OpenThread co-processor.");
429 		goto exit;
430 	}
431 
432 	otIp6SetEnabled(ot_context->instance, true);
433 
434 	/* Sleepy End Device specific configuration. */
435 	if (IS_ENABLED(CONFIG_OPENTHREAD_MTD_SED)) {
436 		otLinkModeConfig ot_mode = otThreadGetLinkMode(ot_instance);
437 
438 		/* A SED should always attach the network as a SED to indicate
439 		 * increased buffer requirement to a parent.
440 		 */
441 		ot_mode.mRxOnWhenIdle = false;
442 
443 		otThreadSetLinkMode(ot_context->instance, ot_mode);
444 		otLinkSetPollPeriod(ot_context->instance, OT_POLL_PERIOD);
445 	}
446 
447 	if (otDatasetIsCommissioned(ot_instance)) {
448 		/* OpenThread already has dataset stored - skip the
449 		 * configuration.
450 		 */
451 		NET_DBG("OpenThread already commissioned.");
452 	} else if (IS_ENABLED(CONFIG_OPENTHREAD_JOINER_AUTOSTART)) {
453 		/* No dataset - initiate network join procedure. */
454 		NET_DBG("Starting OpenThread join procedure.");
455 
456 		error = otJoinerStart(ot_instance, OT_JOINER_PSKD, NULL, ZEPHYR_PACKAGE_NAME,
457 				      OT_PLATFORM_INFO, PACKAGE_VERSION, NULL,
458 				      &ot_joiner_start_handler, ot_context);
459 
460 		if (error != OT_ERROR_NONE) {
461 			NET_ERR("Failed to start joiner [%d]", error);
462 		}
463 
464 		goto exit;
465 	} else {
466 		/* No dataset - load the default configuration. */
467 		NET_DBG("Loading OpenThread default configuration.");
468 
469 		otExtendedPanId xpanid;
470 		otNetworkKey    networkKey;
471 
472 		otThreadSetNetworkName(ot_instance, OT_NETWORK_NAME);
473 		otLinkSetChannel(ot_instance, OT_CHANNEL);
474 		otLinkSetPanId(ot_instance, OT_PANID);
475 		net_bytes_from_str(xpanid.m8, 8, (char *)OT_XPANID);
476 		otThreadSetExtendedPanId(ot_instance, &xpanid);
477 
478 		if (strlen(OT_NETWORKKEY)) {
479 			net_bytes_from_str(networkKey.m8, OT_NETWORK_KEY_SIZE,
480 					   (char *)OT_NETWORKKEY);
481 			otThreadSetNetworkKey(ot_instance, &networkKey);
482 		}
483 	}
484 
485 	NET_INFO("Network name: %s",
486 		 otThreadGetNetworkName(ot_instance));
487 
488 	/* Start the network. */
489 	error = otThreadSetEnabled(ot_instance, true);
490 	if (error != OT_ERROR_NONE) {
491 		NET_ERR("Failed to start the OpenThread network [%d]", error);
492 	}
493 
494 exit:
495 
496 	openthread_api_mutex_unlock(ot_context);
497 
498 	return error == OT_ERROR_NONE ? 0 : -EIO;
499 }
500 
openthread_stop(struct openthread_context * ot_context)501 int openthread_stop(struct openthread_context *ot_context)
502 {
503 	otError error;
504 
505 	if (IS_ENABLED(CONFIG_OPENTHREAD_COPROCESSOR)) {
506 		return 0;
507 	}
508 
509 	openthread_api_mutex_lock(ot_context);
510 
511 	error = otThreadSetEnabled(ot_context->instance, false);
512 	if (error == OT_ERROR_INVALID_STATE) {
513 		NET_DBG("Openthread interface was not up [%d]", error);
514 	}
515 
516 	openthread_api_mutex_unlock(ot_context);
517 
518 	return 0;
519 }
520 
openthread_init(struct net_if * iface)521 static int openthread_init(struct net_if *iface)
522 {
523 	struct openthread_context *ot_context = net_if_l2_data(iface);
524 	struct k_work_queue_config q_cfg = {
525 		.name = "openthread",
526 		.no_yield = true,
527 	};
528 	otError err;
529 
530 	NET_DBG("openthread_init");
531 
532 	k_mutex_init(&ot_context->api_lock);
533 	k_work_init(&ot_context->api_work, openthread_process);
534 
535 	ll_addr = net_if_get_link_addr(iface);
536 
537 	openthread_api_mutex_lock(ot_context);
538 
539 	otSysInit(0, NULL);
540 
541 	ot_context->instance = otInstanceInitSingle();
542 	ot_context->iface = iface;
543 
544 	__ASSERT(ot_context->instance, "OT instance is NULL");
545 
546 	if (IS_ENABLED(CONFIG_OPENTHREAD_SHELL)) {
547 		platformShellInit(ot_context->instance);
548 	}
549 
550 	if (IS_ENABLED(CONFIG_OPENTHREAD_COPROCESSOR)) {
551 		otPlatUartEnable();
552 		otNcpHdlcInit(ot_context->instance, ncp_hdlc_send);
553 	} else {
554 		otIp6SetReceiveFilterEnabled(ot_context->instance, true);
555 		otIp6SetReceiveCallback(ot_context->instance,
556 					ot_receive_handler, ot_context);
557 
558 #if defined(CONFIG_OPENTHREAD_NAT64_TRANSLATOR)
559 
560 		otIp4Cidr nat64_cidr;
561 
562 		if (otIp4CidrFromString(CONFIG_OPENTHREAD_NAT64_CIDR, &nat64_cidr) ==
563 		    OT_ERROR_NONE) {
564 			if (otNat64SetIp4Cidr(openthread_get_default_instance(), &nat64_cidr) !=
565 			    OT_ERROR_NONE) {
566 				NET_ERR("Incorrect NAT64 CIDR");
567 			}
568 		} else {
569 			NET_ERR("Failed to parse NAT64 CIDR");
570 		}
571 		otNat64SetReceiveIp4Callback(ot_context->instance, ot_receive_handler, ot_context);
572 
573 #endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */
574 
575 		sys_slist_init(&ot_context->state_change_cbs);
576 		err = otSetStateChangedCallback(ot_context->instance,
577 						&ot_state_changed_handler,
578 						ot_context);
579 		if (err != OT_ERROR_NONE) {
580 			NET_ERR("Could not set state changed callback: %d", err);
581 		}
582 
583 		net_mgmt_init_event_callback(
584 			&ip6_addr_cb, ipv6_addr_event_handler,
585 			NET_EVENT_IPV6_ADDR_ADD | NET_EVENT_IPV6_MADDR_ADD);
586 		net_mgmt_add_event_callback(&ip6_addr_cb);
587 
588 		net_if_dormant_on(iface);
589 	}
590 
591 	openthread_api_mutex_unlock(ot_context);
592 
593 	k_work_queue_start(&ot_context->work_q, ot_stack_area,
594 			   K_KERNEL_STACK_SIZEOF(ot_stack_area),
595 			   OT_PRIORITY, &q_cfg);
596 
597 	(void)k_work_submit_to_queue(&ot_context->work_q, &ot_context->api_work);
598 
599 	return 0;
600 }
601 
ieee802154_init(struct net_if * iface)602 void ieee802154_init(struct net_if *iface)
603 {
604 	if (IS_ENABLED(CONFIG_IEEE802154_NET_IF_NO_AUTO_START)) {
605 		LOG_DBG("Interface auto start disabled.");
606 		net_if_flag_set(iface, NET_IF_NO_AUTO_START);
607 	}
608 
609 	net_if_flag_set(iface, NET_IF_IPV6_NO_ND);
610 	net_if_flag_set(iface, NET_IF_IPV6_NO_MLD);
611 
612 	openthread_init(iface);
613 }
614 
openthread_flags(struct net_if * iface)615 static enum net_l2_flags openthread_flags(struct net_if *iface)
616 {
617 	/* TODO: Should report NET_L2_PROMISC_MODE if the radio driver
618 	 *       reports the IEEE802154_HW_PROMISC capability.
619 	 */
620 	return NET_L2_MULTICAST | NET_L2_MULTICAST_SKIP_JOIN_SOLICIT_NODE;
621 }
622 
openthread_enable(struct net_if * iface,bool state)623 static int openthread_enable(struct net_if *iface, bool state)
624 {
625 	struct openthread_context *ot_context = net_if_l2_data(iface);
626 
627 	NET_DBG("iface %p %s", iface, state ? "up" : "down");
628 
629 	if (state) {
630 		if (IS_ENABLED(CONFIG_OPENTHREAD_MANUAL_START)) {
631 			NET_DBG("OpenThread manual start.");
632 			return 0;
633 		}
634 
635 		return openthread_start(ot_context);
636 	}
637 
638 	return openthread_stop(ot_context);
639 }
640 
openthread_get_default_context(void)641 struct openthread_context *openthread_get_default_context(void)
642 {
643 	struct net_if *iface;
644 	struct openthread_context *ot_context = NULL;
645 
646 	iface = net_if_get_first_by_type(&NET_L2_GET_NAME(OPENTHREAD));
647 	if (!iface) {
648 		NET_ERR("There is no net interface for OpenThread");
649 		goto exit;
650 	}
651 
652 	ot_context = net_if_l2_data(iface);
653 	if (!ot_context) {
654 		NET_ERR("There is no Openthread context in net interface data");
655 		goto exit;
656 	}
657 
658 exit:
659 	return ot_context;
660 }
661 
openthread_get_default_instance(void)662 struct otInstance *openthread_get_default_instance(void)
663 {
664 	struct openthread_context *ot_context =
665 		openthread_get_default_context();
666 
667 	return ot_context ? ot_context->instance : NULL;
668 }
669 
openthread_state_changed_cb_register(struct openthread_context * ot_context,struct openthread_state_changed_cb * cb)670 int openthread_state_changed_cb_register(struct openthread_context *ot_context,
671 					 struct openthread_state_changed_cb *cb)
672 {
673 	CHECKIF(cb == NULL || cb->state_changed_cb == NULL) {
674 		return -EINVAL;
675 	}
676 
677 	openthread_api_mutex_lock(ot_context);
678 	sys_slist_append(&ot_context->state_change_cbs, &cb->node);
679 	openthread_api_mutex_unlock(ot_context);
680 
681 	return 0;
682 }
683 
openthread_state_changed_cb_unregister(struct openthread_context * ot_context,struct openthread_state_changed_cb * cb)684 int openthread_state_changed_cb_unregister(struct openthread_context *ot_context,
685 					   struct openthread_state_changed_cb *cb)
686 {
687 	bool removed;
688 
689 	CHECKIF(cb == NULL) {
690 		return -EINVAL;
691 	}
692 
693 	openthread_api_mutex_lock(ot_context);
694 	removed = sys_slist_find_and_remove(&ot_context->state_change_cbs, &cb->node);
695 	openthread_api_mutex_unlock(ot_context);
696 
697 	if (!removed) {
698 		return -EALREADY;
699 	}
700 
701 	return 0;
702 }
703 
openthread_set_state_changed_cb(otStateChangedCallback cb)704 void openthread_set_state_changed_cb(otStateChangedCallback cb)
705 {
706 	state_changed_cb = cb;
707 }
708 
openthread_api_mutex_lock(struct openthread_context * ot_context)709 void openthread_api_mutex_lock(struct openthread_context *ot_context)
710 {
711 	(void)k_mutex_lock(&ot_context->api_lock, K_FOREVER);
712 }
713 
openthread_api_mutex_try_lock(struct openthread_context * ot_context)714 int openthread_api_mutex_try_lock(struct openthread_context *ot_context)
715 {
716 	return k_mutex_lock(&ot_context->api_lock, K_NO_WAIT);
717 }
718 
openthread_api_mutex_unlock(struct openthread_context * ot_context)719 void openthread_api_mutex_unlock(struct openthread_context *ot_context)
720 {
721 	(void)k_mutex_unlock(&ot_context->api_lock);
722 }
723 
724 NET_L2_INIT(OPENTHREAD_L2, openthread_recv, openthread_send, openthread_enable,
725 	    openthread_flags);
726