#include #include "Settings.h" using std::vector; enum statusCode { // HAP Table 6-11 SC_OK=0, SC_Unable=-70402, SC_Busy=-70403, SC_ReadOnly=-70404, SC_WriteOnly=-70405, SC_NotifyNotAllowed=-70406, SC_UnknownResource=-70409, SC_InvalidValue=-70410, SC_TBD=-1 // status To-Be-Determined (TBD) once service.update() called }; enum { GET_AID=1, GET_META=2, GET_PERMS=4, GET_TYPE=8, GET_EV=16, GET_DESC=32, GET_ALL=255 }; // Forward-Declarations struct Span; struct SpanAccessory; struct SpanService; struct SpanCharacteristic; struct SpanRange; struct SpanPut; struct SpanPBList; /////////////////////////////// struct SpanConfig { int configNumber=0; // configuration number - broadcast as Bonjour "c#" (computed automatically) uint8_t hashCode[48]={0}; // SHA-384 hash of Span Database stored as a form of unique "signature" to know when to update the config number upon changes }; /////////////////////////////// struct Span{ char *displayName; // display name for this device - broadcast as part of Bonjour MDNS char *hostNameBase; // base of host name of this device - full host name broadcast by Bonjour MDNS will have 6-byte accessoryID as well as '.local' automatically appended char *modelName; // model name of this device - broadcast as Bonjour field "md" char category[3]=""; // category ID of primary accessory - broadcast as Bonjour field "ci" (HAP Section 13) int resetPin=21; // drive this pin low to "factory" reset NVS data on start-up SpanPBList *pbHead=NULL; // head of linked-list of characteristics to auto-turnoff after they are turned on (to emulate a single-shot PushButton) SpanConfig hapConfig; // track configuration changes to the HAP Accessory database; used to increment the configuration number (c#) when changes found vector Accessories; // vector of pointers to all Accessories void begin(Category catID, char *displayName="HomeSpan Server", char *hostNameBase="homespan", char *modelName="HS-ESP32"); void poll(); // 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 initWifi(); // initialize and connect to WiFi network void processSerialCommand(char *c); // process command 'c' (typically from readSerial, though can be called with any 'c') int sprintfAttributes(char *cBuf); // prints Attributes JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL void prettyPrint(char *buf, int nsp=2); // print arbitrary JSON from buf to serial monitor, formatted with indentions of 'nsp' spaces SpanCharacteristic *find(int 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, SpanPut *pObj); // parses PUT /characteristics JSON request 'buf into 'pObj' and updates referenced characteristics; returns 1 on success, 0 on fail int sprintfAttributes(SpanPut *pObj, int nObj, char *cBuf); // prints SpanPut 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 clearNotify(int slotNum); // set ev notification flags for connection 'slotNum' to false across all characteristics int sprintfNotify(SpanPut *pObj, int nObj, char *cBuf, int conNum, int &numNotify); // prints notification JSON into buf based on SpanPut objects and specified connection number void setResetPin(int pin){resetPin=pin;} // sets new pin to be used for factory reset }; /////////////////////////////// struct SpanAccessory{ int aid=0; // Accessory Instance ID (HAP Table 6-1) int iidCount=0; // running count of iid to use for Services and Characteristics associated with this Accessory vector Services; // vector of pointers to all Services in this Accessory SpanAccessory(); int sprintfAttributes(char *cBuf); // prints Accessory JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL }; /////////////////////////////// struct SpanService{ int iid=0; // Instance ID (HAP Table 6-2) const char *type; // Service Type boolean hidden=false; // optional property indicating service is hidden boolean primary=false; // optional property indicating service is primary vector Characteristics; // vector of pointers to all Characteristics in this Service SpanService(const char *type, ServiceType mod=ServiceType::Regular); int sprintfAttributes(char *cBuf); // prints Service JSON records into buf; return number of characters printed, excluding null terminator virtual statusCode update() {return(SC_OK);} // update Service and return final statusCode based on updated Characteristics - should be overridden by DEVICE-SPECIFIC Services }; /////////////////////////////// struct SpanCharacteristic{ enum { // create bitflags based on HAP Table 6-4 PR=1, PW=2, EV=4, AA=8, TW=16, HD=32, WR=64 }; enum FORMAT { // HAP Table 6-5 BOOL, UINT8, UINT16, UINT32, UINT64, INT, FLOAT, STRING }; union UVal { boolean BOOL; uint8_t UINT8; uint16_t UINT16; uint32_t UINT32; uint64_t UINT64; int32_t INT; double FLOAT; const char *STRING; }; int iid=0; // Instance ID (HAP Table 6-3) char *type; // Characteristic Type UVal value; // Characteristic Value uint8_t perms; // Characteristic Permissions 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) 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 UVal newValue; // the updated value requested by PUT /characteristic SpanService *service=NULL; // pointer to Service containing this Characteristic SpanCharacteristic(char *type, uint8_t perms); SpanCharacteristic(char *type, uint8_t perms, boolean value); SpanCharacteristic(char *type, uint8_t perms, uint8_t value); SpanCharacteristic(char *type, uint8_t perms, uint16_t value); SpanCharacteristic(char *type, uint8_t perms, uint32_t value); SpanCharacteristic(char *type, uint8_t perms, uint64_t value); SpanCharacteristic(char *type, uint8_t perms, int32_t value); SpanCharacteristic(char *type, uint8_t perms, double value); SpanCharacteristic(char *type, uint8_t perms, const char* value); int sprintfAttributes(char *cBuf, int flags); // prints Characteristic JSON records into buf, according to flags mask; return number of characters printed, excluding null terminator statusCode loadUpdate(char *val, char *ev); // load updated val/ev from PUT /characteristic JSON request. Return intiial HAP status code (checks to see if characteristic is found, is writable, etc.) void autoOff(int waitTime=250); // turns Characteristic off (false) automatically after waitTime milliseconds; only applicable to BOOL characteristics }; /////////////////////////////// struct SpanRange{ int min; int max; int step; SpanRange(int _min, int _max, int _step) : min{_min}, max{_max}, step{_step} {}; }; /////////////////////////////// struct SpanPut{ // storage to process PUT /characteristics request int aid; // aid to update int iid; // iid to update char *val=NULL; // updated value (optional, though either at least 'val' or 'ev' must be specified) char *ev=NULL; // updated event notification flag (optional, though either at least 'val' or 'ev' must be specified) statusCode status; // return status (HAP Table 6-11) SpanCharacteristic *characteristic=NULL; // Characteristic to update (NULL if not found) }; /////////////////////////////// struct SpanPBList{ SpanPBList *next=NULL; // next item in linked-list SpanCharacteristic *characteristic; // characteristic to auto-turnoff whenever activated int waitTime; // time to wait until auto-turnoff (in milliseconds) unsigned long alarmTime; // alarm time for trigger to auto-turnoff boolean start=false; // alarm timer started boolean trigger=false; // alarm timer triggered }; ///////////////////////////////////////////////// // Extern Variables extern Span homeSpan; ///////////////////////////////////////////////// #include "Services.h"