diff --git a/src/HAP.cpp b/src/HAP.cpp index 04c9d8f..75233ab 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -1741,7 +1741,7 @@ nvs_handle HAPClient::srpNVS; HKDF HAPClient::hkdf; pairState HAPClient::pairStatus; Accessory HAPClient::accessory; -list HAPClient::controllerList; +list> HAPClient::controllerList; SRP6A HAPClient::srp; int HAPClient::conNum; diff --git a/src/HAP.h b/src/HAP.h index 3df5230..a7c9a1a 100644 --- a/src/HAP.h +++ b/src/HAP.h @@ -94,7 +94,7 @@ struct HAPClient { static pairState pairStatus; // tracks pair-setup status static SRP6A srp; // stores all SRP-6A keys used for Pair-Setup static Accessory accessory; // Accessory ID and Ed25519 public and secret keys- permanently stored - static list controllerList; // linked-list of Paired Controller IDs and ED25519 long-term public keys - permanently stored + static list> 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 diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index e1684ef..18a2051 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -69,7 +69,7 @@ void Span::begin(Category catID, const char *displayName, const char *hostNameBa if(requestedMaxCon aidValues; + vector> aidValues; char pNames[][7]={"PR","PW","EV","AA","TW","HD","WR"}; for(auto acc=Accessories.begin(); acc!=Accessories.end(); acc++){ @@ -1825,7 +1829,7 @@ SpanCharacteristic::SpanCharacteristic(HapChar *hapChar, boolean isCustom){ service=homeSpan.Accessories.back()->Services.back(); aid=homeSpan.Accessories.back()->aid; - ev=(boolean *)calloc(homeSpan.maxConnections,sizeof(boolean)); + ev=(boolean *)HS_CALLOC(homeSpan.maxConnections,sizeof(boolean)); } /////////////////////////////// @@ -2152,7 +2156,7 @@ void SpanWebLog::init(uint16_t maxEntries, const char *serv, const char *tz, con timeServer=serv; timeZone=tz; statusURL="GET /" + String(url) + " "; - log = (log_t *)calloc(maxEntries,sizeof(log_t)); + log = (log_t *)HS_CALLOC(maxEntries,sizeof(log_t)); if(timeServer) homeSpan.reserveSocketConnections(1); } @@ -2492,7 +2496,7 @@ void SpanPoint::dataReceived(const uint8_t *mac, const uint8_t *incomingData, in uint8_t SpanPoint::lmk[16]; boolean SpanPoint::initialized=false; boolean SpanPoint::isHub=false; -vector SpanPoint::SpanPoints; +vector> SpanPoint::SpanPoints; uint16_t SpanPoint::channelMask=0x3FFE; QueueHandle_t SpanPoint::statusQueue; nvs_handle SpanPoint::pointNVS; diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 00636d0..80dc1f6 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -31,6 +31,14 @@ #error ERROR: HOMESPAN IS ONLY AVAILABLE FOR ESP32 MICROCONTROLLERS! #endif +#if defined(BOARD_HAS_PSRAM) +#define HS_MALLOC ps_malloc +#define HS_CALLOC ps_calloc +#else +#define HS_MALLOC malloc +#define HS_CALLOC calloc +#endif + #pragma GCC diagnostic ignored "-Wpmf-conversions" // eliminates warning messages from use of pointers to member functions to detect whether update() and loop() are overridden by user #pragma GCC diagnostic ignored "-Wunused-result" // eliminates warning message regarded unused result from call to crypto_scalarmult_curve25519() @@ -69,6 +77,25 @@ enum { /////////////////////////////// +template +struct Mallocator { + typedef T value_type; + Mallocator() = default; + template constexpr Mallocator(const Mallocator&) noexcept {} + [[nodiscard]] T* allocate(std::size_t n) { + if(n > std::size_t(-1) / sizeof(T)) throw std::bad_alloc(); + if(auto p = static_cast(HS_MALLOC(n*sizeof(T)))) return p; + throw std::bad_alloc(); + } + void deallocate(T* p, std::size_t) noexcept { std::free(p); } +}; +template +bool operator==(const Mallocator&, const Mallocator&) { return true; } +template +bool operator!=(const Mallocator&, const Mallocator&) { return false; } + +/////////////////////////////// + #define STATUS_UPDATE(LED_UPDATE,MESSAGE_UPDATE) {homeSpan.statusLED->LED_UPDATE;if(homeSpan.statusCallback)homeSpan.statusCallback(MESSAGE_UPDATE);} enum HS_STATUS { @@ -251,10 +278,10 @@ class Span{ 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 - vector Accessories; // vector of pointers to all Accessories - vector Loops; // vector of pointer to all Services that have over-ridden loop() methods - vector Notifications; // vector of SpanBuf objects that store info for Characteristics that are updated with setVal() and require a Notification Event - vector PushButtons; // vector of pointer to all PushButtons + vector> Accessories; // vector of pointers to all Accessories + vector> Loops; // vector of pointer to all Services that have over-ridden loop() methods + vector> Notifications; // vector of SpanBuf objects that store info for Characteristics that are updated with setVal() and require a Notification Event + vector> PushButtons; // vector of pointer to all PushButtons unordered_map TimedWrites; // map of timed-write PIDs and Alarm Times (based on TTLs) unordered_map UserCommands; // map of pointers to all UserCommands @@ -387,7 +414,7 @@ class SpanAccessory{ uint32_t 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 + vector> Services; // vector of pointers to all Services in this Accessory int sprintfAttributes(char *cBuf, int flags); // prints Accessory JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL @@ -414,8 +441,8 @@ class SpanService{ const char *hapName; // HAP Name 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 - vector linkedServices; // vector of pointers to any optional linked Services + vector> Characteristics; // vector of pointers to all Characteristics in this Service + vector> linkedServices; // vector of pointers to any optional linked Services boolean isCustom; // flag to indicate this is a Custom Service SpanAccessory *accessory=NULL; // pointer to Accessory containing this Service @@ -424,8 +451,8 @@ class SpanService{ protected: virtual ~SpanService(); // destructor - vector req; // vector of pointers to all required HAP Characteristic Types for this Service - vector opt; // vector of pointers to all optional HAP Characteristic Types for this Service + vector> req; // vector of pointers to all required HAP Characteristic Types for this Service + vector> opt; // vector of pointers to all optional HAP Characteristic Types for this Service public: @@ -433,7 +460,7 @@ class SpanService{ SpanService *setPrimary(); // sets the Service Type to be primary and returns pointer to self SpanService *setHidden(); // sets the Service Type to be hidden and returns pointer to self SpanService *addLink(SpanService *svc); // adds svc as a Linked Service and returns pointer to self - vector getLinks(){return(linkedServices);} // returns linkedServices vector for use as range in "for-each" loops + vector> getLinks(){return(linkedServices);} // returns linkedServices vector for use as range in "for-each" loops virtual boolean update() {return(true);} // placeholder for code that is called when a Service is updated via a Controller. Must return true/false depending on success of update virtual void loop(){} // loops for each Service - called every cycle if over-ridden with user-defined code @@ -589,7 +616,7 @@ class SpanCharacteristic{ uvSet(value,val); if(nvsStore){ - nvsKey=(char *)malloc(16); + nvsKey=(char *)HS_MALLOC(16); uint16_t t; sscanf(type,"%hx",&t); sprintf(nvsKey,"%04X%08X%03X",t,aid,iid&0xFFF); @@ -901,7 +928,7 @@ class SpanPoint { static uint8_t lmk[16]; static boolean initialized; static boolean isHub; - static vector SpanPoints; + static vector> SpanPoints; static uint16_t channelMask; // channel mask (only used for remote devices) static QueueHandle_t statusQueue; // queue for communication between SpanPoint::dataSend and SpanPoint::send static nvs_handle pointNVS; // NVS storage for channel number (only used for remote devices) diff --git a/src/Network.cpp b/src/Network.cpp index 5d69ad2..c620d92 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -40,7 +40,7 @@ void Network::scan(){ int n=WiFi.scanNetworks(); free(ssidList); - ssidList=(char **)calloc(n,sizeof(char *)); + ssidList=(char **)HS_CALLOC(n,sizeof(char *)); numSSID=0; for(int i=0;i::create(tagType tag, int maxLen, const char *name){ tlv[numTags].maxLen=maxLen; tlv[numTags].name=name; tlv[numTags].len=-1; - tlv[numTags].val=(uint8_t *)malloc(maxLen); + tlv[numTags].val=(uint8_t *)HS_MALLOC(maxLen); numTags++; return(1); diff --git a/src/Utils.h b/src/Utils.h index 4272494..dbe0bae 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -30,6 +30,14 @@ #include #include +#if defined(BOARD_HAS_PSRAM) +#define HS_MALLOC ps_malloc +#define HS_CALLOC ps_calloc +#else +#define HS_MALLOC malloc +#define HS_CALLOC calloc +#endif + namespace Utils { char *readSerial(char *c, int max); // read serial port into 'c' until , but storing only first 'max' characters (the rest are discarded) @@ -54,7 +62,7 @@ class TempBuffer { TempBuffer(int _nElements) : nElements(_nElements) { nBytes=nElements*sizeof(bufType); - buf=(bufType *)malloc(nBytes); + buf=(bufType *)HS_MALLOC(nBytes); if(buf==NULL){ Serial.print("\n\n*** FATAL ERROR: Requested allocation of "); Serial.print(nBytes); diff --git a/src/src.ino b/src/src.ino index eecb04f..76fbe9d 100644 --- a/src/src.ino +++ b/src/src.ino @@ -25,101 +25,39 @@ * ********************************************************************************/ + #include "HomeSpan.h" -struct LED_Service : Service::LightBulb { - - int ledPin; - SpanCharacteristic *power; - - LED_Service(int ledPin) : Service::LightBulb(){ - power=new Characteristic::On(); - this->ledPin=ledPin; - pinMode(ledPin,OUTPUT); - } - - boolean update(){ - digitalWrite(ledPin,power->getNewVal()); - WEBLOG("Power = %s",power->getNewVal()?"ON":"OFF"); - return(true); - } - -}; - -////////////////////////////////////// - -void extraData(String &r){ - r+="Free DRAM:" + String(esp_get_free_internal_heap_size()) + " bytes\n"; - r+="

Click Here to Access HomeSpan Repo

"; -} - -////////////////////////////////////// - void setup() { - + Serial.begin(115200); -// homeSpan.setHostNameSuffix(""); + homeSpan.setLogLevel(2); -// homeSpan.setControlPin(21); + homeSpan.begin(Category::Lighting,"HomeSpan Max"); - homeSpan.setLogLevel(2).enableWebLog(500).setWebLogCallback(extraData); -// homeSpan.reserveSocketConnections(10); - -// homeSpan.setApSSID("HS_Setup"); -// homeSpan.setApPassword(""); + new(HS_MALLOC(sizeof(SpanAccessory))) SpanAccessory(); + new(HS_MALLOC(sizeof(SpanService))) Service::AccessoryInformation(); + new(HS_MALLOC(sizeof(SpanCharacteristic))) Characteristic::Identify(); -// .setStatusPin(13); -// homeSpan.setSerialInputDisable(true); -// homeSpan.enableOTA(); - - homeSpan.setWifiCallback(wifiCB); - homeSpan.setWifiCallbackAll(wifiCB_ALL).setVerboseWifiReconnect(true); - homeSpan.setRebootCallback( [](uint8_t c) {if(c==3) homeSpan.processSerialCommand("X");} ); - - - new SpanUserCommand('D', " - disconnect WiFi", [](const char *buf){WiFi.disconnect();}); - - homeSpan.begin(Category::Lighting,"HomeSpan LED"); - - new SpanAccessory(); - new Service::AccessoryInformation(); - new Characteristic::Identify(); - new LED_Service(13); - -// homeSpan.autoPoll(); - -// for(int i=0;i<300;i++) -// WEBLOG("Here is some text of a log file %d",i); - -} - -////////////////////////////////////// - -void loop(){ - homeSpan.poll(); -//delay(10000); -//Serial.println(millis()); - -} - -////////////////////////////////////// - -void wifiCB(){ - Serial.printf("\n\n****** IN WIFI CALLBACK *******\n\n"); -} - -////////////////////////////////////// - -void wifiCB_ALL(int n){ - Serial.printf("\n\n****** IN WIFI CALLBACK ALL. Count=%d *******\n\n",n); -} - -////////////////////////////////////// - -void rebootCB(uint8_t count){ - if(count>=3){ - Serial.printf("\n*** Detected 3 or more short reboots. Erasing WiFi data...\n"); - homeSpan.processSerialCommand("X"); + for(int i=0;i<80;i++){ + new(HS_MALLOC(sizeof(SpanAccessory))) SpanAccessory(); + new(HS_MALLOC(sizeof(SpanService))) Service::AccessoryInformation(); + new(HS_MALLOC(sizeof(SpanCharacteristic))) Characteristic::Identify(); + char c[30]; + sprintf(c,"Light-%d",i); + new(HS_MALLOC(sizeof(SpanCharacteristic))) Characteristic::Name(c); + new(HS_MALLOC(sizeof(SpanService))) Service::LightBulb(); + new(HS_MALLOC(sizeof(SpanCharacteristic))) Characteristic::On(); + new(HS_MALLOC(sizeof(SpanCharacteristic))) Characteristic::Brightness(); } + +} + +////////////////////////////////////// + +void loop(){ + + homeSpan.poll(); + }