1 /*
2  * Copyright (c) 2025 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_MODULES_OPENTHREAD_OPENTHREAD_H_
8 #define ZEPHYR_MODULES_OPENTHREAD_OPENTHREAD_H_
9 
10 #include <zephyr/kernel.h>
11 
12 #include <openthread/instance.h>
13 #include <openthread/message.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @brief The common callback type for receiving IPv4 (translated by NAT64) and IPv6 datagrams.
21  *
22  * This callback is called when a datagram is received.
23  *
24  * @param message The message to receive.
25  * @param context The context to pass to the callback.
26  */
27 typedef void (*openthread_receive_cb)(struct otMessage *message, void *context);
28 
29 /** OpenThread state change callback  */
30 
31 /**
32  * @brief OpenThread state change callback structure
33  *
34  * Used to register a callback in the callback list. As many
35  * callbacks as needed can be added as long as each of them
36  * are unique pointers of struct openthread_state_changed_callback.
37  *
38  * @note You may destroy the object only after it is unregistered from the callback list.
39  */
40 struct openthread_state_changed_callback {
41 	/**
42 	 * @brief Callback for notifying configuration or state changes.
43 	 *
44 	 * @param otCallback OpenThread callback to register.
45 	 * See https://openthread.io/reference/group/api-instance#otstatechangedcallback for
46 	 * details.
47 	 */
48 	otStateChangedCallback otCallback;
49 
50 	/** User data if required */
51 	void *user_data;
52 
53 	/**
54 	 * Internally used field for list handling
55 	 *  - user must not directly modify
56 	 */
57 	sys_snode_t node;
58 };
59 
60 /**
61  * @brief Register callbacks that will be called when a certain configuration
62  * or state changes occur within OpenThread.
63  *
64  * @param cb Callback struct to register.
65  */
66 int openthread_state_changed_callback_register(struct openthread_state_changed_callback *cb);
67 
68 /**
69  * @brief Unregister OpenThread configuration or state changed callbacks.
70  *
71  * @param cb Callback struct to unregister.
72  */
73 int openthread_state_changed_callback_unregister(struct openthread_state_changed_callback *cb);
74 
75 /**
76  * @brief Get OpenThread thread identification.
77  */
78 k_tid_t openthread_thread_id_get(void);
79 
80 /**
81  * @brief Get pointer to default OpenThread instance.
82  *
83  * @retval !NULL On success.
84  * @retval NULL  On failure.
85  */
86 struct otInstance *openthread_get_default_instance(void);
87 
88 /**
89  * @brief Initialize the OpenThread module.
90  *
91  * This function:
92  * - Initializes the OpenThread module.
93  * - Creates an OpenThread single instance.
94  * - Starts the shell.
95  * - Enables the UART and NCP HDLC for coprocessor purposes.
96  * - Initializes the NAT64 translator.
97  * - Creates a work queue for the OpenThread module.
98  *
99  * @note This function is automatically called by Zephyr's networking layer.
100  * If you want to initialize the OpenThread independently, call this function
101  * in your application init code.
102  *
103  * @retval 0 On success.
104  * @retval -EIO On failure.
105  */
106 int openthread_init(void);
107 
108 /**
109  * @brief Run the OpenThread network.
110  *
111  * @details Prepares the OpenThread network and enables it.
112  * Depends on active settings: it uses the stored network configuration,
113  * starts the joining procedure or uses the default network configuration.
114  * Additionally, when the device is MTD, it sets the SED mode to properly
115  * attach the network.
116  */
117 int openthread_run(void);
118 
119 /**
120  * @brief Disable the OpenThread network.
121  */
122 int openthread_stop(void);
123 
124 /**
125  * @brief Set the additional callback for receiving packets.
126  *
127  * @details This callback is called once a packet is received and can be
128  * used to inject packets into the Zephyr networking stack.
129  * Setting this callback is optional.
130  *
131  * @param cb Callback to set.
132  * @param context Context to pass to the callback.
133  */
134 void openthread_set_receive_cb(openthread_receive_cb cb, void *context);
135 
136 /**
137  * @brief Lock internal mutex before accessing OpenThread API.
138  *
139  * @details OpenThread API is not thread-safe. Therefore, before accessing any
140  * API function, you need to lock the internal mutex, to prevent the
141  * OpenThread thread from pre-empting the API call.
142  */
143 void openthread_mutex_lock(void);
144 
145 /**
146  * @brief Try to lock internal mutex before accessing OpenThread API.
147  *
148  * @details This function behaves like openthread_mutex_lock(), provided that
149  * the internal mutex is unlocked. Otherwise, it returns a negative value without
150  * waiting.
151  */
152 int openthread_mutex_try_lock(void);
153 
154 /**
155  * @brief Unlock internal mutex after accessing OpenThread API.
156  */
157 void openthread_mutex_unlock(void);
158 
159 #ifdef __cplusplus
160 }
161 #endif
162 
163 #endif /* ZEPHYR_MODULES_OPENTHREAD_OPENTHREAD_H_ */
164