esp_openthread.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "esp_openthread.h"
  7. #include "esp_check.h"
  8. #include "esp_openthread_border_router.h"
  9. #include "esp_openthread_common_macro.h"
  10. #include "esp_openthread_dns64.h"
  11. #include "esp_openthread_lock.h"
  12. #include "esp_openthread_platform.h"
  13. #include "esp_openthread_task_queue.h"
  14. #include "esp_openthread_types.h"
  15. #include "freertos/FreeRTOS.h"
  16. #include "lwip/dns.h"
  17. #include "openthread/instance.h"
  18. #include "openthread/netdata.h"
  19. #include "openthread/tasklet.h"
  20. #include "esp_openthread_sleep.h"
  21. esp_err_t esp_openthread_init(const esp_openthread_platform_config_t *config)
  22. {
  23. #if CONFIG_IEEE802154_SLEEP_ENABLE
  24. ESP_RETURN_ON_ERROR(esp_openthread_sleep_init(), OT_PLAT_LOG_TAG,
  25. "Failed to initialize OpenThread esp pm_lock");
  26. #endif
  27. ESP_RETURN_ON_ERROR(esp_openthread_platform_init(config), OT_PLAT_LOG_TAG,
  28. "Failed to initialize OpenThread platform driver");
  29. esp_openthread_lock_acquire(portMAX_DELAY);
  30. ESP_RETURN_ON_FALSE(otInstanceInitSingle() != NULL, ESP_FAIL, OT_PLAT_LOG_TAG,
  31. "Failed to initialize OpenThread instance");
  32. #if CONFIG_OPENTHREAD_DNS64_CLIENT
  33. ESP_RETURN_ON_ERROR(esp_openthread_dns64_client_init(), OT_PLAT_LOG_TAG,
  34. "Failed to initialize OpenThread dns64 client");
  35. #endif
  36. esp_openthread_lock_release();
  37. return ESP_OK;
  38. }
  39. esp_err_t esp_openthread_launch_mainloop(void)
  40. {
  41. esp_openthread_mainloop_context_t mainloop;
  42. otInstance *instance = esp_openthread_get_instance();
  43. esp_err_t error = ESP_OK;
  44. while (true) {
  45. FD_ZERO(&mainloop.read_fds);
  46. FD_ZERO(&mainloop.write_fds);
  47. FD_ZERO(&mainloop.error_fds);
  48. mainloop.max_fd = -1;
  49. mainloop.timeout.tv_sec = 10;
  50. mainloop.timeout.tv_usec = 0;
  51. esp_openthread_lock_acquire(portMAX_DELAY);
  52. esp_openthread_platform_update(&mainloop);
  53. if (otTaskletsArePending(instance)) {
  54. mainloop.timeout.tv_sec = 0;
  55. mainloop.timeout.tv_usec = 0;
  56. }
  57. #if CONFIG_IEEE802154_SLEEP_ENABLE
  58. esp_openthread_sleep_process();
  59. #endif
  60. esp_openthread_lock_release();
  61. if (select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds,
  62. &mainloop.timeout) >= 0) {
  63. esp_openthread_lock_acquire(portMAX_DELAY);
  64. #if CONFIG_IEEE802154_SLEEP_ENABLE
  65. esp_openthread_wakeup_process();
  66. #endif
  67. error = esp_openthread_platform_process(instance, &mainloop);
  68. while (otTaskletsArePending(instance)) {
  69. otTaskletsProcess(instance);
  70. }
  71. esp_openthread_lock_release();
  72. if (error != ESP_OK) {
  73. ESP_LOGE(OT_PLAT_LOG_TAG, "esp_openthread_platform_process failed");
  74. break;
  75. }
  76. } else {
  77. error = ESP_FAIL;
  78. ESP_LOGE(OT_PLAT_LOG_TAG, "OpenThread system polling failed");
  79. break;
  80. }
  81. }
  82. return error;
  83. }
  84. esp_err_t esp_openthread_deinit(void)
  85. {
  86. otInstanceFinalize(esp_openthread_get_instance());
  87. return esp_openthread_platform_deinit();
  88. }
  89. static void stub_task(void *context)
  90. {
  91. // this is a empty function used for ot-task signal pending
  92. }
  93. void otTaskletsSignalPending(otInstance *aInstance)
  94. {
  95. esp_openthread_task_queue_post(stub_task, NULL);
  96. }