From 318038a746ccb060f17e3c5ccac50060e7d67afa Mon Sep 17 00:00:00 2001 From: "nilesh.kale" Date: Wed, 6 Dec 2023 17:44:44 +0530 Subject: [PATCH] fix: fixed issue faced while starting python server and updated ota readme openssl server does not support for range request mechanism. Consequently, it does not support partial download feature. So, removing commands and steps required for staring openssl server. Also, updated pytest file to avoid unnecssary issues while starting server. --- examples/system/ota/README.md | 54 +++++++++++-------- .../simple_ota_example/pytest_simple_ota.py | 9 +++- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/examples/system/ota/README.md b/examples/system/ota/README.md index f837b56100..39315ca3ff 100644 --- a/examples/system/ota/README.md +++ b/examples/system/ota/README.md @@ -58,7 +58,7 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l ## Example Output -### Run HTTPS Server +### Configure HTTPS Server After a successful build, we need to create a self-signed certificate and run a simple HTTPS server as follows: @@ -67,14 +67,42 @@ After a successful build, we need to create a self-signed certificate and run a * Enter the directory containing build artifact/s of project, that will be hosted by HTTPS server, e.g. `cd build`. * To create a new self-signed certificate and key, run the command `openssl req -x509 -newkey rsa:2048 -keyout ca_key.pem -out ca_cert.pem -days 365 -nodes`. * When prompted for the `Common Name (CN)`, enter the name of the server that the "ESP-Dev-Board" will connect to. When running this example from a development machine, this is probably the IP address. The HTTPS client will check that the `CN` matches the address given in the HTTPS URL. -* To start the HTTPS server, run the command `openssl s_server -WWW -key ca_key.pem -cert ca_cert.pem -port 8070`. * This directory should contain the firmware (e.g. `hello_world.bin`) to be used in the update process. This can be any valid ESP-IDF application, as long as its filename corresponds to the name configured using `Firmware Upgrade URL` in menuconfig. The only difference to flashing a firmware via the serial interface is that the binary is flashed to the `factory` partition, while OTA update use one of the OTA partitions. + +### Start HTTPS Server + +#### OpenSSL based server + +* To start openssl based HTTPS server, run the command `openssl s_server -WWW -key ca_key.pem -cert ca_cert.pem -port 8070`. + +Sample console output as: +```bash +$ openssl s_server -WWW -key ca_key.pem -cert ca_cert.pem -port 8070 +FILE:hello_world.bin +ACCEPT +``` + +* **Note:** The OpenSSL server cannot handle partial HTTP requests, so it does not support partial downloading. Alternatively you can start python based server using [Python based server](#Python-based-server) * **Note:** Make sure incoming access to port *8070* is not prevented by firewall rules. * **Note:** Windows users may encounter issues while running `openssl s_server -WWW`, due to CR/LF translation and/or closing the connection prematurely (Some windows builds of openssl translate CR/LF sequences to LF in the served files, leading to corrupted images received by the OTA client; others interpret the `0x1a`/`SUB` character in a binary as an escape sequence, i.e. end of file, and close the connection prematurely thus preventing the OTA client from receiving a complete image). * We recommend using the `openssl` binary bundled in `Git For Windows` from the [ESP-IDF Tool installer](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/windows-setup.html): Open the ESP-IDF command prompt and add the internal openssl binary to your path: `set PATH=%LocalAppData%\Git\usr\bin;%PATH%` and run openssl's http server command as above. - * Alternatively, use any windows based openssl with version `v1.1.1i` or greater built on the `Msys-x86_64` platform, or a simple python https server -- see `start_https_server` in the [example_test](simple_ota_example/pytest_simple_ota.py) script. + +#### Python based server + +* To start python based HTTPS server using [example_test_scipt](simple_ota_example/pytest_simple_ota.py), run `pytest_simple_ota.py [CERT_DIR]`, where: + - `` is a directory containing the firmware (e.g. `hello_world.bin`) to be used in the update process.` + - `` is the server's port, here `8070` + - `[CERT_DIR]` is an optional argument pointing to a specific directory with the certificate and key file:`ca_cert.pem` and `ca_key.pem'. + +Sample console output as: +``` bash +$ cd idf/examples/system/ota/simple_ota_example +$ python pytest_simple_ota.py build 8070 +Starting HTTPS server at "https://:8070" +192.168.10.106 - - [02/Mar/2021 14:32:26] "GET /simple_ota.bin HTTP/1.1" 200 - +``` ### Flash Certificate to "ESP-Dev-Board" @@ -99,14 +127,6 @@ If you want to rollback to the `factory` app after the upgrade (or to the first **Note:** This assumes that the partition table of this project is the one present on the device. -### Output from the HTTPS server - -```bash -FILE:hello_world.bin -ACCEPT -``` - - ## Supporting Rollback This feature allows you to roll back to a previous firmware if new image is not useable. The menuconfig option `CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` allows you to track the first boot of the application (see the ``Over The Air Updates (OTA)`` article). @@ -149,17 +169,7 @@ Running a local https server might be tricky in some cases (due to self signed c - Execute `python -m http.server 8070` in the directory with the firmware image - Use http://:8070/ as the firmware upgrade URL - Enable *Allow HTTP for OTA* (`CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP`) in `Component config -> ESP HTTPS OTA` so the URI without TLS is accepted -* Start the HTTPS server using [example_test](simple_ota_example/pytest_simple_ota.py) with two or more parameters: `pytest_simple_ota.py [CERT_DIR]`, where: - - `` is a directory containing the image and by default also the certificate and key files:`ca_cert.pem` and `ca_key.pem` - - `` is the server's port, here `8070` - - `[CERT_DIR]` is an optional argument pointing to a specific directory with the certificate and key file. - - example of the script output: -``` bash -$ cd idf/examples/system/ota/simple_ota_example -$ python pytest_simple_ota.py build 8070 -Starting HTTPS server at "https://:8070" -192.168.10.106 - - [02/Mar/2021 14:32:26] "GET /simple_ota.bin HTTP/1.1" 200 - -``` + * Publish the firmware image on a public server (e.g. github.com) and copy its root certificate to the `server_certs` directory as `ca_cert.pem`. The certificate can be downloaded using the `s_client` openssl command as shown below: ``` diff --git a/examples/system/ota/simple_ota_example/pytest_simple_ota.py b/examples/system/ota/simple_ota_example/pytest_simple_ota.py index 3159cdf9e3..a6f4a32679 100644 --- a/examples/system/ota/simple_ota_example/pytest_simple_ota.py +++ b/examples/system/ota/simple_ota_example/pytest_simple_ota.py @@ -10,10 +10,15 @@ from typing import Tuple import pexpect import pytest -from common_test_methods import get_env_config_variable -from common_test_methods import get_host_ip4_by_dest_ip 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'\