Created evList to store notifications
Also updated all code to use hapList and deleted all references to **hap
This commit is contained in:
parent
153ab451fd
commit
983e159adf
29
src/HAP.cpp
29
src/HAP.cpp
|
|
@ -1017,7 +1017,7 @@ int HAPClient::putCharacteristicsURL(char *json){
|
||||||
|
|
||||||
// Create and send Event Notifications if needed
|
// 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
|
eventNotify(pObj,n,this); // transmit EVENT Notification for "n" pObj objects, except DO NOT notify client making request
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
@ -1241,22 +1241,22 @@ void HAPClient::checkTimedWrites(){
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
||||||
void HAPClient::eventNotify(SpanBuf *pObj, int nObj, int ignoreClient){
|
void HAPClient::eventNotify(SpanBuf *pObj, int nObj, HAPClient *ignore){
|
||||||
|
|
||||||
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)
|
for(auto it=homeSpan.hapList.begin(); it!=homeSpan.hapList.end(); ++it){ // loop over all connection slots
|
||||||
|
if(&(*it)!=ignore){ // if NOT flagged to be ignored (in cases where it is the client making a PUT request)
|
||||||
|
|
||||||
|
homeSpan.printfNotify(pObj,nObj,&(*it)); // create JSON (which may be of zero length if there are no applicable notifications for this cNum)
|
||||||
size_t nBytes=hapOut.getSize();
|
size_t nBytes=hapOut.getSize();
|
||||||
hapOut.flush();
|
hapOut.flush();
|
||||||
|
|
||||||
if(nBytes>0){ // if there ARE notifications to send to client cNum
|
if(nBytes>0){ // if there ARE notifications to send to client cNum
|
||||||
|
|
||||||
LOG2("\n>>>>>>>>>> %s >>>>>>>>>>\n",hap[cNum]->client.remoteIP().toString().c_str());
|
LOG2("\n>>>>>>>>>> %s >>>>>>>>>>\n",it->client.remoteIP().toString().c_str());
|
||||||
|
|
||||||
hapOut.setLogLevel(2).setHapClient(hap[cNum]);
|
hapOut.setLogLevel(2).setHapClient(&(*it));
|
||||||
hapOut << "EVENT/1.0 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: " << nBytes << "\r\n\r\n";
|
hapOut << "EVENT/1.0 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: " << nBytes << "\r\n\r\n";
|
||||||
homeSpan.printfNotify(pObj,nObj,cNum);
|
homeSpan.printfNotify(pObj,nObj,&(*it));
|
||||||
hapOut.flush();
|
hapOut.flush();
|
||||||
|
|
||||||
LOG2("\n-------- SENT ENCRYPTED! --------\n");
|
LOG2("\n-------- SENT ENCRYPTED! --------\n");
|
||||||
|
|
@ -1461,11 +1461,11 @@ void HAPClient::removeController(uint8_t *id){
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
||||||
void HAPClient::tearDown(uint8_t *id){
|
void HAPClient::tearDown(uint8_t *id){
|
||||||
|
|
||||||
for(int i=0;i<CONFIG_LWIP_MAX_SOCKETS;i++){ // loop over all connection slots
|
for(HAPClient &hc : homeSpan.hapList){
|
||||||
if(hap[i] && hap[i]->client && (id==NULL || (hap[i]->cPair && !memcmp(id,hap[i]->cPair->ID,hap_controller_IDBYTES)))){
|
if(id==NULL || (hc.cPair && !memcmp(id,hc.cPair->ID,hap_controller_IDBYTES))){
|
||||||
LOG1("*** Terminating Client #%d\n",i);
|
LOG1("*** Terminating Client #%d\n",hc.clientNumber);
|
||||||
hap[i]->client.stop();
|
hc.client.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1691,5 +1691,4 @@ void HapOut::HapStreamBuffer::printFormatted(char *buf, size_t nChars, size_t ns
|
||||||
pairState HAPClient::pairStatus;
|
pairState HAPClient::pairStatus;
|
||||||
Accessory HAPClient::accessory;
|
Accessory HAPClient::accessory;
|
||||||
list<Controller, Mallocator<Controller>> HAPClient::controllerList;
|
list<Controller, Mallocator<Controller>> HAPClient::controllerList;
|
||||||
int HAPClient::conNum;
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,6 @@ struct HAPClient {
|
||||||
static pairState pairStatus; // tracks pair-setup status
|
static pairState pairStatus; // tracks pair-setup status
|
||||||
static Accessory accessory; // Accessory ID and Ed25519 public and secret keys - permanently stored
|
static Accessory accessory; // Accessory ID and Ed25519 public and secret keys - permanently stored
|
||||||
static list<Controller, Mallocator<Controller>> controllerList; // linked-list of Paired Controller IDs and ED25519 long-term public keys - permanently stored
|
static list<Controller, Mallocator<Controller>> controllerList; // linked-list of Paired Controller IDs and ED25519 long-term public keys - permanently stored
|
||||||
static int conNum; // connection number - used to keep track of per-connection EV notifications
|
|
||||||
|
|
||||||
// individual structures and data defined for each Hap Client connection
|
// individual structures and data defined for each Hap Client connection
|
||||||
|
|
||||||
|
|
@ -174,7 +173,7 @@ struct HAPClient {
|
||||||
static void tearDown(uint8_t *id); // tears down connections using Controller with ID=id; tears down all connections if id=NULL
|
static void tearDown(uint8_t *id); // tears down connections using Controller with ID=id; tears down all connections if id=NULL
|
||||||
static void checkNotifications(); // checks for Event Notifications and reports to controllers as needed (HAP Section 6.8)
|
static void checkNotifications(); // checks for Event Notifications and reports to controllers as needed (HAP Section 6.8)
|
||||||
static void checkTimedWrites(); // checks for expired Timed Write PIDs, and clears any found (HAP Section 6.7.2.4)
|
static void checkTimedWrites(); // checks for expired Timed Write PIDs, and clears any found (HAP Section 6.7.2.4)
|
||||||
static void eventNotify(SpanBuf *pObj, int nObj, int ignoreClient=-1); // transmits EVENT Notifications for nObj SpanBuf objects, pObj, with optional flag to ignore a specific client
|
static void eventNotify(SpanBuf *pObj, int nObj, HAPClient *ignore=NULL); // transmits EVENT Notifications for nObj SpanBuf objects, pObj, with optional flag to ignore a specific client
|
||||||
|
|
||||||
static void getStatusURL(HAPClient *, void (*)(const char *, void *), void *); // GET / status (an optional, non-HAP feature)
|
static void getStatusURL(HAPClient *, void (*)(const char *, void *), void *); // GET / status (an optional, non-HAP feature)
|
||||||
|
|
||||||
|
|
@ -237,5 +236,4 @@ class HapOut : public std::ostream {
|
||||||
/////////////////////////////////////////////////
|
/////////////////////////////////////////////////
|
||||||
// Extern Variables
|
// Extern Variables
|
||||||
|
|
||||||
extern HAPClient **hap;
|
|
||||||
extern HapOut hapOut;
|
extern HapOut hapOut;
|
||||||
|
|
|
||||||
121
src/HomeSpan.cpp
121
src/HomeSpan.cpp
|
|
@ -46,9 +46,6 @@ const __attribute__((section(".rodata_custom_desc"))) SpanPartition spanPartitio
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
HapOut hapOut; // Specialized output stream that can both print to serial monitor and encrypt/transmit to HAP Clients with minimal memory usage (global-scoped variable)
|
HapOut hapOut; // Specialized output stream that can both print to serial monitor and encrypt/transmit to HAP Clients with minimal memory usage (global-scoped variable)
|
||||||
HAPClient **hap; // HAP Client structure containing HTTP client connections, parsing routines, and state variables (global-scoped variable)
|
|
||||||
list<HAPClient, Mallocator<HAPClient>> hapList; // linked-list of HAP Client structures 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)
|
Span homeSpan; // HAP Attributes database and all related control functions for this Accessory (global-scoped variable)
|
||||||
HapCharacteristics hapChars; // Instantiation of all HAP Characteristics used to create SpanCharacteristics (global-scoped variable)
|
HapCharacteristics hapChars; // Instantiation of all HAP Characteristics used to create SpanCharacteristics (global-scoped variable)
|
||||||
|
|
||||||
|
|
@ -71,7 +68,6 @@ Span::Span(){
|
||||||
rebootCount++;
|
rebootCount++;
|
||||||
nvs_set_u8(wifiNVS,"REBOOTS",rebootCount);
|
nvs_set_u8(wifiNVS,"REBOOTS",rebootCount);
|
||||||
nvs_commit(wifiNVS);
|
nvs_commit(wifiNVS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
@ -91,8 +87,6 @@ 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
|
esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(0)); // required to avoid watchdog timeout messages from ESP32-C3
|
||||||
|
|
||||||
hap=(HAPClient **)HS_CALLOC(CONFIG_LWIP_MAX_SOCKETS,sizeof(HAPClient *)); // create fixed array of pointers to HAPClient objects (initially set to NULL)
|
|
||||||
|
|
||||||
hapServer=new WiFiServer(tcpPortNum); // create HAP WIFI SERVER
|
hapServer=new WiFiServer(tcpPortNum); // create HAP WIFI SERVER
|
||||||
|
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
@ -233,35 +227,33 @@ void Span::pollTask() {
|
||||||
|
|
||||||
if(hapServer->hasClient()){
|
if(hapServer->hasClient()){
|
||||||
|
|
||||||
auto it=hapList.emplace(hapList.begin());
|
auto it=hapList.emplace(hapList.begin()); // create new HAPClient connection
|
||||||
(*it).client=hapServer->available();
|
it->client=hapServer->available();
|
||||||
(*it).clientNumber=(*it).client.fd()-LWIP_SOCKET_OFFSET;
|
it->clientNumber=it->client.fd()-LWIP_SOCKET_OFFSET;
|
||||||
|
|
||||||
// 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)
|
||||||
|
|
||||||
HAPClient::pairStatus=pairState_M1; // reset starting PAIR STATE (which may be needed if Accessory failed in middle of pair-setup)
|
|
||||||
|
|
||||||
LOG2("=======================================\n");
|
LOG2("=======================================\n");
|
||||||
LOG1("** Client #%d Connected (%lu sec): %s\n",(*it).clientNumber,millis()/1000,(*it).client.remoteIP().toString().c_str());
|
LOG1("** Client #%d Connected (%lu sec): %s\n",it->clientNumber,millis()/1000,it->client.remoteIP().toString().c_str());
|
||||||
LOG2("\n");
|
LOG2("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it=hapList.begin();
|
currentClient=hapList.begin();
|
||||||
while(it!=hapList.end()){
|
while(currentClient!=hapList.end()){
|
||||||
|
|
||||||
if((*it).client.connected()){ // if the client is connected
|
if(currentClient->client.connected()){ // if the client is connected
|
||||||
if((*it).client.available()){ // if client has data available
|
if(currentClient->client.available()){ // if client has data available
|
||||||
// HAPClient::conNum=i; // set connection number
|
homeSpan.lastClientIP=currentClient->client.remoteIP().toString(); // store IP Address for web logging
|
||||||
homeSpan.lastClientIP=(*it).client.remoteIP().toString(); // store IP Address for web logging
|
currentClient->processRequest(); // PROCESS HAP REQUEST
|
||||||
(*it).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
|
||||||
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
|
|
||||||
}
|
}
|
||||||
it++;
|
currentClient++;
|
||||||
} else {
|
} else {
|
||||||
LOG1("** Client #%d DISCONNECTED (%lu sec)\n",(*it).clientNumber,millis()/1000);
|
LOG1("** Client #%d DISCONNECTED (%lu sec)\n",currentClient->clientNumber,millis()/1000);
|
||||||
(*it).client.stop();
|
currentClient->client.stop();
|
||||||
delay(5);
|
delay(5);
|
||||||
it=hapList.erase(it);
|
clearNotify(&*currentClient); // clear all notification requests for this connection
|
||||||
|
currentClient=hapList.erase(currentClient); // remove HAPClient connection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -273,7 +265,7 @@ void Span::pollTask() {
|
||||||
for(auto it=PushButtons.begin();it!=PushButtons.end();it++) // check for SpanButton presses
|
for(auto it=PushButtons.begin();it!=PushButtons.end();it++) // check for SpanButton presses
|
||||||
(*it)->check();
|
(*it)->check();
|
||||||
|
|
||||||
////// HAPClient::checkNotifications();
|
HAPClient::checkNotifications();
|
||||||
HAPClient::checkTimedWrites();
|
HAPClient::checkTimedWrites();
|
||||||
|
|
||||||
if(spanOTA.enabled)
|
if(spanOTA.enabled)
|
||||||
|
|
@ -304,18 +296,6 @@ void Span::pollTask() {
|
||||||
|
|
||||||
} // poll
|
} // poll
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
int Span::getFreeSlot(){
|
|
||||||
|
|
||||||
for(int i=0;i<maxConnections;i++){
|
|
||||||
if(!hap[i]->client)
|
|
||||||
return(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
||||||
void Span::commandMode(){
|
void Span::commandMode(){
|
||||||
|
|
@ -886,11 +866,9 @@ void Span::processSerialCommand(const char *c){
|
||||||
if(((*chr)->perms)&EV){
|
if(((*chr)->perms)&EV){
|
||||||
LOG0(", EV=(");
|
LOG0(", EV=(");
|
||||||
boolean addComma=false;
|
boolean addComma=false;
|
||||||
for(int i=0;i<CONFIG_LWIP_MAX_SOCKETS;i++){
|
for(HAPClient *hc : (*chr)->evList){
|
||||||
if((*chr)->ev[i] && hap[i] && hap[i]->client){
|
LOG0("%s%d",addComma?",":"",hc->clientNumber);
|
||||||
LOG0("%s%d",addComma?",":"",i);
|
addComma=true;
|
||||||
addComma=true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LOG0(")");
|
LOG0(")");
|
||||||
}
|
}
|
||||||
|
|
@ -1463,29 +1441,25 @@ int Span::updateCharacteristics(char *buf, SpanBuf *pObj){
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
void Span::clearNotify(int slotNum){
|
void Span::clearNotify(HAPClient *hc){
|
||||||
|
|
||||||
for(int i=0;i<Accessories.size();i++){
|
for(auto const &acc : Accessories)
|
||||||
for(int j=0;j<Accessories[i]->Services.size();j++){
|
for(auto const &svc : acc->Services)
|
||||||
for(int k=0;k<Accessories[i]->Services[j]->Characteristics.size();k++){
|
for(auto const &chr : svc->Characteristics)
|
||||||
Accessories[i]->Services[j]->Characteristics[k]->ev[slotNum]=false;
|
chr->evList.remove(hc);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
void Span::printfNotify(SpanBuf *pObj, int nObj, int conNum){
|
void Span::printfNotify(SpanBuf *pObj, int nObj, HAPClient *hc){
|
||||||
|
|
||||||
boolean notifyFlag=false;
|
boolean notifyFlag=false;
|
||||||
|
|
||||||
for(int i=0;i<nObj;i++){ // loop over all objects
|
for(int i=0;i<nObj;i++){ // loop over all objects
|
||||||
|
|
||||||
if(pObj[i].status==StatusCode::OK && pObj[i].val){ // characteristic was successfully updated with a new value (i.e. not just an EV request)
|
if(pObj[i].status==StatusCode::OK && pObj[i].val){ // characteristic was successfully updated with a new value (i.e. not just an EV request)
|
||||||
|
if(pObj[i].characteristic->evList.has(hc)){ // if connection hc is subscribed to EV notifications for this characteristic
|
||||||
|
|
||||||
if(pObj[i].characteristic->ev[conNum]){ // if notifications requested for this characteristic by specified connection number
|
|
||||||
|
|
||||||
if(!notifyFlag) // this is first notification for any characteristic
|
if(!notifyFlag) // this is first notification for any characteristic
|
||||||
hapOut << "{\"characteristics\":["; // print start of JSON array
|
hapOut << "{\"characteristics\":["; // print start of JSON array
|
||||||
else // else already printed at least one other characteristic
|
else // else already printed at least one other characteristic
|
||||||
|
|
@ -1829,8 +1803,6 @@ SpanCharacteristic::SpanCharacteristic(HapChar *hapChar, boolean isCustom){
|
||||||
iid=++(homeSpan.Accessories.back()->iidCount);
|
iid=++(homeSpan.Accessories.back()->iidCount);
|
||||||
service=homeSpan.Accessories.back()->Services.back();
|
service=homeSpan.Accessories.back()->Services.back();
|
||||||
aid=homeSpan.Accessories.back()->aid;
|
aid=homeSpan.Accessories.back()->aid;
|
||||||
|
|
||||||
ev=(boolean *)HS_CALLOC(homeSpan.maxConnections,sizeof(boolean));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
@ -1842,7 +1814,6 @@ SpanCharacteristic::~SpanCharacteristic(){
|
||||||
chr++;
|
chr++;
|
||||||
service->Characteristics.erase(chr);
|
service->Characteristics.erase(chr);
|
||||||
|
|
||||||
free(ev);
|
|
||||||
free(desc);
|
free(desc);
|
||||||
free(unit);
|
free(unit);
|
||||||
free(validValues);
|
free(validValues);
|
||||||
|
|
@ -2116,9 +2087,11 @@ void SpanCharacteristic::printfAttributes(int flags){
|
||||||
|
|
||||||
if(flags&GET_AID)
|
if(flags&GET_AID)
|
||||||
hapOut << ",\"aid\":" << aid;
|
hapOut << ",\"aid\":" << aid;
|
||||||
|
|
||||||
|
HAPClient *hc=&(*(homeSpan.currentClient));
|
||||||
|
|
||||||
if(flags&GET_EV)
|
if(flags&GET_EV)
|
||||||
hapOut << ",\"ev\":" << (ev[HAPClient::conNum]?"true":"false");
|
hapOut << ",\"ev\":" << (evList.has(hc)?"true":"false");
|
||||||
|
|
||||||
if(flags&GET_STATUS)
|
if(flags&GET_STATUS)
|
||||||
hapOut << ",\"status\":0";
|
hapOut << ",\"status\":0";
|
||||||
|
|
@ -2144,7 +2117,12 @@ StatusCode SpanCharacteristic::loadUpdate(char *val, char *ev, boolean wr){
|
||||||
return(StatusCode::NotifyNotAllowed);
|
return(StatusCode::NotifyNotAllowed);
|
||||||
|
|
||||||
LOG1("Notification Request for aid=%u iid=%u: %s\n",aid,iid,evFlag?"true":"false");
|
LOG1("Notification Request for aid=%u iid=%u: %s\n",aid,iid,evFlag?"true":"false");
|
||||||
this->ev[HAPClient::conNum]=evFlag;
|
HAPClient *hc=&(*(homeSpan.currentClient));
|
||||||
|
|
||||||
|
if(evFlag)
|
||||||
|
evList.add(hc);
|
||||||
|
else
|
||||||
|
evList.remove(hc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!val) // no request to update value
|
if(!val) // no request to update value
|
||||||
|
|
@ -2325,6 +2303,25 @@ SpanCharacteristic *SpanCharacteristic::setValidValues(int n, ...){
|
||||||
return(this);
|
return(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
boolean SpanCharacteristic::EVLIST::has(HAPClient *hc){
|
||||||
|
return(find_if(begin(), end(), [hc](const HAPClient *hcTemp){return(hc==hcTemp);}) != end());
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
void SpanCharacteristic::EVLIST::add(HAPClient *hc){
|
||||||
|
if(!has(hc))
|
||||||
|
push_back(hc);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
void SpanCharacteristic::EVLIST::remove(HAPClient *hc){
|
||||||
|
remove_if(begin(), end(), [hc](const HAPClient *hcTemp){return(hc==hcTemp);});
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// SpanButton //
|
// SpanButton //
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,8 @@ struct SpanCharacteristic;
|
||||||
struct SpanBuf;
|
struct SpanBuf;
|
||||||
struct SpanButton;
|
struct SpanButton;
|
||||||
struct SpanUserCommand;
|
struct SpanUserCommand;
|
||||||
|
|
||||||
|
struct HAPClient;
|
||||||
class Controller;
|
class Controller;
|
||||||
|
|
||||||
extern Span homeSpan;
|
extern Span homeSpan;
|
||||||
|
|
@ -263,16 +265,17 @@ class Span{
|
||||||
|
|
||||||
SpanOTA spanOTA; // manages OTA process
|
SpanOTA spanOTA; // manages OTA process
|
||||||
SpanConfig hapConfig; // track configuration changes to the HAP Accessory database; used to increment the configuration number (c#) when changes found
|
SpanConfig hapConfig; // track configuration changes to the HAP Accessory database; used to increment the configuration number (c#) when changes found
|
||||||
vector<SpanAccessory *, Mallocator<SpanAccessory *>> Accessories; // vector of pointers to all Accessories
|
|
||||||
vector<SpanService *, Mallocator<SpanService *>> Loops; // vector of pointer to all Services that have over-ridden loop() methods
|
list<HAPClient, Mallocator<HAPClient>> hapList; // linked-list of HAPClient structures containing HTTP client connections, parsing routines, and state variables
|
||||||
|
list<HAPClient, Mallocator<HAPClient>>::iterator currentClient; // iterator to current client
|
||||||
|
vector<SpanAccessory *, Mallocator<SpanAccessory *>> Accessories; // vector of pointers to all Accessories
|
||||||
|
vector<SpanService *, Mallocator<SpanService *>> Loops; // vector of pointer to all Services that have over-ridden loop() methods
|
||||||
vector<SpanBuf, Mallocator<SpanBuf>> Notifications; // vector of SpanBuf objects that store info for Characteristics that are updated with setVal() and require a Notification Event
|
vector<SpanBuf, Mallocator<SpanBuf>> Notifications; // vector of SpanBuf objects that store info for Characteristics that are updated with setVal() and require a Notification Event
|
||||||
vector<SpanButton *, Mallocator<SpanButton *>> PushButtons; // vector of pointer to all PushButtons
|
vector<SpanButton *, Mallocator<SpanButton *>> PushButtons; // vector of pointer to all PushButtons
|
||||||
unordered_map<uint64_t, uint32_t> TimedWrites; // map of timed-write PIDs and Alarm Times (based on TTLs)
|
unordered_map<uint64_t, uint32_t> TimedWrites; // map of timed-write PIDs and Alarm Times (based on TTLs)
|
||||||
|
unordered_map<char, SpanUserCommand *> UserCommands; // map of pointers to all UserCommands
|
||||||
unordered_map<char, SpanUserCommand *> UserCommands; // map of pointers to all UserCommands
|
|
||||||
|
|
||||||
void pollTask(); // poll HAP Clients and process any new HAP requests
|
void pollTask(); // poll HAP Clients and process any new HAP requests
|
||||||
int getFreeSlot(); // returns free HAPClient slot number. HAPClients slot keep track of each active HAPClient connection
|
|
||||||
void checkConnect(); // check WiFi connection; connect if needed
|
void checkConnect(); // check WiFi connection; connect if needed
|
||||||
void commandMode(); // allows user to control and reset HomeSpan settings with the control button
|
void commandMode(); // allows user to control and reset HomeSpan settings with the control button
|
||||||
void resetStatus(); // resets statusLED and calls statusCallback based on current HomeSpan status
|
void resetStatus(); // resets statusLED and calls statusCallback based on current HomeSpan status
|
||||||
|
|
@ -285,8 +288,8 @@ class Span{
|
||||||
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 updateCharacteristics(char *buf, SpanBuf *pObj); // parses PUT /characteristics JSON request 'buf into 'pObj' and updates referenced characteristics; returns 1 on success, 0 on fail
|
||||||
void printfAttributes(SpanBuf *pObj, int nObj); // writes SpanBuf objects to hapOut stream
|
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
|
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 clearNotify(HAPClient *hc); // clear all notifications related to specific client connection
|
||||||
void printfNotify(SpanBuf *pObj, int nObj, int conNum); // writes notification JSON to hapOut stream based on SpanBuf objects and specified connection number
|
void printfNotify(SpanBuf *pObj, int nObj, HAPClient *hc); // writes notification JSON to hapOut stream based on SpanBuf objects and specified connection
|
||||||
|
|
||||||
static boolean invalidUUID(const char *uuid){
|
static boolean invalidUUID(const char *uuid){
|
||||||
int x=0;
|
int x=0;
|
||||||
|
|
@ -487,6 +490,13 @@ class SpanCharacteristic{
|
||||||
STRING_t STRING = NULL;
|
STRING_t STRING = NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EVLIST : public vector<HAPClient *, Mallocator<HAPClient *>>{ // vector of current connections that have subscribed to EV notifications for this Characteristic
|
||||||
|
public:
|
||||||
|
boolean has(HAPClient *hc); // returns true if pointer to connection hc is subscribed, else returns false
|
||||||
|
void add(HAPClient *hc); // adds connection hc as new subscriber, IF not already a subscriber
|
||||||
|
void remove(HAPClient *hc); // removes connection hc as a subscriber; okay to remove even if hc was not already a subscriber
|
||||||
|
};
|
||||||
|
|
||||||
uint32_t iid=0; // Instance ID (HAP Table 6-3)
|
uint32_t iid=0; // Instance ID (HAP Table 6-3)
|
||||||
HapChar *hapChar; // pointer to HAP Characteristic structure
|
HapChar *hapChar; // pointer to HAP Characteristic structure
|
||||||
const char *type; // Characteristic Type
|
const char *type; // Characteristic Type
|
||||||
|
|
@ -502,7 +512,6 @@ class SpanCharacteristic{
|
||||||
boolean staticRange; // Flag that indicates whether Range is static and cannot be changed with setRange()
|
boolean staticRange; // Flag that indicates whether Range is static and cannot be changed with setRange()
|
||||||
boolean customRange=false; // Flag for custom ranges
|
boolean customRange=false; // Flag for custom ranges
|
||||||
char *validValues=NULL; // Optional JSON array of valid values. Applicable only to uint8 Characteristics
|
char *validValues=NULL; // Optional JSON array of valid values. Applicable only to uint8 Characteristics
|
||||||
boolean *ev; // Characteristic Event Notify Enable (per-connection)
|
|
||||||
char *nvsKey=NULL; // key for NVS storage of Characteristic value
|
char *nvsKey=NULL; // key for NVS storage of Characteristic value
|
||||||
boolean isCustom; // flag to indicate this is a Custom Characteristic
|
boolean isCustom; // flag to indicate this is a Custom Characteristic
|
||||||
boolean setRangeError=false; // flag to indicate attempt to set Range on Characteristic that does not support changes to Range
|
boolean setRangeError=false; // flag to indicate attempt to set Range on Characteristic that does not support changes to Range
|
||||||
|
|
@ -513,7 +522,8 @@ class SpanCharacteristic{
|
||||||
unsigned long updateTime=0; // last time value was updated (in millis) either by PUT /characteristic OR by setVal()
|
unsigned long updateTime=0; // last time value was updated (in millis) either by PUT /characteristic OR by setVal()
|
||||||
UVal newValue; // the updated value requested by PUT /characteristic
|
UVal newValue; // the updated value requested by PUT /characteristic
|
||||||
SpanService *service=NULL; // pointer to Service containing this Characteristic
|
SpanService *service=NULL; // pointer to Service containing this Characteristic
|
||||||
|
EVLIST evList; // vector of current connections that have subscribed to EV notifications for this Characteristic
|
||||||
|
|
||||||
void printfAttributes(int flags); // writes Characteristic JSON to hapOut stream
|
void printfAttributes(int flags); // writes Characteristic JSON to hapOut stream
|
||||||
StatusCode loadUpdate(char *val, char *ev, boolean wr); // load updated val/ev from PUT /characteristic JSON request. Return intitial HAP status code (checks to see if characteristic is found, is writable, etc.)
|
StatusCode loadUpdate(char *val, char *ev, boolean wr); // load updated val/ev from PUT /characteristic JSON request. Return intitial HAP status code (checks to see if characteristic is found, is writable, etc.)
|
||||||
String uvPrint(UVal &u); // returns "printable" String for any type of Characteristic
|
String uvPrint(UVal &u); // returns "printable" String for any type of Characteristic
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue