From fbd33bb29de0cd085f6a21d3a294dbc56f93a47f Mon Sep 17 00:00:00 2001 From: Gregg Date: Wed, 30 Sep 2020 10:00:10 -0500 Subject: [PATCH] Created homeSpan::setMaxConnections() to make number of HAP connections dynamic This completes all changes to Settings.h. User will not need to ever access this files or change any settings. --- src/HAP.cpp | 16 +++++++-------- src/HAP.h | 2 +- src/HomeSpan.cpp | 53 +++++++++++++++++++++++++++--------------------- src/HomeSpan.h | 12 ++++++----- src/Settings.h | 6 +----- 5 files changed, 47 insertions(+), 42 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index 47ca60c..f69d73d 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -963,14 +963,14 @@ int HAPClient::postPairingsURL(){ // re-check connections and close any (or all) clients as a result of controllers that were removed above // must be performed AFTER sending the TLV response, since that connection itself may be terminated below - for(int i=0;iclient){ // if slot is connected - if(!nAdminControllers() || (hap[i].cPair && !hap[i].cPair->allocated)){ // accessory unpaired, OR client connection is verified but points to a newly *unallocated* controller + if(!nAdminControllers() || (hap[i]->cPair && !hap[i]->cPair->allocated)){ // accessory unpaired, OR client connection is verified but points to a newly *unallocated* controller LOG1("*** Terminating Client #"); LOG1(i); LOG1("\n"); - hap[i].client.stop(); + hap[i]->client.stop(); } } // if client connected @@ -1234,8 +1234,8 @@ void HAPClient::checkTimedWrites(){ void HAPClient::eventNotify(SpanBuf *pObj, int nObj, int ignoreClient){ - for(int cNum=0;cNumclient && cNum!=ignoreClient){ // if there is a client connected to this slot and it is NOT flagged to be ignored (in cases where it is the client making a PUT request int nBytes=homeSpan.sprintfNotify(pObj,nObj,NULL,cNum); // get JSON response for notifications to client cNum - includes terminating null (will be recast to uint8_t* below) @@ -1248,13 +1248,13 @@ void HAPClient::eventNotify(SpanBuf *pObj, int nObj, int ignoreClient){ sprintf(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()); + LOG2(hap[cNum]->client.remoteIP()); LOG2(" >>>>>>>>>>\n"); LOG2(body); LOG2(jsonBuf); LOG2("\n"); - hap[cNum].sendEncrypted(body,(uint8_t *)jsonBuf,nBytes); // note recasting of jsonBuf into uint8_t* + hap[cNum]->sendEncrypted(body,(uint8_t *)jsonBuf,nBytes); // note recasting of jsonBuf into uint8_t* } // if there are characteristic updates to notify client cNum } // if client exists diff --git a/src/HAP.h b/src/HAP.h index 9689943..efe1a3f 100644 --- a/src/HAP.h +++ b/src/HAP.h @@ -126,4 +126,4 @@ struct HAPClient { ///////////////////////////////////////////////// // Extern Variables -extern HAPClient hap[]; +extern HAPClient **hap; diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 6d23ab8..a06e324 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -11,7 +11,7 @@ using namespace Utils; WiFiServer hapServer(80); // HTTP Server (i.e. this acccesory) running on usual port 80 (local-scoped variable to this file only) -HAPClient hap[MAX_CONNECTIONS]; // HAP Client structure containing HTTP client connections, parsing routines, and state variables (global-scoped variable) +HAPClient **hap; // HAP Client structure containing HTTP client connections, parsing routines, and state variables (global-scoped variable) Span homeSpan; // HAP Attributes database and all related control functions for this Accessory (global-scoped variable) /////////////////////////////// @@ -27,6 +27,10 @@ void Span::begin(Category catID, char *displayName, char *hostNameBase, char *mo controlButton.init(controlPin); statusLED.init(statusPin); + + hap=(HAPClient **)calloc(maxConnections,sizeof(HAPClient *)); + for(int i=0;iclient.remoteIP()); LOG1("\n"); - hap[freeSlot].client.stop(); // disconnect client from first slot and re-use + hap[freeSlot]->client.stop(); // disconnect client from first slot and re-use } - hap[freeSlot].client=newClient; // copy new client handle into free slot + hap[freeSlot]->client=newClient; // copy new client handle into free slot LOG2("=======================================\n"); LOG1("** Client #"); @@ -124,23 +128,23 @@ void Span::poll() { LOG1(" Connected: ("); LOG1(millis()/1000); LOG1(" sec) "); - LOG1(hap[freeSlot].client.remoteIP()); + LOG1(hap[freeSlot]->client.remoteIP()); LOG1("\n"); LOG2("\n"); - hap[freeSlot].cPair=NULL; // reset pointer to verified ID + hap[freeSlot]->cPair=NULL; // reset pointer to verified ID homeSpan.clearNotify(freeSlot); // clear all notification requests for this connection HAPClient::pairStatus=pairState_M1; // reset starting PAIR STATE (which may be needed if Accessory failed in middle of pair-setup) } - for(int i=0;iclient && hap[i]->client.available()){ // if connection exists and data is available HAPClient::conNum=i; // set connection number - hap[i].processRequest(); // process HAP request + hap[i]->processRequest(); // process HAP request - if(!hap[i].client){ // client disconnected by server + if(!hap[i]->client){ // client disconnected by server LOG1("** Disconnecting Client #"); LOG1(i); LOG1(" ("); @@ -181,8 +185,8 @@ void Span::poll() { int Span::getFreeSlot(){ - for(int i=0;iclient) return(i); } @@ -349,7 +353,7 @@ void Span::initWifi(){ mdns_service_txt_item_set("_hap","_tcp","sf","0"); // set Status Flag = 0 Serial.print("\nStarting Web (HTTP) Server supporting up to "); - Serial.print(MAX_CONNECTIONS); + Serial.print(maxConnections); Serial.print(" simultaneous connections...\n\n"); hapServer.begin(); @@ -379,19 +383,19 @@ void Span::processSerialCommand(char *c){ HAPClient::printControllers(); Serial.print("\n"); - for(int i=0;iclient){ - Serial.print(hap[i].client.remoteIP()); + Serial.print(hap[i]->client.remoteIP()); Serial.print(" "); - if(hap[i].cPair){ + if(hap[i]->cPair){ Serial.print("ID="); - HAPClient::charPrintRow(hap[i].cPair->ID,36); - Serial.print(hap[i].cPair->admin?" (admin)":" (regular)"); + HAPClient::charPrintRow(hap[i]->cPair->ID,36); + Serial.print(hap[i]->cPair->admin?" (admin)":" (regular)"); } else { Serial.print("(unverified)"); } @@ -459,12 +463,12 @@ void Span::processSerialCommand(char *c){ nvs_commit(HAPClient::hapNVS); // commit to NVS Serial.print("\n** HomeSpan Pairing Data DELETED **\n\n"); - for(int i=0;iclient){ // if slot is connected LOG1("*** Terminating Client #"); LOG1(i); LOG1("\n"); - hap[i].client.stop(); + hap[i]->client.stop(); } } @@ -1004,6 +1008,9 @@ SpanCharacteristic::SpanCharacteristic(char *type, uint8_t perms){ iid=++(homeSpan.Accessories.back()->iidCount); service=homeSpan.Accessories.back()->Services.back(); aid=homeSpan.Accessories.back()->aid; + + ev=(boolean *)calloc(homeSpan.maxConnections,sizeof(boolean)); + } /////////////////////////////// diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 987ca1c..c4c6727 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -52,10 +52,11 @@ struct Span{ 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() - char *defaultSetupCode=DEFAULT_SETUP_CODE; // Setup Code used for pairing - uint8_t statusPin=DEFAULT_STATUS_PIN; // pin for status LED - uint8_t controlPin=DEFAULT_CONTROL_PIN; // pin for Control Pushbutton - uint8_t logLevel=DEFAULT_LOG_LEVEL; // level for writing out log messages to serial monitor + char *defaultSetupCode=DEFAULT_SETUP_CODE; // Setup Code used for pairing + uint8_t statusPin=DEFAULT_STATUS_PIN; // pin for status LED + uint8_t controlPin=DEFAULT_CONTROL_PIN; // pin for Control Pushbutton + uint8_t logLevel=DEFAULT_LOG_LEVEL; // level for writing out log messages to serial monitor + uint8_t maxConnections=DEFAULT_MAX_CONNECTIONS; // number of simultaneous HAP connections Blinker statusLED; // indicates HomeSpan status PushButton controlButton; // controls HomeSpan configuration and resets @@ -95,6 +96,7 @@ struct Span{ void setApPassword(char *pwd){network.apPassword=pwd;} // sets Access Point Password void setApTimeout(uint16_t nSec){network.lifetime=nSec*1000;} // sets Access Point Timeout (seconds) void setLogLevel(uint8_t level){logLevel=level;} // sets Log Level for log messages (0=baseline, 1=intermediate, 2=all) + void setMaxConnections(uint8_t nCon){maxConnections=nCon;} // sets maximum number of simultaneous HAP connections (HAP requires devices support at least 8) }; /////////////////////////////// @@ -175,7 +177,7 @@ struct SpanCharacteristic{ FORMAT format; // Characteristic Format char *desc=NULL; // Characteristic Description (optional) SpanRange *range=NULL; // Characteristic min/max/step; NULL = default values (optional) - boolean ev[MAX_CONNECTIONS]={false}; // Characteristic Event Notify Enable (per-connection) + boolean *ev; // Characteristic Event Notify Enable (per-connection) int aid=0; // Accessory ID - passed through from Service containing this Characteristic boolean isUpdated=false; // set to true when new value has been requested by PUT /characteristic diff --git a/src/Settings.h b/src/Settings.h index 0a795bb..d09d2a3 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -26,11 +26,7 @@ #define DEFAULT_LOG_LEVEL 0 // change with homeSpan.setLogLevel(level) -////////////////////////////////////////////////////// -// Maximum number of simultaenous IP connections // -// HAP requires at least 8 // - -const int MAX_CONNECTIONS=8; +#define DEFAULT_MAX_CONNECTIONS 8 // change with homeSpan.setMaxConnections(num); ///////////////////////////////////////////////////// // Message Log Level Control Macros //