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