From 7a13b999429e55a8382fc1bb4b6b1623f0aebdc9 Mon Sep 17 00:00:00 2001 From: Gregg Date: Sun, 23 Jun 2024 10:19:32 -0500 Subject: [PATCH] Added initial method to contract TLV8 Characteristic; Added UUID static char to Services; Added hapName filter to getLinks() --- src/HomeSpan.cpp | 26 ++++++++++++++++++++++++++ src/HomeSpan.h | 9 ++++++--- src/Span.h | 20 ++++++++++---------- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 37806b7..f02e895 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -1874,6 +1874,32 @@ void SpanCharacteristic::uvSet(UVal &u, const char *val){ /////////////////////////////// +void SpanCharacteristic::uvSet(UVal &u, TLV8 *tlv){ + + const size_t bufSize=36; // maximum size of buffer to store packed TLV bytes before encoding directly into value; must be multiple of 3 + size_t nBytes=tlv->pack_size(); // total size of packed TLV in bytes + + if(nBytes>0){ + size_t nChars; + mbedtls_base64_encode(NULL,0,&nChars,NULL,nBytes); // get length of string buffer needed (mbedtls includes the trailing null in this size) + u.STRING = (char *)HS_REALLOC(u.STRING,nChars); // allocate sufficient size for storing value + TempBuffer tBuf(bufSize); // create fixed-size buffer to store packed TLV bytes + tlv->pack_init(); // initialize TLV packing + uint8_t *p=(uint8_t *)u.STRING; // set pointer to beginning of value + while((nBytes=tlv->pack(tBuf,bufSize))>0){ // pack the next set of TLV bytes, up to a maximum of bufSize, into tBuf + size_t olen; // number of characters written (excludes null character) + mbedtls_base64_encode(p,nChars,&olen,tBuf,nBytes); // encode data directly into value + p+=olen; // advance pointer to null character + nChars-=olen; // subtract number of characters remaining + } + } else { + u.STRING = (char *)HS_REALLOC(u.STRING,1); // allocate sufficient size for just trailing null character + *u.STRING ='\0'; + } +} + +/////////////////////////////// + char *SpanCharacteristic::getStringGeneric(UVal &val){ if(format>=FORMAT::STRING) return val.STRING; diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 3ba8555..67e06e5 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -461,10 +461,12 @@ class SpanService{ SpanService *setHidden(); // sets the Service Type to be hidden and returns pointer to self SpanService *addLink(SpanService *svc); // adds svc as a Linked Service and returns pointer to self - template vector> getLinks(){ // returns linkedServices vector, mapped to , for use as range in "for-each" loops + template vector> getLinks(const char *hapName=NULL){ // returns linkedServices vector, mapped to , for use as range in "for-each" loops vector> v; - for(auto svc : linkedServices) - v.push_back(static_cast(svc)); + for(auto svc : linkedServices){ + if(hapName==NULL || !strcmp(hapName,svc->hapName)) + v.push_back(static_cast(svc)); + } return(v); } @@ -533,6 +535,7 @@ class SpanCharacteristic{ void uvSet(UVal &dest, UVal &src); // copies UVal src into UVal dest void uvSet(UVal &u, const char *val); // copies string val into UVal u + void uvSet(UVal &u, TLV8 *tlv); // copies TLV8 val into UVal u (after transforming to a char *) template void uvSet(UVal &u, T val){ // copies numeric val into UVal u switch(format){ diff --git a/src/Span.h b/src/Span.h index 624f0f7..f4d6b7f 100644 --- a/src/Span.h +++ b/src/Span.h @@ -29,17 +29,16 @@ // SPAN SERVICES (HAP Chapter 8) // /////////////////////////////////// -// Macros to define services, along with vectors of required and optional characteristics for each Span Service structure -// The names of the macros are picked up by external scripts to help generate documentation - -// Note: These macros below are also parsed by an external awk script to auto-generate Services and Characteristics documentation. +// Macros to define Services, along with vectors of required and optional Characteristics for each Span Service structure. +// +// NOTE: these macros are parsed by an external awk script to auto-generate Services and Characteristics documentation. // // The CREATE_SERV_DEP() macro is the same as the CREATE_SERV() macro, except that it is used for deprecated Services that will not -// be included in documentation. The OPT_DEP() macro is that same as the OPT() macro, except that it is used for deprecated Characteristics -// that will not be included in documentation. +// be included in documentation. The REQ_DEP and OPT_DEP() macros are the same as the REQ() and OPT() macros, except that they are used +// for deprecated Characteristics that will not be included in documentation. -#define CREATE_SERV(NAME,UUID) struct NAME : SpanService { NAME() : SpanService{#UUID,#NAME}{ -#define CREATE_SERV_DEP(NAME,UUID) struct NAME : SpanService { NAME() : SpanService{#UUID,#NAME}{ +#define CREATE_SERV(NAME,_UUID) struct NAME : SpanService { static constexpr const char *UUID=#_UUID; NAME() : SpanService{#_UUID,#NAME}{ +#define CREATE_SERV_DEP(NAME,_UUID) struct NAME : SpanService { static constexpr const char *UUID=#_UUID; NAME() : SpanService{#_UUID,#NAME}{ #define END_SERV }}; #define REQ(HAPCHAR) req.push_back(&hapChars.HAPCHAR) @@ -479,7 +478,7 @@ namespace Service { struct HAPCHAR : SpanCharacteristic { __VA_OPT__(enum{) __VA_ARGS__ __VA_OPT__(};) HAPCHAR(TYPE val=DEFVAL, boolean nvsStore=false) : SpanCharacteristic {&hapChars.HAPCHAR} { init(val,nvsStore,(TYPE)MINVAL,(TYPE)MAXVAL); } }; namespace Characteristic { - + CREATE_CHAR(uint32_t,AccessoryFlags,1,1,1); // not applicable for HomeSpan CREATE_CHAR(uint8_t,Active,0,0,1,INACTIVE,ACTIVE); // indicates if the Service is active/on CREATE_CHAR(uint32_t,ActiveIdentifier,0,0,255); // numerical Identifier of the InputSource selected in the Home App. @@ -514,7 +513,8 @@ namespace Characteristic { CREATE_CHAR(double,CurrentRelativeHumidity,0,0,100); // current humidity measured as a percentage CREATE_CHAR(double,CurrentTemperature,0,0,100); // current temperature measured in Celsius CREATE_CHAR(int,CurrentTiltAngle,0,-90,90); // current angle (in degrees) of slats from fully up or left (-90) to fully open (0) to fully down or right (90) - CREATE_CHAR(const char *,DisplayOrder,"",0,1); // specifies the order in which the TV inputs are displayed for selection in the Home App +// CREATE_CHAR(const char *,DisplayOrder,"",0,1); // specifies the order in which the TV inputs are displayed for selection in the Home App + CREATE_CHAR(TLV8 *,DisplayOrder,NULL,NULL,NULL); // specifies the order in which the TV inputs are displayed for selection in the Home App CREATE_CHAR(double,FilterLifeLevel,100,0,100); // measured as a percentage of remaining life CREATE_CHAR(uint8_t,FilterChangeIndication,0,0,1,NO_CHANGE_NEEDED,CHANGE_NEEDED); // indicates state of filter CREATE_CHAR(const char *,FirmwareRevision,"1.0.0",0,1); // must be in form x[.y[.z]] - informational only