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.
This commit is contained in:
Gregg 2023-07-26 22:46:20 -05:00
parent 0f6e58435e
commit 793f7882b1
4 changed files with 37 additions and 43 deletions

View File

@ -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 <char> 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
//////////////////////////////////////

View File

@ -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

View File

@ -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()

View File

@ -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();