main.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /* main.c
  2. *
  3. * Copyright (C) 2006-2024 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #include "sdkconfig.h"
  22. #include "main.h"
  23. /* ESP specific */
  24. #include <nvs_flash.h>
  25. #include <esp_log.h>
  26. #include <esp_event.h>
  27. /* wolfSSL */
  28. /* Always include wolfcrypt/settings.h before any other wolfSSL file. */
  29. /* Reminder: settings.h pulls in user_settings.h; don't include it here. */
  30. #ifdef WOLFSSL_USER_SETTINGS
  31. #include <wolfssl/wolfcrypt/settings.h>
  32. #ifndef WOLFSSL_ESPIDF
  33. #warning "Problem with wolfSSL user_settings."
  34. #warning "Check components/wolfssl/include"
  35. #endif
  36. /* This project not yet using the library */
  37. #undef USE_WOLFSSL_ESP_SDK_WIFI
  38. #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
  39. #else
  40. /* Define WOLFSSL_USER_SETTINGS project wide for settings.h to include */
  41. /* wolfSSL user settings in ./components/wolfssl/include/user_settings.h */
  42. #error "Missing WOLFSSL_USER_SETTINGS in CMakeLists or Makefile:\
  43. CFLAGS +=-DWOLFSSL_USER_SETTINGS"
  44. #endif
  45. /* this project */
  46. #include "client-tls.h"
  47. #include "time_helper.h"
  48. #ifdef CONFIG_IDF_TARGET_ESP32H2
  49. /* There's no WiFi on ESP32-H2.
  50. * For wired ethernet, see:
  51. * https://github.com/wolfSSL/wolfssl-examples/tree/master/ESP32/TLS13-ENC28J60-client */
  52. #else
  53. #include "wifi_connect.h"
  54. /*
  55. * Note ModBus TCP cannot be disabled on ESP8266 tos-sdk/v3.4
  56. * See https://github.com/espressif/esp-modbus/issues/2
  57. */
  58. #endif
  59. #ifdef WOLFSSL_TRACK_MEMORY
  60. #include <wolfssl/wolfcrypt/mem_track.h>
  61. #endif
  62. static const char* TAG = "main";
  63. #if defined(WOLFSSL_ESPWROOM32SE) && defined(HAVE_PK_CALLBACKS) \
  64. && defined(WOLFSSL_ATECC508A)
  65. #include "wolfssl/wolfcrypt/port/atmel/atmel.h"
  66. /* when you want to use a custom slot allocation */
  67. /* enable the definition CUSTOM_SLOT_ALLOCATION. */
  68. #if defined(CUSTOM_SLOT_ALLOCATION)
  69. static byte mSlotList[ATECC_MAX_SLOT];
  70. int atmel_set_slot_allocator(atmel_slot_alloc_cb alloc, atmel_slot_dealloc_cb dealloc);
  71. /* initialize slot array */
  72. void my_atmel_slotInit()
  73. {
  74. int i;
  75. for(i = 0;i < ATECC_MAX_SLOT;i++) {
  76. mSlotList[i] = ATECC_INVALID_SLOT;
  77. }
  78. }
  79. /* allocate slot depending on slotType */
  80. int my_atmel_alloc(int slotType)
  81. {
  82. int i, slot = -1;
  83. switch(slotType){
  84. case ATMEL_SLOT_ENCKEY:
  85. slot = 4;
  86. break;
  87. case ATMEL_SLOT_DEVICE:
  88. slot = 0;
  89. break;
  90. case ATMEL_SLOT_ECDHE:
  91. slot = 0;
  92. break;
  93. case ATMEL_SLOT_ECDHE_ENC:
  94. slot = 4;
  95. break;
  96. case ATMEL_SLOT_ANY:
  97. for(i = 0;i < ATECC_MAX_SLOT;i++){
  98. if(mSlotList[i] == ATECC_INVALID_SLOT){
  99. slot = i;
  100. break;
  101. }
  102. }
  103. }
  104. return slot;
  105. }
  106. /* free slot array */
  107. void my_atmel_free(int slotId)
  108. {
  109. if(slotId >= 0 && slotId < ATECC_MAX_SLOT){
  110. mSlotList[slotId] = ATECC_INVALID_SLOT;
  111. }
  112. }
  113. #endif /* CUSTOM_SLOT_ALLOCATION */
  114. #endif /* WOLFSSL_ESPWROOM32SE && HAVE_PK_CALLBACK && WOLFSSL_ATECC508A */
  115. /* Entry for FreeRTOS */
  116. void app_main(void)
  117. {
  118. #if !defined(SINGLE_THREADED) && INCLUDE_uxTaskGetStackHighWaterMark
  119. int stack_start = 0;
  120. #endif
  121. #if !defined(SINGLE_THREADED)
  122. int this_heap = 0;
  123. #endif
  124. esp_err_t ret = 0;
  125. ESP_LOGI(TAG, "---------------- wolfSSL TLS Client Example ------------");
  126. ESP_LOGI(TAG, "--------------------------------------------------------");
  127. ESP_LOGI(TAG, "--------------------------------------------------------");
  128. ESP_LOGI(TAG, "---------------------- BEGIN MAIN ----------------------");
  129. ESP_LOGI(TAG, "--------------------------------------------------------");
  130. ESP_LOGI(TAG, "--------------------------------------------------------");
  131. #if !defined(CONFIG_WOLFSSL_EXAMPLE_NAME_TLS_CLIENT)
  132. ESP_LOGW(TAG, "Warning: Example wolfSSL misconfigured? Check menuconfig.");
  133. #endif
  134. #ifdef ESP_SDK_MEM_LIB_VERSION
  135. sdk_init_meminfo();
  136. #endif
  137. #ifdef ESP_TASK_MAIN_STACK
  138. ESP_LOGI(TAG, "ESP_TASK_MAIN_STACK: %d", ESP_TASK_MAIN_STACK);
  139. #endif
  140. #ifdef TASK_EXTRA_STACK_SIZE
  141. ESP_LOGI(TAG, "TASK_EXTRA_STACK_SIZE: %d", TASK_EXTRA_STACK_SIZE);
  142. #endif
  143. #ifdef SINGLE_THREADED
  144. ESP_LOGI(TAG, "Single threaded");
  145. #else
  146. ESP_LOGI(TAG, "CONFIG_ESP_MAIN_TASK_STACK_SIZE = %d bytes (%d words)",
  147. CONFIG_ESP_MAIN_TASK_STACK_SIZE,
  148. (int)(CONFIG_ESP_MAIN_TASK_STACK_SIZE / sizeof(void*)));
  149. #ifdef INCLUDE_uxTaskGetStackHighWaterMark
  150. {
  151. /* Returns the high water mark of the stack associated with xTask. That is,
  152. * the minimum free stack space there has been (in bytes not words, unlike
  153. * vanilla FreeRTOS) since the task started. The smaller the returned
  154. * number the closer the task has come to overflowing its stack.
  155. * see Espressif api-reference/system/freertos_idf
  156. */
  157. stack_start = uxTaskGetStackHighWaterMark(NULL);
  158. #ifdef ESP_SDK_MEM_LIB_VERSION
  159. {
  160. sdk_var_whereis("stack_start", &stack_start);
  161. }
  162. #endif
  163. ESP_LOGI(TAG, "Stack Start HWM: %d bytes", stack_start);
  164. }
  165. #endif /* INCLUDE_uxTaskGetStackHighWaterMark */
  166. #endif /* SINGLE_THREADED */
  167. #ifdef HAVE_VERSION_EXTENDED_INFO
  168. esp_ShowExtendedSystemInfo();
  169. #endif
  170. #ifdef DEBUG_WOLFSSL
  171. wolfSSL_Debugging_OFF();
  172. #endif
  173. #ifdef CONFIG_IDF_TARGET_ESP32H2
  174. ESP_LOGE(TAG, "No WiFi on the ESP32-H2 and ethernet not yet supported");
  175. while (1) {
  176. vTaskDelay(60000);
  177. }
  178. #endif
  179. /* Set time for cert validation.
  180. * Some lwIP APIs, including SNTP functions, are not thread safe. */
  181. ret = set_time(); /* need to setup NTP before WiFi */
  182. /* Optionally erase flash */
  183. /* ESP_ERROR_CHECK(nvs_flash_erase()); */
  184. #ifdef FOUND_PROTOCOL_EXAMPLES_DIR
  185. ESP_LOGI(TAG, "FOUND_PROTOCOL_EXAMPLES_DIR active, using example code.");
  186. ESP_ERROR_CHECK(nvs_flash_init());
  187. #if defined(CONFIG_IDF_TARGET_ESP32H2)
  188. ESP_LOGE(TAG, "There's no WiFi on ESP32-H2.");
  189. #else
  190. #ifdef CONFIG_EXAMPLE_WIFI_SSID
  191. if (XSTRCMP(CONFIG_EXAMPLE_WIFI_SSID, "myssid") == 0) {
  192. ESP_LOGW(TAG, "WARNING: CONFIG_EXAMPLE_WIFI_SSID is myssid.");
  193. ESP_LOGW(TAG, " Do you have a WiFi AP called myssid, or ");
  194. ESP_LOGW(TAG, " did you forget the ESP-IDF configuration?");
  195. }
  196. #else
  197. #define CONFIG_EXAMPLE_WIFI_SSID "myssid"
  198. ESP_LOGW(TAG, "WARNING: CONFIG_EXAMPLE_WIFI_SSID not defined.");
  199. #endif
  200. ESP_ERROR_CHECK(esp_netif_init());
  201. ESP_ERROR_CHECK(esp_event_loop_create_default());
  202. ESP_ERROR_CHECK(example_connect());
  203. #endif
  204. #else
  205. ESP_ERROR_CHECK(nvs_flash_init());
  206. /* Initialize NVS */
  207. ret = nvs_flash_init();
  208. #if defined(CONFIG_IDF_TARGET_ESP8266)
  209. {
  210. if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
  211. ESP_ERROR_CHECK(nvs_flash_erase());
  212. ret = nvs_flash_init();
  213. }
  214. }
  215. #else
  216. {
  217. /* Non-ESP8266 initialization is slightly different */
  218. if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
  219. ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  220. ESP_ERROR_CHECK(nvs_flash_erase());
  221. ret = nvs_flash_init();
  222. }
  223. }
  224. #endif /* else not CONFIG_IDF_TARGET_ESP8266 */
  225. ESP_ERROR_CHECK(ret);
  226. #if defined(CONFIG_IDF_TARGET_ESP32H2)
  227. ESP_LOGE(TAG, "There's no WiFi on ESP32-H2. ");
  228. #else
  229. /* Initialize WiFi */
  230. ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
  231. ret = wifi_init_sta();
  232. while (ret != 0) {
  233. ESP_LOGI(TAG, "Waiting...");
  234. vTaskDelay(60000 / portTICK_PERIOD_MS);
  235. ESP_LOGI(TAG, "Trying WiFi again...");
  236. ret = wifi_init_sta();
  237. }
  238. #endif /* else not CONFIG_IDF_TARGET_ESP32H2 */
  239. #endif /* else FOUND_PROTOCOL_EXAMPLES_DIR not found */
  240. /* Once we are connected to the network, start & wait for NTP time */
  241. ret = set_time_wait_for_ntp();
  242. if (ret < -1) {
  243. /* a value of -1 means there was no NTP server, so no need to wait */
  244. ESP_LOGI(TAG, "Waiting 10 more seconds for NTP to complete." );
  245. vTaskDelay(10000 / portTICK_PERIOD_MS); /* brute-force solution */
  246. esp_show_current_datetime();
  247. }
  248. #if defined(SINGLE_THREADED)
  249. /* just call the task */
  250. tls_smp_client_task((void*)NULL);
  251. #else
  252. tls_args args[1] = {0};
  253. /* start a thread with the task */
  254. args[0].loops = 10;
  255. args[0].port = 11111;
  256. /* HWM is maximum amount of stack space that has been unused, in bytes
  257. * not words (unlike vanilla freeRTOS). */
  258. this_heap = esp_get_free_heap_size();
  259. ESP_LOGI(TAG, "Initial Stack Used (before wolfSSL Server): %d bytes",
  260. CONFIG_ESP_MAIN_TASK_STACK_SIZE
  261. - (uxTaskGetStackHighWaterMark(NULL))
  262. );
  263. ESP_LOGI(TAG, "Starting TLS Client task ...\n");
  264. ESP_LOGI(TAG, "main tls_smp_client_init heap @ %p = %d",
  265. &this_heap, this_heap);
  266. tls_smp_client_init(args);
  267. /* optional additional client threads
  268. tls_smp_client_init(args);
  269. tls_smp_client_init(args);
  270. tls_smp_client_init(args);
  271. tls_smp_client_init(args);
  272. tls_smp_client_init(args);
  273. tls_smp_client_init(args);
  274. tls_smp_client_init(args);
  275. */
  276. #endif
  277. /* Done */
  278. #ifdef SINGLE_THREADED
  279. ESP_LOGV(TAG, "\n\nDone!\n\n");
  280. while (1);
  281. #else
  282. ESP_LOGV(TAG, "\n\nvTaskDelete...\n\n");
  283. vTaskDelete(NULL);
  284. /* done */
  285. while (1) {
  286. ESP_LOGV(TAG, "\n\nLoop...\n\n");
  287. #ifdef INCLUDE_uxTaskGetStackHighWaterMark
  288. ESP_LOGI(TAG, "Stack HWM: %d", uxTaskGetStackHighWaterMark(NULL));
  289. ESP_LOGI(TAG, "Stack used: %d", CONFIG_ESP_MAIN_TASK_STACK_SIZE
  290. - (uxTaskGetStackHighWaterMark(NULL) ));
  291. #endif
  292. vTaskDelay(60000);
  293. } /* done while */
  294. #endif /* else not SINGLE_THREADED */
  295. } /* app_main */