Converted all remaining sprintfAttributes to printfAttributes
This removes last of large-sized JSON buffers - everything has now been converted to using hapOut. Next up: Must add prettyPrint to hapOut to support 'd' command
This commit is contained in:
parent
6c3df551eb
commit
bef151cdb1
82
src/HAP.cpp
82
src/HAP.cpp
|
|
@ -898,7 +898,7 @@ int HAPClient::getAccessoriesURL(){
|
|||
return(0);
|
||||
}
|
||||
|
||||
LOG1("In Get Accessories #%d (%s)...",conNum,client.remoteIP().toString().c_str());
|
||||
LOG1("In Get Accessories #%d (%s)...\n",conNum,client.remoteIP().toString().c_str());
|
||||
|
||||
homeSpan.printfAttributes();
|
||||
size_t nBytes=hapOut.getSize();
|
||||
|
|
@ -926,19 +926,15 @@ int HAPClient::getCharacteristicsURL(char *urlBuf){
|
|||
return(0);
|
||||
}
|
||||
|
||||
LOG1("In Get Characteristics #");
|
||||
LOG1(conNum);
|
||||
LOG1(" (");
|
||||
LOG1(client.remoteIP());
|
||||
LOG1(")...\n");
|
||||
LOG1("In Get Characteristics #%d (%s)...\n",conNum,client.remoteIP().toString().c_str());
|
||||
|
||||
int len=strlen(urlBuf); // determine number of IDs specificed by counting commas in URL
|
||||
int len=strlen(urlBuf); // determine number of IDs specified by counting commas in URL
|
||||
int numIDs=1;
|
||||
for(int i=0;i<len;i++)
|
||||
if(urlBuf[i]==',')
|
||||
numIDs++;
|
||||
|
||||
TempBuffer<char *> ids(numIDs); // reserve space for number of IDs found
|
||||
TempBuffer<char *> ids(numIDs); // reserve space for number of IDs found
|
||||
int flags=GET_VALUE|GET_AID; // flags indicating which characteristic fields to include in response (HAP Table 6-13)
|
||||
numIDs=0; // reset number of IDs found
|
||||
|
||||
|
|
@ -975,24 +971,16 @@ int HAPClient::getCharacteristicsURL(char *urlBuf){
|
|||
if(!numIDs) // could not find any IDs
|
||||
return(0);
|
||||
|
||||
int nBytes=homeSpan.sprintfAttributes(ids,numIDs,flags,NULL); // get JSON response - includes terminating null (will be recast to uint8_t* below)
|
||||
TempBuffer<char> jsonBuf(nBytes+1);
|
||||
homeSpan.sprintfAttributes(ids,numIDs,flags,jsonBuf);
|
||||
boolean statusFlag=homeSpan.printfAttributes(ids,numIDs,flags); // get statusFlag returned to use below
|
||||
size_t nBytes=hapOut.getSize();
|
||||
hapOut.flush();
|
||||
|
||||
boolean sFlag=strstr(jsonBuf,"status"); // status attribute found?
|
||||
hapOut.setLogLevel(2).setHapClient(this);
|
||||
hapOut << "HTTP/1.1 " << (!statusFlag?"200 OK":"207 Multi-Status") << "\r\nContent-Type: application/hap+json\r\nContent-Length: " << nBytes << "\r\n\r\n";
|
||||
homeSpan.printfAttributes(ids,numIDs,flags);
|
||||
hapOut.flush();
|
||||
|
||||
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());
|
||||
LOG2(" >>>>>>>>>>\n");
|
||||
LOG2(body);
|
||||
LOG2(jsonBuf.get());
|
||||
LOG2("\n");
|
||||
|
||||
sendEncrypted(body,(uint8_t *)jsonBuf.get(),nBytes); // note recasting of jsonBuf into uint8_t*
|
||||
free(body);
|
||||
LOG2("\n-------- SENT ENCRYPTED! --------\n");
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
|
@ -1006,11 +994,7 @@ int HAPClient::putCharacteristicsURL(char *json){
|
|||
return(0);
|
||||
}
|
||||
|
||||
LOG1("In Put Characteristics #");
|
||||
LOG1(conNum);
|
||||
LOG1(" (");
|
||||
LOG1(client.remoteIP());
|
||||
LOG1(")...\n");
|
||||
LOG1("In Put Characteristics #%d (%s)...\n",conNum,client.remoteIP().toString().c_str());
|
||||
|
||||
int n=homeSpan.countCharacteristics(json); // count number of objects in JSON request
|
||||
if(n==0) // if no objects found, return
|
||||
|
|
@ -1025,38 +1009,28 @@ int HAPClient::putCharacteristicsURL(char *json){
|
|||
if(pObj[i].status!=StatusCode::OK)
|
||||
multiCast=1;
|
||||
|
||||
LOG2("\n>>>>>>>>>> %s >>>>>>>>>>\n",client.remoteIP().toString().c_str());
|
||||
|
||||
if(!multiCast){ // JSON object has no content
|
||||
|
||||
char body[]="HTTP/1.1 204 No Content\r\n\r\n";
|
||||
hapOut.setLogLevel(2).setHapClient(this);
|
||||
hapOut << "HTTP/1.1 204 No Content\r\n\r\n";
|
||||
hapOut.flush();
|
||||
|
||||
LOG2("\n>>>>>>>>>> ");
|
||||
LOG2(client.remoteIP());
|
||||
LOG2(" >>>>>>>>>>\n");
|
||||
LOG2(body);
|
||||
} else { // multicast respose is required
|
||||
|
||||
sendEncrypted(body,NULL,0);
|
||||
|
||||
} else { // multicast respose is required
|
||||
|
||||
int nBytes=homeSpan.sprintfAttributes(pObj,n,NULL); // get JSON response - includes terminating null (will be recast to uint8_t* below)
|
||||
TempBuffer<char> jsonBuf(nBytes+1);
|
||||
homeSpan.sprintfAttributes(pObj,n,jsonBuf);
|
||||
|
||||
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());
|
||||
LOG2(" >>>>>>>>>>\n");
|
||||
LOG2(body);
|
||||
LOG2(jsonBuf.get());
|
||||
LOG2("\n");
|
||||
|
||||
sendEncrypted(body,(uint8_t *)jsonBuf.get(),nBytes); // note recasting of jsonBuf into uint8_t*
|
||||
free(body);
|
||||
homeSpan.printfAttributes(pObj,n);
|
||||
size_t nBytes=hapOut.getSize();
|
||||
hapOut.flush();
|
||||
|
||||
hapOut.setLogLevel(2).setHapClient(this);
|
||||
hapOut << "HTTP/1.1 207 Multi-Status\r\nContent-Type: application/hap+json\r\nContent-Length: " << nBytes << "\r\n\r\n";
|
||||
homeSpan.printfAttributes(pObj,n);
|
||||
hapOut.flush();
|
||||
}
|
||||
|
||||
LOG2("\n-------- SENT ENCRYPTED! --------\n");
|
||||
|
||||
// Create and send Event Notifications if needed
|
||||
|
||||
eventNotify(pObj,n,HAPClient::conNum); // transmit EVENT Notification for "n" pObj objects, except DO NOT notify client making request
|
||||
|
|
|
|||
131
src/HomeSpan.cpp
131
src/HomeSpan.cpp
|
|
@ -1516,77 +1516,65 @@ void Span::printfNotify(SpanBuf *pObj, int nObj, int conNum){
|
|||
|
||||
///////////////////////////////
|
||||
|
||||
int Span::sprintfAttributes(SpanBuf *pObj, int nObj, char *cBuf){
|
||||
void Span::printfAttributes(SpanBuf *pObj, int nObj){
|
||||
|
||||
int nChars=0;
|
||||
|
||||
nChars+=snprintf(cBuf,cBuf?64:0,"{\"characteristics\":[");
|
||||
hapOut << "{\"characteristics\":[";
|
||||
|
||||
for(int i=0;i<nObj;i++){
|
||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?128:0,"{\"aid\":%u,\"iid\":%d,\"status\":%d}",pObj[i].aid,pObj[i].iid,(int)pObj[i].status);
|
||||
if(i+1<nObj)
|
||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,",");
|
||||
hapOut << "{\"aid\":" << pObj[i].aid << ",\"iid\":" << pObj[i].iid << ",\"status\":" << (int)pObj[i].status << "}";
|
||||
if(i+1<nObj)
|
||||
hapOut << ",";
|
||||
}
|
||||
|
||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,"]}");
|
||||
|
||||
return(nChars);
|
||||
hapOut << "]}";
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
int Span::sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf){
|
||||
boolean Span::printfAttributes(char **ids, int numIDs, int flags){
|
||||
|
||||
int nChars=0;
|
||||
uint32_t aid;
|
||||
int iid;
|
||||
|
||||
SpanCharacteristic *Characteristics[numIDs];
|
||||
StatusCode status[numIDs];
|
||||
boolean sFlag=false;
|
||||
|
||||
for(int i=0;i<numIDs;i++){ // PASS 1: loop over all ids requested to check status codes - only errors are if characteristic not found, or not readable
|
||||
sscanf(ids[i],"%u.%d",&aid,&iid); // parse aid and iid
|
||||
Characteristics[i]=find(aid,iid); // find matching chararacteristic
|
||||
|
||||
if(Characteristics[i]){ // if found
|
||||
if(Characteristics[i]->perms&PERMS::PR){ // if permissions allow reading
|
||||
status[i]=StatusCode::OK; // always set status to OK (since no actual reading of device is needed)
|
||||
if(Characteristics[i]){ // if found
|
||||
if(Characteristics[i]->perms&PERMS::PR){ // if permissions allow reading
|
||||
status[i]=StatusCode::OK; // always set status to OK (since no actual reading of device is needed)
|
||||
} else {
|
||||
Characteristics[i]=NULL;
|
||||
Characteristics[i]=NULL; // set to NULL to trigger not-found in Pass 2 below
|
||||
status[i]=StatusCode::WriteOnly;
|
||||
sFlag=true; // set flag indicating there was an error
|
||||
flags|=GET_STATUS; // update flags to require status attribute for all characteristics
|
||||
}
|
||||
} else {
|
||||
status[i]=StatusCode::UnknownResource;
|
||||
sFlag=true; // set flag indicating there was an error
|
||||
flags|=GET_STATUS; // update flags to require status attribute for all characteristics
|
||||
}
|
||||
}
|
||||
|
||||
nChars+=snprintf(cBuf,cBuf?64:0,"{\"characteristics\":[");
|
||||
hapOut << "{\"characteristics\":[";
|
||||
|
||||
for(int i=0;i<numIDs;i++){ // PASS 2: loop over all ids requested and create JSON for each (with or without status code base on sFlag set above)
|
||||
for(int i=0;i<numIDs;i++){ // PASS 2: loop over all ids requested and create JSON for each (either all with, or all without, a status attribute based on final flags setting)
|
||||
|
||||
if(Characteristics[i]) // if found
|
||||
nChars+=Characteristics[i]->sprintfAttributes(cBuf?(cBuf+nChars):NULL,flags); // get JSON attributes for characteristic
|
||||
else{
|
||||
sscanf(ids[i],"%u.%d",&aid,&iid); // parse aid and iid
|
||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,"{\"iid\":%d,\"aid\":%u}",iid,aid); // else create JSON attributes based on requested aid/iid
|
||||
}
|
||||
|
||||
if(sFlag){ // status flag is needed - overlay at end
|
||||
nChars--;
|
||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,",\"status\":%d}",(int)status[i]);
|
||||
if(Characteristics[i]) // if found
|
||||
Characteristics[i]->printfAttributes(flags); // get JSON attributes for characteristic (may or may not include status=0 attribute)
|
||||
else{ // else create JSON status attribute based on requested aid/iid
|
||||
sscanf(ids[i],"%u.%d",&aid,&iid);
|
||||
hapOut << "{\"iid\":" << iid << ",\"aid\":" << aid << ",\"status\":" << (int)status[i] << "}";
|
||||
}
|
||||
|
||||
if(i+1<numIDs)
|
||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,",");
|
||||
|
||||
hapOut << ",";
|
||||
}
|
||||
|
||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,"]}");
|
||||
hapOut << "]}";
|
||||
|
||||
return(nChars);
|
||||
return(flags&GET_STATUS);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
|
@ -1909,81 +1897,14 @@ void SpanCharacteristic::printfAttributes(int flags){
|
|||
if(flags&GET_EV)
|
||||
hapOut << ",\"ev\":" << (ev[HAPClient::conNum]?"true":"false");
|
||||
|
||||
if(flags&GET_STATUS)
|
||||
hapOut << ",\"status\":0";
|
||||
|
||||
hapOut << "}";
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
int SpanCharacteristic::sprintfAttributes(char *cBuf, int flags){
|
||||
int nBytes=0;
|
||||
|
||||
const char permCodes[][7]={"pr","pw","ev","aa","tw","hd","wr"};
|
||||
|
||||
const char formatCodes[][9]={"bool","uint8","uint16","uint32","uint64","int","float","string","data"};
|
||||
|
||||
nBytes+=snprintf(cBuf,cBuf?64:0,"{\"iid\":%d",iid);
|
||||
|
||||
if(flags&GET_TYPE)
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"type\":\"%s\"",type);
|
||||
|
||||
if((perms&PR) && (flags&GET_VALUE)){
|
||||
if(perms&NV && !(flags&GET_NV))
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"value\":null");
|
||||
else
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"value\":%s",uvPrint(value).c_str());
|
||||
}
|
||||
|
||||
if(flags&GET_META){
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"format\":\"%s\"",formatCodes[format]);
|
||||
|
||||
if(customRange && (flags&GET_META)){
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?128:0,",\"minValue\":%s,\"maxValue\":%s",uvPrint(minValue).c_str(),uvPrint(maxValue).c_str());
|
||||
|
||||
if(uvGet<float>(stepValue)>0)
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?128:0,",\"minStep\":%s",uvPrint(stepValue).c_str());
|
||||
}
|
||||
|
||||
if(unit){
|
||||
if(strlen(unit)>0)
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?128:0,",\"unit\":\"%s\"",unit);
|
||||
else
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?128:0,",\"unit\":null");
|
||||
}
|
||||
|
||||
if(validValues){
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?128:0,",\"valid-values\":%s",validValues);
|
||||
}
|
||||
}
|
||||
|
||||
if(desc && (flags&GET_DESC)){
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?128:0,",\"description\":\"%s\"",desc);
|
||||
}
|
||||
|
||||
if(flags&GET_PERMS){
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"perms\":[");
|
||||
for(int i=0;i<7;i++){
|
||||
if(perms&(1<<i)){
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,"\"%s\"",permCodes[i]);
|
||||
if(perms>=(1<<(i+1)))
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",");
|
||||
}
|
||||
}
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,"]");
|
||||
}
|
||||
|
||||
if(flags&GET_AID)
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"aid\":%u",aid);
|
||||
|
||||
if(flags&GET_EV)
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"ev\":%s",ev[HAPClient::conNum]?"true":"false");
|
||||
|
||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,"}");
|
||||
|
||||
return(nBytes);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
StatusCode SpanCharacteristic::loadUpdate(char *val, char *ev){
|
||||
|
||||
if(ev){ // request for notification
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ enum {
|
|||
GET_EV=16,
|
||||
GET_DESC=32,
|
||||
GET_NV=64,
|
||||
GET_VALUE=128
|
||||
GET_VALUE=128,
|
||||
GET_STATUS=256
|
||||
};
|
||||
|
||||
///////////////////////////////
|
||||
|
|
@ -291,8 +292,8 @@ class Span{
|
|||
SpanCharacteristic *find(uint32_t aid, int iid); // return Characteristic with matching aid and iid (else NULL if not found)
|
||||
int countCharacteristics(char *buf); // return number of characteristic objects referenced in PUT /characteristics JSON request
|
||||
int updateCharacteristics(char *buf, SpanBuf *pObj); // parses PUT /characteristics JSON request 'buf into 'pObj' and updates referenced characteristics; returns 1 on success, 0 on fail
|
||||
int sprintfAttributes(SpanBuf *pObj, int nObj, char *cBuf); // prints SpanBuf object into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL
|
||||
int sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf); // prints accessory.characteristic ids into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL
|
||||
void printfAttributes(SpanBuf *pObj, int nObj); // writes SpanBuf objects to hapOut stream
|
||||
boolean printfAttributes(char **ids, int numIDs, int flags); // writes accessory requested characteristic ids to hapOut stream - returns true if all characteristics are found and readable, else returns false
|
||||
void clearNotify(int slotNum); // set ev notification flags for connection 'slotNum' to false across all characteristics
|
||||
void printfNotify(SpanBuf *pObj, int nObj, int conNum); // writes notification JSON to hapOut stream based on SpanBuf objects and specified connection number
|
||||
|
||||
|
|
@ -506,7 +507,6 @@ class SpanCharacteristic{
|
|||
UVal newValue; // the updated value requested by PUT /characteristic
|
||||
SpanService *service=NULL; // pointer to Service containing this Characteristic
|
||||
|
||||
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.)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue