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:
parent
158274cac6
commit
fc4d8d85d1
14
src/HAP.cpp
14
src/HAP.cpp
|
|
@ -40,13 +40,13 @@ void HAPClient::init(){
|
|||
|
||||
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(!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.
|
||||
// } else { // otherwise...
|
||||
// homeSpan.spanOTA.setPassword(DEFAULT_OTA_PASSWORD); // ...use default password
|
||||
// }
|
||||
// }
|
||||
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...
|
||||
nvs_get_str(homeSpan.otaNVS,"OTADATA",homeSpan.spanOTA.otaPwd,&len); // ...retrieve data.
|
||||
} else { // otherwise...
|
||||
homeSpan.spanOTA.setPassword(DEFAULT_OTA_PASSWORD); // ...use default password
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
263
src/HomeSpan.cpp
263
src/HomeSpan.cpp
|
|
@ -38,6 +38,7 @@
|
|||
#include <esp_sntp.h>
|
||||
#include <esp_ota_ops.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_app_format.h>
|
||||
|
||||
#include "HomeSpan.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_set_u8(otaNVS,"OTA_REQUIRED",0);
|
||||
nvs_commit(otaNVS);
|
||||
// if(otaRequired && !spanOTA.enabled){
|
||||
// LOG0("\n\n*** OTA SAFE MODE ALERT: OTA REQUIRED BUT NOT ENABLED. ROLLING BACK TO PREVIOUS APPLICATION ***\n\n");
|
||||
// delay(100);
|
||||
// esp_ota_mark_app_invalid_rollback_and_reboot();
|
||||
// }
|
||||
if(otaRequired && !spanOTA.enabled){
|
||||
LOG0("\n\n*** OTA SAFE MODE ALERT: OTA REQUIRED BUT NOT ENABLED. ROLLING BACK TO PREVIOUS APPLICATION ***\n\n");
|
||||
delay(100);
|
||||
esp_ota_mark_app_invalid_rollback_and_reboot();
|
||||
}
|
||||
|
||||
} // begin
|
||||
|
||||
|
|
@ -268,8 +269,8 @@ void Span::pollTask() {
|
|||
HAPClient::checkNotifications();
|
||||
HAPClient::checkTimedWrites();
|
||||
|
||||
//D if(spanOTA.enabled)
|
||||
//D ArduinoOTA.handle();
|
||||
if(spanOTA.enabled)
|
||||
ArduinoOTA.handle();
|
||||
|
||||
if(controlButton && controlButton->primed())
|
||||
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
|
||||
mdns_service_txt_item_set("_hap","_tcp","sh",setupHash); // Step 4: broadcast the resulting Setup Hash
|
||||
|
||||
// if(spanOTA.enabled){
|
||||
// ArduinoOTA.setHostname(hostName);
|
||||
//
|
||||
// if(spanOTA.auth)
|
||||
// ArduinoOTA.setPasswordHash(spanOTA.otaPwd);
|
||||
//
|
||||
// ArduinoOTA.onStart(spanOTA.start).onEnd(spanOTA.end).onProgress(spanOTA.progress).onError(spanOTA.error);
|
||||
//
|
||||
// ArduinoOTA.begin();
|
||||
// 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");
|
||||
// }
|
||||
if(spanOTA.enabled){
|
||||
ArduinoOTA.setHostname(hostName);
|
||||
|
||||
//D mdns_service_txt_item_set("_hap","_tcp","ota",spanOTA.enabled?"yes":"no"); // OTA status (info only - NOT used by HAP)
|
||||
if(spanOTA.auth)
|
||||
ArduinoOTA.setPasswordHash(spanOTA.otaPwd);
|
||||
|
||||
ArduinoOTA.onStart(spanOTA.start).onEnd(spanOTA.end).onProgress(spanOTA.progress).onError(spanOTA.error);
|
||||
|
||||
ArduinoOTA.begin();
|
||||
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");
|
||||
}
|
||||
|
||||
mdns_service_txt_item_set("_hap","_tcp","ota",spanOTA.enabled?"yes":"no"); // OTA status (info only - NOT used by HAP)
|
||||
|
||||
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)
|
||||
|
|
@ -608,34 +609,34 @@ void Span::processSerialCommand(const char *c){
|
|||
}
|
||||
break;
|
||||
|
||||
// case 'O': {
|
||||
//
|
||||
// char textPwd[34]="\0";
|
||||
//
|
||||
// LOG0("\n>>> New OTA Password, or <return> to cancel request: ");
|
||||
// readSerial(textPwd,33);
|
||||
//
|
||||
// if(strlen(textPwd)==0){
|
||||
// LOG0("(cancelled)\n\n");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(strlen(textPwd)==33){
|
||||
// LOG0("\n*** Sorry, 32 character limit - request cancelled\n\n");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// LOG0("%s\n",mask(textPwd,2).c_str());
|
||||
// spanOTA.setPassword(textPwd);
|
||||
// nvs_set_str(otaNVS,"OTADATA",spanOTA.otaPwd); // update data
|
||||
// nvs_commit(otaNVS);
|
||||
//
|
||||
// LOG0("... Accepted! Password change will take effect after next restart.\n");
|
||||
// if(!spanOTA.enabled)
|
||||
// LOG0("... Note: OTA has not been enabled in this sketch.\n");
|
||||
// LOG0("\n");
|
||||
// }
|
||||
// break;
|
||||
case 'O': {
|
||||
|
||||
char textPwd[34]="\0";
|
||||
|
||||
LOG0("\n>>> New OTA Password, or <return> to cancel request: ");
|
||||
readSerial(textPwd,33);
|
||||
|
||||
if(strlen(textPwd)==0){
|
||||
LOG0("(cancelled)\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(textPwd)==33){
|
||||
LOG0("\n*** Sorry, 32 character limit - request cancelled\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG0("%s\n",mask(textPwd,2).c_str());
|
||||
spanOTA.setPassword(textPwd);
|
||||
nvs_set_str(otaNVS,"OTADATA",spanOTA.otaPwd); // update data
|
||||
nvs_commit(otaNVS);
|
||||
|
||||
LOG0("... Accepted! Password change will take effect after next restart.\n");
|
||||
if(!spanOTA.enabled)
|
||||
LOG0("... Note: OTA has not been enabled in this sketch.\n");
|
||||
LOG0("\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S': {
|
||||
|
||||
|
|
@ -2457,89 +2458,89 @@ void SpanWebLog::vLog(boolean sysMsg, const char *fmt, va_list ap){
|
|||
// SpanOTA //
|
||||
///////////////////////////////
|
||||
|
||||
//int SpanOTA::init(boolean _auth, boolean _safeLoad, const char *pwd){
|
||||
// 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");
|
||||
// return(-1);
|
||||
// }
|
||||
//
|
||||
// enabled=true;
|
||||
// safeLoad=_safeLoad;
|
||||
// auth=_auth;
|
||||
// if(pwd==NULL)
|
||||
// return(0);
|
||||
// return(setPassword(pwd));
|
||||
//}
|
||||
//
|
||||
/////////////////////////////////
|
||||
//
|
||||
//int SpanOTA::setPassword(const char *pwd){
|
||||
// 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);
|
||||
// return(-1);
|
||||
// }
|
||||
//
|
||||
// MD5Builder otaPwdHash;
|
||||
// otaPwdHash.begin();
|
||||
// otaPwdHash.add(pwd);
|
||||
// otaPwdHash.calculate();
|
||||
// otaPwdHash.getChars(homeSpan.spanOTA.otaPwd);
|
||||
// return(0);
|
||||
//}
|
||||
//
|
||||
/////////////////////////////////
|
||||
//
|
||||
//void SpanOTA::start(){
|
||||
// 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);
|
||||
// otaPercent=0;
|
||||
// STATUS_UPDATE(start(LED_OTA_STARTED),HS_OTA_STARTED)
|
||||
//}
|
||||
//
|
||||
/////////////////////////////////
|
||||
//
|
||||
//void SpanOTA::end(){
|
||||
// nvs_set_u8(homeSpan.otaNVS,"OTA_REQUIRED",safeLoad);
|
||||
// nvs_commit(homeSpan.otaNVS);
|
||||
// LOG0(" DONE! Rebooting...\n");
|
||||
// homeSpan.reboot();
|
||||
//}
|
||||
//
|
||||
/////////////////////////////////
|
||||
//
|
||||
//void SpanOTA::progress(uint32_t progress, uint32_t total){
|
||||
// int percent=progress*100/total;
|
||||
// if(percent/10 != otaPercent/10){
|
||||
// otaPercent=percent;
|
||||
// LOG0("%d%%..",progress*100/total);
|
||||
// }
|
||||
//
|
||||
// if(safeLoad && progress==total){
|
||||
// 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));
|
||||
// LOG0("Checking for HomeSpan Magic Cookie: %s..",newSpanPartition.magicCookie);
|
||||
// if(strcmp(newSpanPartition.magicCookie,spanPartition.magicCookie))
|
||||
// Update.abort();
|
||||
// }
|
||||
//}
|
||||
//
|
||||
/////////////////////////////////
|
||||
//
|
||||
//void SpanOTA::error(ota_error_t err){
|
||||
// LOG0("*** OTA Error[%u]: ", err);
|
||||
// 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_CONNECT_ERROR) LOG0("Connect 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");
|
||||
//}
|
||||
//
|
||||
/////////////////////////////////
|
||||
//
|
||||
//int SpanOTA::otaPercent;
|
||||
//boolean SpanOTA::safeLoad;
|
||||
//boolean SpanOTA::enabled=false;
|
||||
//boolean SpanOTA::auth;
|
||||
int SpanOTA::init(boolean _auth, boolean _safeLoad, const char *pwd){
|
||||
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");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
enabled=true;
|
||||
safeLoad=_safeLoad;
|
||||
auth=_auth;
|
||||
if(pwd==NULL)
|
||||
return(0);
|
||||
return(setPassword(pwd));
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
int SpanOTA::setPassword(const char *pwd){
|
||||
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);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
MD5Builder otaPwdHash;
|
||||
otaPwdHash.begin();
|
||||
otaPwdHash.add(pwd);
|
||||
otaPwdHash.calculate();
|
||||
otaPwdHash.getChars(homeSpan.spanOTA.otaPwd);
|
||||
return(0);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void SpanOTA::start(){
|
||||
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);
|
||||
otaPercent=0;
|
||||
STATUS_UPDATE(start(LED_OTA_STARTED),HS_OTA_STARTED)
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void SpanOTA::end(){
|
||||
nvs_set_u8(homeSpan.otaNVS,"OTA_REQUIRED",safeLoad);
|
||||
nvs_commit(homeSpan.otaNVS);
|
||||
LOG0(" DONE! Rebooting...\n");
|
||||
homeSpan.reboot();
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void SpanOTA::progress(uint32_t progress, uint32_t total){
|
||||
int percent=progress*100/total;
|
||||
if(percent/10 != otaPercent/10){
|
||||
otaPercent=percent;
|
||||
LOG0("%d%%..",percent);
|
||||
}
|
||||
|
||||
if(safeLoad && progress==total){
|
||||
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));
|
||||
LOG0("Checking for HomeSpan Magic Cookie: %s..",newSpanPartition.magicCookie);
|
||||
if(strcmp(newSpanPartition.magicCookie,spanPartition.magicCookie))
|
||||
Update.abort();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void SpanOTA::error(ota_error_t err){
|
||||
LOG0("*** OTA Error[%u]: ", err);
|
||||
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_CONNECT_ERROR) LOG0("Connect 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");
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
int SpanOTA::otaPercent;
|
||||
boolean SpanOTA::safeLoad;
|
||||
boolean SpanOTA::enabled=false;
|
||||
boolean SpanOTA::auth;
|
||||
|
||||
///////////////////////////////
|
||||
// SpanPoint //
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include <vector>
|
||||
#include <list>
|
||||
#include <nvs.h>
|
||||
//D#include <ArduinoOTA.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <esp_now.h>
|
||||
#include <mbedtls/base64.h>
|
||||
|
||||
|
|
@ -186,22 +186,22 @@ struct SpanWebLog{ // optional web status/log data
|
|||
|
||||
///////////////////////////////
|
||||
|
||||
//struct SpanOTA{ // manages OTA process
|
||||
//
|
||||
// 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 auth; // indicates whether OTA password is required
|
||||
// static int otaPercent;
|
||||
// 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 setPassword(const char *pwd);
|
||||
// static void start();
|
||||
// static void end();
|
||||
// static void progress(uint32_t progress, uint32_t total);
|
||||
// static void error(ota_error_t err);
|
||||
//};
|
||||
struct SpanOTA{ // manages OTA process
|
||||
|
||||
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 auth; // indicates whether OTA password is required
|
||||
static int otaPercent;
|
||||
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 setPassword(const char *pwd);
|
||||
static void start();
|
||||
static void end();
|
||||
static void progress(uint32_t progress, uint32_t total);
|
||||
static void error(ota_error_t err);
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// USER API CLASSES BEGINS HERE //
|
||||
|
|
@ -273,7 +273,7 @@ class Span{
|
|||
TaskHandle_t loopTaskHandle; // Arduino Loop Task handle
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
//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
|
||||
//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(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(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
|
||||
webLog.init(maxEntries, serv, tz, url);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ void setup() {
|
|||
Serial.begin(115200);
|
||||
|
||||
homeSpan.enableWebLog(50);
|
||||
homeSpan.begin(Category::Lighting,"HomeSpan LightBulb");
|
||||
homeSpan.enableOTA();
|
||||
homeSpan.begin(Category::Lighting,"HomeSpan OTA Test");
|
||||
|
||||
new SpanAccessory();
|
||||
new Service::AccessoryInformation();
|
||||
|
|
|
|||
Loading…
Reference in New Issue