1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  * @brief
32  *   This file includes the platform-specific initializers.
33  */
34 
35 #ifndef OT_PLATFORM_POSIX_H_
36 #define OT_PLATFORM_POSIX_H_
37 
38 #include "openthread-posix-config.h"
39 
40 #include <errno.h>
41 #include <net/if.h>
42 #include <stdint.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <sys/select.h>
46 #include <sys/time.h>
47 
48 #include <openthread/error.h>
49 #include <openthread/instance.h>
50 #include <openthread/ip6.h>
51 #include <openthread/logging.h>
52 #include <openthread/openthread-system.h>
53 #include <openthread/platform/time.h>
54 
55 #include "lib/platform/exit_code.h"
56 #include "lib/spinel/coprocessor_type.h"
57 #include "lib/url/url.hpp"
58 
59 /**
60  * @def OPENTHREAD_POSIX_VIRTUAL_TIME
61  *
62  * This setting configures whether to use virtual time.
63  */
64 #ifndef OPENTHREAD_POSIX_VIRTUAL_TIME
65 #define OPENTHREAD_POSIX_VIRTUAL_TIME 0
66 #endif
67 
68 /**
69  * This is the socket name used by daemon mode.
70  */
71 #define OPENTHREAD_POSIX_DAEMON_SOCKET_NAME OPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME ".sock"
72 
73 #ifdef __cplusplus
74 extern "C" {
75 #endif
76 
77 enum
78 {
79     OT_SIM_EVENT_ALARM_FIRED        = 0,
80     OT_SIM_EVENT_RADIO_RECEIVED     = 1,
81     OT_SIM_EVENT_UART_WRITE         = 2,
82     OT_SIM_EVENT_RADIO_SPINEL_WRITE = 3,
83     OT_EVENT_DATA_MAX_SIZE          = 1024,
84 };
85 
86 OT_TOOL_PACKED_BEGIN
87 struct VirtualTimeEvent
88 {
89     uint64_t mDelay;
90     uint8_t  mEvent;
91     uint16_t mDataLength;
92     uint8_t  mData[OT_EVENT_DATA_MAX_SIZE];
93 } OT_TOOL_PACKED_END;
94 
95 /**
96  * Initializes the alarm service used by OpenThread.
97  *
98  * @param[in]  aSpeedUpFactor   The speed up factor.
99  * @param[in]  aRealTimeSignal  The real time signal for microsecond alarms.
100  */
101 void platformAlarmInit(uint32_t aSpeedUpFactor, int aRealTimeSignal);
102 
103 /**
104  * Retrieves the time remaining until the alarm fires.
105  *
106  * @param[out]  aTimeval  A pointer to the timeval struct.
107  */
108 void platformAlarmUpdateTimeout(struct timeval *tv);
109 
110 /**
111  * Performs alarm driver processing.
112  *
113  * @param[in]  aInstance  The OpenThread instance structure.
114  */
115 void platformAlarmProcess(otInstance *aInstance);
116 
117 /**
118  * Returns the next alarm event time.
119  *
120  * @returns The next alarm fire time.
121  */
122 int32_t platformAlarmGetNext(void);
123 
124 /**
125  * Advances the alarm time by @p aDelta.
126  *
127  * @param[in]  aDelta  The amount of time to advance.
128  */
129 void platformAlarmAdvanceNow(uint64_t aDelta);
130 
131 /**
132  * Initializes the radio service used by OpenThread.
133  *
134  * @note Even when @p aPlatformConfig->mResetRadio is false, a reset event (i.e. a PROP_LAST_STATUS between
135  * [SPINEL_STATUS_RESET__BEGIN, SPINEL_STATUS_RESET__END]) is still expected from RCP.
136  *
137  * @param[in]   aUrl  A pointer to the null-terminated radio URL.
138  */
139 void platformRadioInit(const char *aUrl);
140 
141 /**
142  * Shuts down the radio service used by OpenThread.
143  */
144 void platformRadioDeinit(void);
145 
146 /**
147  * Handles the state change events for the radio driver.
148  *
149  * @param[in] aInstance  A pointer to the OpenThread instance.
150  * @param[in] aFlags     Flags that denote the state change events.
151  */
152 void platformRadioHandleStateChange(otInstance *aInstance, otChangedFlags aFlags);
153 
154 /**
155  * Inputs a received radio frame.
156  *
157  * @param[in]  aInstance   A pointer to the OpenThread instance.
158  * @param[in]  aBuf        A pointer to the received radio frame.
159  * @param[in]  aBufLength  The size of the received radio frame.
160  */
161 void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLength);
162 
163 /**
164  * Updates the file descriptor sets with file descriptors used by the radio driver.
165  *
166  * @param[in]   aContext    A pointer to the mainloop context.
167  */
168 void platformRadioUpdateFdSet(otSysMainloopContext *aContext);
169 
170 /**
171  * Performs radio driver processing.
172  *
173  * @param[in]   aContext    A pointer to the mainloop context.
174  */
175 void platformRadioProcess(otInstance *aInstance, const otSysMainloopContext *aContext);
176 
177 /**
178  * Initializes the random number service used by OpenThread.
179  */
180 void platformRandomInit(void);
181 
182 /**
183  * Initializes the logging service used by OpenThread.
184  *
185  * @param[in] aName   A name string which will be prefixed to each log line.
186  */
187 void platformLoggingInit(const char *aName);
188 
189 /**
190  * Updates the file descriptor sets with file descriptors used by the UART driver.
191  *
192  * @param[in]   aContext    A pointer to the mainloop context.
193  */
194 void platformUartUpdateFdSet(otSysMainloopContext *aContext);
195 
196 /**
197  * Performs radio driver processing.
198  *
199  * @param[in]   aContext    A pointer to the mainloop context.
200  */
201 void platformUartProcess(const otSysMainloopContext *aContext);
202 
203 /**
204  * Initializes platform netif.
205  *
206  * @note This function is called before OpenThread instance is created.
207  *
208  * @param[in]   aInterfaceName  A pointer to Thread network interface name.
209  */
210 void platformNetifInit(otPlatformConfig *aPlatformConfig);
211 
212 /**
213  * Sets up platform netif.
214  *
215  * @note This function is called after OpenThread instance is created.
216  *
217  * @param[in]   aInstance       A pointer to the OpenThread instance.
218  */
219 void platformNetifSetUp(void);
220 
221 /**
222  * Tears down platform netif.
223  *
224  * @note This function is called before OpenThread instance is destructed.
225  */
226 void platformNetifTearDown(void);
227 
228 /**
229  * Deinitializes platform netif.
230  *
231  * @note This function is called after OpenThread instance is destructed.
232  */
233 void platformNetifDeinit(void);
234 
235 /**
236  * Updates the file descriptor sets with file descriptors used by platform netif module.
237  *
238  * @param[in,out]  aContext  A pointer to the mainloop context.
239  */
240 void platformNetifUpdateFdSet(otSysMainloopContext *aContext);
241 
242 /**
243  * Performs platform netif processing.
244  *
245  * @param[in]  aContext  A pointer to the mainloop context.
246  */
247 void platformNetifProcess(const otSysMainloopContext *aContext);
248 
249 /**
250  * Performs notifies state changes to platform netif.
251  *
252  * @param[in]   aInstance       A pointer to the OpenThread instance.
253  * @param[in]   aFlags          Flags that denote the state change events.
254  */
255 void platformNetifStateChange(otInstance *aInstance, otChangedFlags aFlags);
256 
257 /**
258  * Initialize virtual time simulation.
259  *
260  * @params[in]  aNodeId     Node id of this simulated device.
261  */
262 void virtualTimeInit(uint16_t aNodeId);
263 
264 /**
265  * Deinitialize virtual time simulation.
266  */
267 void virtualTimeDeinit(void);
268 
269 /**
270  * Performs virtual time simulation processing.
271  *
272  * @param[in]  aContext  A pointer to the mainloop context.
273  */
274 void virtualTimeProcess(otInstance *aInstance, const otSysMainloopContext *aContext);
275 
276 /**
277  * Updates the file descriptor sets with file descriptors
278  * used by the virtual time simulation.
279  *
280  * @param[in,out]  aContext  A pointer to the mainloop context.
281  */
282 void virtualTimeUpdateFdSet(otSysMainloopContext *aContext);
283 
284 /**
285  * Sends radio spinel event of virtual time simulation.
286  *
287  * @param[in] aData     A pointer to the spinel frame.
288  * @param[in] aLength   Length of the spinel frame.
289  */
290 void virtualTimeSendRadioSpinelWriteEvent(const uint8_t *aData, uint16_t aLength);
291 
292 /**
293  * Receives an event of virtual time simulation.
294  *
295  * @param[out]  aEvent  A pointer to the event receiving the event.
296  */
297 void virtualTimeReceiveEvent(struct VirtualTimeEvent *aEvent);
298 
299 /**
300  * Sends sleep event through virtual time simulation.
301  *
302  * @param[in]   aTimeout    A pointer to the time sleeping.
303  */
304 void virtualTimeSendSleepEvent(const struct timeval *aTimeout);
305 
306 /**
307  * Performs radio processing of virtual time simulation.
308  *
309  * @param[in]   aInstance   A pointer to the OpenThread instance.
310  * @param[in]   aEvent      A pointer to the current event.
311  */
312 void virtualTimeRadioProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent);
313 
314 /**
315  * Performs radio  processing of virtual time simulation.
316  *
317  * @param[in]   aInstance   A pointer to the OpenThread instance.
318  * @param[in]   aEvent      A pointer to the current event.
319  */
320 void virtualTimeSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent);
321 
322 enum SocketBlockOption
323 {
324     kSocketBlock,
325     kSocketNonBlock,
326 };
327 
328 /**
329  * Initializes platform TREL UDP6 driver.
330  *
331  * @param[in]   aTrelUrl   The TREL URL (configuration for TREL platform).
332  */
333 void platformTrelInit(const char *aTrelUrl);
334 
335 /**
336  * Shuts down the platform TREL UDP6 platform driver.
337  */
338 void platformTrelDeinit(void);
339 
340 /**
341  * Updates the file descriptor sets with file descriptors used by the TREL driver.
342  *
343  * @param[in,out]  aContext  A pointer to the mainloop context.
344  */
345 void platformTrelUpdateFdSet(otSysMainloopContext *aContext);
346 
347 /**
348  * Performs TREL driver processing.
349  *
350  * @param[in]  aContext  A pointer to the mainloop context.
351  */
352 void platformTrelProcess(otInstance *aInstance, const otSysMainloopContext *aContext);
353 
354 /**
355  * Creates a socket with SOCK_CLOEXEC flag set.
356  *
357  * @param[in]   aDomain       The communication domain.
358  * @param[in]   aType         The semantics of communication.
359  * @param[in]   aProtocol     The protocol to use.
360  * @param[in]   aBlockOption  Whether to add nonblock flags.
361  *
362  * @returns The file descriptor of the created socket.
363  *
364  * @retval  -1  Failed to create socket.
365  */
366 int SocketWithCloseExec(int aDomain, int aType, int aProtocol, SocketBlockOption aBlockOption);
367 
368 /**
369  * The name of Thread network interface.
370  */
371 extern char gNetifName[IFNAMSIZ];
372 
373 /**
374  * The index of Thread network interface.
375  */
376 extern unsigned int gNetifIndex;
377 
378 /**
379  * A pointer to the OpenThread instance.
380  */
381 extern otInstance *gInstance;
382 
383 /**
384  * Initializes backtrace module.
385  */
386 void platformBacktraceInit(void);
387 
388 /**
389  * Initializes the spinel service used by OpenThread.
390  *
391  * @param[in]   aUrl  A pointer to the null-terminated spinel URL.
392  *
393  * @retval  OT_COPROCESSOR_UNKNOWN  The initialization fails.
394  * @retval  OT_COPROCESSOR_RCP      The Co-processor is a RCP.
395  * @retval  OT_COPROCESSOR_NCP      The Co-processor is a NCP.
396  */
397 CoprocessorType platformSpinelManagerInit(const char *aUrl);
398 
399 /**
400  * Shuts down the spinel service used by OpenThread.
401  */
402 void platformSpinelManagerDeinit(void);
403 
404 /**
405  * Performs spinel driver processing.
406  *
407  * @param[in]   aInstance   A pointer to the OT instance.
408  * @param[in]   aContext    A pointer to the mainloop context.
409  */
410 void platformSpinelManagerProcess(otInstance *aInstance, const otSysMainloopContext *aContext);
411 
412 /**
413  * Updates the file descriptor sets with file descriptors used by the spinel driver.
414  *
415  * @param[in]   aContext    A pointer to the mainloop context.
416  */
417 void platformSpinelManagerUpdateFdSet(otSysMainloopContext *aContext);
418 
419 /**
420  * Initializes the resolver used by OpenThread.
421  */
422 void platformResolverInit(void);
423 
424 /**
425  * Updates the file descriptor sets with file descriptors used by the resolver.
426  *
427  * @param[in]   aContext    A pointer to the mainloop context.
428  */
429 void platformResolverUpdateFdSet(otSysMainloopContext *aContext);
430 
431 /**
432  * Performs the resolver processing.
433  *
434  * @param[in]  aContext  A pointer to the mainloop context.
435  */
436 void platformResolverProcess(const otSysMainloopContext *aContext);
437 
438 #ifdef __cplusplus
439 }
440 #endif
441 #endif // OT_PLATFORM_POSIX_H_
442