From 793f7882b1eee80ef0d8aadc605731f0c8bee976 Mon Sep 17 00:00:00 2001 From: Gregg Date: Wed, 26 Jul 2023 22:46:20 -0500 Subject: [PATCH] Replaced appropriate snprintf() with asprintf() and used *m in sscanf Optimized use of heap memory instead of stack memory for temporary variables, and makes code easier to read, provided all heap usage is free() at end of each function. Also removed char *hostName as a member variable of homeSpan. It's never actually used since MDNS constructs its own copy of hostName as needed. --- src/HAP.cpp | 45 ++++++++++++++++++++------------------------- src/HomeSpan.cpp | 25 +++++++++++-------------- src/HomeSpan.h | 1 - src/src.ino | 9 ++++++--- 4 files changed, 37 insertions(+), 43 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index cd0012a..15ae469 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -114,12 +114,6 @@ void HAPClient::init(){ printControllers(); - // create broadcaset name from server base name plus accessory ID (without ':') - - int nChars=snprintf(NULL,0,"%s-%2.2s%2.2s%2.2s%2.2s%2.2s%2.2s",homeSpan.hostNameBase,accessory.ID,accessory.ID+3,accessory.ID+6,accessory.ID+9,accessory.ID+12,accessory.ID+15); - homeSpan.hostName=(char *)malloc(nChars+1); - sprintf(homeSpan.hostName,"%s-%2.2s%2.2s%2.2s%2.2s%2.2s%2.2s",homeSpan.hostNameBase,accessory.ID,accessory.ID+3,accessory.ID+6,accessory.ID+9,accessory.ID+12,accessory.ID+15); - tlv8.create(kTLVType_State,1,"STATE"); // define the actual TLV records needed for the implementation of HAP; one for each kTLVType needed (HAP Table 5-6) tlv8.create(kTLVType_PublicKey,384,"PUBKEY"); tlv8.create(kTLVType_Method,1,"METHOD"); @@ -876,9 +870,8 @@ int HAPClient::getAccessoriesURL(){ TempBuffer jBuf(nBytes+1); homeSpan.sprintfAttributes(jBuf.get()); // create JSON database (will need to re-cast to uint8_t* below) - 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 '200 OK' 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); + 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()); @@ -888,6 +881,7 @@ int HAPClient::getAccessoriesURL(){ LOG2("\n"); sendEncrypted(body,(uint8_t *)jBuf.get(),nBytes); + free(body); return(1); @@ -1087,9 +1081,8 @@ int HAPClient::getCharacteristicsURL(char *urlBuf){ boolean sFlag=strstr(jsonBuf,"status"); // status attribute found? - int nChars=snprintf(NULL,0,"HTTP/1.1 %s\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",!sFlag?"200 OK":"207 Multi-Status",nBytes); - char body[nChars+1]; - sprintf(body,"HTTP/1.1 %s\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",!sFlag?"200 OK":"207 Multi-Status",nBytes); + char *body; + asprintf(&body,"HTTP/1.1 %s\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",!sFlag?"200 OK":"207 Multi-Status",nBytes); LOG2("\n>>>>>>>>>> "); LOG2(client.remoteIP()); @@ -1099,7 +1092,8 @@ int HAPClient::getCharacteristicsURL(char *urlBuf){ LOG2("\n"); sendEncrypted(body,(uint8_t *)jsonBuf,nBytes); // note recasting of jsonBuf into uint8_t* - + free(body); + return(1); } @@ -1148,9 +1142,8 @@ int HAPClient::putCharacteristicsURL(char *json){ char jsonBuf[nBytes+1]; homeSpan.sprintfAttributes(pObj,n,jsonBuf); - int nChars=snprintf(NULL,0,"HTTP/1.1 207 Multi-Status\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 207 Multi-Status\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",nBytes); + char *body; + asprintf(&body,"HTTP/1.1 207 Multi-Status\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",nBytes); LOG2("\n>>>>>>>>>> "); LOG2(client.remoteIP()); @@ -1160,6 +1153,7 @@ int HAPClient::putCharacteristicsURL(char *json){ LOG2("\n"); sendEncrypted(body,(uint8_t *)jsonBuf,nBytes); // note recasting of jsonBuf into uint8_t* + free(body); } @@ -1209,9 +1203,8 @@ int HAPClient::putPrepareURL(char *json){ sprintf(jsonBuf,"{\"status\":%d}",(int)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); + 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()); @@ -1221,6 +1214,7 @@ int HAPClient::putPrepareURL(char *json){ LOG2("\n"); sendEncrypted(body,(uint8_t *)jsonBuf,nBytes); // note recasting of jsonBuf into uint8_t* + free(body); return(1); } @@ -1403,9 +1397,8 @@ void HAPClient::eventNotify(SpanBuf *pObj, int nObj, int ignoreClient){ char jsonBuf[nBytes+1]; homeSpan.sprintfNotify(pObj,nObj,jsonBuf,cNum); - int nChars=snprintf(NULL,0,"EVENT/1.0 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,"EVENT/1.0 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",nBytes); + char *body; + asprintf(&body,"EVENT/1.0 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: %d\r\n\r\n",nBytes); LOG2("\n>>>>>>>>>> "); LOG2(hap[cNum]->client.remoteIP()); @@ -1415,6 +1408,7 @@ void HAPClient::eventNotify(SpanBuf *pObj, int nObj, int ignoreClient){ LOG2("\n"); hap[cNum]->sendEncrypted(body,(uint8_t *)jsonBuf,nBytes); // note recasting of jsonBuf into uint8_t* + free(body); } // if there are characteristic updates to notify client cNum } // if client exists @@ -1431,9 +1425,8 @@ void HAPClient::tlvRespond(){ uint8_t tlvData[nBytes]; // create buffer tlv8.pack(tlvData); // pack TLV records into buffer - int nChars=snprintf(NULL,0,"HTTP/1.1 200 OK\r\nContent-Type: application/pairing+tlv8\r\nContent-Length: %d\r\n\r\n",nBytes); // create Body with Content Length = size of TLV data - char body[nChars+1]; - sprintf(body,"HTTP/1.1 200 OK\r\nContent-Type: application/pairing+tlv8\r\nContent-Length: %d\r\n\r\n",nBytes); + char *body; + asprintf(&body,"HTTP/1.1 200 OK\r\nContent-Type: application/pairing+tlv8\r\nContent-Length: %d\r\n\r\n",nBytes); // create Body with Content Length = size of TLV data LOG2("\n>>>>>>>>>> "); LOG2(client.remoteIP()); @@ -1449,6 +1442,8 @@ void HAPClient::tlvRespond(){ sendEncrypted(body,tlvData,nBytes); } + free(body); + } // tlvRespond ////////////////////////////////////// diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 6d74cb0..70ab0d2 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -429,31 +429,26 @@ void Span::checkConnect(){ memcpy(id,HAPClient::accessory.ID,17); // copy ID bytes id[17]='\0'; // add terminating null - // create broadcaset name from server base name plus accessory ID (without ':') + // create broadcast name from server base name plus accessory ID (without ':') - int nChars; - - if(!hostNameSuffix) - nChars=snprintf(NULL,0,"%s-%.2s%.2s%.2s%.2s%.2s%.2s",hostNameBase,id,id+3,id+6,id+9,id+12,id+15); - else - nChars=snprintf(NULL,0,"%s%s",hostNameBase,hostNameSuffix); - - char hostName[nChars+1]; + char *hostName; if(!hostNameSuffix) - sprintf(hostName,"%s-%.2s%.2s%.2s%.2s%.2s%.2s",hostNameBase,id,id+3,id+6,id+9,id+12,id+15); + asprintf(&hostName,"%s-%.2s%.2s%.2s%.2s%.2s%.2s",hostNameBase,id,id+3,id+6,id+9,id+12,id+15); else - sprintf(hostName,"%s%s",hostNameBase,hostNameSuffix); + asprintf(&hostName,"%s%s",hostNameBase,hostNameSuffix); - char d[strlen(hostName)+1]; - sscanf(hostName,"%[A-Za-z0-9-]",d); + char *d; + sscanf(hostName,"%m[A-Za-z0-9-]",&d); - if(strlen(hostName)>255|| hostName[0]=='-' || hostName[strlen(hostName)-1]=='-' || strlen(hostName)!=strlen(d)){ + if(strlen(hostName)>255 || hostName[0]=='-' || hostName[strlen(hostName)-1]=='-' || strlen(hostName)!=strlen(d)){ LOG0("\n*** Error: Can't start MDNS due to invalid hostname '%s'.\n",hostName); LOG0("*** Hostname must consist of 255 or less alphanumeric characters or a hyphen, except that the hyphen cannot be the first or last character.\n"); LOG0("*** PROGRAM HALTED!\n\n"); while(1); } + + free(d); LOG0("\nStarting MDNS...\n\n"); LOG0("HostName: %s.local:%d\n",hostName,tcpPortNum); @@ -534,6 +529,8 @@ void Span::checkConnect(){ if(wifiCallback) wifiCallback(); + + free(hostName); } // initWiFi diff --git a/src/HomeSpan.h b/src/HomeSpan.h index c1fe5ed..7edb2c7 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -202,7 +202,6 @@ class Span{ const char *displayName; // display name for this device - broadcast as part of Bonjour MDNS const char *hostNameBase; // base of hostName of this device - full host name broadcast by Bonjour MDNS will have 6-byte accessoryID as well as '.local' automatically appended const char *hostNameSuffix=NULL; // optional "suffix" of hostName of this device. If specified, will be used as the hostName suffix instead of the 6-byte accessoryID - char *hostName; // full host name of this device - constructed from hostNameBase and 6-byte AccessoryID const char *modelName; // model name of this device - broadcast as Bonjour field "md" char category[3]=""; // category ID of primary accessory - broadcast as Bonjour field "ci" (HAP Section 13) unsigned long snapTime; // current time (in millis) snapped before entering Service loops() or updates() diff --git a/src/src.ino b/src/src.ino index 378710a..9e8ed0c 100644 --- a/src/src.ino +++ b/src/src.ino @@ -51,10 +51,13 @@ void setup() { Serial.begin(115200); - homeSpan.setControlPin(21); +// homeSpan.setHostNameSuffix(""); + +// homeSpan.setControlPin(21); - homeSpan.setLogLevel(2) - .setStatusPin(13); + homeSpan.setLogLevel(2); + +// .setStatusPin(13); // homeSpan.setSerialInputDisable(true); // homeSpan.enableOTA();