1 /*
2  * Copyright (c) 2017 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /** @file
8  * @brief OpenThread L2 stack public header
9  */
10 
11 #ifndef ZEPHYR_INCLUDE_NET_OPENTHREAD_H_
12 #define ZEPHYR_INCLUDE_NET_OPENTHREAD_H_
13 
14 /**
15  * @brief OpenThread Layer 2 abstraction layer
16  * @defgroup openthread OpenThread L2 abstraction layer
17  * @since 1.11
18  * @version 0.8.0
19  * @ingroup ieee802154
20  * @{
21  */
22 
23 #include <zephyr/kernel.h>
24 
25 #include <zephyr/net/net_if.h>
26 
27 #include <openthread/instance.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /**
34  * @cond INTERNAL_HIDDEN
35  */
36 /**
37  * @brief Type of pkt_list
38  */
39 struct pkt_list_elem {
40 	struct net_pkt *pkt;
41 };
42 
43 /**
44  * @brief OpenThread l2 private data.
45  */
46 struct openthread_context {
47 	/** Pointer to OpenThread stack instance */
48 	otInstance *instance;
49 
50 	/** Pointer to OpenThread network interface */
51 	struct net_if *iface;
52 
53 	/** Index indicates the head of pkt_list ring buffer */
54 	uint16_t pkt_list_in_idx;
55 
56 	/** Index indicates the tail of pkt_list ring buffer */
57 	uint16_t pkt_list_out_idx;
58 
59 	/** Flag indicates that pkt_list is full */
60 	uint8_t pkt_list_full;
61 
62 	/** Array for storing net_pkt for OpenThread internal usage */
63 	struct pkt_list_elem pkt_list[CONFIG_OPENTHREAD_PKT_LIST_SIZE];
64 
65 	/** A mutex to protect API calls from being preempted. */
66 	struct k_mutex api_lock;
67 
68 	/** A work queue for all OpenThread activity */
69 	struct k_work_q work_q;
70 
71 	/** Work object for OpenThread internal usage */
72 	struct k_work api_work;
73 
74 	/** A list for state change callbacks */
75 	sys_slist_t state_change_cbs;
76 };
77 /**
78  * INTERNAL_HIDDEN @endcond
79  */
80 
81 /** OpenThread state change callback  */
82 
83 /**
84  * @brief OpenThread state change callback structure
85  *
86  * Used to register a callback in the callback list. As many
87  * callbacks as needed can be added as long as each of them
88  * are unique pointers of struct openthread_state_changed_cb.
89  * Beware such structure should not be allocated on stack.
90  */
91 struct openthread_state_changed_cb {
92 	/**
93 	 * @brief Callback for notifying configuration or state changes.
94 	 *
95 	 * @param flags as per OpenThread otStateChangedCallback() aFlags parameter.
96 	 *        See https://openthread.io/reference/group/api-instance#otstatechangedcallback
97 	 * @param ot_context the OpenThread context the callback is registered with.
98 	 * @param user_data Data to pass to the callback.
99 	 */
100 	void (*state_changed_cb)(otChangedFlags flags, struct openthread_context *ot_context,
101 				 void *user_data);
102 
103 	/** User data if required */
104 	void *user_data;
105 
106 	/**
107 	 * Internally used field for list handling
108 	 *  - user must not directly modify
109 	 */
110 	sys_snode_t node;
111 };
112 
113 /**
114  * @brief Registers callbacks which will be called when certain configuration
115  * or state changes occur within OpenThread.
116  *
117  * @param ot_context the OpenThread context to register the callback with.
118  * @param cb callback struct to register.
119  */
120 int openthread_state_changed_cb_register(struct openthread_context *ot_context,
121 					 struct openthread_state_changed_cb *cb);
122 
123 /**
124  * @brief Unregisters OpenThread configuration or state changed callbacks.
125  *
126  * @param ot_context the OpenThread context to unregister the callback from.
127  * @param cb callback struct to unregister.
128  */
129 int openthread_state_changed_cb_unregister(struct openthread_context *ot_context,
130 					   struct openthread_state_changed_cb *cb);
131 
132 /**
133  * @brief Get OpenThread thread identification.
134  */
135 k_tid_t openthread_thread_id_get(void);
136 
137 /**
138  * @brief Get pointer to default OpenThread context.
139  *
140  * @retval !NULL On success.
141  * @retval NULL  On failure.
142  */
143 struct openthread_context *openthread_get_default_context(void);
144 
145 /**
146  * @brief Get pointer to default OpenThread instance.
147  *
148  * @retval !NULL On success.
149  * @retval NULL  On failure.
150  */
151 struct otInstance *openthread_get_default_instance(void);
152 
153 /**
154  * @brief Starts the OpenThread network.
155  *
156  * @details Depends on active settings: it uses stored network configuration,
157  * start joining procedure or uses default network configuration. Additionally
158  * when the device is MTD, it sets the SED mode to properly attach the network.
159  *
160  * @param ot_context
161  */
162 int openthread_start(struct openthread_context *ot_context);
163 
164 /**
165  * @brief Lock internal mutex before accessing OT API.
166  *
167  * @details OpenThread API is not thread-safe, therefore before accessing any
168  * API function, it's needed to lock the internal mutex, to prevent the
169  * OpenThread thread from preempting the API call.
170  *
171  * @param ot_context Context to lock.
172  */
173 void openthread_api_mutex_lock(struct openthread_context *ot_context);
174 
175 /**
176  * @brief Try to lock internal mutex before accessing OT API.
177  *
178  * @details This function behaves like openthread_api_mutex_lock() provided that
179  * the internal mutex is unlocked. Otherwise, it exists immediately and returns
180  * a negative value.
181  *
182  * @param ot_context Context to lock.
183  * @retval 0  On success.
184  * @retval <0 On failure.
185  */
186 int openthread_api_mutex_try_lock(struct openthread_context *ot_context);
187 
188 /**
189  * @brief Unlock internal mutex after accessing OT API.
190  *
191  * @param ot_context Context to unlock.
192  */
193 void openthread_api_mutex_unlock(struct openthread_context *ot_context);
194 
195 /** @cond INTERNAL_HIDDEN */
196 
197 #define OPENTHREAD_L2_CTX_TYPE struct openthread_context
198 
199 /** @endcond */
200 
201 #ifdef __cplusplus
202 }
203 #endif
204 
205 /**
206  * @}
207  */
208 
209 #endif /* ZEPHYR_INCLUDE_NET_OPENTHREAD_H_ */
210