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