mirror of
https://github.com/ok-home/ota_ws_update.git
synced 2025-11-13 22:03:27 +03:00
first
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.vscode/
|
||||||
|
.devcontainer/
|
||||||
10
CMakeLists.txt
Normal file
10
CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||||
|
# in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
# (Not part of the boilerplate)
|
||||||
|
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
|
||||||
|
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(ota)
|
||||||
12
README.md
Normal file
12
README.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
|
||||||
|
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
|
||||||
|
|
||||||
|
# Simple OTA example
|
||||||
|
|
||||||
|
This example is based on `esp_https_ota` component's APIs.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Refer README.md in the parent directory for setup details.
|
||||||
|
|
||||||
|
Example also supports binding to specific interface (either "Ethernet" or "WiFi Station"), which will allow firmware upgrade to happen through specific interface (in case multiple networking interfaces are enabled). Please see more on this through example configuration in `idf.py menuconfig -> Example Configuration -> Support firmware upgrade bind specificied interface->Choose OTA data bind interface`.
|
||||||
5
main/CMakeLists.txt
Normal file
5
main/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Embed the server root certificate into the final binary
|
||||||
|
idf_build_get_property(project_dir PROJECT_DIR)
|
||||||
|
idf_component_register(SRCS "simple_ota_example.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
EMBED_TXTFILES ${project_dir}/server_certs/ca_cert.pem)
|
||||||
54
main/Kconfig.projbuild
Normal file
54
main/Kconfig.projbuild
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
menu "Example Configuration"
|
||||||
|
|
||||||
|
config EXAMPLE_FIRMWARE_UPGRADE_URL
|
||||||
|
string "firmware upgrade url endpoint"
|
||||||
|
default "https://192.168.0.3:8070/hello_world.bin"
|
||||||
|
help
|
||||||
|
URL of server which hosts the firmware
|
||||||
|
image.
|
||||||
|
|
||||||
|
config EXAMPLE_USE_CERT_BUNDLE
|
||||||
|
bool "Enable certificate bundle"
|
||||||
|
default y
|
||||||
|
depends on MBEDTLS_CERTIFICATE_BUNDLE
|
||||||
|
help
|
||||||
|
Enable trusted root certificate bundle. This approach allows to have
|
||||||
|
OTA updates functional with any public server without requirement
|
||||||
|
to explicitly add its server certificate.
|
||||||
|
|
||||||
|
config EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
|
||||||
|
bool
|
||||||
|
default y if EXAMPLE_FIRMWARE_UPGRADE_URL = "FROM_STDIN"
|
||||||
|
|
||||||
|
config EXAMPLE_SKIP_COMMON_NAME_CHECK
|
||||||
|
bool "Skip server certificate CN fieldcheck"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This allows you to skip the validation of OTA server certificate CN field.
|
||||||
|
|
||||||
|
config EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
|
||||||
|
bool "Support firmware upgrade bind specified interface"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This allows you to bind specified interface in OTA example.
|
||||||
|
|
||||||
|
choice EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_TYPE
|
||||||
|
prompt "Choose OTA data bind interface"
|
||||||
|
default EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_STA
|
||||||
|
depends on EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
|
||||||
|
help
|
||||||
|
Select which interface type of OTA data go through.
|
||||||
|
|
||||||
|
config EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_STA
|
||||||
|
bool "Bind wifi station interface"
|
||||||
|
depends on EXAMPLE_CONNECT_WIFI
|
||||||
|
help
|
||||||
|
Select wifi station interface to pass the OTA data.
|
||||||
|
|
||||||
|
config EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_ETH
|
||||||
|
bool "Bind ethernet interface"
|
||||||
|
depends on EXAMPLE_CONNECT_ETHERNET
|
||||||
|
help
|
||||||
|
Select ethernet interface to pass the OTA data.
|
||||||
|
endchoice
|
||||||
|
endmenu
|
||||||
201
main/simple_ota_example.c
Normal file
201
main/simple_ota_example.c
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
/* OTA example
|
||||||
|
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_ota_ops.h"
|
||||||
|
#include "esp_http_client.h"
|
||||||
|
#include "esp_https_ota.h"
|
||||||
|
#include "protocol_examples_common.h"
|
||||||
|
#include "string.h"
|
||||||
|
#ifdef CONFIG_EXAMPLE_USE_CERT_BUNDLE
|
||||||
|
#include "esp_crt_bundle.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nvs.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "protocol_examples_common.h"
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HASH_LEN 32
|
||||||
|
|
||||||
|
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
|
||||||
|
/* The interface name value can refer to if_desc in esp_netif_defaults.h */
|
||||||
|
#if CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_ETH
|
||||||
|
static const char *bind_interface_name = EXAMPLE_NETIF_DESC_ETH;
|
||||||
|
#elif CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_STA
|
||||||
|
static const char *bind_interface_name = EXAMPLE_NETIF_DESC_STA;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char *TAG = "simple_ota_example";
|
||||||
|
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");
|
||||||
|
|
||||||
|
#define OTA_URL_SIZE 256
|
||||||
|
|
||||||
|
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
||||||
|
{
|
||||||
|
switch (evt->event_id) {
|
||||||
|
case HTTP_EVENT_ERROR:
|
||||||
|
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_ON_CONNECTED:
|
||||||
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_HEADER_SENT:
|
||||||
|
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_ON_HEADER:
|
||||||
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_ON_DATA:
|
||||||
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_ON_FINISH:
|
||||||
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_DISCONNECTED:
|
||||||
|
ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_REDIRECT:
|
||||||
|
ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void simple_ota_example_task(void *pvParameter)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
if (netif == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Can't find netif from interface description");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
struct ifreq ifr;
|
||||||
|
esp_netif_get_netif_impl_name(netif, ifr.ifr_name);
|
||||||
|
ESP_LOGI(TAG, "Bind interface name is %s", ifr.ifr_name);
|
||||||
|
#endif
|
||||||
|
esp_http_client_config_t config = {
|
||||||
|
.url = CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL,
|
||||||
|
#ifdef CONFIG_EXAMPLE_USE_CERT_BUNDLE
|
||||||
|
.crt_bundle_attach = esp_crt_bundle_attach,
|
||||||
|
#else
|
||||||
|
.cert_pem = (char *)server_cert_pem_start,
|
||||||
|
#endif /* CONFIG_EXAMPLE_USE_CERT_BUNDLE */
|
||||||
|
.event_handler = _http_event_handler,
|
||||||
|
.keep_alive_enable = true,
|
||||||
|
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
|
||||||
|
.if_name = &ifr,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
|
||||||
|
char url_buf[OTA_URL_SIZE];
|
||||||
|
if (strcmp(config.url, "FROM_STDIN") == 0) {
|
||||||
|
example_configure_stdin_stdout();
|
||||||
|
fgets(url_buf, OTA_URL_SIZE, stdin);
|
||||||
|
int len = strlen(url_buf);
|
||||||
|
url_buf[len - 1] = '\0';
|
||||||
|
config.url = url_buf;
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Configuration mismatch: wrong firmware upgrade image url");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK
|
||||||
|
config.skip_cert_common_name_check = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_https_ota_config_t ota_config = {
|
||||||
|
.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");
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_sha256(const uint8_t *image_hash, const char *label)
|
||||||
|
{
|
||||||
|
char hash_print[HASH_LEN * 2 + 1];
|
||||||
|
hash_print[HASH_LEN * 2] = 0;
|
||||||
|
for (int i = 0; i < HASH_LEN; ++i) {
|
||||||
|
sprintf(&hash_print[i * 2], "%02x", image_hash[i]);
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "%s %s", label, hash_print);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_sha256_of_partitions(void)
|
||||||
|
{
|
||||||
|
uint8_t sha_256[HASH_LEN] = { 0 };
|
||||||
|
esp_partition_t partition;
|
||||||
|
|
||||||
|
// get sha256 digest for bootloader
|
||||||
|
partition.address = ESP_BOOTLOADER_OFFSET;
|
||||||
|
partition.size = ESP_PARTITION_TABLE_OFFSET;
|
||||||
|
partition.type = ESP_PARTITION_TYPE_APP;
|
||||||
|
esp_partition_get_sha256(&partition, sha_256);
|
||||||
|
print_sha256(sha_256, "SHA-256 for bootloader: ");
|
||||||
|
|
||||||
|
// get sha256 digest for running partition
|
||||||
|
esp_partition_get_sha256(esp_ota_get_running_partition(), sha_256);
|
||||||
|
print_sha256(sha_256, "SHA-256 for current firmware: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "OTA example app_main start");
|
||||||
|
// Initialize NVS.
|
||||||
|
esp_err_t err = nvs_flash_init();
|
||||||
|
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
// 1.OTA app partition table has a smaller NVS partition size than the non-OTA
|
||||||
|
// partition table. This size mismatch may cause NVS initialization to fail.
|
||||||
|
// 2.NVS partition contains data in new format and cannot be recognized by this version of code.
|
||||||
|
// If this happens, we erase NVS partition and initialize NVS again.
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
|
err = nvs_flash_init();
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
|
get_sha256_of_partitions();
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
|
||||||
|
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||||
|
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||||
|
* examples/protocols/README.md for more information about this function.
|
||||||
|
*/
|
||||||
|
ESP_ERROR_CHECK(example_connect());
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||||
|
/* 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);
|
||||||
|
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
|
||||||
|
|
||||||
|
xTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL);
|
||||||
|
}
|
||||||
402
pytest_simple_ota.py
Normal file
402
pytest_simple_ota.py
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022-2023 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 Tuple
|
||||||
|
|
||||||
|
import pexpect
|
||||||
|
import pytest
|
||||||
|
from common_test_methods import get_env_config_variable, get_host_ip4_by_dest_ip
|
||||||
|
from pytest_embedded import Dut
|
||||||
|
|
||||||
|
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'
|
||||||
|
|
||||||
|
|
||||||
|
def start_https_server(ota_image_dir: str, server_ip: str, server_port: int, server_file: str = None, key_file: 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+')
|
||||||
|
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+')
|
||||||
|
key_file_handle.write(server_key)
|
||||||
|
key_file_handle.close()
|
||||||
|
|
||||||
|
httpd = http.server.HTTPServer((server_ip, server_port), http.server.SimpleHTTPRequestHandler)
|
||||||
|
|
||||||
|
httpd.socket = ssl.wrap_socket(httpd.socket,
|
||||||
|
keyfile=key_file,
|
||||||
|
certfile=server_file, 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+')
|
||||||
|
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+')
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.esp32c3
|
||||||
|
@pytest.mark.esp32s2
|
||||||
|
@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('Loaded app from partition at offset 0x10000', 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
|
||||||
|
if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True:
|
||||||
|
env_name = 'wifi_high_traffic'
|
||||||
|
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('Connected to AP/Ethernet with IP: {}'.format(ip_address))
|
||||||
|
except pexpect.exceptions.TIMEOUT:
|
||||||
|
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
|
||||||
|
host_ip = get_host_ip4_by_dest_ip(ip_address)
|
||||||
|
|
||||||
|
dut.expect('Starting OTA example task', timeout=30)
|
||||||
|
print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin'))
|
||||||
|
dut.write('https://' + host_ip + ':8000/simple_ota.bin')
|
||||||
|
dut.expect('OTA Succeed, Rebooting...', timeout=60)
|
||||||
|
# after reboot
|
||||||
|
dut.expect('Loaded app from partition at offset 0x110000', timeout=30)
|
||||||
|
dut.expect('OTA example app_main start', timeout=10)
|
||||||
|
finally:
|
||||||
|
thread1.terminate()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.esp32c3
|
||||||
|
@pytest.mark.esp32s2
|
||||||
|
@pytest.mark.esp32s3
|
||||||
|
@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('Loaded app from partition at offset 0x10000', timeout=30)
|
||||||
|
try:
|
||||||
|
ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode()
|
||||||
|
print('Connected to AP/Ethernet with IP: {}'.format(ip_address))
|
||||||
|
except pexpect.exceptions.TIMEOUT:
|
||||||
|
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
|
||||||
|
host_ip = get_host_ip4_by_dest_ip(ip_address)
|
||||||
|
|
||||||
|
dut.expect('Starting OTA example task', timeout=30)
|
||||||
|
print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin'))
|
||||||
|
dut.write('https://' + host_ip + ':8000/simple_ota.bin')
|
||||||
|
dut.expect('OTA Succeed, Rebooting...', timeout=60)
|
||||||
|
# after reboot
|
||||||
|
dut.expect('Loaded app from partition at offset 0x110000', 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
|
||||||
|
"""
|
||||||
|
# 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('Loaded app from partition at offset 0x20000', timeout=30)
|
||||||
|
dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10)
|
||||||
|
# Parse IP address of STA
|
||||||
|
if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True:
|
||||||
|
env_name = 'flash_encryption_wifi_high_traffic'
|
||||||
|
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('Connected to AP/Ethernet with IP: {}'.format(ip_address))
|
||||||
|
except pexpect.exceptions.TIMEOUT:
|
||||||
|
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
|
||||||
|
host_ip = get_host_ip4_by_dest_ip(ip_address)
|
||||||
|
|
||||||
|
dut.expect('Starting OTA example task', timeout=30)
|
||||||
|
print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin'))
|
||||||
|
dut.write('https://' + host_ip + ':8000/simple_ota.bin')
|
||||||
|
dut.expect('OTA Succeed, Rebooting...', timeout=60)
|
||||||
|
# after reboot
|
||||||
|
dut.expect('Loaded app from partition at offset 0x120000', 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.esp32c3
|
||||||
|
@pytest.mark.esp32s2
|
||||||
|
@pytest.mark.esp32s3
|
||||||
|
@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('Loaded app from partition at offset 0x20000', 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]))
|
||||||
|
try:
|
||||||
|
ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode()
|
||||||
|
print('Connected to AP/Ethernet with IP: {}'.format(ip_address))
|
||||||
|
except pexpect.exceptions.TIMEOUT:
|
||||||
|
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
|
||||||
|
host_ip = get_host_ip4_by_dest_ip(ip_address)
|
||||||
|
|
||||||
|
dut.expect('Starting OTA example task', timeout=30)
|
||||||
|
print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin'))
|
||||||
|
dut.write('https://' + host_ip + ':8000/simple_ota.bin')
|
||||||
|
dut.expect('Writing to partition subtype 16 at offset 0x120000', timeout=20)
|
||||||
|
dut.expect('Verifying image signature...', timeout=60)
|
||||||
|
dut.expect('OTA Succeed, Rebooting...', timeout=60)
|
||||||
|
# after reboot
|
||||||
|
dut.expect('Loaded app from partition at offset 0x120000', timeout=20)
|
||||||
|
dut.expect('OTA example app_main start', timeout=10)
|
||||||
|
finally:
|
||||||
|
thread1.terminate()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.esp32c3
|
||||||
|
@pytest.mark.esp32s2
|
||||||
|
@pytest.mark.esp32s3
|
||||||
|
@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('Loaded app from partition at offset 0x20000', 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]))
|
||||||
|
try:
|
||||||
|
ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode()
|
||||||
|
print('Connected to AP/Ethernet with IP: {}'.format(ip_address))
|
||||||
|
except pexpect.exceptions.TIMEOUT:
|
||||||
|
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
|
||||||
|
host_ip = get_host_ip4_by_dest_ip(ip_address)
|
||||||
|
|
||||||
|
dut.expect('Starting OTA example task', timeout=30)
|
||||||
|
print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin'))
|
||||||
|
dut.write('https://' + host_ip + ':8000/simple_ota.bin')
|
||||||
|
dut.expect('Writing to partition subtype 16 at offset 0x120000', 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('Loaded app from partition at offset 0x120000', 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('Loaded app from partition at offset 0x10000', 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
|
||||||
|
if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True:
|
||||||
|
env_name = 'wifi_high_traffic'
|
||||||
|
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('Connected to AP/Ethernet with IP: {}'.format(ip_address))
|
||||||
|
except pexpect.exceptions.TIMEOUT:
|
||||||
|
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
|
||||||
|
host_ip = get_host_ip4_by_dest_ip(ip_address)
|
||||||
|
|
||||||
|
dut.expect('Starting OTA example task', timeout=30)
|
||||||
|
print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin'))
|
||||||
|
dut.write('https://' + host_ip + ':8000/simple_ota.bin')
|
||||||
|
dut.expect('OTA Succeed, Rebooting...', timeout=120)
|
||||||
|
# after reboot
|
||||||
|
dut.expect('Loaded app from partition at offset 0x110000', 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 <image_dir> <server_port> [cert_di>]
|
||||||
|
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('Starting HTTPS server at "https://:{}"'.format(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'))
|
||||||
8
sdkconfig.ci
Normal file
8
sdkconfig.ci
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y
|
||||||
|
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||||
|
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||||
|
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF=y
|
||||||
|
|
||||||
|
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||||
|
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||||
20
sdkconfig.ci.flash_enc_wifi
Normal file
20
sdkconfig.ci.flash_enc_wifi
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||||
|
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||||
|
CONFIG_SECURE_FLASH_ENC_ENABLED=y
|
||||||
|
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y
|
||||||
|
CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y
|
||||||
|
CONFIG_SECURE_BOOT_ALLOW_JTAG=y
|
||||||
|
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y
|
||||||
|
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y
|
||||||
|
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y
|
||||||
|
CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y
|
||||||
|
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||||
|
CONFIG_EXAMPLE_CONNECT_ETHERNET=n
|
||||||
|
CONFIG_EXAMPLE_CONNECT_WIFI=y
|
||||||
|
CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y
|
||||||
|
# This is required for nvs encryption (which is enabled by default with flash encryption)
|
||||||
|
CONFIG_PARTITION_TABLE_TWO_OTA_ENCRYPTED_NVS=y
|
||||||
|
|
||||||
|
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||||
|
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||||
22
sdkconfig.ci.on_update_no_sb_ecdsa
Normal file
22
sdkconfig.ci.on_update_no_sb_ecdsa
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# ECDSA is available only in ESP32
|
||||||
|
CONFIG_IDF_TARGET="esp32"
|
||||||
|
|
||||||
|
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||||
|
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||||
|
|
||||||
|
CONFIG_PARTITION_TABLE_OFFSET=0xC000
|
||||||
|
|
||||||
|
CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT=y
|
||||||
|
CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT=y
|
||||||
|
CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME=y
|
||||||
|
CONFIG_SECURE_BOOT_SIGNING_KEY="test/secure_boot_signing_key_ecdsa.pem"
|
||||||
|
|
||||||
|
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||||
|
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||||
|
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_IP101=y
|
||||||
|
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
|
||||||
|
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
|
||||||
|
CONFIG_EXAMPLE_CONNECT_IPV6=y
|
||||||
27
sdkconfig.ci.on_update_no_sb_rsa
Normal file
27
sdkconfig.ci.on_update_no_sb_rsa
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# ESP32 supports SIGNED_APPS_RSA_SCHEME only in ECO3
|
||||||
|
CONFIG_ESP32_REV_MIN_3=y
|
||||||
|
CONFIG_ESP32_REV_MIN=3
|
||||||
|
|
||||||
|
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||||
|
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||||
|
|
||||||
|
CONFIG_PARTITION_TABLE_OFFSET=0xC000
|
||||||
|
|
||||||
|
CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT=y
|
||||||
|
CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT=y
|
||||||
|
CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=y
|
||||||
|
CONFIG_SECURE_BOOT_SIGNING_KEY="test/secure_boot_signing_key.pem"
|
||||||
|
CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION=y
|
||||||
|
|
||||||
|
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||||
|
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||||
|
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_IP101=y
|
||||||
|
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
|
||||||
|
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
|
||||||
|
|
||||||
|
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||||
|
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||||
13
sdkconfig.ci.spiram
Normal file
13
sdkconfig.ci.spiram
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||||
|
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||||
|
CONFIG_SPIRAM=y
|
||||||
|
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
|
||||||
|
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||||
|
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||||
|
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_IP101=y
|
||||||
|
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
|
||||||
|
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
|
||||||
|
CONFIG_EXAMPLE_CONNECT_IPV6=y
|
||||||
12
sdkconfig.ci.tls1_3
Normal file
12
sdkconfig.ci.tls1_3
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||||
|
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||||
|
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||||
|
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||||
|
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_IP101=y
|
||||||
|
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
|
||||||
|
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
|
||||||
|
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
|
||||||
|
CONFIG_EXAMPLE_CONNECT_IPV6=y
|
||||||
|
CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y
|
||||||
9
sdkconfig.defaults
Normal file
9
sdkconfig.defaults
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Default sdkconfig parameters to use the OTA
|
||||||
|
# partition table layout, with a 4MB flash size
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
|
CONFIG_PARTITION_TABLE_TWO_OTA=y
|
||||||
|
|
||||||
|
# Certificate bundle configuration
|
||||||
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
|
||||||
|
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y
|
||||||
|
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="server_certs/ca_cert.pem"
|
||||||
20
server_certs/ca_cert.pem
Normal file
20
server_certs/ca_cert.pem
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ
|
||||||
|
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
|
||||||
|
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
|
||||||
|
b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ
|
||||||
|
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
|
||||||
|
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
|
||||||
|
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL
|
||||||
|
SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W
|
||||||
|
ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ
|
||||||
|
S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz
|
||||||
|
YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz
|
||||||
|
3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap
|
||||||
|
rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud
|
||||||
|
IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk
|
||||||
|
B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32
|
||||||
|
3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9
|
||||||
|
RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN
|
||||||
|
lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
39
test/secure_boot_signing_key.pem
Normal file
39
test/secure_boot_signing_key.pem
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
5
test/secure_boot_signing_key_ecdsa.pem
Normal file
5
test/secure_boot_signing_key_ecdsa.pem
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MHcCAQEEIOvP45grF4dSM2fWbOAp4W8PgFm30HIZqtNEK13O5hVHoAoGCCqGSM49
|
||||||
|
AwEHoUQDQgAE1IL73BARrNpkHj1jG50eHoF2LERCwz1BfbshuAeLcsED5aT92Xgu
|
||||||
|
gJvq45LN9p6eBi62ZZwr6Z2ZfX3YB3/8KA==
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
Reference in New Issue
Block a user