From 8c888ff92aeb27d66715b1b78d7cd31cb772321b Mon Sep 17 00:00:00 2001 From: Gregg Date: Thu, 13 Aug 2020 22:17:58 -0500 Subject: [PATCH] Created putPrepare() Used unordered_map to store PID and TTL data. Next step is to now read PID in updateCharacteristics() when needed. --- src/HAP.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/HAP.h | 1 + src/HomeSpan.h | 11 ++++--- 3 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index 88ffa15..cf21e38 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -227,6 +227,17 @@ void HAPClient::processRequest(){ putCharacteristicsURL((char *)content); // process URL return; } + + if(!strncmp(body,"PUT /prepare ",13) && // PUT PREPARE + strstr(body,"Content-Type: application/hap+json")){ // check that content is JSON + + content[cLen]='\0'; // add a trailing null on end of JSON + LOG2((char *)content); // print JSON + LOG2("\n------------ END JSON! ------------\n"); + + putPrepareURL((char *)content); // process URL + return; + } notFoundError(); Serial.print("\n*** ERROR: Bad PUT request - URL not found\n\n"); @@ -1090,6 +1101,78 @@ int HAPClient::putCharacteristicsURL(char *json){ ////////////////////////////////////// +int HAPClient::putPrepareURL(char *json){ + + if(!cPair){ // unverified, unencrypted session + unauthorizedError(); + return(0); + } + + LOG1("In Put Prepare #"); + LOG1(conNum); + LOG1(" ("); + LOG1(client.remoteIP()); + LOG1(")...\n"); + + char ttlToken[]="\"ttl\":"; + char pidToken[]="\"pid\":"; + + char *cBuf; + uint32_t ttl; + uint64_t pid; + + if(cBuf=strstr(json,ttlToken)) + sscanf(cBuf+strlen(ttlToken),"%lu",&ttl); + + if(cBuf=strstr(json,pidToken)) + sscanf(cBuf+strlen(ttlToken),"%llu",&pid); + + char jsonBuf[32]; + int status=0; + + if(ttl>0 && pid>0){ // found required elements + homeSpan.TimedWrites[pid]=ttl+millis(); // store this pid/alarmTime combination + } else { // problems parsing request + status=-70410; + } + + sprintf(jsonBuf,"{\"status\":%d}",status); + int nBytes=strlen(jsonBuf); + int nChars=snprintf(NULL,0,"HTTP/1.1 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",nBytes); // create Body with Content Length = size of JSON Buf + char body[nChars+1]; + sprintf(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(jsonBuf); + LOG2("\n"); + + sendEncrypted(body,(uint8_t *)jsonBuf,nBytes); // note recasting of jsonBuf into uint8_t* + + return(1); + +/* + + char c[100]; + sprintf(c,"FOUND: %lu %llu\n",ttl,pid); + Serial.print(c); + + Serial.println(homeSpan.TimedWrites.count((uint64_t)213456)); + Serial.println(homeSpan.TimedWrites.count(pid)); + Serial.println(homeSpan.TimedWrites[pid]); + + homeSpan.TimedWrites.erase(pid); + + Serial.println(homeSpan.TimedWrites.count(pid)); + +*/ + +} + +////////////////////////////////////// + void HAPClient::checkEvents(){ unsigned long cTime=millis(); // current time diff --git a/src/HAP.h b/src/HAP.h index 2e1d179..b3a3d89 100644 --- a/src/HAP.h +++ b/src/HAP.h @@ -87,6 +87,7 @@ struct HAPClient { int postPairingsURL(); // POST /pairings (HAP Sections 5.10-5.12) int getCharacteristicsURL(char *urlBuf); // GET /characteristics (HAP Section 6.7.4) int putCharacteristicsURL(char *json); // PUT /characteristics (HAP Section 6.7.2) + int putPrepareURL(char *json); // PUT /prepare (HAP Section 6.7.2.4) void tlvRespond(); // respond to client with HTTP OK header and all defined TLV data records (those with length>0) void sendEncrypted(char *body, uint8_t *dataBuf, int dataLen); // send client complete ChaCha20-Poly1305 encrypted HTTP mesage comprising a null-terminated 'body' and 'dataBuf' with 'dataLen' bytes diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 3b1e5f6..8fb01bc 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -1,9 +1,11 @@ #include +#include #include "Settings.h" using std::vector; +using std::unordered_map; enum { GET_AID=1, @@ -44,10 +46,11 @@ struct Span{ int resetPin=21; // drive this pin low to "factory" reset NVS data on start-up - SpanConfig hapConfig; // track configuration changes to the HAP Accessory database; used to increment the configuration number (c#) when changes found - vector Accessories; // vector of pointers to all Accessories - vector TimedResets; // vector of pointers to all TimedResets - vector Events; // vector of pointer to all Events + SpanConfig hapConfig; // track configuration changes to the HAP Accessory database; used to increment the configuration number (c#) when changes found + vector Accessories; // vector of pointers to all Accessories + vector TimedResets; // vector of pointers to all TimedResets + vector Events; // vector of pointer to all Events + unordered_map TimedWrites; // map of timed-write PIDs and Alarm Times (based on TTLs) void begin(Category catID, char *displayName="HomeSpan Server",