Skip to content

Commit 1fd5cd7

Browse files
Add OTA update feature
This sketch provide functionality for OTA firmware upgrade.
1 parent 4d98cea commit 1fd5cd7

File tree

5 files changed

+259
-0
lines changed

5 files changed

+259
-0
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ set(LIBRARY_SRCS
6060
libraries/SPI/src/SPI.cpp
6161
libraries/Ticker/src/Ticker.cpp
6262
libraries/Update/src/Updater.cpp
63+
libraries/Update/src/HttpsOTAUpdate.cpp
6364
libraries/WebServer/src/WebServer.cpp
6465
libraries/WebServer/src/Parsing.cpp
6566
libraries/WebServer/src/detail/mimetable.cpp
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// This sketch provide the functionality of OTA Firmware Upgrade
2+
#include "WiFi.h"
3+
#include "HttpsOTAUpdate.h"
4+
// This sketch shows how to implement HTTPS firmware update Over The Air.
5+
// Please provide your WiFi credentials, https URL to the firmware image and the server certificate.
6+
7+
static const char *ssid = "your-ssid"; // your network SSID (name of wifi network)
8+
static const char *password = "your-password"; // your network password
9+
10+
static const char *url = "https://example.com/firmware.bin"; //state url of your firmware image
11+
12+
static const char *server_certificate = "-----BEGIN CERTIFICATE-----\n" \
13+
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \
14+
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \
15+
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \
16+
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \
17+
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \
18+
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \
19+
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \
20+
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \
21+
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \
22+
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \
23+
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \
24+
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \
25+
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \
26+
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \
27+
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \
28+
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \
29+
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \
30+
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \
31+
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \
32+
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \
33+
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \
34+
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \
35+
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \
36+
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \
37+
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \
38+
"-----END CERTIFICATE-----";
39+
40+
static HttpsOTAStatus_t otastatus;
41+
42+
void HttpEvent(HttpEvent_t *event)
43+
{
44+
switch(event->event_id) {
45+
case HTTP_EVENT_ERROR:
46+
Serial.println("Http Event Error");
47+
break;
48+
case HTTP_EVENT_ON_CONNECTED:
49+
Serial.println("Http Event On Connected");
50+
break;
51+
case HTTP_EVENT_HEADER_SENT:
52+
Serial.println("Http Event Header Sent");
53+
break;
54+
case HTTP_EVENT_ON_HEADER:
55+
Serial.printf("Http Event On Header, key=%s, value=%s\n", event->header_key, event->header_value);
56+
break;
57+
case HTTP_EVENT_ON_DATA:
58+
break;
59+
case HTTP_EVENT_ON_FINISH:
60+
Serial.println("Http Event On Finish");
61+
break;
62+
case HTTP_EVENT_DISCONNECTED:
63+
Serial.println("Http Event Disconnected");
64+
break;
65+
}
66+
}
67+
68+
void setup(){
69+
70+
Serial.begin(115200);
71+
Serial.print("Attempting to connect to SSID: ");
72+
WiFi.begin(ssid, password);
73+
74+
// attempt to connect to Wifi network:
75+
while (WiFi.status() != WL_CONNECTED) {
76+
Serial.print(".");
77+
delay(1000);
78+
}
79+
80+
Serial.print("Connected to ");
81+
Serial.println(ssid);
82+
83+
HttpsOTA.onHttpEvent(HttpEvent);
84+
Serial.println("Starting OTA");
85+
HttpsOTA.begin(url, server_certificate);
86+
87+
Serial.println("Please Wait it takes some time ...");
88+
}
89+
90+
void loop(){
91+
otastatus = HttpsOTA.status();
92+
if(otastatus == HTTPS_OTA_SUCCESS) {
93+
Serial.println("Firmware written successfully. To reboot device, call API ESP.restart() or PUSH restart button on device");
94+
} else if(otastatus == HTTPS_OTA_FAIL) {
95+
Serial.println("Firmware Upgrade Fail");
96+
}
97+
delay(1000);
98+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# OTA Firmware Upgrade for Arduino
2+
This sketch allows Arduino user to perform Over The Air (OTA) firmware upgrade. It uses HTTPS.
3+
4+
# API introduced for OTA
5+
6+
## HttpsOTA.begin(const char * url, const char * server_certificate, bool skip_cert_common_name_check)
7+
8+
Main API which starts firmware upgrade
9+
10+
### Parameters
11+
* url : URL for the uploaded firmware image
12+
* server_certificate : Provide the ota server certificate for authentication via HTTPS
13+
* skip_cert_common_name_check : Skip any validation of server certificate CN field
14+
15+
The default value provided to skip_cert_common_name_check is true
16+
17+
## HttpsOTA.onHttpEvent(function)
18+
19+
This API exposes HTTP Events to the user
20+
21+
### Parameter
22+
Function passed has following signature
23+
void HttpEvent (HttpEvent_t * event);
24+
25+
# HttpsOTA.otaStatus()
26+
27+
It tracks the progress of OTA firmware upgrade.
28+
* HTTPS_OTA_IDLE : OTA upgrade have not started yet.
29+
* HTTPS_OTA_UPDATNG : OTA upgarde is in progress.
30+
* HTTPS_OTA_SUCCESS : OTA upgrade is successful.
31+
* HTTPS_OTA_FAIL : OTA upgrade failed.
32+
* HTTPS_OTA_ERR : Error occured while creating xEventGroup().
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/* OTA task
2+
3+
This example code is in the Public Domain (or CC0 licensed, at your option.)
4+
5+
Unless required by applicable law or agreed to in writing, this
6+
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7+
CONDITIONS OF ANY KIND, either express or implied.
8+
*/
9+
#include <stdio.h>
10+
#include <string.h>
11+
12+
#include <freertos/FreeRTOS.h>
13+
#include <freertos/task.h>
14+
15+
#include "esp32-hal-log.h"
16+
#include "esp_http_client.h"
17+
#include "esp_https_ota.h"
18+
19+
#include "HttpsOTAUpdate.h"
20+
#include "Esp.h"
21+
#define OTA_TASK_STACK_SIZE 9216
22+
23+
typedef void (*HttpEventCb)(HttpEvent_t*);
24+
25+
static esp_http_client_config_t config;
26+
static HttpEventCb cb;
27+
static EventGroupHandle_t ota_status = NULL;//check for ota status
28+
static EventBits_t set_bit;
29+
30+
const int OTA_IDLE_BIT = BIT0;
31+
const int OTA_UPDATING_BIT = BIT1;
32+
const int OTA_SUCCESS_BIT = BIT2;
33+
const int OTA_FAIL_BIT = BIT3;
34+
35+
esp_err_t http_event_handler(esp_http_client_event_t *event)
36+
{
37+
cb(event);
38+
return ESP_OK;
39+
}
40+
41+
void https_ota_task(void *param)
42+
{
43+
if(ota_status) {
44+
xEventGroupSetBits(ota_status, OTA_UPDATING_BIT);
45+
xEventGroupClearBits(ota_status, OTA_IDLE_BIT);
46+
}
47+
esp_err_t ret = esp_https_ota((const esp_http_client_config_t *)param);
48+
if(ret == ESP_OK) {
49+
if(ota_status) {
50+
xEventGroupClearBits(ota_status, OTA_UPDATING_BIT);
51+
xEventGroupSetBits(ota_status, OTA_SUCCESS_BIT);
52+
}
53+
} else {
54+
if(ota_status) {
55+
xEventGroupClearBits(ota_status, OTA_UPDATING_BIT);
56+
xEventGroupSetBits(ota_status, OTA_FAIL_BIT);
57+
}
58+
}
59+
vTaskDelete(NULL);
60+
}
61+
62+
HttpsOTAStatus_t HttpsOTAUpdateClass::status()
63+
{
64+
if(ota_status) {
65+
set_bit = xEventGroupGetBits(ota_status);
66+
if(set_bit == OTA_IDLE_BIT) {
67+
return HTTPS_OTA_IDLE;
68+
}
69+
if(set_bit == OTA_UPDATING_BIT) {
70+
return HTTPS_OTA_UPDATING;
71+
}
72+
if(set_bit == OTA_SUCCESS_BIT) {
73+
return HTTPS_OTA_SUCCESS;
74+
}
75+
if(set_bit == OTA_FAIL_BIT) {
76+
return HTTPS_OTA_FAIL;
77+
}
78+
}
79+
return HTTPS_OTA_ERR;
80+
}
81+
82+
void HttpsOTAUpdateClass::onHttpEvent(HttpEventCb cbEvent)
83+
{
84+
cb = cbEvent;
85+
}
86+
87+
void HttpsOTAUpdateClass::begin(const char *url, const char *cert_pem, bool skip_cert_common_name_check)
88+
{
89+
config.url = url;
90+
config.cert_pem = cert_pem;
91+
config.skip_cert_common_name_check = skip_cert_common_name_check;
92+
config.event_handler = http_event_handler;
93+
94+
if(!ota_status) {
95+
ota_status = xEventGroupCreate();
96+
if(!ota_status) {
97+
log_e("OTA Event Group Create Failed");
98+
}
99+
xEventGroupSetBits(ota_status, OTA_IDLE_BIT);
100+
}
101+
102+
if (xTaskCreate(&https_ota_task, "https_ota_task", OTA_TASK_STACK_SIZE, &config, 5, NULL) != pdPASS) {
103+
log_e("Couldn't create ota task\n");
104+
}
105+
}
106+
107+
HttpsOTAUpdateClass HttpsOTA;

libraries/Update/src/HttpsOTAUpdate.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "esp_http_client.h"
2+
#define HttpEvent_t esp_http_client_event_t
3+
4+
typedef enum
5+
{
6+
HTTPS_OTA_IDLE,
7+
HTTPS_OTA_UPDATING,
8+
HTTPS_OTA_SUCCESS,
9+
HTTPS_OTA_FAIL,
10+
HTTPS_OTA_ERR
11+
}HttpsOTAStatus_t;
12+
13+
class HttpsOTAUpdateClass {
14+
15+
public:
16+
void begin(const char *url, const char *cert_pem, bool skip_cert_common_name_check = true);
17+
void onHttpEvent(void (*http_event_cb_t)(HttpEvent_t *));
18+
HttpsOTAStatus_t status();
19+
};
20+
21+
extern HttpsOTAUpdateClass HttpsOTA;

0 commit comments

Comments
 (0)