diff --git a/src/HAP.cpp b/src/HAP.cpp index 32c854d..c29658b 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "HAP.h" #include "HomeSpan.h" @@ -43,10 +44,21 @@ void HAPClient::init(){ nvs_open("WIFI",NVS_READWRITE,&wifiNVS); // open WIFI data namespace in NVS nvs_open("SRP",NVS_READWRITE,&srpNVS); // open SRP data namespace in NVS nvs_open("HAP",NVS_READWRITE,&hapNVS); // open HAP data namespace in NVS + nvs_open("OTA",NVS_READWRITE,&otaNVS); // open OTA data namespace in NVS if(!nvs_get_blob(wifiNVS,"WIFIDATA",NULL,&len)) // if found WiFi data in NVS nvs_get_blob(wifiNVS,"WIFIDATA",&homeSpan.network.wifiData,&len); // retrieve data - + + if(!nvs_get_str(otaNVS,"OTADATA",NULL,&len)){ // if found OTA data in NVS + nvs_get_str(otaNVS,"OTADATA",homeSpan.otaPwd,&len); // retrieve data + } else { + MD5Builder otaPwdHash; + otaPwdHash.begin(); + otaPwdHash.add(DEFAULT_OTA_PASSWORD); + otaPwdHash.calculate(); + otaPwdHash.getChars(homeSpan.otaPwd); + } + struct { // temporary structure to hold SRP verification code and salt stored in NVS uint8_t salt[16]; uint8_t verifyCode[384]; @@ -1643,6 +1655,7 @@ TLV HAPClient::tlv8; nvs_handle HAPClient::hapNVS; nvs_handle HAPClient::wifiNVS; nvs_handle HAPClient::srpNVS; +nvs_handle HAPClient::otaNVS; uint8_t HAPClient::httpBuf[MAX_HTTP+1]; HKDF HAPClient::hkdf; pairState HAPClient::pairStatus; diff --git a/src/HAP.h b/src/HAP.h index 9730215..070a170 100644 --- a/src/HAP.h +++ b/src/HAP.h @@ -82,6 +82,7 @@ struct HAPClient { static nvs_handle hapNVS; // handle for non-volatile-storage of HAP data static nvs_handle wifiNVS; // handle for non-volatile-storage of WiFi data static nvs_handle srpNVS; // handle for non-volatile-storage of SRP data + static nvs_handle otaNVS; // handle for non-volatile-storage of OTA data static uint8_t httpBuf[MAX_HTTP+1]; // buffer to store HTTP messages (+1 to leave room for storing an extra 'overflow' character) static HKDF hkdf; // generates (and stores) HKDF-SHA-512 32-byte keys derived from an inputKey of arbitrary length, a salt string, and an info string static pairState pairStatus; // tracks pair-setup status diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index d3b300d..7516093 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -434,7 +434,8 @@ void Span::checkConnect(){ if(otaEnabled){ ArduinoOTA.setHostname(hostName); - + ArduinoOTA.setPasswordHash(otaPwd); + ArduinoOTA .onStart([]() { String type; @@ -539,7 +540,7 @@ void Span::processSerialCommand(const char *c){ Serial.print("\n"); } - Serial.print("\n*** End Status ***\n"); + Serial.print("\n*** End Status ***\n\n"); } break; @@ -565,7 +566,7 @@ void Span::processSerialCommand(const char *c){ if(strlen(s)==4 && strlen(tBuf)==4){ sprintf(qrID,"%s",tBuf); - Serial.print("\n\nChanging default Setup ID for QR Code to : '"); + Serial.print("\nChanging default Setup ID for QR Code to: '"); Serial.print(qrID); Serial.print("'. Will take effect after next restart.\n\n"); nvs_set_str(HAPClient::hapNVS,"SETUPID",qrID); // update data @@ -578,6 +579,32 @@ void Span::processSerialCommand(const char *c){ } break; + case 'O': { + + char textPwd[33]="\0"; + + while(!strlen(textPwd)){ + Serial.print("\n>>> OTA Password (32 characters max): "); + readSerial(textPwd,32); + Serial.print(mask(textPwd,2)); + Serial.print("\n"); + } + + MD5Builder otaPwdHash; + otaPwdHash.begin(); + otaPwdHash.add(textPwd); + otaPwdHash.calculate(); + otaPwdHash.getChars(otaPwd); + nvs_set_str(HAPClient::otaNVS,"OTADATA",otaPwd); // update data + nvs_commit(HAPClient::otaNVS); + + Serial.print("\nPassword change will take effect after next restart.\n"); + if(!otaEnabled) + Serial.print("Note: OTA has not been enabled in this sketch.\n"); + Serial.print("\n"); + } + break; + case 'S': { char buf[128]; @@ -791,6 +818,7 @@ void Span::processSerialCommand(const char *c){ Serial.print(" X - delete WiFi Credentials and restart\n"); Serial.print(" S - change the HomeKit Pairing Setup Code to \n"); Serial.print(" Q - change the HomeKit Setup ID for QR Codes to \n"); + Serial.print(" O - change the OTA password\n"); Serial.print(" A - start the HomeSpan Setup Access Point\n"); Serial.print("\n"); Serial.print(" U - unpair device by deleting all Controller data\n"); diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 7a8777f..c84e6eb 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -100,7 +100,8 @@ struct Span{ unsigned long comModeLife=DEFAULT_COMMAND_TIMEOUT*1000; // length of time (in milliseconds) to keep Command Mode alive before resuming normal operations uint16_t tcpPortNum=DEFAULT_TCP_PORT; // port for TCP communications between HomeKit and HomeSpan char qrID[5]=""; // Setup ID used for pairing with QR Code - boolean otaEnabled=false; // enables Over-the-Air updates + boolean otaEnabled=false; // enables Over-the-Air ("OTA") updates + char otaPwd[33]; // MD5 Hash of OTA password, represented as a string of hexidecimal characters WiFiServer *hapServer; // pointer to the HAP Server connection Blinker statusLED; // indicates HomeSpan status diff --git a/src/Settings.h b/src/Settings.h index fb1417b..8cfff31 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -66,8 +66,9 @@ #define DEFAULT_CONTROL_PIN 21 // change with homeSpan.setControlPin(pin) #define DEFAULT_STATUS_PIN 13 // change with homeSpan.setStatusPin(pin) -#define DEFAULT_AP_SSID "HomeSpan-Setup" // change with homeSpan.setApSSID(pwd) +#define DEFAULT_AP_SSID "HomeSpan-Setup" // change with homeSpan.setApSSID(ssid) #define DEFAULT_AP_PASSWORD "homespan" // change with homeSpan.setApPassword(pwd) +#define DEFAULT_OTA_PASSWORD "homespan-ota" // change with 'O' command #define DEFAULT_AP_TIMEOUT 300 // change with homeSpan.setApTimeout(nSeconds) #define DEFAULT_COMMAND_TIMEOUT 120 // change with homeSpan.setCommandTimeout(nSeconds) @@ -87,7 +88,7 @@ #define LED_WIFI_CONNECTING 2000 // slow flashing #define LED_AP_STARTED 100,0.5,2,300 // rapid double-blink #define LED_AP_CONNECTED 300,0.5,2,400 // medium double-blink -#define LED_OTA_STARTED 300,0.5,5,500 // rapid 5-blink +#define LED_OTA_STARTED 300,0.5,3,400 // medium triple-blink ///////////////////////////////////////////////////// // Message Log Level Control Macros //