Re-established SpanOTA code and tested OTA upload

Only problem was that the definition for esp_image_header_t was moved to a new IDF header file.  Solution was to add: #include <esp_app_format.h>.
This commit is contained in:
Gregg 2024-07-20 09:38:54 -05:00
parent 158274cac6
commit fc4d8d85d1
4 changed files with 161 additions and 159 deletions

View File

@ -40,13 +40,13 @@ void HAPClient::init(){
size_t len; // not used but required to read blobs from NVS size_t len; // not used but required to read blobs from NVS
// if(strlen(homeSpan.spanOTA.otaPwd)==0){ // OTA password has not been specified in sketch if(strlen(homeSpan.spanOTA.otaPwd)==0){ // OTA password has not been specified in sketch
// if(!nvs_get_str(homeSpan.otaNVS,"OTADATA",NULL,&len)){ // if found OTA data in NVS... if(!nvs_get_str(homeSpan.otaNVS,"OTADATA",NULL,&len)){ // if found OTA data in NVS...
// nvs_get_str(homeSpan.otaNVS,"OTADATA",homeSpan.spanOTA.otaPwd,&len); // ...retrieve data. nvs_get_str(homeSpan.otaNVS,"OTADATA",homeSpan.spanOTA.otaPwd,&len); // ...retrieve data.
// } else { // otherwise... } else { // otherwise...
// homeSpan.spanOTA.setPassword(DEFAULT_OTA_PASSWORD); // ...use default password homeSpan.spanOTA.setPassword(DEFAULT_OTA_PASSWORD); // ...use default password
// } }
// } }
if(!strlen(homeSpan.qrID)){ // if Setup ID has not been specified in sketch if(!strlen(homeSpan.qrID)){ // if Setup ID has not been specified in sketch
if(!nvs_get_str(homeSpan.hapNVS,"SETUPID",NULL,&len)){ // check for saved value if(!nvs_get_str(homeSpan.hapNVS,"SETUPID",NULL,&len)){ // check for saved value

View File

@ -38,6 +38,7 @@
#include <esp_sntp.h> #include <esp_sntp.h>
#include <esp_ota_ops.h> #include <esp_ota_ops.h>
#include <esp_wifi.h> #include <esp_wifi.h>
#include <esp_app_format.h>
#include "HomeSpan.h" #include "HomeSpan.h"
#include "HAP.h" #include "HAP.h"
@ -155,11 +156,11 @@ void Span::begin(Category catID, const char *_displayName, const char *_hostName
nvs_get_u8(otaNVS,"OTA_REQUIRED",&otaRequired); nvs_get_u8(otaNVS,"OTA_REQUIRED",&otaRequired);
nvs_set_u8(otaNVS,"OTA_REQUIRED",0); nvs_set_u8(otaNVS,"OTA_REQUIRED",0);
nvs_commit(otaNVS); nvs_commit(otaNVS);
// if(otaRequired && !spanOTA.enabled){ if(otaRequired && !spanOTA.enabled){
// LOG0("\n\n*** OTA SAFE MODE ALERT: OTA REQUIRED BUT NOT ENABLED. ROLLING BACK TO PREVIOUS APPLICATION ***\n\n"); LOG0("\n\n*** OTA SAFE MODE ALERT: OTA REQUIRED BUT NOT ENABLED. ROLLING BACK TO PREVIOUS APPLICATION ***\n\n");
// delay(100); delay(100);
// esp_ota_mark_app_invalid_rollback_and_reboot(); esp_ota_mark_app_invalid_rollback_and_reboot();
// } }
} // begin } // begin
@ -268,8 +269,8 @@ void Span::pollTask() {
HAPClient::checkNotifications(); HAPClient::checkNotifications();
HAPClient::checkTimedWrites(); HAPClient::checkTimedWrites();
//D if(spanOTA.enabled) if(spanOTA.enabled)
//D ArduinoOTA.handle(); ArduinoOTA.handle();
if(controlButton && controlButton->primed()) if(controlButton && controlButton->primed())
STATUS_UPDATE(start(LED_ALERT),HS_ENTERING_CONFIG_MODE) STATUS_UPDATE(start(LED_ALERT),HS_ENTERING_CONFIG_MODE)
@ -476,20 +477,20 @@ void Span::checkConnect(){
mbedtls_base64_encode((uint8_t *)setupHash,9,&len,hashOutput,4); // Step 3: Encode the first 4 bytes of hashOutput in base64, which results in an 8-character, null-terminated, setupHash mbedtls_base64_encode((uint8_t *)setupHash,9,&len,hashOutput,4); // Step 3: Encode the first 4 bytes of hashOutput in base64, which results in an 8-character, null-terminated, setupHash
mdns_service_txt_item_set("_hap","_tcp","sh",setupHash); // Step 4: broadcast the resulting Setup Hash mdns_service_txt_item_set("_hap","_tcp","sh",setupHash); // Step 4: broadcast the resulting Setup Hash
// if(spanOTA.enabled){ if(spanOTA.enabled){
// ArduinoOTA.setHostname(hostName); ArduinoOTA.setHostname(hostName);
//
// if(spanOTA.auth) if(spanOTA.auth)
// ArduinoOTA.setPasswordHash(spanOTA.otaPwd); ArduinoOTA.setPasswordHash(spanOTA.otaPwd);
//
// ArduinoOTA.onStart(spanOTA.start).onEnd(spanOTA.end).onProgress(spanOTA.progress).onError(spanOTA.error); ArduinoOTA.onStart(spanOTA.start).onEnd(spanOTA.end).onProgress(spanOTA.progress).onError(spanOTA.error);
//
// ArduinoOTA.begin(); ArduinoOTA.begin();
// LOG0("Starting OTA Server: %s at %s\n",displayName,WiFi.localIP().toString().c_str()); LOG0("Starting OTA Server: %s at %s\n",displayName,WiFi.localIP().toString().c_str());
// LOG0("Authorization Password: %s",spanOTA.auth?"Enabled\n\n":"DISABLED!\n\n"); LOG0("Authorization Password: %s",spanOTA.auth?"Enabled\n\n":"DISABLED!\n\n");
// } }
//D mdns_service_txt_item_set("_hap","_tcp","ota",spanOTA.enabled?"yes":"no"); // OTA status (info only - NOT used by HAP) mdns_service_txt_item_set("_hap","_tcp","ota",spanOTA.enabled?"yes":"no"); // OTA status (info only - NOT used by HAP)
if(webLog.isEnabled){ if(webLog.isEnabled){
mdns_service_txt_item_set("_hap","_tcp","logURL",webLog.statusURL.c_str()+4); // Web Log status (info only - NOT used by HAP) mdns_service_txt_item_set("_hap","_tcp","logURL",webLog.statusURL.c_str()+4); // Web Log status (info only - NOT used by HAP)
@ -608,34 +609,34 @@ void Span::processSerialCommand(const char *c){
} }
break; break;
// case 'O': { case 'O': {
//
// char textPwd[34]="\0"; char textPwd[34]="\0";
//
// LOG0("\n>>> New OTA Password, or <return> to cancel request: "); LOG0("\n>>> New OTA Password, or <return> to cancel request: ");
// readSerial(textPwd,33); readSerial(textPwd,33);
//
// if(strlen(textPwd)==0){ if(strlen(textPwd)==0){
// LOG0("(cancelled)\n\n"); LOG0("(cancelled)\n\n");
// return; return;
// } }
//
// if(strlen(textPwd)==33){ if(strlen(textPwd)==33){
// LOG0("\n*** Sorry, 32 character limit - request cancelled\n\n"); LOG0("\n*** Sorry, 32 character limit - request cancelled\n\n");
// return; return;
// } }
//
// LOG0("%s\n",mask(textPwd,2).c_str()); LOG0("%s\n",mask(textPwd,2).c_str());
// spanOTA.setPassword(textPwd); spanOTA.setPassword(textPwd);
// nvs_set_str(otaNVS,"OTADATA",spanOTA.otaPwd); // update data nvs_set_str(otaNVS,"OTADATA",spanOTA.otaPwd); // update data
// nvs_commit(otaNVS); nvs_commit(otaNVS);
//
// LOG0("... Accepted! Password change will take effect after next restart.\n"); LOG0("... Accepted! Password change will take effect after next restart.\n");
// if(!spanOTA.enabled) if(!spanOTA.enabled)
// LOG0("... Note: OTA has not been enabled in this sketch.\n"); LOG0("... Note: OTA has not been enabled in this sketch.\n");
// LOG0("\n"); LOG0("\n");
// } }
// break; break;
case 'S': { case 'S': {
@ -2457,89 +2458,89 @@ void SpanWebLog::vLog(boolean sysMsg, const char *fmt, va_list ap){
// SpanOTA // // SpanOTA //
/////////////////////////////// ///////////////////////////////
//int SpanOTA::init(boolean _auth, boolean _safeLoad, const char *pwd){ int SpanOTA::init(boolean _auth, boolean _safeLoad, const char *pwd){
// if(esp_ota_get_running_partition()==esp_ota_get_next_update_partition(NULL)){ if(esp_ota_get_running_partition()==esp_ota_get_next_update_partition(NULL)){
// LOG0("\n*** WARNING: Can't start OTA Server - Partition table used to compile this sketch is not configured for OTA.\n\n"); LOG0("\n*** WARNING: Can't start OTA Server - Partition table used to compile this sketch is not configured for OTA.\n\n");
// return(-1); return(-1);
// } }
//
// enabled=true; enabled=true;
// safeLoad=_safeLoad; safeLoad=_safeLoad;
// auth=_auth; auth=_auth;
// if(pwd==NULL) if(pwd==NULL)
// return(0); return(0);
// return(setPassword(pwd)); return(setPassword(pwd));
//} }
//
///////////////////////////////// ///////////////////////////////
//
//int SpanOTA::setPassword(const char *pwd){ int SpanOTA::setPassword(const char *pwd){
// if(strlen(pwd)<1 || strlen(pwd)>32){ if(strlen(pwd)<1 || strlen(pwd)>32){
// LOG0("\n*** WARNING: Cannot change OTA password to '%s'. Password length must be between 1 and 32 characters.\n\n",pwd); LOG0("\n*** WARNING: Cannot change OTA password to '%s'. Password length must be between 1 and 32 characters.\n\n",pwd);
// return(-1); return(-1);
// } }
//
// MD5Builder otaPwdHash; MD5Builder otaPwdHash;
// otaPwdHash.begin(); otaPwdHash.begin();
// otaPwdHash.add(pwd); otaPwdHash.add(pwd);
// otaPwdHash.calculate(); otaPwdHash.calculate();
// otaPwdHash.getChars(homeSpan.spanOTA.otaPwd); otaPwdHash.getChars(homeSpan.spanOTA.otaPwd);
// return(0); return(0);
//} }
//
///////////////////////////////// ///////////////////////////////
//
//void SpanOTA::start(){ void SpanOTA::start(){
// LOG0("\n*** Current Partition: %s\n*** New Partition: %s\n*** OTA Starting..", LOG0("\n*** Current Partition: %s\n*** New Partition: %s\n*** OTA Starting..",
// esp_ota_get_running_partition()->label,esp_ota_get_next_update_partition(NULL)->label); esp_ota_get_running_partition()->label,esp_ota_get_next_update_partition(NULL)->label);
// otaPercent=0; otaPercent=0;
// STATUS_UPDATE(start(LED_OTA_STARTED),HS_OTA_STARTED) STATUS_UPDATE(start(LED_OTA_STARTED),HS_OTA_STARTED)
//} }
//
///////////////////////////////// ///////////////////////////////
//
//void SpanOTA::end(){ void SpanOTA::end(){
// nvs_set_u8(homeSpan.otaNVS,"OTA_REQUIRED",safeLoad); nvs_set_u8(homeSpan.otaNVS,"OTA_REQUIRED",safeLoad);
// nvs_commit(homeSpan.otaNVS); nvs_commit(homeSpan.otaNVS);
// LOG0(" DONE! Rebooting...\n"); LOG0(" DONE! Rebooting...\n");
// homeSpan.reboot(); homeSpan.reboot();
//} }
//
///////////////////////////////// ///////////////////////////////
//
//void SpanOTA::progress(uint32_t progress, uint32_t total){ void SpanOTA::progress(uint32_t progress, uint32_t total){
// int percent=progress*100/total; int percent=progress*100/total;
// if(percent/10 != otaPercent/10){ if(percent/10 != otaPercent/10){
// otaPercent=percent; otaPercent=percent;
// LOG0("%d%%..",progress*100/total); LOG0("%d%%..",percent);
// } }
//
// if(safeLoad && progress==total){ if(safeLoad && progress==total){
// SpanPartition newSpanPartition; SpanPartition newSpanPartition;
// esp_partition_read(esp_ota_get_next_update_partition(NULL), sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t), &newSpanPartition, sizeof(newSpanPartition)); esp_partition_read(esp_ota_get_next_update_partition(NULL), sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t), &newSpanPartition, sizeof(newSpanPartition));
// LOG0("Checking for HomeSpan Magic Cookie: %s..",newSpanPartition.magicCookie); LOG0("Checking for HomeSpan Magic Cookie: %s..",newSpanPartition.magicCookie);
// if(strcmp(newSpanPartition.magicCookie,spanPartition.magicCookie)) if(strcmp(newSpanPartition.magicCookie,spanPartition.magicCookie))
// Update.abort(); Update.abort();
// } }
//} }
//
///////////////////////////////// ///////////////////////////////
//
//void SpanOTA::error(ota_error_t err){ void SpanOTA::error(ota_error_t err){
// LOG0("*** OTA Error[%u]: ", err); LOG0("*** OTA Error[%u]: ", err);
// if (err == OTA_AUTH_ERROR) LOG0("Auth Failed\n\n"); if (err == OTA_AUTH_ERROR) LOG0("Auth Failed\n\n");
// else if (err == OTA_BEGIN_ERROR) LOG0("Begin Failed\n\n"); else if (err == OTA_BEGIN_ERROR) LOG0("Begin Failed\n\n");
// else if (err == OTA_CONNECT_ERROR) LOG0("Connect Failed\n\n"); else if (err == OTA_CONNECT_ERROR) LOG0("Connect Failed\n\n");
// else if (err == OTA_RECEIVE_ERROR) LOG0("Receive Failed\n\n"); else if (err == OTA_RECEIVE_ERROR) LOG0("Receive Failed\n\n");
// else if (err == OTA_END_ERROR) LOG0("End Failed\n\n"); else if (err == OTA_END_ERROR) LOG0("End Failed\n\n");
//} }
//
///////////////////////////////// ///////////////////////////////
//
//int SpanOTA::otaPercent; int SpanOTA::otaPercent;
//boolean SpanOTA::safeLoad; boolean SpanOTA::safeLoad;
//boolean SpanOTA::enabled=false; boolean SpanOTA::enabled=false;
//boolean SpanOTA::auth; boolean SpanOTA::auth;
/////////////////////////////// ///////////////////////////////
// SpanPoint // // SpanPoint //

View File

@ -37,7 +37,7 @@
#include <vector> #include <vector>
#include <list> #include <list>
#include <nvs.h> #include <nvs.h>
//D#include <ArduinoOTA.h> #include <ArduinoOTA.h>
#include <esp_now.h> #include <esp_now.h>
#include <mbedtls/base64.h> #include <mbedtls/base64.h>
@ -186,22 +186,22 @@ struct SpanWebLog{ // optional web status/log data
/////////////////////////////// ///////////////////////////////
//struct SpanOTA{ // manages OTA process struct SpanOTA{ // manages OTA process
//
// char otaPwd[33]=""; // MD5 Hash of OTA password, represented as a string of hexidecimal characters char otaPwd[33]=""; // MD5 Hash of OTA password, represented as a string of hexidecimal characters
//
// static boolean enabled; // enables OTA - default if not enabled static boolean enabled; // enables OTA - default if not enabled
// static boolean auth; // indicates whether OTA password is required static boolean auth; // indicates whether OTA password is required
// static int otaPercent; static int otaPercent;
// static boolean safeLoad; // indicates whether OTA update should reject any application update that is not another HomeSpan sketch static boolean safeLoad; // indicates whether OTA update should reject any application update that is not another HomeSpan sketch
//
// int init(boolean auth, boolean safeLoad, const char *pwd); int init(boolean auth, boolean safeLoad, const char *pwd);
// int setPassword(const char *pwd); int setPassword(const char *pwd);
// static void start(); static void start();
// static void end(); static void end();
// static void progress(uint32_t progress, uint32_t total); static void progress(uint32_t progress, uint32_t total);
// static void error(ota_error_t err); static void error(ota_error_t err);
//}; };
////////////////////////////////////// //////////////////////////////////////
// USER API CLASSES BEGINS HERE // // USER API CLASSES BEGINS HERE //
@ -273,7 +273,7 @@ class Span{
TaskHandle_t loopTaskHandle; // Arduino Loop Task handle TaskHandle_t loopTaskHandle; // Arduino Loop Task handle
boolean verboseWifiReconnect = true; // set to false to not print WiFi reconnect attempts messages boolean verboseWifiReconnect = true; // set to false to not print WiFi reconnect attempts messages
//D SpanOTA spanOTA; // manages OTA process SpanOTA spanOTA; // manages OTA process
SpanConfig hapConfig; // track configuration changes to the HAP Accessory database; used to increment the configuration number (c#) when changes found SpanConfig hapConfig; // track configuration changes to the HAP Accessory database; used to increment the configuration number (c#) when changes found
list<HAPClient, Mallocator<HAPClient>> hapList; // linked-list of HAPClient structures containing HTTP client connections, parsing routines, and state variables list<HAPClient, Mallocator<HAPClient>> hapList; // linked-list of HAPClient structures containing HTTP client connections, parsing routines, and state variables
@ -370,8 +370,8 @@ class Span{
Span& setHostNameSuffix(const char *suffix){asprintf(&hostNameSuffix,"%s",suffix);return(*this);} // sets the hostName suffix to be used instead of the 6-byte AccessoryID Span& setHostNameSuffix(const char *suffix){asprintf(&hostNameSuffix,"%s",suffix);return(*this);} // sets the hostName suffix to be used instead of the 6-byte AccessoryID
//D int enableOTA(boolean auth=true, boolean safeLoad=true){return(spanOTA.init(auth, safeLoad, NULL));} // enables Over-the-Air updates, with (auth=true) or without (auth=false) authorization password int enableOTA(boolean auth=true, boolean safeLoad=true){return(spanOTA.init(auth, safeLoad, NULL));} // enables Over-the-Air updates, with (auth=true) or without (auth=false) authorization password
//D int enableOTA(const char *pwd, boolean safeLoad=true){return(spanOTA.init(true, safeLoad, pwd));} // enables Over-the-Air updates, with custom authorization password (overrides any password stored with the 'O' command) int enableOTA(const char *pwd, boolean safeLoad=true){return(spanOTA.init(true, safeLoad, pwd));} // enables Over-the-Air updates, with custom authorization password (overrides any password stored with the 'O' command)
Span& enableWebLog(uint16_t maxEntries=0, const char *serv=NULL, const char *tz="UTC", const char *url=DEFAULT_WEBLOG_URL){ // enable Web Logging Span& enableWebLog(uint16_t maxEntries=0, const char *serv=NULL, const char *tz="UTC", const char *url=DEFAULT_WEBLOG_URL){ // enable Web Logging
webLog.init(maxEntries, serv, tz, url); webLog.init(maxEntries, serv, tz, url);

View File

@ -32,7 +32,8 @@ void setup() {
Serial.begin(115200); Serial.begin(115200);
homeSpan.enableWebLog(50); homeSpan.enableWebLog(50);
homeSpan.begin(Category::Lighting,"HomeSpan LightBulb"); homeSpan.enableOTA();
homeSpan.begin(Category::Lighting,"HomeSpan OTA Test");
new SpanAccessory(); new SpanAccessory();
new Service::AccessoryInformation(); new Service::AccessoryInformation();