diff --git a/src/HAP.cpp b/src/HAP.cpp index f4d2657..0afc429 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -337,7 +337,7 @@ int HAPClient::postPairSetupURL(uint8_t *content, size_t len){ iosTLV.print(); LOG2("------------ END TLVS! ------------\n"); - LOG2("In Pair Setup #%d (%s)...",conNum,client.remoteIP().toString().c_str()); + LOG1("In Pair Setup #%d (%s)...",conNum,client.remoteIP().toString().c_str()); auto itState=iosTLV.find(kTLVType_State); @@ -584,7 +584,7 @@ int HAPClient::postPairVerifyURL(uint8_t *content, size_t len){ iosTLV.print(); LOG2("------------ END TLVS! ------------\n"); - LOG2("In Pair Verify #%d (%s)...",conNum,client.remoteIP().toString().c_str()); + LOG1("In Pair Verify #%d (%s)...",conNum,client.remoteIP().toString().c_str()); auto itState=iosTLV.find(kTLVType_State); @@ -772,7 +772,7 @@ int HAPClient::postPairingsURL(uint8_t *content, size_t len){ iosTLV.print(); LOG2("------------ END TLVS! ------------\n"); - LOG2("In Post Pairings #%d (%s)...",conNum,client.remoteIP().toString().c_str()); + LOG1("In Post Pairings #%d (%s)...",conNum,client.remoteIP().toString().c_str()); auto itState=iosTLV.find(kTLVType_State); auto itMethod=iosTLV.find(kTLVType_Method); @@ -898,28 +898,38 @@ int HAPClient::getAccessoriesURL(){ return(0); } - LOG1("In Get Accessories #"); - LOG1(conNum); - LOG1(" ("); - LOG1(client.remoteIP()); - LOG1(")...\n"); + LOG1("In Get Accessories #%d (%s)...",conNum,client.remoteIP().toString().c_str()); - int nBytes = homeSpan.sprintfAttributes(NULL); // get size of HAP attributes JSON - TempBuffer jBuf(nBytes+1); - homeSpan.sprintfAttributes(jBuf); // create JSON database (will need to re-cast to uint8_t* below) + homeSpan.printfAttributes(); + size_t nBytes=hapOut.getSize(); + hapOut.flush(); - char *body; - asprintf(&body,"HTTP/1.1 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",nBytes); + LOG2("\n>>>>>>>>>> %s >>>>>>>>>>\n",client.remoteIP().toString().c_str()); + + hapOut.setLogLevel(2).setHapClient(this); + hapOut << "HTTP/1.1 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: " << nBytes << "\r\n\r\n"; + homeSpan.printfAttributes(); + hapOut.flush(); + + LOG2("\n-------- SENT ENCRYPTED! --------\n"); + + +// int nBytes = homeSpan.sprintfAttributes(NULL); // get size of HAP attributes JSON +// TempBuffer jBuf(nBytes+1); +// homeSpan.sprintfAttributes(jBuf); // create JSON database (will need to re-cast to uint8_t* below) + +// char *body; +// asprintf(&body,"HTTP/1.1 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",nBytes); - LOG2("\n>>>>>>>>>> "); - LOG2(client.remoteIP()); - LOG2(" >>>>>>>>>>\n"); - LOG2(body); - LOG2(jBuf.get()); - LOG2("\n"); +// LOG2("\n>>>>>>>>>> "); +// LOG2(client.remoteIP()); +// LOG2(" >>>>>>>>>>\n"); +// LOG2(body); +// LOG2(jBuf.get()); +// LOG2("\n"); - sendEncrypted(body,(uint8_t *)jBuf.get(),nBytes); - free(body); +// sendEncrypted(body,(uint8_t *)jBuf.get(),nBytes); +// free(body); return(1); @@ -1638,7 +1648,8 @@ void Nonce::inc(){ HapOut::HapStreamBuffer::HapStreamBuffer(){ - buffer=(char *)HS_MALLOC(bufSize+1); // add 1 for adding null terminator when printing text + buffer=(char *)HS_MALLOC(bufSize+1); // add 1 for adding null terminator when printing text + encBuf=(uint8_t *)HS_MALLOC(bufSize+18); // 2-byte AAD + encrypted data + 16-byte authentication tag setp(buffer, buffer+bufSize-1); } @@ -1664,7 +1675,19 @@ void HapOut::HapStreamBuffer::flushBuffer(){ } if(hapClient!=NULL){ - hapClient->client.write(buffer,num); + if(!hapClient->cPair){ // if not encrypted + hapClient->client.write(buffer,num); // transmit data buffer + + } else { // if encrypted + + encBuf[0]=num%256; // store number of bytes that encrypts this frame (AAD bytes) + encBuf[1]=num/256; + crypto_aead_chacha20poly1305_ietf_encrypt(encBuf+2,NULL,(uint8_t *)buffer,num,encBuf,2,NULL,hapClient->a2cNonce.get(),hapClient->a2cKey); // encrypt buffer with AAD prepended and authentication tag appended + + hapClient->client.write(encBuf,num+18); // transmit encrypted frame + hapClient->a2cNonce.inc(); // increment nonce + } + delay(1); } diff --git a/src/HAP.h b/src/HAP.h index ae766d0..d6ef177 100644 --- a/src/HAP.h +++ b/src/HAP.h @@ -190,6 +190,7 @@ class HapOut : public std::ostream { const size_t bufSize=1024; // max allowed for HAP encrypted records char *buffer; + uint8_t *encBuf; HAPClient *hapClient=NULL; int logLevel=255; // default is NOT to print anything boolean enablePrettyPrint=false; diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 73f1593..82ecee3 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -620,12 +620,20 @@ void Span::processSerialCommand(const char *c){ case 'd': { - TempBuffer qBuf(sprintfAttributes(NULL)+1); - sprintfAttributes(qBuf); +// TempBuffer qBuf(sprintfAttributes(NULL)+1); +// sprintfAttributes(qBuf); - LOG0("\n*** Attributes Database: size=%d configuration=%d ***\n\n",qBuf.len()-1,hapConfig.configNumber); - prettyPrint(qBuf); - LOG0("\n*** End Database ***\n\n"); + printfAttributes(); + LOG0("\n*** Attributes Database: size=%d configuration=%d ***\n\n",hapOut.getSize(),hapConfig.configNumber); + hapOut.flush(); + +// LOG0("\n*** Attributes Database: size=%d configuration=%d ***\n\n",qBuf.len()-1,hapConfig.configNumber); +// prettyPrint(qBuf); + + hapOut.setLogLevel(0); + printfAttributes(); + hapOut.flush(); + LOG0("\n\n*** End Database ***\n\n"); } break; @@ -1232,6 +1240,21 @@ Span& Span::setWifiCredentials(const char *ssid, const char *pwd){ /////////////////////////////// +void Span::printfAttributes(int flags){ + + hapOut << "{\"accessories\":["; + + for(int i=0;iprintfAttributes(flags); + if(i+1printfAttributes(flags); + if(i+1iid; + if(i+1printfAttributes(flags); + if(i+1(stepValue)>0) + hapOut << ",\"minStep\":" << uvPrint(stepValue).c_str(); + } + + if(unit){ + if(strlen(unit)>0) + hapOut << ",\"unit\":\"" << unit << "\""; + else + hapOut << ",\"unit\":null"; + } + + if(validValues){ + hapOut << ",\"valid-values\":" << validValues; + } + } + + if(desc && (flags&GET_DESC)){ + hapOut << ",\"description\":\"" << desc << "\""; + } + + if(flags&GET_PERMS){ + hapOut << ",\"perms\":["; + for(int i=0;i<7;i++){ + if(perms&(1<=(1<<(i+1))) + hapOut << ","; + } + } + hapOut << "]"; + } + + if(flags&GET_AID) + hapOut << ",\"aid\":" << aid; + + if(flags&GET_EV) + hapOut << ",\"ev\":" << (ev[HAPClient::conNum]?"true":"false"); + + hapOut << "}"; +} + +/////////////////////////////// + int SpanCharacteristic::sprintfAttributes(char *cBuf, int flags){ int nBytes=0; diff --git a/src/HomeSpan.h b/src/HomeSpan.h index e3be0a6..f067457 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -286,6 +286,7 @@ class Span{ void reboot(); // reboots device 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 + void printfAttributes(int flags=GET_VALUE|GET_META|GET_PERMS|GET_TYPE|GET_DESC); // writes Attributes JSON database to hapOut stream void prettyPrint(char *buf, int nsp=2, int minLogLevel=0); // print arbitrary JSON from buf to serial monitor, formatted with indentions of 'nsp' spaces, subject to specified minimum log level SpanCharacteristic *find(uint32_t aid, int iid); // return Characteristic with matching aid and iid (else NULL if not found) @@ -409,6 +410,7 @@ class SpanAccessory{ vector> Services; // vector of pointers to all Services in this Accessory int sprintfAttributes(char *cBuf, int flags); // prints Accessory JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL + void printfAttributes(int flags); // writes Accessory JSON to hapOut stream protected: @@ -440,6 +442,7 @@ class SpanService{ SpanAccessory *accessory=NULL; // pointer to Accessory containing this Service int sprintfAttributes(char *cBuf, int flags); // prints Service JSON records into buf; return number of characters printed, excluding null terminator + void printfAttributes(int flags); // writes Service JSON to hapOut stream protected: @@ -505,8 +508,10 @@ class SpanCharacteristic{ unsigned long updateTime=0; // last time value was updated (in millis) either by PUT /characteristic OR by setVal() UVal newValue; // the updated value requested by PUT /characteristic SpanService *service=NULL; // pointer to Service containing this Characteristic + - int sprintfAttributes(char *cBuf, int flags); // prints Characteristic JSON records into buf, according to flags mask; return number of characters printed, excluding null terminator + int sprintfAttributes(char *val, int flags); // prints Characteristic JSON records into buf; return number of characters printed, excluding null terminator + void printfAttributes(int flags); // writes Characteristic JSON to hapOut stream StatusCode loadUpdate(char *val, char *ev); // load updated val/ev from PUT /characteristic JSON request. Return intitial HAP status code (checks to see if characteristic is found, is writable, etc.) String uvPrint(UVal &u){ diff --git a/src/src.ino b/src/src.ino index 2eb556f..0baceef 100644 --- a/src/src.ino +++ b/src/src.ino @@ -27,7 +27,7 @@ #include "HomeSpan.h" -#define MAX_LIGHTS 1 +#define MAX_LIGHTS 3 void setup() {