From 8ce80157b335d36e358a55a218fce2f07f519d53 Mon Sep 17 00:00:00 2001 From: Gregg Date: Fri, 15 Mar 2024 17:35:04 -0500 Subject: [PATCH] Added native support for WR (write-response) HAPClient::putCharacteristics() now parses for "r":true in JSON, which is the HAP request for a write-response. When found, HomeSpan will return with a full write-response for all Characteristics updated using "207 Multi-Status", where "value" will be included only if "r":true was specified for a Characteristic. HomeSpan processes "r":true for any Characteristic regardless if permissions includes WR. To change the value of the Characteristic from within an update() method, use setVal() WITH OPTIONAL SECOND ARGUMENT AS FALSE to supress an EV broadcast (in the unlikely event that there was a notification subscriber). To do: Consider generally disallowing the changing of any Characteristic value from within update() using setVal() unless the Characteristic has WR permission. And if so, automatically surpress EV notification. --- src/HAP.cpp | 8 ++++---- src/HomeSpan.cpp | 12 ++++++++++-- src/HomeSpan.h | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index 322219f..a036ba8 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -998,10 +998,10 @@ int HAPClient::putCharacteristicsURL(char *json){ if(!homeSpan.updateCharacteristics(json, pObj)) // perform update return(0); // return if failed to update (error message will have been printed in update) - int multiCast=0; // check if all status is OK, or if multicast response is request - for(int i=0;i>>>>>>>>> %s >>>>>>>>>>\n",client.remoteIP().toString().c_str()); diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 876b329..1dde9af 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -1378,6 +1378,9 @@ int Span::updateCharacteristics(char *buf, SpanBuf *pObj){ pObj[nObj].ev=t3; okay|=8; } else + if(!strcmp(t2,"r") && (t3=strtok_r(t1,"}[]:, \"\t\n\r",&p2))){ + pObj[nObj].wr=(t3 && (!strcmp(t3,"1") || !strcmp(t3,"true"))); + } else if(!strcmp(t2,"pid") && (t3=strtok_r(t1,"}[]:, \"\t\n\r",&p2))){ uint64_t pid=strtoull(t3,NULL,0); if(!TimedWrites.count(pid)){ @@ -1395,7 +1398,9 @@ int Span::updateCharacteristics(char *buf, SpanBuf *pObj){ } // parse property tokens if(!t1){ // at least one token was found that was not initial "characteristics" - if(okay==7 || okay==11 || okay==15){ // all required properties found + if(okay==7 || okay==11 || okay==15){ // all required properties found + if(!pObj[nObj].val) // if value is NOT being updated + pObj[nObj].wr=false; // ignore any request for write-response nObj++; // increment number of characteristic objects found } else { LOG0("\n*** ERROR: Problems parsing JSON characteristics object - missing required properties\n\n"); @@ -1507,7 +1512,10 @@ void Span::printfAttributes(SpanBuf *pObj, int nObj){ hapOut << "{\"characteristics\":["; for(int i=0;iuvPrint(pObj[i].characteristic->value).c_str(); + hapOut << "}"; if(i+1