Upgraded TempBuffer logic to use .get() to return pointer

Next up: update Network.cpp to use client.available() and reduce fixed memory usage.
This commit is contained in:
Gregg 2023-07-26 06:27:54 -05:00
parent 5f9458e625
commit 62f68cb33c
6 changed files with 53 additions and 45 deletions

View File

@ -164,15 +164,14 @@ void HAPClient::processRequest(){
return; return;
} }
TempBuffer <uint8_t> tempBuffer(messageSize+1); // leave room for null character added below TempBuffer <uint8_t> httpBuf(messageSize+1); // leave room for null character added below
uint8_t *httpBuf=tempBuffer.buf;
if(cPair){ // expecting encrypted message if(cPair){ // expecting encrypted message
LOG2("<<<< #### "); LOG2("<<<< #### ");
LOG2(client.remoteIP()); LOG2(client.remoteIP());
LOG2(" #### <<<<\n"); LOG2(" #### <<<<\n");
nBytes=receiveEncrypted(httpBuf,messageSize); // decrypt and return number of bytes read nBytes=receiveEncrypted(httpBuf.get(),messageSize); // decrypt and return number of bytes read
if(!nBytes){ // decryption failed (error message already printed in function) if(!nBytes){ // decryption failed (error message already printed in function)
badRequestError(); badRequestError();
@ -184,7 +183,7 @@ void HAPClient::processRequest(){
LOG2(client.remoteIP()); LOG2(client.remoteIP());
LOG2(" <<<<<<<<<\n"); LOG2(" <<<<<<<<<\n");
nBytes=client.read(httpBuf,messageSize); // read expected number of bytes nBytes=client.read(httpBuf.get(),messageSize); // read expected number of bytes
if(nBytes!=messageSize || client.available()!=0){ if(nBytes!=messageSize || client.available()!=0){
badRequestError(); badRequestError();
@ -194,12 +193,12 @@ void HAPClient::processRequest(){
} // encrypted/plaintext } // encrypted/plaintext
httpBuf[nBytes]='\0'; // add null character to enable string functions httpBuf.get()[nBytes]='\0'; // add null character to enable string functions
char *body=(char *)httpBuf; // char pointer to start of HTTP Body char *body=(char *)httpBuf.get(); // char pointer to start of HTTP Body
char *p; // char pointer used for searches char *p; // char pointer used for searches
if(!(p=strstr((char *)httpBuf,"\r\n\r\n"))){ if(!(p=strstr((char *)httpBuf.get(),"\r\n\r\n"))){
badRequestError(); badRequestError();
LOG0("\n*** ERROR: Malformed HTTP request (can't find blank line indicating end of BODY)\n\n"); LOG0("\n*** ERROR: Malformed HTTP request (can't find blank line indicating end of BODY)\n\n");
return; return;
@ -875,7 +874,7 @@ int HAPClient::getAccessoriesURL(){
int nBytes = homeSpan.sprintfAttributes(NULL); // get size of HAP attributes JSON int nBytes = homeSpan.sprintfAttributes(NULL); // get size of HAP attributes JSON
TempBuffer <char> jBuf(nBytes+1); TempBuffer <char> jBuf(nBytes+1);
homeSpan.sprintfAttributes(jBuf.buf); // create JSON database (will need to re-cast to uint8_t* below) 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 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]; char body[nChars+1];
@ -885,10 +884,10 @@ int HAPClient::getAccessoriesURL(){
LOG2(client.remoteIP()); LOG2(client.remoteIP());
LOG2(" >>>>>>>>>>\n"); LOG2(" >>>>>>>>>>\n");
LOG2(body); LOG2(body);
LOG2(jBuf.buf); LOG2(jBuf.get());
LOG2("\n"); LOG2("\n");
sendEncrypted(body,(uint8_t *)jBuf.buf,nBytes); sendEncrypted(body,(uint8_t *)jBuf.get(),nBytes);
return(1); return(1);
@ -1507,10 +1506,10 @@ void HAPClient::sendEncrypted(char *body, uint8_t *dataBuf, int dataLen){
TempBuffer <uint8_t> tBuf(totalBytes); TempBuffer <uint8_t> tBuf(totalBytes);
tBuf.buf[count]=bodyLen%256; // store number of bytes in first frame that encrypts the Body (AAD bytes) tBuf.get()[count]=bodyLen%256; // store number of bytes in first frame that encrypts the Body (AAD bytes)
tBuf.buf[count+1]=bodyLen/256; tBuf.get()[count+1]=bodyLen/256;
crypto_aead_chacha20poly1305_ietf_encrypt(tBuf.buf+count+2,&nBytes,(uint8_t *)body,bodyLen,tBuf.buf+count,2,NULL,a2cNonce.get(),a2cKey); // encrypt the Body with authentication tag appended crypto_aead_chacha20poly1305_ietf_encrypt(tBuf.get()+count+2,&nBytes,(uint8_t *)body,bodyLen,tBuf.get()+count,2,NULL,a2cNonce.get(),a2cKey); // encrypt the Body with authentication tag appended
a2cNonce.inc(); // increment nonce a2cNonce.inc(); // increment nonce
@ -1523,17 +1522,17 @@ void HAPClient::sendEncrypted(char *body, uint8_t *dataBuf, int dataLen){
if(n>FRAME_SIZE) // maximum number of bytes to encrypt=FRAME_SIZE if(n>FRAME_SIZE) // maximum number of bytes to encrypt=FRAME_SIZE
n=FRAME_SIZE; n=FRAME_SIZE;
tBuf.buf[count]=n%256; // store number of bytes that encrypts this frame (AAD bytes) tBuf.get()[count]=n%256; // store number of bytes that encrypts this frame (AAD bytes)
tBuf.buf[count+1]=n/256; tBuf.get()[count+1]=n/256;
crypto_aead_chacha20poly1305_ietf_encrypt(tBuf.buf+count+2,&nBytes,dataBuf+i,n,tBuf.buf+count,2,NULL,a2cNonce.get(),a2cKey); // encrypt the next portion of dataBuf with authentication tag appended crypto_aead_chacha20poly1305_ietf_encrypt(tBuf.get()+count+2,&nBytes,dataBuf+i,n,tBuf.get()+count,2,NULL,a2cNonce.get(),a2cKey); // encrypt the next portion of dataBuf with authentication tag appended
a2cNonce.inc(); // increment nonce a2cNonce.inc(); // increment nonce
count+=2+n+16; // increment count by 2-byte AAD record + length of JSON + 16-byte authentication tag count+=2+n+16; // increment count by 2-byte AAD record + length of JSON + 16-byte authentication tag
} }
client.write(tBuf.buf,count); // transmit all encrypted frames to Client client.write(tBuf.get(),count); // transmit all encrypted frames to Client
LOG2("-------- SENT ENCRYPTED! --------\n"); LOG2("-------- SENT ENCRYPTED! --------\n");

View File

@ -134,7 +134,7 @@ struct HAPClient {
static void hexPrintRow(uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as HEX, all on one row, subject to specified minimum log level static void hexPrintRow(uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as HEX, all on one row, subject to specified minimum log level
static void charPrintRow(uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as CHAR, all on one row, subject to specified minimum log level static void charPrintRow(uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as CHAR, all on one row, subject to specified minimum log level
static Controller *findController(uint8_t *id); // returns pointer to controller with mathching ID (or NULL if no match) static Controller *findController(uint8_t *id); // returns pointer to controller with matching ID (or NULL if no match)
static Controller *getFreeController(); // return pointer to next free controller slot (or NULL if no free slots) static Controller *getFreeController(); // return pointer to next free controller slot (or NULL if no free slots)
static Controller *addController(uint8_t *id, uint8_t *ltpk, boolean admin); // stores data for new Controller with specified data. Returns pointer to Controller slot on success, else NULL static Controller *addController(uint8_t *id, uint8_t *ltpk, boolean admin); // stores data for new Controller with specified data. Returns pointer to Controller slot on success, else NULL
static int nAdminControllers(); // returns number of admin Controllers stored static int nAdminControllers(); // returns number of admin Controllers stored

View File

@ -599,10 +599,10 @@ void Span::processSerialCommand(const char *c){
case 'd': { case 'd': {
TempBuffer <char> qBuf(sprintfAttributes(NULL)+1); TempBuffer <char> qBuf(sprintfAttributes(NULL)+1);
sprintfAttributes(qBuf.buf); sprintfAttributes(qBuf.get());
LOG0("\n*** Attributes Database: size=%d configuration=%d ***\n\n",qBuf.len()-1,hapConfig.configNumber); LOG0("\n*** Attributes Database: size=%d configuration=%d ***\n\n",qBuf.len()-1,hapConfig.configNumber);
prettyPrint(qBuf.buf); prettyPrint(qBuf.get());
LOG0("\n*** End Database ***\n\n"); LOG0("\n*** End Database ***\n\n");
} }
break; break;
@ -1009,12 +1009,12 @@ void Span::processSerialCommand(const char *c){
LOG0("\n*** Pairing Data used for Cloning another Device\n\n"); LOG0("\n*** Pairing Data used for Cloning another Device\n\n");
size_t olen; size_t olen;
TempBuffer<char> tBuf(256); TempBuffer<char> tBuf(256);
mbedtls_base64_encode((uint8_t *)tBuf.buf,256,&olen,(uint8_t *)&HAPClient::accessory,sizeof(struct Accessory)); mbedtls_base64_encode((uint8_t *)tBuf.get(),256,&olen,(uint8_t *)&HAPClient::accessory,sizeof(struct Accessory));
LOG0("Accessory data: %s\n",tBuf.buf); LOG0("Accessory data: %s\n",tBuf.get());
for(int i=0;i<HAPClient::MAX_CONTROLLERS;i++){ for(int i=0;i<HAPClient::MAX_CONTROLLERS;i++){
if(HAPClient::controllers[i].allocated){ if(HAPClient::controllers[i].allocated){
mbedtls_base64_encode((uint8_t *)tBuf.buf,256,&olen,(uint8_t *)(HAPClient::controllers+i),sizeof(struct Controller)); mbedtls_base64_encode((uint8_t *)tBuf.get(),256,&olen,(uint8_t *)(HAPClient::controllers+i),sizeof(struct Controller));
LOG0("Controller data: %s\n",tBuf.buf); LOG0("Controller data: %s\n",tBuf.get());
} }
} }
LOG0("\n*** End Pairing Data\n\n"); LOG0("\n*** End Pairing Data\n\n");
@ -1027,14 +1027,14 @@ void Span::processSerialCommand(const char *c){
TempBuffer<char> tBuf(200); TempBuffer<char> tBuf(200);
size_t olen; size_t olen;
tBuf.buf[0]='\0'; tBuf.get()[0]='\0';
LOG0(">>> Accessory data: "); LOG0(">>> Accessory data: ");
readSerial(tBuf.buf,199); readSerial(tBuf.get(),199);
if(strlen(tBuf.buf)==0){ if(strlen(tBuf.get())==0){
LOG0("(cancelled)\n\n"); LOG0("(cancelled)\n\n");
return; return;
} }
mbedtls_base64_decode((uint8_t *)&HAPClient::accessory,sizeof(struct Accessory),&olen,(uint8_t *)tBuf.buf,strlen(tBuf.buf)); mbedtls_base64_decode((uint8_t *)&HAPClient::accessory,sizeof(struct Accessory),&olen,(uint8_t *)tBuf.get(),strlen(tBuf.get()));
if(olen!=sizeof(struct Accessory)){ if(olen!=sizeof(struct Accessory)){
LOG0("\n*** Error in size of Accessory data - cloning cancelled. Restarting...\n\n"); LOG0("\n*** Error in size of Accessory data - cloning cancelled. Restarting...\n\n");
reboot(); reboot();
@ -1044,15 +1044,15 @@ void Span::processSerialCommand(const char *c){
} }
for(int i=0;i<HAPClient::MAX_CONTROLLERS;i++){ for(int i=0;i<HAPClient::MAX_CONTROLLERS;i++){
tBuf.buf[0]='\0'; tBuf.get()[0]='\0';
LOG0(">>> Controller data: "); LOG0(">>> Controller data: ");
readSerial(tBuf.buf,199); readSerial(tBuf.get(),199);
if(strlen(tBuf.buf)==0){ if(strlen(tBuf.get())==0){
LOG0("(done)\n"); LOG0("(done)\n");
while(i<HAPClient::MAX_CONTROLLERS) // clear data from remaining controller slots while(i<HAPClient::MAX_CONTROLLERS) // clear data from remaining controller slots
HAPClient::controllers[i++].allocated=false; HAPClient::controllers[i++].allocated=false;
} else { } else {
mbedtls_base64_decode((uint8_t *)(HAPClient::controllers+i),sizeof(struct Controller),&olen,(uint8_t *)tBuf.buf,strlen(tBuf.buf)); mbedtls_base64_decode((uint8_t *)(HAPClient::controllers+i),sizeof(struct Controller),&olen,(uint8_t *)tBuf.get(),strlen(tBuf.get()));
if(olen!=sizeof(struct Controller)){ if(olen!=sizeof(struct Controller)){
LOG0("\n*** Error in size of Controller data - cloning cancelled. Restarting...\n\n"); LOG0("\n*** Error in size of Controller data - cloning cancelled. Restarting...\n\n");
reboot(); reboot();
@ -1577,8 +1577,8 @@ boolean Span::updateDatabase(boolean updateMDNS){
uint8_t tHash[48]; uint8_t tHash[48];
TempBuffer <char> tBuf(sprintfAttributes(NULL,GET_META|GET_PERMS|GET_TYPE|GET_DESC)+1); TempBuffer <char> tBuf(sprintfAttributes(NULL,GET_META|GET_PERMS|GET_TYPE|GET_DESC)+1);
sprintfAttributes(tBuf.buf,GET_META|GET_PERMS|GET_TYPE|GET_DESC); sprintfAttributes(tBuf.get(),GET_META|GET_PERMS|GET_TYPE|GET_DESC);
mbedtls_sha512_ret((uint8_t *)tBuf.buf,tBuf.len(),tHash,1); // create SHA-384 hash of JSON (can be any hash - just looking for a unique key) mbedtls_sha512_ret((uint8_t *)tBuf.get(),tBuf.len(),tHash,1); // create SHA-384 hash of JSON (can be any hash - just looking for a unique key)
boolean changed=false; boolean changed=false;

View File

@ -712,8 +712,8 @@ class SpanCharacteristic{
size_t olen; size_t olen;
mbedtls_base64_encode(NULL,0,&olen,data,len); // get length of string buffer needed (mbedtls includes the trailing null in this size) mbedtls_base64_encode(NULL,0,&olen,data,len); // get length of string buffer needed (mbedtls includes the trailing null in this size)
TempBuffer<char> tBuf(olen); // create temporary string buffer, with room for trailing null TempBuffer<char> tBuf(olen); // create temporary string buffer, with room for trailing null
mbedtls_base64_encode((uint8_t*)tBuf.buf,olen,&olen,data,len ); // encode data into string buf mbedtls_base64_encode((uint8_t*)tBuf.get(),olen,&olen,data,len ); // encode data into string buf
setString(tBuf.buf); // call setString to continue processing as if characteristic was a string setString(tBuf.get()); // call setString to continue processing as if characteristic was a string
} }
template <typename T> void setVal(T val, boolean notify=true){ template <typename T> void setVal(T val, boolean notify=true){

View File

@ -117,8 +117,8 @@ void Network::apConfigure(){
WiFiServer apServer(80); WiFiServer apServer(80);
client=0; client=0;
TempBuffer <uint8_t> tempBuffer(MAX_HTTP+1); TempBuffer <uint8_t> httpBuf(MAX_HTTP+1);
uint8_t *httpBuf=tempBuffer.buf; // uint8_t *httpBuf=tempBuffer.buf;
const byte DNS_PORT = 53; const byte DNS_PORT = 53;
DNSServer dnsServer; DNSServer dnsServer;
@ -179,7 +179,7 @@ void Network::apConfigure(){
LOG2(client.remoteIP()); LOG2(client.remoteIP());
LOG2(" <<<<<<<<<\n"); LOG2(" <<<<<<<<<\n");
int nBytes=client.read(httpBuf,MAX_HTTP+1); // read all available bytes up to maximum allowed+1 int nBytes=client.read(httpBuf.get(),MAX_HTTP+1); // read all available bytes up to maximum allowed+1
if(nBytes>MAX_HTTP){ // exceeded maximum number of bytes allowed if(nBytes>MAX_HTTP){ // exceeded maximum number of bytes allowed
badRequestError(); badRequestError();
@ -187,11 +187,11 @@ void Network::apConfigure(){
continue; continue;
} }
httpBuf[nBytes]='\0'; // add null character to enable string functions httpBuf.get()[nBytes]='\0'; // add null character to enable string functions
char *body=(char *)httpBuf; // char pointer to start of HTTP Body char *body=(char *)httpBuf.get(); // char pointer to start of HTTP Body
char *p; // char pointer used for searches char *p; // char pointer used for searches
if(!(p=strstr((char *)httpBuf,"\r\n\r\n"))){ if(!(p=strstr((char *)httpBuf.get(),"\r\n\r\n"))){
badRequestError(); badRequestError();
LOG0("\n*** ERROR: Malformed HTTP request (can't find blank line indicating end of BODY)\n\n"); LOG0("\n*** ERROR: Malformed HTTP request (can't find blank line indicating end of BODY)\n\n");
continue; continue;

View File

@ -42,10 +42,15 @@ String mask(char *c, int n); // simply utility that creates a String fr
// going out of scope // going out of scope
template <class bufType> template <class bufType>
struct TempBuffer { class TempBuffer {
private:
bufType *buf; bufType *buf;
int nBytes; int nBytes;
public:
TempBuffer(size_t len){ TempBuffer(size_t len){
nBytes=len*sizeof(bufType); nBytes=len*sizeof(bufType);
buf=(bufType *)malloc(nBytes); buf=(bufType *)malloc(nBytes);
@ -65,6 +70,10 @@ struct TempBuffer {
return(nBytes); return(nBytes);
} }
bufType *get(){
return(buf);
}
}; };
//////////////////////////////// ////////////////////////////////