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  */
65 #ifndef OPENTHREAD_POSIX_VIRTUAL_TIME
66 #define OPENTHREAD_POSIX_VIRTUAL_TIME 0
67 #endif
68 
69 /**
70  * This is the socket name used by daemon mode.
71  *
72  */
73 #define OPENTHREAD_POSIX_DAEMON_SOCKET_NAME OPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME ".sock"
74 
75 #ifdef __cplusplus
76 extern "C" {
77 #endif
78 
79 enum
80 {
81     OT_SIM_EVENT_ALARM_FIRED        = 0,
82     OT_SIM_EVENT_RADIO_RECEIVED     = 1,
83     OT_SIM_EVENT_UART_WRITE         = 2,
84     OT_SIM_EVENT_RADIO_SPINEL_WRITE = 3,
85     OT_EVENT_DATA_MAX_SIZE          = 1024,
86 };
87 
88 OT_TOOL_PACKED_BEGIN
89 struct VirtualTimeEvent
90 {
91     uint64_t mDelay;
92     uint8_t  mEvent;
93     uint16_t mDataLength;
94     uint8_t  mData[OT_EVENT_DATA_MAX_SIZE];
95 } OT_TOOL_PACKED_END;
96 
97 /**
98  * Initializes the alarm service used by OpenThread.
99  *
100  * @param[in]  aSpeedUpFactor   The speed up factor.
101  * @param[in]  aRealTimeSignal  The real time signal for microsecond alarms.
102  *
103  */
104 void platformAlarmInit(uint32_t aSpeedUpFactor, int aRealTimeSignal);
105 
106 /**
107  * Retrieves the time remaining until the alarm fires.
108  *
109  * @param[out]  aTimeval  A pointer to the timeval struct.
110  *
111  */
112 void platformAlarmUpdateTimeout(struct timeval *tv);
113 
114 /**
115  * Performs alarm driver processing.
116  *
117  * @param[in]  aInstance  The OpenThread instance structure.
118  *
119  */
120 void platformAlarmProcess(otInstance *aInstance);
121 
122 /**
123  * Returns the next alarm event time.
124  *
125  * @returns The next alarm fire time.
126  *
127  */
128 int32_t platformAlarmGetNext(void);
129 
130 /**
131  * Advances the alarm time by @p aDelta.
132  *
133  * @param[in]  aDelta  The amount of time to advance.
134  *
135  */
136 void platformAlarmAdvanceNow(uint64_t aDelta);
137 
138 /**
139  * Initializes the radio service used by OpenThread.
140  *
141  * @note Even when @p aPlatformConfig->mResetRadio is false, a reset event (i.e. a PROP_LAST_STATUS between
142  * [SPINEL_STATUS_RESET__BEGIN, SPINEL_STATUS_RESET__END]) is still expected from RCP.
143  *
144  * @param[in]   aUrl  A pointer to the null-terminated radio URL.
145  *
146  */
147 void platformRadioInit(const char *aUrl);
148 
149 /**
150  * Shuts down the radio service used by OpenThread.
151  *
152  */
153 void platformRadioDeinit(void);
154 
155 /**
156  * Handles the state change events for the radio driver.
157  *
158  * @param[in] aInstance  A pointer to the OpenThread instance.
159  * @param[in] aFlags     Flags that denote the state change events.
160  *
161  */
162 void platformRadioHandleStateChange(otInstance *aInstance, otChangedFlags aFlags);
163 
164 /**
165  * Inputs a received radio frame.
166  *
167  * @param[in]  aInstance   A pointer to the OpenThread instance.
168  * @param[in]  aBuf        A pointer to the received radio frame.
169  * @param[in]  aBufLength  The size of the received radio frame.
170  *
171  */
172 void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLength);
173 
174 /**
175  * Updates the file descriptor sets with file descriptors used by the radio driver.
176  *
177  * @param[in]   aContext    A pointer to the mainloop context.
178  *
179  */
180 void platformRadioUpdateFdSet(otSysMainloopContext *aContext);
181 
182 /**
183  * Performs radio driver processing.
184  *
185  * @param[in]   aContext    A pointer to the mainloop context.
186  *
187  */
188 void platformRadioProcess(otInstance *aInstance, const otSysMainloopContext *aContext);
189 
190 /**
191  * Initializes the random number service used by OpenThread.
192  *
193  */
194 void platformRandomInit(void);
195 
196 /**
197  * Initializes the logging service used by OpenThread.
198  *
199  * @param[in] aName   A name string which will be prefixed to each log line.
200  *
201  */
202 void platformLoggingInit(const char *aName);
203 
204 /**
205  * Updates the file descriptor sets with file descriptors used by the UART driver.
206  *
207  * @param[in]   aContext    A pointer to the mainloop context.
208  *
209  */
210 void platformUartUpdateFdSet(otSysMainloopContext *aContext);
211 
212 /**
213  * Performs radio driver processing.
214  *
215  * @param[in]   aContext    A pointer to the mainloop context.
216  *
217  */
218 void platformUartProcess(const otSysMainloopContext *aContext);
219 
220 /**
221  * Initializes platform netif.
222  *
223  * @note This function is called before OpenThread instance is created.
224  *
225  * @param[in]   aInterfaceName  A pointer to Thread network interface name.
226  *
227  */
228 void platformNetifInit(otPlatformConfig *aPlatformConfig);
229 
230 /**
231  * Sets up platform netif.
232  *
233  * @note This function is called after OpenThread instance is created.
234  *
235  * @param[in]   aInstance       A pointer to the OpenThread instance.
236  *
237  */
238 void platformNetifSetUp(void);
239 
240 /**
241  * Tears down platform netif.
242  *
243  * @note This function is called before OpenThread instance is destructed.
244  *
245  */
246 void platformNetifTearDown(void);
247 
248 /**
249  * Deinitializes platform netif.
250  *
251  * @note This function is called after OpenThread instance is destructed.
252  *
253  */
254 void platformNetifDeinit(void);
255 
256 /**
257  * Updates the file descriptor sets with file descriptors used by platform netif module.
258  *
259  * @param[in,out]  aContext  A pointer to the mainloop context.
260  *
261  */
262 void platformNetifUpdateFdSet(otSysMainloopContext *aContext);
263 
264 /**
265  * Performs platform netif processing.
266  *
267  * @param[in]  aContext  A pointer to the mainloop context.
268  *
269  */
270 void platformNetifProcess(const otSysMainloopContext *aContext);
271 
272 /**
273  * Performs notifies state changes to platform netif.
274  *
275  * @param[in]   aInstance       A pointer to the OpenThread instance.
276  * @param[in]   aFlags          Flags that denote the state change events.
277  *
278  */
279 void platformNetifStateChange(otInstance *aInstance, otChangedFlags aFlags);
280 
281 /**
282  * Initialize virtual time simulation.
283  *
284  * @params[in]  aNodeId     Node id of this simulated device.
285  *
286  */
287 void virtualTimeInit(uint16_t aNodeId);
288 
289 /**
290  * Deinitialize virtual time simulation.
291  *
292  */
293 void virtualTimeDeinit(void);
294 
295 /**
296  * Performs virtual time simulation processing.
297  *
298  * @param[in]  aContext  A pointer to the mainloop context.
299  *
300  */
301 void virtualTimeProcess(otInstance *aInstance, const otSysMainloopContext *aContext);
302 
303 /**
304  * Updates the file descriptor sets with file descriptors
305  * used by the virtual time simulation.
306  *
307  * @param[in,out]  aContext  A pointer to the mainloop context.
308  *
309  */
310 void virtualTimeUpdateFdSet(otSysMainloopContext *aContext);
311 
312 /**
313  * Sends radio spinel event of virtual time simulation.
314  *
315  * @param[in] aData     A pointer to the spinel frame.
316  * @param[in] aLength   Length of the spinel frame.
317  *
318  */
319 void virtualTimeSendRadioSpinelWriteEvent(const uint8_t *aData, uint16_t aLength);
320 
321 /**
322  * Receives an event of virtual time simulation.
323  *
324  * @param[out]  aEvent  A pointer to the event receiving the event.
325  *
326  */
327 void virtualTimeReceiveEvent(struct VirtualTimeEvent *aEvent);
328 
329 /**
330  * Sends sleep event through virtual time simulation.
331  *
332  * @param[in]   aTimeout    A pointer to the time sleeping.
333  *
334  */
335 void virtualTimeSendSleepEvent(const struct timeval *aTimeout);
336 
337 /**
338  * Performs radio processing of virtual time simulation.
339  *
340  * @param[in]   aInstance   A pointer to the OpenThread instance.
341  * @param[in]   aEvent      A pointer to the current event.
342  *
343  */
344 void virtualTimeRadioProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent);
345 
346 /**
347  * Performs radio  processing of virtual time simulation.
348  *
349  * @param[in]   aInstance   A pointer to the OpenThread instance.
350  * @param[in]   aEvent      A pointer to the current event.
351  *
352  */
353 void virtualTimeSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent);
354 
355 enum SocketBlockOption
356 {
357     kSocketBlock,
358     kSocketNonBlock,
359 };
360 
361 /**
362  * Initializes platform TREL UDP6 driver.
363  *
364  * @param[in]   aTrelUrl   The TREL URL (configuration for TREL platform).
365  *
366  */
367 void platformTrelInit(const char *aTrelUrl);
368 
369 /**
370  * Shuts down the platform TREL UDP6 platform driver.
371  *
372  */
373 void platformTrelDeinit(void);
374 
375 /**
376  * Updates the file descriptor sets with file descriptors used by the TREL driver.
377  *
378  * @param[in,out]  aContext  A pointer to the mainloop context.
379  *
380  */
381 void platformTrelUpdateFdSet(otSysMainloopContext *aContext);
382 
383 /**
384  * Performs TREL driver processing.
385  *
386  * @param[in]  aContext  A pointer to the mainloop context.
387  *
388  */
389 void platformTrelProcess(otInstance *aInstance, const otSysMainloopContext *aContext);
390 
391 /**
392  * Creates a socket with SOCK_CLOEXEC flag set.
393  *
394  * @param[in]   aDomain       The communication domain.
395  * @param[in]   aType         The semantics of communication.
396  * @param[in]   aProtocol     The protocol to use.
397  * @param[in]   aBlockOption  Whether to add nonblock flags.
398  *
399  * @returns The file descriptor of the created socket.
400  *
401  * @retval  -1  Failed to create socket.
402  *
403  */
404 int SocketWithCloseExec(int aDomain, int aType, int aProtocol, SocketBlockOption aBlockOption);
405 
406 /**
407  * The name of Thread network interface.
408  *
409  */
410 extern char gNetifName[IFNAMSIZ];
411 
412 /**
413  * The index of Thread network interface.
414  *
415  */
416 extern unsigned int gNetifIndex;
417 
418 /**
419  * A pointer to the OpenThread instance.
420  *
421  */
422 extern otInstance *gInstance;
423 
424 /**
425  * Initializes backtrace module.
426  *
427  */
428 void platformBacktraceInit(void);
429 
430 /**
431  * Initializes the spinel service used by OpenThread.
432  *
433  * @param[in]   aUrl  A pointer to the null-terminated spinel URL.
434  *
435  * @retval  OT_COPROCESSOR_UNKNOWN  The initialization fails.
436  * @retval  OT_COPROCESSOR_RCP      The Co-processor is a RCP.
437  * @retval  OT_COPROCESSOR_NCP      The Co-processor is a NCP.
438  */
439 CoprocessorType platformSpinelManagerInit(const char *aUrl);
440 
441 /**
442  * Shuts down the spinel service used by OpenThread.
443  *
444  */
445 void platformSpinelManagerDeinit(void);
446 
447 /**
448  * Performs spinel driver processing.
449  *
450  * @param[in]   aInstance   A pointer to the OT instance.
451  * @param[in]   aContext    A pointer to the mainloop context.
452  *
453  */
454 void platformSpinelManagerProcess(otInstance *aInstance, const otSysMainloopContext *aContext);
455 
456 /**
457  * Updates the file descriptor sets with file descriptors used by the spinel driver.
458  *
459  * @param[in]   aContext    A pointer to the mainloop context.
460  *
461  */
462 void platformSpinelManagerUpdateFdSet(otSysMainloopContext *aContext);
463 
464 /**
465  * Initializes the resolver used by OpenThread.
466  *
467  */
468 void platformResolverInit(void);
469 
470 /**
471  * Updates the file descriptor sets with file descriptors used by the resolver.
472  *
473  * @param[in]   aContext    A pointer to the mainloop context.
474  *
475  */
476 void platformResolverUpdateFdSet(otSysMainloopContext *aContext);
477 
478 /**
479  * Performs the resolver processing.
480  *
481  * @param[in]  aContext  A pointer to the mainloop context.
482  *
483  */
484 void platformResolverProcess(const otSysMainloopContext *aContext);
485 
486 #ifdef __cplusplus
487 }
488 #endif
489 #endif // OT_PLATFORM_POSIX_H_
490