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