Added "C" CLI command and updated/fixed config number logic
The "C" command computes a hash of the current database config and updates the config number if needed. If config number has changed, the MDNS "c#" record is updated and the new config number is rebroadcast. This triggers HomeKit to immediately request an update of the HAP database so that the changes can be shortly reflected in the Home App without the need to close any Client connections or reboot the device. The config number logic has also been updated/fixed. Previously it would create a hash from the full HAP database, which includes the value of each characteristic. Thus, initial value changes of Characteristics, as a result of stored values in NVS, would cause an update to the config number upon reboot. This is not problematic, but also not intended, as a change in value is not really a change in the database config. The new logic computes a hash of the database that EXCLUDES all Characteristic values.
This commit is contained in:
parent
628c29c6b6
commit
7546350775
26
src/HAP.cpp
26
src/HAP.cpp
|
|
@ -142,34 +142,14 @@ void HAPClient::init(){
|
|||
nvs_get_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,&len); // retrieve data
|
||||
} else {
|
||||
Serial.print("Resetting Accessory Configuration number...\n");
|
||||
nvs_set_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,sizeof(homeSpan.hapConfig)); // update data
|
||||
nvs_set_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,sizeof(homeSpan.hapConfig)); // save data (will default to all zero values, which will then be updated below)
|
||||
nvs_commit(hapNVS); // commit to NVS
|
||||
}
|
||||
|
||||
Serial.print("\n");
|
||||
|
||||
uint8_t tHash[48];
|
||||
TempBuffer <char> tBuf(homeSpan.sprintfAttributes(NULL,GET_META|GET_PERMS|GET_TYPE|GET_DESC)+1);
|
||||
homeSpan.sprintfAttributes(tBuf.buf,GET_META|GET_PERMS|GET_TYPE|GET_DESC);
|
||||
mbedtls_sha512_ret((uint8_t *)tBuf.buf,tBuf.len(),tHash,1); // create SHA-384 hash of JSON (can be any hash - just looking for a unique key)
|
||||
|
||||
if(memcmp(tHash,homeSpan.hapConfig.hashCode,48)){ // if hash code of current HAP database does not match stored hash code
|
||||
memcpy(homeSpan.hapConfig.hashCode,tHash,48); // update stored hash code
|
||||
homeSpan.hapConfig.configNumber++; // increment configuration number
|
||||
if(homeSpan.hapConfig.configNumber==65536) // reached max value
|
||||
homeSpan.hapConfig.configNumber=1; // reset to 1
|
||||
|
||||
Serial.print("Accessory configuration has changed. Updating configuration number to ");
|
||||
Serial.print(homeSpan.hapConfig.configNumber);
|
||||
Serial.print("\n\n");
|
||||
nvs_set_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,sizeof(homeSpan.hapConfig)); // update data
|
||||
nvs_commit(hapNVS); // commit to NVS
|
||||
} else {
|
||||
Serial.print("Accessory configuration number: ");
|
||||
Serial.print(homeSpan.hapConfig.configNumber);
|
||||
Serial.print("\n\n");
|
||||
}
|
||||
|
||||
homeSpan.updateConfigNum();
|
||||
|
||||
for(int i=0;i<homeSpan.Accessories.size();i++){ // identify all services with over-ridden loop() methods
|
||||
for(int j=0;j<homeSpan.Accessories[i]->Services.size();j++){
|
||||
SpanService *s=homeSpan.Accessories[i]->Services[j];
|
||||
|
|
|
|||
|
|
@ -899,14 +899,13 @@ void Span::processSerialCommand(const char *c){
|
|||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'C': {
|
||||
|
||||
char cNum[16];
|
||||
sprintf(cNum,"%d",++hapConfig.configNumber);
|
||||
mdns_service_txt_item_set("_hap","_tcp","c#",cNum); // Accessory Current Configuration Number (updated whenever config of HAP Accessory Attribute Database is updated)
|
||||
|
||||
Serial.printf("\n*** Configuration number updated to: %d\n\n",hapConfig.configNumber);
|
||||
if(updateConfigNum()){ // if config number changed, update MDNS record
|
||||
char cNum[16];
|
||||
sprintf(cNum,"%d",hapConfig.configNumber);
|
||||
mdns_service_txt_item_set("_hap","_tcp","c#",cNum);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1055,7 +1054,8 @@ void Span::processSerialCommand(const char *c){
|
|||
Serial.print(" S <code> - change the HomeKit Pairing Setup Code to <code>\n");
|
||||
Serial.print(" Q <id> - change the HomeKit Setup ID for QR Codes to <id>\n");
|
||||
Serial.print(" O - change the OTA password\n");
|
||||
Serial.print(" A - start the HomeSpan Setup Access Point\n");
|
||||
Serial.print(" A - start the HomeSpan Setup Access Point\n");
|
||||
Serial.print(" C - update database configuration number\n");
|
||||
Serial.print("\n");
|
||||
Serial.print(" V - delete value settings for all saved Characteristics\n");
|
||||
Serial.print(" U - unpair device by deleting all Controller data\n");
|
||||
|
|
@ -1459,6 +1459,38 @@ int Span::sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf){
|
|||
return(nChars);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
boolean Span::updateConfigNum(){
|
||||
|
||||
uint8_t tHash[48];
|
||||
TempBuffer <char> tBuf(sprintfAttributes(NULL,GET_META|GET_PERMS|GET_TYPE|GET_DESC)+1);
|
||||
sprintfAttributes(tBuf.buf,GET_META|GET_PERMS|GET_TYPE|GET_DESC);
|
||||
mbedtls_sha512_ret((uint8_t *)tBuf.buf,tBuf.len(),tHash,1); // create SHA-384 hash of JSON (can be any hash - just looking for a unique key)
|
||||
|
||||
boolean changed=false;
|
||||
|
||||
if(memcmp(tHash,hapConfig.hashCode,48)){ // if hash code of current HAP database does not match stored hash code
|
||||
memcpy(hapConfig.hashCode,tHash,48); // update stored hash code
|
||||
hapConfig.configNumber++; // increment configuration number
|
||||
if(hapConfig.configNumber==65536) // reached max value
|
||||
hapConfig.configNumber=1; // reset to 1
|
||||
|
||||
Serial.print("Accessory configuration has changed. Updating configuration number to ");
|
||||
Serial.print(hapConfig.configNumber);
|
||||
Serial.print("\n\n");
|
||||
nvs_set_blob(HAPClient::hapNVS,"HAPHASH",&hapConfig,sizeof(hapConfig)); // update data
|
||||
nvs_commit(HAPClient::hapNVS); // commit to NVS
|
||||
changed=true;
|
||||
} else {
|
||||
Serial.print("Accessory configuration number: ");
|
||||
Serial.print(hapConfig.configNumber);
|
||||
Serial.print("\n\n");
|
||||
}
|
||||
|
||||
return(changed);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// SpanAccessory //
|
||||
///////////////////////////////
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@ struct Span{
|
|||
void checkConnect(); // check WiFi connection; connect if needed
|
||||
void commandMode(); // allows user to control and reset HomeSpan settings with the control button
|
||||
void processSerialCommand(const char *c); // process command 'c' (typically from readSerial, though can be called with any 'c')
|
||||
boolean updateConfigNum(); // updates HAP configuration number (MDNS 'c#' record) if hash of current config database is different from previously-stored hash; returns true if config number changed
|
||||
|
||||
int sprintfAttributes(char *cBuf, int flags=GET_VALUE|GET_META|GET_PERMS|GET_TYPE|GET_DESC); // prints Attributes JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue