Add OTA update feature

This sketch provide functionality for OTA firmware upgrade.
This commit is contained in:
Sweety 2020-08-25 13:31:58 +05:30 committed by GitHub
parent 4d98cea085
commit 1fd5cd79c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 259 additions and 0 deletions

View File

@ -60,6 +60,7 @@ set(LIBRARY_SRCS
libraries/SPI/src/SPI.cpp
libraries/Ticker/src/Ticker.cpp
libraries/Update/src/Updater.cpp
libraries/Update/src/HttpsOTAUpdate.cpp
libraries/WebServer/src/WebServer.cpp
libraries/WebServer/src/Parsing.cpp
libraries/WebServer/src/detail/mimetable.cpp

View File

@ -0,0 +1,98 @@
// This sketch provide the functionality of OTA Firmware Upgrade
#include "WiFi.h"
#include "HttpsOTAUpdate.h"
// This sketch shows how to implement HTTPS firmware update Over The Air.
// Please provide your WiFi credentials, https URL to the firmware image and the server certificate.
static const char *ssid = "your-ssid"; // your network SSID (name of wifi network)
static const char *password = "your-password"; // your network password
static const char *url = "https://example.com/firmware.bin"; //state url of your firmware image
static const char *server_certificate = "-----BEGIN CERTIFICATE-----\n" \
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \
"-----END CERTIFICATE-----";
static HttpsOTAStatus_t otastatus;
void HttpEvent(HttpEvent_t *event)
{
switch(event->event_id) {
case HTTP_EVENT_ERROR:
Serial.println("Http Event Error");
break;
case HTTP_EVENT_ON_CONNECTED:
Serial.println("Http Event On Connected");
break;
case HTTP_EVENT_HEADER_SENT:
Serial.println("Http Event Header Sent");
break;
case HTTP_EVENT_ON_HEADER:
Serial.printf("Http Event On Header, key=%s, value=%s\n", event->header_key, event->header_value);
break;
case HTTP_EVENT_ON_DATA:
break;
case HTTP_EVENT_ON_FINISH:
Serial.println("Http Event On Finish");
break;
case HTTP_EVENT_DISCONNECTED:
Serial.println("Http Event Disconnected");
break;
}
}
void setup(){
Serial.begin(115200);
Serial.print("Attempting to connect to SSID: ");
WiFi.begin(ssid, password);
// attempt to connect to Wifi network:
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.print("Connected to ");
Serial.println(ssid);
HttpsOTA.onHttpEvent(HttpEvent);
Serial.println("Starting OTA");
HttpsOTA.begin(url, server_certificate);
Serial.println("Please Wait it takes some time ...");
}
void loop(){
otastatus = HttpsOTA.status();
if(otastatus == HTTPS_OTA_SUCCESS) {
Serial.println("Firmware written successfully. To reboot device, call API ESP.restart() or PUSH restart button on device");
} else if(otastatus == HTTPS_OTA_FAIL) {
Serial.println("Firmware Upgrade Fail");
}
delay(1000);
}

View File

@ -0,0 +1,32 @@
# OTA Firmware Upgrade for Arduino
This sketch allows Arduino user to perform Over The Air (OTA) firmware upgrade. It uses HTTPS.
# API introduced for OTA
## HttpsOTA.begin(const char * url, const char * server_certificate, bool skip_cert_common_name_check)
Main API which starts firmware upgrade
### Parameters
* url : URL for the uploaded firmware image
* server_certificate : Provide the ota server certificate for authentication via HTTPS
* skip_cert_common_name_check : Skip any validation of server certificate CN field
The default value provided to skip_cert_common_name_check is true
## HttpsOTA.onHttpEvent(function)
This API exposes HTTP Events to the user
### Parameter
Function passed has following signature
void HttpEvent (HttpEvent_t * event);
# HttpsOTA.otaStatus()
It tracks the progress of OTA firmware upgrade.
* HTTPS_OTA_IDLE : OTA upgrade have not started yet.
* HTTPS_OTA_UPDATNG : OTA upgarde is in progress.
* HTTPS_OTA_SUCCESS : OTA upgrade is successful.
* HTTPS_OTA_FAIL : OTA upgrade failed.
* HTTPS_OTA_ERR : Error occured while creating xEventGroup().

View File

@ -0,0 +1,107 @@
/* OTA task
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 <stdio.h>
#include <string.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "esp32-hal-log.h"
#include "esp_http_client.h"
#include "esp_https_ota.h"
#include "HttpsOTAUpdate.h"
#include "Esp.h"
#define OTA_TASK_STACK_SIZE 9216
typedef void (*HttpEventCb)(HttpEvent_t*);
static esp_http_client_config_t config;
static HttpEventCb cb;
static EventGroupHandle_t ota_status = NULL;//check for ota status
static EventBits_t set_bit;
const int OTA_IDLE_BIT = BIT0;
const int OTA_UPDATING_BIT = BIT1;
const int OTA_SUCCESS_BIT = BIT2;
const int OTA_FAIL_BIT = BIT3;
esp_err_t http_event_handler(esp_http_client_event_t *event)
{
cb(event);
return ESP_OK;
}
void https_ota_task(void *param)
{
if(ota_status) {
xEventGroupSetBits(ota_status, OTA_UPDATING_BIT);
xEventGroupClearBits(ota_status, OTA_IDLE_BIT);
}
esp_err_t ret = esp_https_ota((const esp_http_client_config_t *)param);
if(ret == ESP_OK) {
if(ota_status) {
xEventGroupClearBits(ota_status, OTA_UPDATING_BIT);
xEventGroupSetBits(ota_status, OTA_SUCCESS_BIT);
}
} else {
if(ota_status) {
xEventGroupClearBits(ota_status, OTA_UPDATING_BIT);
xEventGroupSetBits(ota_status, OTA_FAIL_BIT);
}
}
vTaskDelete(NULL);
}
HttpsOTAStatus_t HttpsOTAUpdateClass::status()
{
if(ota_status) {
set_bit = xEventGroupGetBits(ota_status);
if(set_bit == OTA_IDLE_BIT) {
return HTTPS_OTA_IDLE;
}
if(set_bit == OTA_UPDATING_BIT) {
return HTTPS_OTA_UPDATING;
}
if(set_bit == OTA_SUCCESS_BIT) {
return HTTPS_OTA_SUCCESS;
}
if(set_bit == OTA_FAIL_BIT) {
return HTTPS_OTA_FAIL;
}
}
return HTTPS_OTA_ERR;
}
void HttpsOTAUpdateClass::onHttpEvent(HttpEventCb cbEvent)
{
cb = cbEvent;
}
void HttpsOTAUpdateClass::begin(const char *url, const char *cert_pem, bool skip_cert_common_name_check)
{
config.url = url;
config.cert_pem = cert_pem;
config.skip_cert_common_name_check = skip_cert_common_name_check;
config.event_handler = http_event_handler;
if(!ota_status) {
ota_status = xEventGroupCreate();
if(!ota_status) {
log_e("OTA Event Group Create Failed");
}
xEventGroupSetBits(ota_status, OTA_IDLE_BIT);
}
if (xTaskCreate(&https_ota_task, "https_ota_task", OTA_TASK_STACK_SIZE, &config, 5, NULL) != pdPASS) {
log_e("Couldn't create ota task\n");
}
}
HttpsOTAUpdateClass HttpsOTA;

View File

@ -0,0 +1,21 @@
#include "esp_http_client.h"
#define HttpEvent_t esp_http_client_event_t
typedef enum
{
HTTPS_OTA_IDLE,
HTTPS_OTA_UPDATING,
HTTPS_OTA_SUCCESS,
HTTPS_OTA_FAIL,
HTTPS_OTA_ERR
}HttpsOTAStatus_t;
class HttpsOTAUpdateClass {
public:
void begin(const char *url, const char *cert_pem, bool skip_cert_common_name_check = true);
void onHttpEvent(void (*http_event_cb_t)(HttpEvent_t *));
HttpsOTAStatus_t status();
};
extern HttpsOTAUpdateClass HttpsOTA;