From 2000e459c952814929ab589ebee159bf1197ec86 Mon Sep 17 00:00:00 2001 From: marc Date: Sun, 27 Apr 2025 19:22:17 +0200 Subject: [PATCH 1/5] ajout capteur presence --- components/communication/communication.c | 3 +- main/CMakeLists.txt | 2 +- main/Kconfig.projbuild | 59 ++--------------- main/main.c | 81 ++++++++++++++++++++++-- 4 files changed, 86 insertions(+), 59 deletions(-) diff --git a/components/communication/communication.c b/components/communication/communication.c index 131d183..06b2983 100644 --- a/components/communication/communication.c +++ b/components/communication/communication.c @@ -320,7 +320,6 @@ static EventGroupHandle_t s_wifi_event_group; #define EXAMPLE_ESP_MAXIMUM_RETRY 5 #define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_BOTH -#define EXAMPLE_H2E_IDENTIFIER CONFIG_ESP_WIFI_PW_ID #define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK static int s_retry_num = 0; @@ -434,7 +433,7 @@ void wifi_init_sta(void) */ .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD, .sae_pwe_h2e = ESP_WIFI_SAE_MODE, - .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER, + .sae_h2e_identifier = "", }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 39c1c1e..7d352d2 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -2,7 +2,7 @@ set(EXTRA_COMPONENT_DIRS ../components) idf_component_register(SRC_DIRS . fonts INCLUDE_DIRS "." - REQUIRES heap nvs_flash meteofrance communication esp_netif image_downloader fatfs sdmmc vfs littlefs wifi_logger protocol_examples_common app_update esp_https_ota bsp_extra esp32_p4_function_ev_board + REQUIRES heap nvs_flash meteofrance communication esp_netif image_downloader fatfs sdmmc vfs littlefs wifi_logger protocol_examples_common app_update esp_https_ota bsp_extra esp32_p4_function_ev_board esp_driver_gpio EMBED_TXTFILES ${project_dir}/main/ca_cert.pem) diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 6908f20..bd7b37c 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -1,4 +1,4 @@ -menu "Example Configuration" +menu "Domotic Configuration" config ESP_WIFI_SSID string "WiFi SSID" @@ -12,56 +12,11 @@ menu "Example Configuration" help WiFi password (WPA or WPA2) for the example to use. - choice ESP_WIFI_SAE_MODE - prompt "WPA3 SAE mode selection" - default ESP_WPA3_SAE_PWE_BOTH + config GPIO_INPUT_CAPTEUR_PIR + int "GPIO PIN Capteur PIR" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 4 help - Select mode for SAE as Hunt and Peck, H2E or both. - config ESP_WPA3_SAE_PWE_HUNT_AND_PECK - bool "HUNT AND PECK" - config ESP_WPA3_SAE_PWE_HASH_TO_ELEMENT - bool "H2E" - config ESP_WPA3_SAE_PWE_BOTH - bool "BOTH" - endchoice - - config ESP_WIFI_PW_ID - string "PASSWORD IDENTIFIER" - depends on ESP_WPA3_SAE_PWE_HASH_TO_ELEMENT|| ESP_WPA3_SAE_PWE_BOTH - default "" - help - password identifier for SAE H2E - - config ESP_MAXIMUM_RETRY - int "Maximum retry" - default 5 - help - Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent. - - choice ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD - prompt "WiFi Scan auth mode threshold" - default ESP_WIFI_AUTH_WPA2_PSK - help - The weakest authmode to accept in the scan mode. - This value defaults to ESP_WIFI_AUTH_WPA2_PSK incase password is present and ESP_WIFI_AUTH_OPEN is used. - Please select ESP_WIFI_AUTH_WEP/ESP_WIFI_AUTH_WPA_PSK incase AP is operating in WEP/WPA mode. - - config ESP_WIFI_AUTH_OPEN - bool "OPEN" - config ESP_WIFI_AUTH_WEP - bool "WEP" - config ESP_WIFI_AUTH_WPA_PSK - bool "WPA PSK" - config ESP_WIFI_AUTH_WPA2_PSK - bool "WPA2 PSK" - config ESP_WIFI_AUTH_WPA_WPA2_PSK - bool "WPA/WPA2 PSK" - config ESP_WIFI_AUTH_WPA3_PSK - bool "WPA3 PSK" - config ESP_WIFI_AUTH_WPA2_WPA3_PSK - bool "WPA2/WPA3 PSK" - config ESP_WIFI_AUTH_WAPI_PSK - bool "WAPI PSK" - endchoice - + GPIO pin à utiliser pour le capteur de présence IR. + endmenu diff --git a/main/main.c b/main/main.c index a6aba0d..9dc87da 100644 --- a/main/main.c +++ b/main/main.c @@ -29,9 +29,11 @@ #include "image_downloader.h" #include "communication.h" #include "stateManagement.h" - +#include "driver/gpio.h" #include "am2302_rmt.h" +#include "esp_timer.h" + // GPIO assignment #define AM2302_GPIO 4 @@ -237,9 +239,81 @@ void alloc_fail(size_t size, uint32_t caps, const char * function_name){ ESP_LOGE(TAG,"fail alloc %u in %" PRIu32 " in %s", size,caps,function_name); } +static QueueHandle_t gpio_evt_queue = NULL; +esp_timer_handle_t periodic_timer; + +static void IRAM_ATTR gpio_isr_handler(void* arg) +{ + uint32_t gpio_num = (uint32_t) arg; + xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); + +} +static void gpio_task_example(void* arg) +{ + uint32_t io_num; + int delay=50; + for (;;) { + if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { + ESP_LOGE(TAG,"Got it !"); + for (int i = 0; i < 100; i++) + { + bsp_display_brightness_set(i); + vTaskDelay(delay/portTICK_PERIOD_MS); + } + //On arrete le timer de presence + esp_timer_stop(periodic_timer); + //Pour le redemarrer + ESP_ERROR_CHECK(esp_timer_start_once(periodic_timer, 10*1000*1000)); + + } + } +} +#define GPIO_INPUT_IO_0 CONFIG_GPIO_INPUT_CAPTEUR_PIR + +void initPirSensor(){ + //create a queue to handle gpio event from isr + gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t)); + //start gpio task + xTaskCreate(gpio_task_example, "gpio_task_example", 5000, NULL, 10, NULL); + + gpio_config_t gpioconf={ + .pin_bit_mask= 1ULL<= 0; i--) + { + bsp_display_brightness_set(i); + vTaskDelay(20/portTICK_PERIOD_MS); + } +} void app_main(void) { + const esp_timer_create_args_t periodic_timer_args = { + .callback = &periodic_timer_callback, + /* name is optional, but may help identify the timer when debugging */ + .name = "presence" + }; + ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer)); + /* Start the timers */ + ESP_ERROR_CHECK(esp_timer_start_once(periodic_timer, 30*1000*1000)); + + + initPirSensor(); + printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size()); printf("Free heap size: %" PRIu32 " bytes\n", esp_get_free_heap_size()); heap_caps_print_heap_info(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); @@ -378,8 +452,7 @@ void app_main(void) mqtt_app_start(); - - +/* // Configuration de la sonde Temp/Humid. am2302_config_t am2302_config = { .gpio_num = AM2302_GPIO, @@ -391,7 +464,7 @@ void app_main(void) xTaskCreate(&readTempHumid, "read_temp_task", 8192, NULL, 5, NULL); - +*/ //xTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL); From 7c7d298af1d7d5180e5c470f1ccdb152bb9d3df3 Mon Sep 17 00:00:00 2001 From: marc Date: Tue, 6 May 2025 20:57:25 +0200 Subject: [PATCH 2/5] coredump httpserver --- main/CMakeLists.txt | 5 +- main/index.html | 80 ++++++++++++++++++++++++++++++ main/main.c | 115 +++++++++++++++++++++++++++++++++++++++++--- partitions.csv | 1 + sdkconfig | 69 ++++++++++++++++++-------- 5 files changed, 242 insertions(+), 28 deletions(-) create mode 100644 main/index.html diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 7d352d2..5938d21 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -2,8 +2,9 @@ set(EXTRA_COMPONENT_DIRS ../components) idf_component_register(SRC_DIRS . fonts INCLUDE_DIRS "." - REQUIRES heap nvs_flash meteofrance communication esp_netif image_downloader fatfs sdmmc vfs littlefs wifi_logger protocol_examples_common app_update esp_https_ota bsp_extra esp32_p4_function_ev_board esp_driver_gpio - EMBED_TXTFILES ${project_dir}/main/ca_cert.pem) + REQUIRES heap espcoredump esp_http_server nvs_flash meteofrance communication esp_netif image_downloader fatfs sdmmc vfs littlefs wifi_logger protocol_examples_common app_update esp_https_ota bsp_extra esp32_p4_function_ev_board esp_driver_gpio + EMBED_TXTFILES ${project_dir}/main/ca_cert.pem + EMBED_FILES "index.html") set_source_files_properties( diff --git a/main/index.html b/main/index.html new file mode 100644 index 0000000..9daf545 --- /dev/null +++ b/main/index.html @@ -0,0 +1,80 @@ + + + + + + + + +
+

