Completed error-checking/validation
Added validation to ensure all Accessories have a AccessoryInformation Service and all Accessories have a HAPProtocolInformation Service, unless the device is configured as a bridge, in which case only the first Accessory requires a HAPProtocolInformation Service.
This commit is contained in:
parent
254406c802
commit
c7f762da5f
|
|
@ -71,11 +71,19 @@ void Span::poll() {
|
|||
}
|
||||
|
||||
if(!isInitialized){
|
||||
|
||||
if(logLevel>0 || nFatalErrors>0){
|
||||
Serial.print(configLog);
|
||||
Serial.print("\n*** End Config Log ***\n");
|
||||
|
||||
if(!homeSpan.Accessories.empty()){
|
||||
|
||||
if(!homeSpan.Accessories.back()->Services.empty())
|
||||
homeSpan.Accessories.back()->Services.back()->validate();
|
||||
|
||||
homeSpan.Accessories.back()->validate();
|
||||
}
|
||||
|
||||
Serial.print(configLog);
|
||||
Serial.print("\nConfigured as Bridge: ");
|
||||
Serial.print(homeSpan.isBridge?"YES":"NO");
|
||||
Serial.print("\n\n*** End Config Log ***\n");
|
||||
|
||||
if(nFatalErrors>0){
|
||||
Serial.print("\n*** PROGRAM HALTED DUE TO ");
|
||||
|
|
@ -1006,6 +1014,14 @@ int Span::sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf){
|
|||
///////////////////////////////
|
||||
|
||||
SpanAccessory::SpanAccessory(){
|
||||
|
||||
if(!homeSpan.Accessories.empty()){
|
||||
|
||||
if(!homeSpan.Accessories.back()->Services.empty())
|
||||
homeSpan.Accessories.back()->Services.back()->validate();
|
||||
|
||||
homeSpan.Accessories.back()->validate();
|
||||
}
|
||||
|
||||
homeSpan.Accessories.push_back(this);
|
||||
aid=homeSpan.Accessories.size();
|
||||
|
|
@ -1015,6 +1031,35 @@ SpanAccessory::SpanAccessory(){
|
|||
|
||||
///////////////////////////////
|
||||
|
||||
void SpanAccessory::validate(){
|
||||
|
||||
boolean foundInfo=false;
|
||||
boolean foundProtocol=false;
|
||||
|
||||
for(int i=0;i<Services.size();i++){
|
||||
if(!strcmp(Services[i]->type,"3E"))
|
||||
foundInfo=true;
|
||||
else if(!strcmp(Services[i]->type,"A2"))
|
||||
foundProtocol=true;
|
||||
else if(aid==1) // this is the first Accessory and it has more than just AccessoryInfo and HAPProtocolInformation
|
||||
homeSpan.isBridge=false; // this is not a bridge device
|
||||
}
|
||||
|
||||
if(!foundInfo){
|
||||
homeSpan.configLog+=" !Service AccessoryInformation";
|
||||
homeSpan.configLog+=" *** ERROR! Required Service for this Accessory not found. ***\n";
|
||||
homeSpan.nFatalErrors++;
|
||||
}
|
||||
|
||||
if(!foundProtocol && (aid==1 || !homeSpan.isBridge)){ // HAPProtocolInformation must always be present in first Accessory, and any other Accessory is the device is not a bridge)
|
||||
homeSpan.configLog+=" !Service HAPProtocolInformation";
|
||||
homeSpan.configLog+=" *** ERROR! Required Service for this Accessory not found. ***\n";
|
||||
homeSpan.nFatalErrors++;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
int SpanAccessory::sprintfAttributes(char *cBuf){
|
||||
int nBytes=0;
|
||||
|
||||
|
|
@ -1037,6 +1082,9 @@ int SpanAccessory::sprintfAttributes(char *cBuf){
|
|||
|
||||
SpanService::SpanService(const char *type, const char *hapName){
|
||||
|
||||
if(!homeSpan.Accessories.back()->Services.empty()) // this is not the first Service to be defined for this Accessory
|
||||
homeSpan.Accessories.back()->Services.back()->validate();
|
||||
|
||||
this->type=type;
|
||||
this->hapName=hapName;
|
||||
|
||||
|
|
@ -1093,6 +1141,23 @@ int SpanService::sprintfAttributes(char *cBuf){
|
|||
return(nBytes);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void SpanService::validate(){
|
||||
|
||||
for(int i=0;i<req.size();i++){
|
||||
boolean valid=false;
|
||||
for(int j=0;!valid && j<Characteristics.size();j++)
|
||||
valid=!strcmp(req[i]->id,Characteristics[j]->type);
|
||||
|
||||
if(!valid){
|
||||
homeSpan.configLog+=" !Characteristic " + String(req[i]->name);
|
||||
homeSpan.configLog+=" *** ERROR! Required Characteristic for this Service not found. ***\n";
|
||||
homeSpan.nFatalErrors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// SpanCharacteristic //
|
||||
///////////////////////////////
|
||||
|
|
@ -1110,7 +1175,7 @@ SpanCharacteristic::SpanCharacteristic(char *type, uint8_t perms, char *hapName)
|
|||
return;
|
||||
}
|
||||
|
||||
char valid=false;
|
||||
boolean valid=false;
|
||||
|
||||
for(int i=0; !valid && i<homeSpan.Accessories.back()->Services.back()->req.size(); i++)
|
||||
valid=!strcmp(type,homeSpan.Accessories.back()->Services.back()->req[i]->id);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ struct Span{
|
|||
boolean isInitialized=false; // flag indicating HomeSpan has been initialized
|
||||
int nFatalErrors=0; // number of fatal errors in user-defined configuration
|
||||
String configLog="\n*** Config Log ***\n\n"; // log of configuration process, including any errors
|
||||
boolean isBridge=true; // flag indicating whether device is configured as a bridge (i.e. first Accessory contains nothing but AccessoryInformation and HAPProtocolInformation)
|
||||
|
||||
char *defaultSetupCode=DEFAULT_SETUP_CODE; // Setup Code used for pairing
|
||||
uint8_t statusPin=DEFAULT_STATUS_PIN; // pin for status LED
|
||||
|
|
@ -121,6 +122,7 @@ struct SpanAccessory{
|
|||
SpanAccessory();
|
||||
|
||||
int sprintfAttributes(char *cBuf); // prints Accessory JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL
|
||||
void validate(); // error-checks Accessory
|
||||
};
|
||||
|
||||
///////////////////////////////
|
||||
|
|
@ -142,6 +144,8 @@ struct SpanService{
|
|||
SpanService *setHidden(); // sets the Service Type to be hidden and returns pointer to self
|
||||
|
||||
int sprintfAttributes(char *cBuf); // prints Service JSON records into buf; return number of characters printed, excluding null terminator
|
||||
void validate(); // error-checks Service
|
||||
|
||||
virtual boolean update() {return(true);} // placeholder for code that is called when a Service is updated via a Controller. Must return true/false depending on success of update
|
||||
virtual void loop(){} // loops for each Service - called every cycle and can be over-ridden with user-defined code
|
||||
virtual void button(int pin, boolean isLong){} // method called for a Service when a button attached to "pin" has a Short-Press or Long-Press, according to "isLong"
|
||||
|
|
|
|||
Loading…
Reference in New Issue