initial change in hap[i] array to reserve space according to socket number

This commit is contained in:
Gregg 2024-05-08 06:45:57 -05:00
parent be4825dacb
commit 747b8c3244
5 changed files with 65 additions and 100 deletions

View File

@ -1253,8 +1253,8 @@ void HAPClient::checkTimedWrites(){
void HAPClient::eventNotify(SpanBuf *pObj, int nObj, int ignoreClient){
for(int cNum=0;cNum<homeSpan.maxConnections;cNum++){ // loop over all connection slots
if(hap[cNum]->client && 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)
for(int cNum=0;cNum<CONFIG_LWIP_MAX_SOCKETS;cNum++){ // loop over all connection slots
if(hap[cNum] && hap[cNum]->client && 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)
homeSpan.printfNotify(pObj,nObj,cNum); // create JSON (which may be of zero length if there are no applicable notifications for this cNum)
size_t nBytes=hapOut.getSize();
@ -1470,8 +1470,8 @@ void HAPClient::removeController(uint8_t *id){
void HAPClient::tearDown(uint8_t *id){
for(int i=0;i<homeSpan.maxConnections;i++){ // loop over all connection slots
if(hap[i]->client && (id==NULL || (hap[i]->cPair && !memcmp(id,hap[i]->cPair->ID,hap_controller_IDBYTES)))){
for(int i=0;i<CONFIG_LWIP_MAX_SOCKETS;i++){ // loop over all connection slots
if(hap[i] && hap[i]->client && (id==NULL || (hap[i]->cPair && !memcmp(id,hap[i]->cPair->ID,hap_controller_IDBYTES)))){
LOG1("*** Terminating Client #%d\n",i);
hap[i]->client.stop();
}

View File

@ -93,6 +93,7 @@ struct HAPClient {
WiFiClient client; // handle to client
Controller *cPair=NULL; // pointer to info on current, session-verified Paired Controller (NULL=un-verified, and therefore un-encrypted, connection)
boolean isConnected=false; // flag to indicate client is connect
// These temporary Curve25519 keys are generated in the first call to pair-verify and used in the second call to pair-verify so must persist for a short period

View File

@ -89,14 +89,9 @@ void Span::begin(Category catID, const char *displayName, const char *hostNameBa
esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(0)); // required to avoid watchdog timeout messages from ESP32-C3
if(requestedMaxCon<maxConnections) // if specific request for max connections is less than computed max connections
maxConnections=requestedMaxCon; // over-ride max connections with requested value
hap=(HAPClient **)HS_CALLOC(CONFIG_LWIP_MAX_SOCKETS,sizeof(HAPClient *)); // create fixed array of pointers to HAPClient objects (initially set to NULL)
hap=(HAPClient **)HS_CALLOC(maxConnections,sizeof(HAPClient *));
for(int i=0;i<maxConnections;i++)
hap[i]=new HAPClient;
hapServer=new WiFiServer(tcpPortNum);
hapServer=new WiFiServer(tcpPortNum); // create HAP WIFI SERVER
size_t len;
@ -234,66 +229,43 @@ void Span::pollTask() {
processSerialCommand(cBuf);
}
WiFiClient newClient;
if(hapServer->hasClient()){ // found new client
if(newClient=hapServer->available()){ // found a new HTTP client
int freeSlot=getFreeSlot(); // get next free slot
WiFiClient newClient=hapServer->available(); // get new client
if(freeSlot==-1){ // no available free slots
freeSlot=randombytes_uniform(maxConnections);
LOG2("=======================================\n");
LOG1("** Freeing Client #");
LOG1(freeSlot);
LOG1(" (");
LOG1(millis()/1000);
LOG1(" sec) ");
LOG1(hap[freeSlot]->client.remoteIP());
LOG1("\n");
hap[freeSlot]->client.stop(); // disconnect client from first slot and re-use
}
int socket=newClient.fd()-LWIP_SOCKET_OFFSET; // get socket number (starting at zero)
hap[freeSlot]->client=newClient; // copy new client handle into free slot
if(hap[socket]==NULL) // create HAPClient at that socket if it does not alreay exist
hap[socket]=new HAPClient;
hap[socket]->client=newClient; // copy new client handle
hap[socket]->isConnected=true; // set isConnected flag
hap[socket]->cPair=NULL; // reset pointer to verified ID
homeSpan.clearNotify(socket); // 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)
LOG2("=======================================\n");
LOG1("** Client #");
LOG1(freeSlot);
LOG1(" Connected: (");
LOG1(millis()/1000);
LOG1(" sec) ");
LOG1(hap[freeSlot]->client.remoteIP());
LOG1(" on Socket ");
LOG1(hap[freeSlot]->client.fd()-LWIP_SOCKET_OFFSET+1);
LOG1("/");
LOG1(CONFIG_LWIP_MAX_SOCKETS);
LOG1("\n");
LOG1("** Client #%d Connected (%lu sec): %s\n",socket,millis()/1000,newClient.remoteIP().toString().c_str());
LOG2("\n");
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;i<maxConnections;i++){ // loop over all HAP Connection slots
for(int i=0;i<CONFIG_LWIP_MAX_SOCKETS;i++){ // loop over all HAP Connection slots
if(hap[i]->client && hap[i]->client.available()){ // if connection exists and data is available
HAPClient::conNum=i; // set connection number
homeSpan.lastClientIP=hap[i]->client.remoteIP().toString(); // store IP Address for web logging
hap[i]->processRequest(); // process HAP request
homeSpan.lastClientIP="0.0.0.0"; // reset stored IP address to show "0.0.0.0" if homeSpan.getClientIP() is used in any other context
if(!hap[i]->client){ // client disconnected by server
LOG1("** Disconnected Client #");
LOG1(i);
LOG1(" (");
LOG1(millis()/1000);
LOG1(" sec)\n");
if(hap[i]){ // if this socket has a configured HAPClient
if(hap[i]->client){ // if the client is connected
if(hap[i]->client.available()){ // if client has data available
HAPClient::conNum=i; // set connection number
homeSpan.lastClientIP=hap[i]->client.remoteIP().toString(); // store IP Address for web logging
hap[i]->processRequest(); // PROCESS HAP REQUEST
homeSpan.lastClientIP="0.0.0.0"; // reset stored IP address to show "0.0.0.0" if homeSpan.getClientIP() is used in any other context
}
}
LOG2("\n");
} // process HAP Client
} // for-loop over connection slots
else if(hap[i]->isConnected){ // if client is not connected, but HAPClient thinks it is
LOG1("** Client #%d DISCONNECTED (%lu sec)\n",i,millis()/1000);
hap[i]->isConnected=false;
}
}
}
snapTime=millis(); // snap the current time for use in ALL loop routines
@ -587,6 +559,13 @@ void Span::processSerialCommand(const char *c){
switch(c[0]){
case 'Z': {
for(int i=0;i<CONFIG_LWIP_MAX_SOCKETS;i++)
if(hap[i] && hap[i]->client)
hap[i]->client.stop();
}
break;
case 's': {
LOG0("\n*** HomeSpan Status ***\n\n");
@ -603,27 +582,26 @@ void Span::processSerialCommand(const char *c){
HAPClient::printControllers();
LOG0("\n");
for(int i=0;i<maxConnections;i++){
LOG0("Connection #%d ",i);
if(hap[i]->client){
for(int i=0;i<CONFIG_LWIP_MAX_SOCKETS;i++){
if(hap[i]){
LOG0("Client #%d:",i);
LOG0("%s on Socket %d/%d",hap[i]->client.remoteIP().toString().c_str(),hap[i]->client.fd()-LWIP_SOCKET_OFFSET+1,CONFIG_LWIP_MAX_SOCKETS);
if(hap[i]->client){
LOG0(" %s",hap[i]->client.remoteIP().toString().c_str());
if(hap[i]->cPair){
LOG0(" ID=");
HAPClient::charPrintRow(hap[i]->cPair->getID(),36);
LOG0(hap[i]->cPair->isAdmin()?" (admin)":" (regular)");
if(hap[i]->cPair){
LOG0(" ID=");
HAPClient::charPrintRow(hap[i]->cPair->getID(),36);
LOG0(hap[i]->cPair->isAdmin()?" (admin)":" (regular)");
} else {
LOG0(" (unverified)");
}
} else {
LOG0(" (unverified)");
LOG0(" unconnected");
}
} else {
LOG0("(unconnected)");
LOG0("\n");
}
LOG0("\n");
}
LOG0("\n*** End Status ***\n\n");
}
break;
@ -914,8 +892,8 @@ void Span::processSerialCommand(const char *c){
if(((*chr)->perms)&EV){
LOG0(", EV=(");
boolean addComma=false;
for(int i=0;i<homeSpan.maxConnections;i++){
if((*chr)->ev[i] && hap[i]->client){
for(int i=0;i<CONFIG_LWIP_MAX_SOCKETS;i++){
if((*chr)->ev[i] && hap[i] && hap[i]->client){
LOG0("%s%d",addComma?",":"",i);
addComma=true;
}

View File

@ -1 +0,0 @@
-fno-exceptions

View File

@ -31,7 +31,10 @@ void setup() {
Serial.begin(115200);
homeSpan.begin(Category::Lighting,"HomeSpan Light");
homeSpan.setLogLevel(2);
homeSpan.enableWebLog();
homeSpan.begin(Category::Lighting,"HomeSpan LightBulb");
new SpanAccessory();
new Service::AccessoryInformation();
@ -39,8 +42,6 @@ void setup() {
new Service::LightBulb();
new Characteristic::On();
// new SpanUserCommand('k',"- list controllers",list_controllers);
homeSpan.setControllerCallback(list_controllers);
}
@ -52,17 +53,3 @@ void loop(){
}
//////////////////////////////////////
void list_controllers(){
Serial.printf("\nControllers\n");
for(auto it=homeSpan.controllerListBegin(); it!=homeSpan.controllerListEnd(); ++it){
Serial.printf("Admin=%d ID=",it->isAdmin());
for(int i=0;i<36;i++)
Serial.printf("%02X",it->getID()[i]);
Serial.printf(" LTPK=");
for(int i=0;i<32;i++)
Serial.printf("%02X",it->getLTPK()[i]);
Serial.printf("\n");
}
}