Developed by Mark

+

How to save and Download crash dump

+

+

+ +
+ + diff --git a/main/main.c b/main/main.c index 9dc87da..81d56eb 100644 --- a/main/main.c +++ b/main/main.c @@ -13,6 +13,8 @@ #include "sdmmc_cmd.h" #include +#include "esp_http_server.h" + #include "bsp/esp-bsp.h" #include "main.h" @@ -292,12 +294,108 @@ void initPirSensor(){ static void periodic_timer_callback(void* arg) { int64_t time_since_boot = esp_timer_get_time(); - ESP_LOGI(TAG, "Periodic timer called, time since boot: %lld us", time_since_boot); - for (int i = 100; i >= 0; i--) - { - bsp_display_brightness_set(i); - vTaskDelay(20/portTICK_PERIOD_MS); - } + if(bsp_display_lock(0)){ + for (int i = 100; i >= 0; i--) + { + bsp_display_brightness_set(i); + vTaskDelay(20/portTICK_PERIOD_MS); + } + bsp_display_unlock(); + } + ecranEteint=true; +} + +static esp_err_t download_get_handler(httpd_req_t *req) { + httpd_resp_set_type(req, "application/octet-stream"); + httpd_resp_set_hdr(req, "Content-Disposition", + "attachment;filename=core.bin"); + + esp_partition_iterator_t partition_iterator = esp_partition_find( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, "coredump"); + + const esp_partition_t *partition = esp_partition_get(partition_iterator); + + int file_size = 65536; + int chunk_size = 1024; + int i = 0; + for (i = 0; i < (file_size / chunk_size); i++) { + char store_data[chunk_size]; + ESP_ERROR_CHECK( + esp_partition_read(partition, i * chunk_size, store_data, chunk_size)); + httpd_resp_send_chunk(req, store_data, chunk_size); + } + uint16_t pending_size = file_size - (i * chunk_size); + char pending_data[pending_size]; + if (pending_size > 0) { + ESP_ERROR_CHECK(esp_partition_read(partition, i * chunk_size, pending_data, + pending_size)); + httpd_resp_send_chunk(req, pending_data, pending_size); + } + httpd_resp_send_chunk(req, NULL, 0); + return ESP_OK; +} + + +extern const unsigned char index_start[] asm("_binary_index_html_start"); +extern const unsigned char index_end[] asm("_binary_index_html_end"); + +static esp_err_t crash_get_handler(httpd_req_t *req) { + const size_t index_size = (index_end - index_start); + httpd_resp_set_type(req, "text/html"); + httpd_resp_send_chunk(req, (const char *)index_start, index_size); + httpd_resp_send_chunk(req, NULL, 0); + assert(0); + return ESP_OK; +} + +static const httpd_uri_t download = { + .uri = "/download", + .method = HTTP_GET, + .handler = download_get_handler, + .user_ctx = NULL, +}; + +static const httpd_uri_t crash = { + .uri = "/crash", + .method = HTTP_GET, + .handler = crash_get_handler, + .user_ctx = NULL, +}; +static esp_err_t root_get_handler(httpd_req_t *req) { + const size_t index_size = (index_end - index_start); + httpd_resp_set_type(req, "text/html"); + httpd_resp_send_chunk(req, (const char *)index_start, index_size); + httpd_resp_send_chunk(req, NULL, 0); + return ESP_OK; +} +static const httpd_uri_t root = { + .uri = "/", + .method = HTTP_GET, + .handler = root_get_handler, + .user_ctx = NULL, +}; + + + +static httpd_handle_t start_webserver(void) { + httpd_handle_t server = NULL; + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + config.max_resp_headers = 1024; + config.lru_purge_enable = true; + + // Start the httpd server + ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port); + if (httpd_start(&server, &config) == ESP_OK) { + // Set URI handlers + ESP_LOGI(TAG, "Registering URI handlers"); + httpd_register_uri_handler(server, &root); + httpd_register_uri_handler(server, &download); + httpd_register_uri_handler(server, &crash); + return server; + } + + ESP_LOGI(TAG, "Error starting server!"); + return NULL; } void app_main(void) @@ -451,6 +549,11 @@ void app_main(void) } mqtt_app_start(); + while(!mainState.wifi_init){ + vTaskDelay(pdTICKS_TO_MS(10)); + } + start_webserver(); + /* // Configuration de la sonde Temp/Humid. diff --git a/partitions.csv b/partitions.csv index b37897a..7d99991 100644 --- a/partitions.csv +++ b/partitions.csv @@ -7,3 +7,4 @@ factory,app,factory,,3M,, ota_0,app,ota_0,,3M,, ota_1,app,ota_1,,3M,, littlefs,data,littlefs,,1M,, +coredump, data, coredump,,64K,, diff --git a/sdkconfig b/sdkconfig index a9e9305..b8d0b71 100644 --- a/sdkconfig +++ b/sdkconfig @@ -687,24 +687,12 @@ CONFIG_PARTITION_TABLE_MD5=y # end of Partition Table # -# Example Configuration +# Domotic Configuration # CONFIG_ESP_WIFI_SSID="myssid" CONFIG_ESP_WIFI_PASSWORD="mypassword" -# CONFIG_ESP_WPA3_SAE_PWE_HUNT_AND_PECK is not set -# CONFIG_ESP_WPA3_SAE_PWE_HASH_TO_ELEMENT is not set -CONFIG_ESP_WPA3_SAE_PWE_BOTH=y -CONFIG_ESP_WIFI_PW_ID="" -CONFIG_ESP_MAXIMUM_RETRY=5 -# CONFIG_ESP_WIFI_AUTH_OPEN is not set -# CONFIG_ESP_WIFI_AUTH_WEP is not set -# CONFIG_ESP_WIFI_AUTH_WPA_PSK is not set -CONFIG_ESP_WIFI_AUTH_WPA2_PSK=y -# CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK is not set -# CONFIG_ESP_WIFI_AUTH_WPA3_PSK is not set -# CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK is not set -# CONFIG_ESP_WIFI_AUTH_WAPI_PSK is not set -# end of Example Configuration +CONFIG_GPIO_INPUT_CAPTEUR_PIR=4 +# end of Domotic Configuration # # Example Connection Configuration @@ -1037,6 +1025,19 @@ CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 # end of ESP HTTP client +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 +# end of HTTP Server + # # ESP HTTPS OTA # @@ -1228,10 +1229,7 @@ CONFIG_SPIRAM_MODE_HEX=y CONFIG_SPIRAM_SPEED_200M=y # CONFIG_SPIRAM_SPEED_20M is not set CONFIG_SPIRAM_SPEED=200 -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y -CONFIG_SPIRAM_RODATA=y -CONFIG_SPIRAM_XIP_FROM_PSRAM=y -CONFIG_SPIRAM_FLASH_LOAD_TO_PSRAM=y +# CONFIG_SPIRAM_XIP_FROM_PSRAM is not set # CONFIG_SPIRAM_ECC_ENABLE is not set CONFIG_SPIRAM_BOOT_INIT=y # CONFIG_SPIRAM_IGNORE_NOTFOUND is not set @@ -1400,6 +1398,26 @@ CONFIG_ESP_WIFI_TX_HETB_QUEUE_NUM=3 CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y # end of Wi-Fi +# +# Core dump +# +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_NONE is not set +# CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN is not set +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_CRC32=y +# CONFIG_ESP_COREDUMP_CHECKSUM_SHA256 is not set +# CONFIG_ESP_COREDUMP_CAPTURE_DRAM is not set +CONFIG_ESP_COREDUMP_CHECK_BOOT=y +CONFIG_ESP_COREDUMP_ENABLE=y +CONFIG_ESP_COREDUMP_LOGS=y +CONFIG_ESP_COREDUMP_MAX_TASKS_NUM=64 +# CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE is not set +CONFIG_ESP_COREDUMP_STACK_SIZE=0 +CONFIG_ESP_COREDUMP_SUMMARY_STACKDUMP_SIZE=1024 +# end of Core dump + # # FAT Filesystem support # @@ -1491,12 +1509,13 @@ CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U32=y # # Port # +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_ISR_STACKSIZE=2096 CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y @@ -2969,6 +2988,16 @@ CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y CONFIG_WPA_MBEDTLS_CRYPTO=y CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE is not set +# CONFIG_ESP32_COREDUMP_DATA_FORMAT_BIN is not set +CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP32_COREDUMP_CHECKSUM_CRC32=y +# CONFIG_ESP32_COREDUMP_CHECKSUM_SHA256 is not set +CONFIG_ESP32_ENABLE_COREDUMP=y +CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM=64 +CONFIG_ESP32_CORE_DUMP_STACK_SIZE=0 CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 From ad4cd34559cb743ce136f5810497606a9158390f Mon Sep 17 00:00:00 2001 From: marc Date: Tue, 6 May 2025 20:58:57 +0200 Subject: [PATCH 3/5] amelioration pir --- main/main.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/main/main.c b/main/main.c index 81d56eb..81b84c6 100644 --- a/main/main.c +++ b/main/main.c @@ -242,7 +242,11 @@ void alloc_fail(size_t size, uint32_t caps, const char * function_name){ } static QueueHandle_t gpio_evt_queue = NULL; -esp_timer_handle_t periodic_timer; +// Durée pour l'arret automatique (micro-secondes ^^) +uint64_t arretAuto=5*60*1000*1000; +bool ecranEteint=true; +// Ce timer permet d'eteindre l'ecran "arretAuto" apres la derniere présence détectée +esp_timer_handle_t presence_timer; static void IRAM_ATTR gpio_isr_handler(void* arg) { @@ -257,16 +261,23 @@ static void gpio_task_example(void* arg) for (;;) { if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { ESP_LOGE(TAG,"Got it !"); - for (int i = 0; i < 100; i++) - { - bsp_display_brightness_set(i); - vTaskDelay(delay/portTICK_PERIOD_MS); + if(ecranEteint){ + if(bsp_display_lock(0)){ + for (int i = 0; i < 100; i++) + { + bsp_display_brightness_set(i); + vTaskDelay(delay/portTICK_PERIOD_MS); + } + bsp_display_unlock(); + ecranEteint=false; + } + }else{ + ESP_LOGI(TAG, "Ecran déjà allumé"); } //On arrete le timer de presence - esp_timer_stop(periodic_timer); + esp_timer_stop(presence_timer); //Pour le redemarrer - ESP_ERROR_CHECK(esp_timer_start_once(periodic_timer, 10*1000*1000)); - + ESP_ERROR_CHECK(esp_timer_start_once(presence_timer, arretAuto)); } } } @@ -290,8 +301,8 @@ void initPirSensor(){ } -/* Ce timer permet d'eteindre l'ecran apres 30s de présence*/ -static void periodic_timer_callback(void* arg) +/* Ce timer permet d'eteindre l'ecran apres @arretAuto de présence*/ +static void presence_timer_callback(void* arg) { int64_t time_since_boot = esp_timer_get_time(); if(bsp_display_lock(0)){ @@ -401,13 +412,13 @@ static httpd_handle_t start_webserver(void) { void app_main(void) { const esp_timer_create_args_t periodic_timer_args = { - .callback = &periodic_timer_callback, + .callback = &presence_timer_callback, /* name is optional, but may help identify the timer when debugging */ .name = "presence" }; - ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer)); + ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &presence_timer)); /* Start the timers */ - ESP_ERROR_CHECK(esp_timer_start_once(periodic_timer, 30*1000*1000)); + ESP_ERROR_CHECK(esp_timer_start_once(presence_timer, 30*1000*1000)); initPirSensor(); From e963d43a018eef2f43352401c21259f0cb0ccf6c Mon Sep 17 00:00:00 2001 From: marc Date: Wed, 7 May 2025 12:30:35 +0200 Subject: [PATCH 4/5] OTA fonctionnel ! --- main/ca_cert.pem | 34 +++++++++--------- main/main.c | 92 +++++++++++++++++++++++++++++++++++++++++------- version.txt | 1 + 3 files changed, 98 insertions(+), 29 deletions(-) create mode 100644 version.txt diff --git a/main/ca_cert.pem b/main/ca_cert.pem index 7eff939..bd2b618 100644 --- a/main/ca_cert.pem +++ b/main/ca_cert.pem @@ -1,22 +1,22 @@ -----BEGIN CERTIFICATE----- -MIIDmTCCAoGgAwIBAgIUd5qKY6blEffPyHQZnmQfxkcCO7AwDQYJKoZIhvcNAQEL -BQAwXDELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +MIIDmTCCAoGgAwIBAgIUJyG8nVHyoUV/0lOqRtSCjVnEtfYwDQYJKoZIhvcNAQEL +BQAwXDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEVMBMGA1UEAwwMMTkyLjE2OC4wLjI4 -MB4XDTI0MTExMzE4MjYxOVoXDTI1MTExMzE4MjYxOVowXDELMAkGA1UEBhMCRlIx +MB4XDTI1MDUwNzA3NTMzMVoXDTI2MDUwNzA3NTMzMVowXDELMAkGA1UEBhMCQVUx EzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg UHR5IEx0ZDEVMBMGA1UEAwwMMTkyLjE2OC4wLjI4MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA8lKPcpJ6/FhrI+E8fzR93N/XIfEW7GpFa+KNp+DK9DGS -hHno2yVGXNdUFRQEL/2pL8aiZzZ7xGMubzEIr1dlHrb/PplGRTXCxQWnDJDsOu4w -7TbzjYxDhgMwXhSGuFlMexFBh+W9qcO85l4wNSOhHusyf7XZaPAd3NGmK4XsoeXJ -DSROJLLpvyZM3yt1kuC3GTWSqUe4Ldv+kaAfyW+X/PJ7Tgb6frLGNCs5A0zLhFxb -FS2omnqX6+H2Bjvk3nCQr85zcuIrnXQ+Hy58MayS+dRqPTSNw7RqRVvrGUuQuj5y -/ruAVLjG6F9wTZZFJ8Nk2veuFxIG+8ADpglWoYrokQIDAQABo1MwUTAdBgNVHQ4E -FgQUUa64jnTc+VqWQB93Fp/yPuirm2cwHwYDVR0jBBgwFoAUUa64jnTc+VqWQB93 -Fp/yPuirm2cwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAnqg9 -DeBozovXmwcbDTlTqz1b5LJ3Xz4mhUnEssmlDvvlXMqL1CjeXDKgOXtkWaomTJNO -MfMTmkkKg2lomNe2O84nUyPJnHYle5cbxZXAvbkmsi6R95lXFf5+bHAtU05TFYKc -BWMPB3Vwym9qrAc8G1LPr05LYgrJsQ9xkf0pVR7hrjgu9k6ElNAQSiH4dlyK4b/T -12U4zBawZNv3f6OnKOTq2NuwwzxWSwRRbEGUf0qO6Z8LNsj7yvmp2ImfN1e3a39p -+WmxJkHBzg5LxUon8jtiZLKeAPNlAPvKTs/4umE0LdZnsdlYrNR+kFeMMurxHvfZ -ykxPELUVUWEgv/IRbA== +AAOCAQ8AMIIBCgKCAQEAvG8y2D7/NR+7YZIRLUYgpe88nWxU/WPTgq5+0wZElEhx +e7ZG0YvYFy298RHhZ3m2KsMrWTaZcnjS41QRsMajoeIjCwnmJ5MkNfCMxAoeFC4D +p26CIzkA6h++RK8MmHLwEdB3sjskafd+Iu/bBA+KDUdQiy6GL3zXVOUjdUFB5MFT +EO0vNZhfjdpv4iQ71KIvS9ORCh6OfvSkUaRCoIa2NQXbLi4be0onV+8UXpX06V6Y +dADj+Gdw32STOb8PI24Ri1EQkED34IaGeaNte0+882ma3J8hX3vnXQbhpC1N+TqA +1szvZUDNs2qmRiLqXyZkxhXJRS055n0wjGdFUmzPgwIDAQABo1MwUTAdBgNVHQ4E +FgQUk7EOCIXLo4LGatOpmk1XdGr7tkwwHwYDVR0jBBgwFoAUk7EOCIXLo4LGatOp +mk1XdGr7tkwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAkGpE +Q8n9za+NxdAnBMcV4GB0zPBK2NNEY7OXbRv0GA/qBAd0CsvP9QbidC/9Toz7ptT4 +KyCZFGx8Xx2AWRx60kJ/f2VVUZIZzUoOA6qj3lN8keAT+OGWszvaXlXIbW/TJrs0 +lCv4ynkXI4dBhAd3DnXPQSrEyr1h8DValqh1R/kxi+Kb4SYODIoLz0aRbPJFes3z +n10wPTlxARiz6iKQrZP5UKIrFuWyBPZ5xCHn7AmNdqZqtBKB+ERychSjh5b0oznO +AzZDnBoB4lriWTM0yVV1w1eurz0B0Qtz/rqQnYEhWLJodZC8ipjeUoap6BcPHOMq +tx49i3GdxzVoewbZFQ== -----END CERTIFICATE----- diff --git a/main/main.c b/main/main.c index 81b84c6..f334fdd 100644 --- a/main/main.c +++ b/main/main.c @@ -157,9 +157,32 @@ esp_err_t _ota_http_event_handler(esp_http_client_event_t *evt) extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start"); extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end"); +static esp_err_t validate_image_header(esp_app_desc_t *new_app_info) +{ + if (new_app_info == NULL) { + return ESP_ERR_INVALID_ARG; + } + + const esp_partition_t *running = esp_ota_get_running_partition(); + esp_app_desc_t running_app_info; + if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) { + ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version); + } + +#ifndef CONFIG_EXAMPLE_SKIP_VERSION_CHECK + if (memcmp(new_app_info->version, running_app_info.version, sizeof(new_app_info->version)) == 0) { + ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update."); + return ESP_FAIL; + } +#endif + + return ESP_OK; +} + void simple_ota_example_task(void *pvParameter) { + esp_err_t ota_finish_err = ESP_OK; ESP_LOGI(TAG, "Starting OTA example task"); #ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF esp_netif_t *netif = get_example_netif_from_desc(bind_interface_name); @@ -172,7 +195,7 @@ void simple_ota_example_task(void *pvParameter) ESP_LOGI(TAG, "Bind interface name is %s", ifr.ifr_name); #endif esp_http_client_config_t config = { - .url = "http://192.168.0.28:8070/rgb_lcd.bin", + .url = "https://192.168.0.28:8070/rgb_lcd.bin", .timeout_ms = 30000, .buffer_size = 6144, .buffer_size_tx = 6144, //TX Buffer, Main Buffer @@ -206,18 +229,59 @@ void simple_ota_example_task(void *pvParameter) .http_config = &config, }; ESP_LOGI(TAG, "Attempting to download update from %s", config.url); - esp_err_t ret = esp_https_ota(&ota_config); - if (ret == ESP_OK) { - ESP_LOGI(TAG, "OTA Succeed, Rebooting..."); - esp_restart(); - } else { - ESP_LOGE(TAG, "Firmware upgrade failed"); + esp_https_ota_handle_t https_ota_handle = NULL; + esp_err_t err = esp_https_ota_begin(&ota_config, &https_ota_handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "ESP HTTPS OTA Begin failed"); + vTaskDelete(NULL); } - while (1) { - vTaskDelay(1000 / portTICK_PERIOD_MS); - } -} + esp_app_desc_t app_desc; + err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_https_ota_get_img_desc failed"); + goto ota_end; + } + err = validate_image_header(&app_desc); + if (err != ESP_OK) { + ESP_LOGE(TAG, "image header verification failed"); + goto ota_end; + } + + while (1) { + err = esp_https_ota_perform(https_ota_handle); + if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) { + break; + } + // esp_https_ota_perform returns after every read operation which gives user the ability to + // monitor the status of OTA upgrade by calling esp_https_ota_get_image_len_read, which gives length of image + // data read so far. + ESP_LOGD(TAG, "Image bytes read: %d", esp_https_ota_get_image_len_read(https_ota_handle)); + } + + if (esp_https_ota_is_complete_data_received(https_ota_handle) != true) { + // the OTA image was not completely received and user can customise the response to this situation. + ESP_LOGE(TAG, "Complete data was not received."); + } else { + ota_finish_err = esp_https_ota_finish(https_ota_handle); + if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) { + ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ..."); + vTaskDelay(1000 / portTICK_PERIOD_MS); + esp_restart(); + } else { + if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) { + ESP_LOGE(TAG, "Image validation failed, image is corrupted"); + } + ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err); + vTaskDelete(NULL); + } + } + +ota_end: + esp_https_ota_abort(https_ota_handle); + ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed"); + vTaskDelete(NULL); +} am2302_handle_t sensor = NULL; @@ -579,7 +643,11 @@ void app_main(void) xTaskCreate(&readTempHumid, "read_temp_task", 8192, NULL, 5, NULL); */ - //xTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL); + /* Ensure to disable any WiFi power save mode, this allows best throughput + * and hence timings for overall OTA operation. + */ + esp_wifi_set_ps(WIFI_PS_NONE); + xTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL); } diff --git a/version.txt b/version.txt new file mode 100644 index 0000000..2f45361 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +0.2 \ No newline at end of file From ce83025eb2bfa04731df13f5d44b42257990c351 Mon Sep 17 00:00:00 2001 From: marc Date: Thu, 8 May 2025 19:55:17 +0200 Subject: [PATCH 5/5] ota & screen --- .../image_downloader/image_downloader.c | 25 +- components/meteofrance/meteofrance.c | 2 +- main/ihm.c | 79 +++- main/ihm.h | 2 + main/main.c | 67 +-- sdkconfig | 59 ++- server.py | 380 ++++++++++++++++++ version.txt | 2 +- 8 files changed, 542 insertions(+), 74 deletions(-) create mode 100644 server.py diff --git a/components/image_downloader/image_downloader.c b/components/image_downloader/image_downloader.c index bf7ac53..8d91a66 100644 --- a/components/image_downloader/image_downloader.c +++ b/components/image_downloader/image_downloader.c @@ -186,19 +186,24 @@ static void download(void) void imgdwn(void *pvParameter) { - ESP_LOGE(TAG, "beginning"); + for(;;) + { + ESP_LOGE(TAG, "beginning"); - // Should be big enough to allocate the JPEG file size, width * height should suffice - source_buf = (uint8_t *)heap_caps_malloc(IMGDWN_HEIGHT * IMGDWN_WIDTH, MALLOC_CAP_SPIRAM); - if (source_buf == NULL) { - ESP_LOGE(TAG, "Initial alloc source_buf failed!"); + // Should be big enough to allocate the JPEG file size, width * height should suffice + source_buf = (uint8_t *)heap_caps_malloc(IMGDWN_HEIGHT * IMGDWN_WIDTH, MALLOC_CAP_SPIRAM); + if (source_buf == NULL) { + ESP_LOGE(TAG, "Initial alloc source_buf failed!"); + } + printf("Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); + + download(); + + heap_caps_free(source_buf); + printf("Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); + vTaskDelay(pdTICKS_TO_MS(60*60*1000)); } - printf("Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); - - download(); - heap_caps_free(source_buf); - printf("Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); } \ No newline at end of file diff --git a/components/meteofrance/meteofrance.c b/components/meteofrance/meteofrance.c index 873e7cb..f93392c 100644 --- a/components/meteofrance/meteofrance.c +++ b/components/meteofrance/meteofrance.c @@ -399,7 +399,7 @@ void initialise_weather_data_retrieval(unsigned long retreival_period) // http_client_on_process_chunk(&http_client, process_chunk); // http_client_on_disconnected(&http_client, disconnected); TaskHandle_t xHandle = NULL; - BaseType_t ret1 = xTaskCreate(&http_request_task, "http_meteof", 5 * 1024, NULL, 5, &xHandle); + BaseType_t ret1 = xTaskCreate(&http_request_task, "http_meteof", 5 * 1024, NULL, 1, &xHandle); if(ret1!=pdPASS ){ ESP_LOGE(TAG, "Impossible de creer la tache %i", ret1); } diff --git a/main/ihm.c b/main/ihm.c index a4643ea..2704167 100644 --- a/main/ihm.c +++ b/main/ihm.c @@ -80,10 +80,12 @@ static void event_handler(lv_event_t *e) } void init_display(){ + lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG(); + //lvgl_cfg.task_priority=15; bsp_display_cfg_t cfg = { - .lvgl_port_cfg = ESP_LVGL_PORT_INIT_CONFIG(), + .lvgl_port_cfg = lvgl_cfg, .buffer_size = BSP_LCD_DRAW_BUFF_SIZE, - .double_buffer = BSP_LCD_DRAW_BUFF_DOUBLE, + .double_buffer = 1, .flags = { .buff_dma = true, .buff_spiram = false, @@ -99,11 +101,49 @@ void init_display(){ mainState.display_init=true; } +lv_obj_t * otaStatus; +lv_obj_t * arcProgress; +static void value_changed_event_cb(lv_event_t * e) +{ + //lv_obj_t * arc = lv_event_get_target_obj(e); + lv_obj_t * label = (lv_obj_t *)lv_event_get_user_data(e); + + lv_label_set_text_fmt(label, "%" LV_PRId32 "%%", lv_arc_get_value(arcProgress)); + + /*Rotate the label to the current position of the arc*/ + lv_arc_rotate_obj_to_angle(arcProgress, label, 25); +} + +void app_ota_display(){ + lv_obj_clean(lv_scr_act()); + lv_obj_t * label = lv_label_create(lv_screen_active()); + otaStatus=lv_label_create(lv_scr_act()); + lv_label_set_text(otaStatus, "Mise à jour OTA en cours"); + /*Create an Arc*/ + arcProgress = lv_arc_create(lv_screen_active()); + lv_obj_set_size(arcProgress, 150, 150); + lv_arc_set_rotation(arcProgress, 135); + lv_arc_set_bg_angles(arcProgress, 0, 270); + lv_arc_set_value(arcProgress, 0); + lv_obj_center(arcProgress); + lv_obj_add_event_cb(arcProgress, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, label); + + /*Manually update the label for the first time*/ + lv_obj_send_event(arcProgress, LV_EVENT_VALUE_CHANGED, NULL); +} + +void setOTAProgress(int value){ + lv_arc_set_value(arcProgress, value); + lv_obj_send_event(arcProgress, LV_EVENT_VALUE_CHANGED, NULL); +} void app_main_display() { - lv_subject_init_int(&meteoStatus, -1); + if(display_lock("meteoStatus")){ + lv_subject_init_int(&meteoStatus, -1); + display_unlock("meteoStatus"); + } struct meteodailyforecast_data d; @@ -222,23 +262,23 @@ void display_unlock(const char* TAG){ // Ce callback est applé lorsque meteoStatus change void meteo_obs_cb(lv_observer_t *observer, lv_subject_t *subject) { - ESP_LOGI(TAG, "On passe dans le callback de chgt de statut meteo; %li", lv_subject_get_int(subject)); - if (display_lock("meteo_obs_cb")) - { - lv_obj_t *meteoSt = observer->target; - switch (lv_subject_get_int(subject)) + ESP_LOGI(TAG, "On passe dans le callback de chgt de statut meteo; %li", lv_subject_get_int(subject)); + if (display_lock("meteo_obs_cb")) { - case 0: - lv_obj_set_style_text_color(meteoSt, lv_color_make(0x00, 0xff, 0xff), 0); - break; - case 1: - lv_obj_set_style_text_color(meteoSt, lv_color_make(0xff, 0x00, 0x00), 0); - break; + lv_obj_t *meteoSt = observer->target; + switch (lv_subject_get_int(subject)) + { + case 0: + lv_obj_set_style_text_color(meteoSt, lv_color_make(0x00, 0xff, 0xff), 0); + break; + case 1: + lv_obj_set_style_text_color(meteoSt, lv_color_make(0xff, 0x00, 0x00), 0); + break; + } + display_unlock("meteo_obs_cb"); + }else{ + ESP_LOGE(TAG,"Impossible d'obtenir le mutex dans meteo_obs_cb"); } - display_unlock("meteo_obs_cb"); - }else{ - ESP_LOGE(TAG,"Impossible d'obtenir le mutex dans meteo_obs_cb"); - } } LV_IMAGE_DECLARE(plan_rdc); @@ -791,7 +831,7 @@ void draw_ihm() // lv_obj_set_style_bg_color(tabview, lv_palette_lighten(LV_PALETTE_RED, 2), 0); lv_obj_t *tab_buttons = lv_tabview_get_tab_bar(tabview); - lv_obj_set_width(tab_buttons, 100); + lv_obj_set_width(tab_buttons, 120); lv_obj_set_style_text_font(tab_buttons, lv_theme_get_font_large(tab_buttons), 0); lv_obj_set_style_bg_color(tab_buttons, lv_palette_darken(LV_PALETTE_GREY, 3), 0); lv_obj_set_style_text_color(tab_buttons, lv_palette_lighten(LV_PALETTE_GREY, 5), 0); @@ -803,6 +843,7 @@ void draw_ihm() lv_obj_t* tabMeteo = lv_tabview_add_tab(tabview, "Météo"); lv_obj_t* tabCuve = lv_tabview_add_tab(tabview, "\xEF\x95\xB5" "Cuve"); + lv_obj_t* tabMinuteur = lv_tabview_add_tab(tabview, "Minuteur"); lv_obj_t* tabSettings = lv_tabview_add_tab(tabview, "Settings"); // lv_obj_set_style_bg_color(tab2b, lv_palette_lighten(LV_PALETTE_AMBER, 3), 0); diff --git a/main/ihm.h b/main/ihm.h index d1bf8d7..2afb518 100644 --- a/main/ihm.h +++ b/main/ihm.h @@ -4,6 +4,8 @@ #include "bsp/esp-bsp.h" void app_main_display(); +void app_ota_display(); +void setOTAProgress(int value); void init_display(); bool display_lock(const char *TAG); diff --git a/main/main.c b/main/main.c index f334fdd..9c4a6c2 100644 --- a/main/main.c +++ b/main/main.c @@ -247,7 +247,10 @@ void simple_ota_example_task(void *pvParameter) ESP_LOGE(TAG, "image header verification failed"); goto ota_end; } - + if(bsp_display_lock(100)){ + app_ota_display(); + bsp_display_unlock(); + } while (1) { err = esp_https_ota_perform(https_ota_handle); if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) { @@ -256,9 +259,14 @@ void simple_ota_example_task(void *pvParameter) // esp_https_ota_perform returns after every read operation which gives user the ability to // monitor the status of OTA upgrade by calling esp_https_ota_get_image_len_read, which gives length of image // data read so far. - ESP_LOGD(TAG, "Image bytes read: %d", esp_https_ota_get_image_len_read(https_ota_handle)); + //ESP_LOGE(TAG,"Image size : %i", esp_https_ota_get_image_size(https_ota_handle)); + int percent=esp_https_ota_get_image_len_read(https_ota_handle)*100/esp_https_ota_get_image_size(https_ota_handle); + //ESP_LOGE(TAG, "Image bytes read: %d %i%%", esp_https_ota_get_image_len_read(https_ota_handle),percent); + if(bsp_display_lock(100)){ + setOTAProgress(percent); + bsp_display_unlock(); + } } - if (esp_https_ota_is_complete_data_received(https_ota_handle) != true) { // the OTA image was not completely received and user can customise the response to this situation. ESP_LOGE(TAG, "Complete data was not received."); @@ -326,15 +334,15 @@ static void gpio_task_example(void* arg) if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { ESP_LOGE(TAG,"Got it !"); if(ecranEteint){ - if(bsp_display_lock(0)){ - for (int i = 0; i < 100; i++) + for (int i = 0; i < 100; i+=2) { - bsp_display_brightness_set(i); + if(bsp_display_lock(0)){ + bsp_display_brightness_set(i); + bsp_display_unlock(); + } vTaskDelay(delay/portTICK_PERIOD_MS); } - bsp_display_unlock(); ecranEteint=false; - } }else{ ESP_LOGI(TAG, "Ecran déjà allumé"); } @@ -369,13 +377,13 @@ void initPirSensor(){ static void presence_timer_callback(void* arg) { int64_t time_since_boot = esp_timer_get_time(); - if(bsp_display_lock(0)){ - for (int i = 100; i >= 0; i--) - { + for (int i = 100; i >= 0; i-=2) + { + if(bsp_display_lock(0)){ bsp_display_brightness_set(i); - vTaskDelay(20/portTICK_PERIOD_MS); + bsp_display_unlock(); } - bsp_display_unlock(); + vTaskDelay(20/portTICK_PERIOD_MS); } ecranEteint=true; } @@ -475,6 +483,7 @@ static httpd_handle_t start_webserver(void) { void app_main(void) { + init_display(); const esp_timer_create_args_t periodic_timer_args = { .callback = &presence_timer_callback, /* name is optional, but may help identify the timer when debugging */ @@ -554,10 +563,19 @@ void app_main(void) // On affiche au plus tot l'ecran de démarrage // ESP_ERROR_CHECK(esp_lcd_panel_mirror(lcd_panel,true,true)); - init_display(); + /* display_lock("app_main"); - app_main_display(); + app_ota_display(); display_unlock("app_main"); + for (size_t i = 0; i < 100; i++) + { + display_lock("app_main"); + setOTAProgress(i); + display_unlock("app_main"); + vTaskDelay(100/portTICK_PERIOD_MS); + } + */ + app_main_display(); printf("7 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); // Initialize NVS @@ -572,12 +590,18 @@ void app_main(void) printf("8 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); wifi_init_sta(); - //start_wifi_logger(); - //wifi_log_e("test", "%s %d %f", "hello world wifi logger", 43, 45.341223242); // write log over wifi with log level -> ERROR + start_wifi_logger(); + wifi_log_e("test", "%s %d %f", "hello world wifi logger", 43, 45.341223242); // write log over wifi with log level -> ERROR esp_log_level_set("tcp_handler", ESP_LOG_NONE); printf("8b - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); printf("9 - Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); + + /* Ensure to disable any WiFi power save mode, this allows best throughput + * and hence timings for overall OTA operation. + */ + esp_wifi_set_ps(WIFI_PS_NONE); + xTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 1, NULL); time_t now; struct tm timeinfo; @@ -602,13 +626,13 @@ void app_main(void) TaskHandle_t xHandle = NULL; BaseType_t ret1; - ret1 = xTaskCreate(&imgdwn, "imageDownload_task", 3 * 1024, NULL, 5, &xHandle); + ret1 = xTaskCreate(&imgdwn, "imageDownload_task", 3 * 1024, NULL, 1, &xHandle); if (ret1 != pdPASS) { ESP_LOGE(TAG, "Impossiblke de creer la tache imageDownload_task %i", ret1); } - BaseType_t ret2 = xTaskCreate(&updateTime, "updateTimeTask", 3 * 1024, NULL, 5, NULL); + BaseType_t ret2 = xTaskCreate(&updateTime, "updateTimeTask", 3 * 1024, NULL, 1, NULL); if (ret2 != pdPASS) { ESP_LOGE(TAG, "Impossiblke de creer la tache updateTimeTask %i", ret2); @@ -643,11 +667,6 @@ void app_main(void) xTaskCreate(&readTempHumid, "read_temp_task", 8192, NULL, 5, NULL); */ - /* Ensure to disable any WiFi power save mode, this allows best throughput - * and hence timings for overall OTA operation. - */ - esp_wifi_set_ps(WIFI_PS_NONE); - xTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL); } diff --git a/sdkconfig b/sdkconfig index b8d0b71..bccd5d9 100644 --- a/sdkconfig +++ b/sdkconfig @@ -515,7 +515,7 @@ CONFIG_IDF_TOOLCHAIN_GCC=y CONFIG_IDF_TARGET_ARCH_RISCV=y CONFIG_IDF_TARGET_ARCH="riscv" CONFIG_IDF_TARGET="esp32p4" -CONFIG_IDF_INIT_VERSION="5.4.0" +CONFIG_IDF_INIT_VERSION="$IDF_INIT_VERSION" CONFIG_IDF_TARGET_ESP32P4=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0012 @@ -701,7 +701,32 @@ CONFIG_ENV_GPIO_RANGE_MIN=0 CONFIG_ENV_GPIO_RANGE_MAX=56 CONFIG_ENV_GPIO_IN_RANGE_MAX=56 CONFIG_ENV_GPIO_OUT_RANGE_MAX=56 -# CONFIG_EXAMPLE_CONNECT_WIFI is not set +CONFIG_EXAMPLE_CONNECT_WIFI=y +# CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN is not set +CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD=y +CONFIG_EXAMPLE_WIFI_SSID="wifimms3" +CONFIG_EXAMPLE_WIFI_PASSWORD="mmswifi0611" +CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY=6 +# CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST is not set +CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL=y + +# +# WiFi Scan threshold +# +CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD=-127 +CONFIG_EXAMPLE_WIFI_AUTH_OPEN=y +# CONFIG_EXAMPLE_WIFI_AUTH_WEP is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK is not set +# end of WiFi Scan threshold + +CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL=y +# CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY is not set CONFIG_EXAMPLE_CONNECT_ETHERNET=y CONFIG_EXAMPLE_ETHERNET_EMAC_TASK_STACK_SIZE=2048 CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y @@ -1042,7 +1067,7 @@ CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 # ESP HTTPS OTA # # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set -CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP=y +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 # end of ESP HTTPS OTA @@ -1238,7 +1263,7 @@ CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_USE_MALLOC=y CONFIG_SPIRAM_MEMTEST=y CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 -CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +# CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 # CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set # CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set @@ -1292,10 +1317,10 @@ CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=y CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0 is not set # CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set -# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY=y +CONFIG_ESP_MAIN_TASK_AFFINITY=0x7FFFFFFF CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 CONFIG_ESP_CONSOLE_UART_DEFAULT=y # CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set @@ -1369,7 +1394,6 @@ CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y @@ -1702,7 +1726,6 @@ CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set # CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# CONFIG_LWIP_WND_SCALE is not set CONFIG_LWIP_TCP_RTO_TIME=1500 # end of TCP @@ -2186,7 +2209,7 @@ CONFIG_BSP_I2S_NUM=1 CONFIG_TRANSPORT_PROTOCOL_UDP=y # CONFIG_TRANSPORT_PROTOCOL_TCP is not set # CONFIG_TRANSPORT_PROTOCOL_WEBSOCKET is not set -# CONFIG_ROUTE_ESP_IDF_API_LOGS_TO_WIFI is not set +CONFIG_ROUTE_ESP_IDF_API_LOGS_TO_WIFI=y CONFIG_SERVER_IP_ADDRESS="192.168.0.10" CONFIG_SERVER_PORT=9999 CONFIG_MESSAGE_QUEUE_SIZE=1000 @@ -2417,9 +2440,9 @@ CONFIG_ESP_WIFI_REMOTE_LIBRARY_HOSTED=y CONFIG_WIFI_RMT_STATIC_RX_BUFFER_NUM=10 CONFIG_WIFI_RMT_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_WIFI_RMT_STATIC_TX_BUFFER=y +# CONFIG_WIFI_RMT_DYNAMIC_TX_BUFFER is not set CONFIG_WIFI_RMT_TX_BUFFER_TYPE=0 CONFIG_WIFI_RMT_STATIC_TX_BUFFER_NUM=16 -CONFIG_WIFI_RMT_CACHE_TX_BUFFER_NUM=32 CONFIG_WIFI_RMT_STATIC_RX_MGMT_BUFFER=y # CONFIG_WIFI_RMT_DYNAMIC_RX_MGMT_BUFFER is not set CONFIG_WIFI_RMT_DYNAMIC_RX_MGMT_BUF=0 @@ -2429,7 +2452,6 @@ CONFIG_WIFI_RMT_AMPDU_TX_ENABLED=y CONFIG_WIFI_RMT_TX_BA_WIN=6 CONFIG_WIFI_RMT_AMPDU_RX_ENABLED=y CONFIG_WIFI_RMT_RX_BA_WIN=6 -# CONFIG_WIFI_RMT_AMSDU_TX_ENABLED is not set CONFIG_WIFI_RMT_NVS_ENABLED=y CONFIG_WIFI_RMT_SOFTAP_BEACON_MAX_LEN=752 CONFIG_WIFI_RMT_MGMT_SBUF_NUM=32 @@ -2552,15 +2574,15 @@ CONFIG_LV_DPI_DEF=130 # # Operating System (OS) # -CONFIG_LV_OS_NONE=y +# CONFIG_LV_OS_NONE is not set # CONFIG_LV_OS_PTHREAD is not set -# CONFIG_LV_OS_FREERTOS is not set +CONFIG_LV_OS_FREERTOS=y # CONFIG_LV_OS_CMSIS_RTOS2 is not set # CONFIG_LV_OS_RTTHREAD is not set # CONFIG_LV_OS_WINDOWS is not set # CONFIG_LV_OS_MQX is not set # CONFIG_LV_OS_CUSTOM is not set -CONFIG_LV_USE_OS=0 +CONFIG_LV_USE_OS=2 # end of Operating System (OS) # @@ -2569,6 +2591,7 @@ CONFIG_LV_USE_OS=0 CONFIG_LV_DRAW_BUF_STRIDE_ALIGN=1 CONFIG_LV_DRAW_BUF_ALIGN=4 CONFIG_LV_DRAW_LAYER_SIMPLE_BUF_SIZE=24576 +CONFIG_LV_DRAW_THREAD_STACK_SIZE=8192 CONFIG_LV_USE_DRAW_SW=y CONFIG_LV_DRAW_SW_SUPPORT_RGB565=y CONFIG_LV_DRAW_SW_SUPPORT_RGB565A8=y @@ -2756,7 +2779,7 @@ CONFIG_LV_TXT_LINE_BREAK_LONG_LEN=0 # CONFIG_LV_WIDGETS_HAS_DEFAULT_VALUE=y # CONFIG_LV_USE_ANIMIMG is not set -# CONFIG_LV_USE_ARC is not set +CONFIG_LV_USE_ARC=y CONFIG_LV_USE_BAR=y CONFIG_LV_USE_BUTTON=y CONFIG_LV_USE_BUTTONMATRIX=y @@ -2940,7 +2963,7 @@ CONFIG_STACK_CHECK_NONE=y # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -CONFIG_OTA_ALLOW_HTTP=y +# CONFIG_OTA_ALLOW_HTTP is not set CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 CONFIG_MAIN_TASK_STACK_SIZE=3584 @@ -2972,7 +2995,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y @@ -3085,7 +3107,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=6 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y diff --git a/server.py b/server.py new file mode 100644 index 0000000..ec982d6 --- /dev/null +++ b/server.py @@ -0,0 +1,380 @@ +#!/usr/bin/python3 +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import http.server +import multiprocessing +import os +import ssl +import subprocess +import sys +from typing import Any +from typing import Optional +from typing import Tuple + +import pexpect +import pytest +from pytest_embedded import Dut + +try: + from common_test_methods import get_env_config_variable, get_host_ip4_by_dest_ip +except ModuleNotFoundError: + idf_path = os.environ['IDF_PATH'] + sys.path.insert(0, idf_path + '/tools/ci/python_packages') + from common_test_methods import get_env_config_variable, get_host_ip4_by_dest_ip + +server_cert = '-----BEGIN CERTIFICATE-----\n' \ + 'MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ\n'\ + 'TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD\n'\ + 'VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j\n'\ + 'b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ\n'\ + 'TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD\n'\ + 'VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j\n'\ + 'b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL\n'\ + 'SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W\n'\ + 'ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ\n'\ + 'S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz\n'\ + 'YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz\n'\ + '3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap\n'\ + 'rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud\n'\ + 'IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk\n'\ + 'B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32\n'\ + '3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9\n'\ + 'RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN\n'\ + 'lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=\n'\ + '-----END CERTIFICATE-----\n' + +server_key = '-----BEGIN PRIVATE KEY-----\n'\ + 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhxF/y7bygndxP\n'\ + 'wiWLSwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQu\n'\ + 'c32WukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2m\n'\ + 'KRbQS5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO\n'\ + '2fEzYaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnv\n'\ + 'L6Oz3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdO\n'\ + 'AoaprFTRAgMBAAECggEAE0HCxV/N1Q1h+1OeDDGL5+74yjKSFKyb/vTVcaPCrmaH\n'\ + 'fPvp0ddOvMZJ4FDMAsiQS6/n4gQ7EKKEnYmwTqj4eUYW8yxGUn3f0YbPHbZT+Mkj\n'\ + 'z5woi3nMKi/MxCGDQZX4Ow3xUQlITUqibsfWcFHis8c4mTqdh4qj7xJzehD2PVYF\n'\ + 'gNHZsvVj6MltjBDAVwV1IlGoHjuElm6vuzkfX7phxcA1B4ZqdYY17yCXUnvui46z\n'\ + 'Xn2kUTOOUCEgfgvGa9E+l4OtdXi5IxjaSraU+dlg2KsE4TpCuN2MEVkeR5Ms3Y7Q\n'\ + 'jgJl8vlNFJDQpbFukLcYwG7rO5N5dQ6WWfVia/5XgQKBgQD74at/bXAPrh9NxPmz\n'\ + 'i1oqCHMDoM9sz8xIMZLF9YVu3Jf8ux4xVpRSnNy5RU1gl7ZXbpdgeIQ4v04zy5aw\n'\ + '8T4tu9K3XnR3UXOy25AK0q+cnnxZg3kFQm+PhtOCKEFjPHrgo2MUfnj+EDddod7N\n'\ + 'JQr9q5rEFbqHupFPpWlqCa3QmQKBgQDldWUGokNaEpmgHDMnHxiibXV5LQhzf8Rq\n'\ + 'gJIQXb7R9EsTSXEvsDyqTBb7PHp2Ko7rZ5YQfyf8OogGGjGElnPoU/a+Jij1gVFv\n'\ + 'kZ064uXAAISBkwHdcuobqc5EbG3ceyH46F+FBFhqM8KcbxJxx08objmh58+83InN\n'\ + 'P9Qr25Xw+QKBgEGXMHuMWgQbSZeM1aFFhoMvlBO7yogBTKb4Ecpu9wI5e3Kan3Al\n'\ + 'pZYltuyf+VhP6XG3IMBEYdoNJyYhu+nzyEdMg8CwXg+8LC7FMis/Ve+o7aS5scgG\n'\ + '1to/N9DK/swCsdTRdzmc/ZDbVC+TuVsebFBGYZTyO5KgqLpezqaIQrTxAoGALFCU\n'\ + '10glO9MVyl9H3clap5v+MQ3qcOv/EhaMnw6L2N6WVT481tnxjW4ujgzrFcE4YuxZ\n'\ + 'hgwYu9TOCmeqopGwBvGYWLbj+C4mfSahOAs0FfXDoYazuIIGBpuv03UhbpB1Si4O\n'\ + 'rJDfRnuCnVWyOTkl54gKJ2OusinhjztBjcrV1XkCgYEA3qNi4uBsPdyz9BZGb/3G\n'\ + 'rOMSw0CaT4pEMTLZqURmDP/0hxvTk1polP7O/FYwxVuJnBb6mzDa0xpLFPTpIAnJ\n'\ + 'YXB8xpXU69QVh+EBbemdJWOd+zp5UCfXvb2shAeG3Tn/Dz4cBBMEUutbzP+or0nG\n'\ + 'vSXnRLaxQhooWm+IuX9SuBQ=\n'\ + '-----END PRIVATE KEY-----\n' + +OTA_0_ADDRESS = '0x20000' +OTA_1_ADDRESS = '0x1d0000' + + +def start_https_server(ota_image_dir: str, server_ip: str, server_port: int, server_file: Optional[str] = None, key_file: Optional[str] = None) -> None: + os.chdir(ota_image_dir) + + if server_file is None: + server_file = os.path.join(ota_image_dir, 'server_cert.pem') + cert_file_handle = open(server_file, 'w+', encoding='utf-8') + cert_file_handle.write(server_cert) + cert_file_handle.close() + + if key_file is None: + key_file = os.path.join(ota_image_dir, 'server_key.pem') + key_file_handle = open('server_key.pem', 'w+', encoding='utf-8') + key_file_handle.write(server_key) + key_file_handle.close() + + httpd = http.server.HTTPServer((server_ip, server_port), http.server.SimpleHTTPRequestHandler) + + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.load_cert_chain(certfile=server_file, keyfile=key_file) + + httpd.socket = ssl_context.wrap_socket(httpd.socket, server_side=True) + httpd.serve_forever() + + +def start_tls1_3_server(ota_image_dir: str, server_port: int) -> subprocess.Popen: + os.chdir(ota_image_dir) + server_file = os.path.join(ota_image_dir, 'server_cert.pem') + cert_file_handle = open(server_file, 'w+', encoding='utf-8') + cert_file_handle.write(server_cert) + cert_file_handle.close() + + key_file = os.path.join(ota_image_dir, 'server_key.pem') + key_file_handle = open('server_key.pem', 'w+', encoding='utf-8') + key_file_handle.write(server_key) + key_file_handle.close() + + chunked_server = subprocess.Popen(['openssl', 's_server', '-tls1_3', '-WWW', '-key', key_file, '-cert', server_file, '-port', str(server_port)]) + return chunked_server + + +def check_sha256(sha256_expected: str, sha256_reported: str) -> None: + print('sha256_expected: %s' % (sha256_expected)) + print('sha256_reported: %s' % (sha256_reported)) + if sha256_expected not in sha256_reported: + raise ValueError('SHA256 mismatch') + else: + print('SHA256 expected and reported are the same') + + +def calc_all_sha256(dut: Dut) -> Tuple[str, str]: + bootloader_path = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') + sha256_bootloader = dut.app.get_sha256(bootloader_path) + + app_path = os.path.join(dut.app.binary_path, 'simple_ota.bin') + sha256_app = dut.app.get_sha256(app_path) + + return str(sha256_bootloader), str(sha256_app) + + +def setting_connection(dut: Dut, env_name: Optional[str] = None) -> Any: + if env_name is not None and dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + dut.expect('Please input ssid password:') + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() + print(f'Connected to AP/Ethernet with IP: {ip_address}') + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + return get_host_ip4_by_dest_ip(ip_address) + + +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.esp32s3 +@pytest.mark.wifi_high_traffic +def test_examples_protocol_simple_ota_example(dut: Dut) -> None: + """ + steps: | + 1. join AP/Ethernet + 2. Fetch OTA image over HTTPS + 3. Reboot with the new OTA image + """ + sha256_bootloader, sha256_app = calc_all_sha256(dut) + # Start server + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) + thread1.daemon = True + thread1.start() + try: + # start test + dut.expect(f'Loaded app from partition at offset {OTA_0_ADDRESS}', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) + # Parse IP address of STA + env_name = 'wifi_high_traffic' if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True else None + host_ip = setting_connection(dut, env_name) + dut.expect('Starting OTA example task', timeout=30) + print(f'writing to device: https://{host_ip}:8000/simple_ota.bin') + dut.write(f'https://{host_ip}:8000/simple_ota.bin') + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot + dut.expect(f'Loaded app from partition at offset {OTA_1_ADDRESS}', timeout=30) + dut.expect('OTA example app_main start', timeout=10) + finally: + thread1.terminate() + + +@pytest.mark.esp32 +@pytest.mark.ethernet_ota +@pytest.mark.parametrize('config', ['spiram',], indirect=True) +def test_examples_protocol_simple_ota_example_ethernet_with_spiram_config(dut: Dut) -> None: + """ + steps: | + 1. join AP/Ethernet + 2. Fetch OTA image over HTTPS + 3. Reboot with the new OTA image + """ + # Start server + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) + thread1.daemon = True + thread1.start() + try: + # start test + dut.expect(f'Loaded app from partition at offset {OTA_0_ADDRESS}', timeout=30) + host_ip = setting_connection(dut) + dut.expect('Starting OTA example task', timeout=30) + print(f'writing to device: https://{host_ip}:8000/simple_ota.bin') + dut.write(f'https://{host_ip}:8000/simple_ota.bin') + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot + dut.expect(f'Loaded app from partition at offset {OTA_1_ADDRESS}', timeout=30) + dut.expect('OTA example app_main start', timeout=10) + finally: + thread1.terminate() + + +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.flash_encryption_wifi_high_traffic +@pytest.mark.nightly_run +@pytest.mark.parametrize('config', ['flash_enc_wifi',], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_protocol_simple_ota_example_with_flash_encryption_wifi(dut: Dut) -> None: + """ + steps: | + 1. join AP/Ethernet + 2. Fetch OTA image over HTTPS + 3. Reboot with the new OTA image + """ + # CONFIG_PARTITION_TABLE_TWO_OTA_ENCRYPTED_NVS==y, it includes partitions_two_ota_encr_nvs.csv + FACTORY_ADDRESS = '0x20000' + OTA_0_ADDRESS = '0x120000' + # OTA_1_ADDRESS = '0x220000' + + # start test + # Erase flash + dut.serial.erase_flash() + dut.serial.flash() + # Start server + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) + thread1.daemon = True + thread1.start() + try: + dut.expect(f'Loaded app from partition at offset {FACTORY_ADDRESS}', timeout=30) + dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) + # Parse IP address of STA + env_name = 'flash_encryption_wifi_high_traffic' if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True else None + host_ip = setting_connection(dut, env_name) + + dut.expect('Starting OTA example task', timeout=30) + print(f'writing to device: https://{host_ip}:8000/simple_ota.bin') + dut.write(f'https://{host_ip}:8000/simple_ota.bin') + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot + dut.expect(f'Loaded app from partition at offset {OTA_0_ADDRESS}', timeout=30) + dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) + dut.expect('OTA example app_main start', timeout=10) + finally: + thread1.terminate() + + +@pytest.mark.esp32 +@pytest.mark.ethernet_ota +@pytest.mark.parametrize('config', ['on_update_no_sb_ecdsa',], indirect=True) +def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_update_no_secure_boot_ecdsa(dut: Dut) -> None: + """ + steps: | + 1. join AP/Ethernet + 2. Fetch OTA image over HTTPS + 3. Reboot with the new OTA image + """ + sha256_bootloader, sha256_app = calc_all_sha256(dut) + # Start server + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) + thread1.daemon = True + thread1.start() + try: + # start test + dut.expect(f'Loaded app from partition at offset {OTA_0_ADDRESS}', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) + + host_ip = setting_connection(dut) + + dut.expect('Starting OTA example task', timeout=30) + print(f'writing to device: https://{host_ip}:8000/simple_ota.bin') + dut.write(f'https://{host_ip}:8000/simple_ota.bin') + dut.expect(f'Writing to partition at offset {OTA_1_ADDRESS}', timeout=20) + dut.expect('Verifying image signature...', timeout=60) + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot + dut.expect(f'Loaded app from partition at offset {OTA_1_ADDRESS}', timeout=20) + dut.expect('OTA example app_main start', timeout=10) + finally: + thread1.terminate() + + +@pytest.mark.esp32 +@pytest.mark.ethernet_ota +@pytest.mark.parametrize('config', ['on_update_no_sb_rsa',], indirect=True) +def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_update_no_secure_boot_rsa(dut: Dut) -> None: + """ + steps: | + 1. join AP/Ethernet + 2. Fetch OTA image over HTTPS + 3. Reboot with the new OTA image + """ + sha256_bootloader, sha256_app = calc_all_sha256(dut) + # Start server + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) + thread1.daemon = True + thread1.start() + try: + # start test + dut.expect(f'Loaded app from partition at offset {OTA_0_ADDRESS}', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) + + host_ip = setting_connection(dut) + + dut.expect('Starting OTA example task', timeout=30) + print(f'writing to device: https://{host_ip}:8000/simple_ota.bin') + dut.write(f'https://{host_ip}:8000/simple_ota.bin') + dut.expect(f'Writing to partition at offset {OTA_1_ADDRESS}', timeout=20) + dut.expect('Verifying image signature...', timeout=60) + dut.expect('#0 app key digest == #0 trusted key digest', timeout=10) + dut.expect('Verifying with RSA-PSS...', timeout=10) + dut.expect('Signature verified successfully!', timeout=10) + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot + dut.expect(f'Loaded app from partition at offset {OTA_1_ADDRESS}', timeout=20) + dut.expect('OTA example app_main start', timeout=10) + finally: + thread1.terminate() + + +@pytest.mark.esp32 +@pytest.mark.ethernet_ota +@pytest.mark.parametrize('config', ['tls1_3',], indirect=True) +def test_examples_protocol_simple_ota_example_tls1_3(dut: Dut) -> None: + """ + steps: | + 1. join AP/Ethernet + 2. Fetch OTA image over HTTPS + 3. Reboot with the new OTA image + """ + sha256_bootloader, sha256_app = calc_all_sha256(dut) + # Start server + tls1_3_server = start_tls1_3_server(dut.app.binary_path, 8000) + try: + # start test + dut.expect(f'Loaded app from partition at offset {OTA_0_ADDRESS}', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) + # Parse IP address of STA + env_name = 'wifi_high_traffic' if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True else None + host_ip = setting_connection(dut, env_name) + + dut.expect('Starting OTA example task', timeout=30) + print(f'writing to device: https://{host_ip}:8000/simple_ota.bin') + dut.write(f'https://{host_ip}:8000/simple_ota.bin') + dut.expect('OTA Succeed, Rebooting...', timeout=120) + # after reboot + dut.expect(f'Loaded app from partition at offset {OTA_1_ADDRESS}', timeout=30) + dut.expect('OTA example app_main start', timeout=10) + finally: + tls1_3_server.kill() + + +if __name__ == '__main__': + if sys.argv[2:]: # if two or more arguments provided: + # Usage: pytest_simple_ota.py [cert_dir] + this_dir = os.path.dirname(os.path.realpath(__file__)) + bin_dir = os.path.join(this_dir, sys.argv[1]) + port = int(sys.argv[2]) + cert_dir = bin_dir if not sys.argv[3:] else os.path.join(this_dir, sys.argv[3]) # optional argument + print(f'Starting HTTPS server at "https://0.0.0.0:{port}"') + start_https_server(bin_dir, '', port, + server_file=os.path.join(cert_dir, 'ca_cert.pem'), + key_file=os.path.join(cert_dir, 'ca_key.pem')) + diff --git a/version.txt b/version.txt index 2f45361..ceab6e1 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.2 \ No newline at end of file +0.1 \ No newline at end of file