From 74d27485d53e5cd76213adaad11c956f080ac4c4 Mon Sep 17 00:00:00 2001 From: Gregg Date: Sun, 28 Apr 2024 08:15:04 -0500 Subject: [PATCH] Added homeSpan.setControllerCallback() Also adds: homeSpan.controllerListBegin(), homeSpan.controllerListEnd() Also adds: Controller::isAdmin(), Controller::getID(), Controller::getLTPK() To accomplish this, needed to move Controller definition from HAP.h to HomeSpan.h Also, converted Controller from struct to class to ensure Controller data is protected from being modified now that it is exposed through condstant iterators. --- src/HAP.cpp | 9 +- src/HAP.h | 26 +---- src/HomeSpan.cpp | 18 +++- src/HomeSpan.h | 35 +++++++ src/src.ino | 242 +++++------------------------------------------ 5 files changed, 84 insertions(+), 246 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index 417fbcd..e5d6d07 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -1345,7 +1345,7 @@ int HAPClient::receiveEncrypted(uint8_t *httpBuf, int messageSize){ ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// -void HAPClient::hexPrintColumn(uint8_t *buf, int n, int minLogLevel){ +void HAPClient::hexPrintColumn(const uint8_t *buf, int n, int minLogLevel){ if(homeSpan.logLevelcPair){ LOG0(" ID="); - HAPClient::charPrintRow(hap[i]->cPair->ID,36); - LOG0(hap[i]->cPair->admin?" (admin)":" (regular)"); + HAPClient::charPrintRow(hap[i]->cPair->getID(),36); + LOG0(hap[i]->cPair->isAdmin()?" (admin)":" (regular)"); } else { LOG0(" (unverified)"); } @@ -1092,7 +1092,7 @@ void Span::processSerialCommand(const char *c){ reboot(); } else { HAPClient::controllerList.push_back(tCont); - HAPClient::charPrintRow(tCont.ID,36); + HAPClient::charPrintRow(tCont.getID(),36); LOG0("\n"); } } @@ -1658,6 +1658,18 @@ boolean Span::updateDatabase(boolean updateMDNS){ return(changed); } +/////////////////////////////// + +list>::const_iterator Span::controllerListBegin(){ + return(HAPClient::controllerList.cbegin()); +} + +/////////////////////////////// + +list>::const_iterator Span::controllerListEnd(){ + return(HAPClient::controllerList.cend()); +} + /////////////////////////////// // SpanAccessory // /////////////////////////////// diff --git a/src/HomeSpan.h b/src/HomeSpan.h index be024b8..d5b656b 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -113,6 +113,7 @@ struct SpanRange; struct SpanBuf; struct SpanButton; struct SpanUserCommand; +class Controller; extern Span homeSpan; @@ -189,6 +190,35 @@ struct SpanOTA{ // manages OTA process static void error(ota_error_t err); }; + +////////////////////////////////////////////////////////// +// Paired Controller Structure for Permanently-Stored Data + +class Controller { + friend class HAPClient; + + boolean allocated=false; // DEPRECATED (but needed for backwards compatability with original NVS storage of Controller info) + boolean admin; // Controller has admin privileges + uint8_t ID[36]; // Pairing ID + uint8_t LTPK[32]; // Long Term Ed2519 Public Key + + public: + + Controller(uint8_t *id, uint8_t *ltpk, boolean ad){ + allocated=true; + admin=ad; + memcpy(ID,id,36); + memcpy(LTPK,ltpk,32); + } + + Controller(){} + + const uint8_t *getID() const {return(ID);} + const uint8_t *getLTPK() const {return(LTPK);} + boolean isAdmin() const {return(admin);} + +}; + ////////////////////////////////////// // USER API CLASSES BEGINS HERE // ////////////////////////////////////// @@ -250,6 +280,7 @@ class Span{ void (*apFunction)()=NULL; // optional function to invoke when starting Access Point void (*statusCallback)(HS_STATUS status)=NULL; // optional callback when HomeSpan status changes void (*rebootCallback)(uint8_t)=NULL; // optional callback when device reboots + void (*controllerCallback)()=NULL; // optional callback when Controller is added/removed/changed WiFiServer *hapServer; // pointer to the HAP Server connection Blinker *statusLED; // indicates HomeSpan status @@ -355,6 +386,7 @@ class Span{ Span& setPairingCode(const char *s, boolean progCall=true); // sets the Pairing Code - use is NOT recommended. Use 'S' from CLI instead void deleteStoredValues(){processSerialCommand("V");} // deletes stored Characteristic values from NVS Span& resetIID(uint32_t newIID); // resets the IID count for the current Accessory to start at newIID + Span& setControllerCallback(void (*f)()){controllerCallback=f;return(*this);} // sets an optional user-defined function to call whenever a Controller is added/removed/changed int enableOTA(boolean auth=true, boolean safeLoad=true){return(spanOTA.init(auth, safeLoad, NULL));} // enables Over-the-Air updates, with (auth=true) or without (auth=false) authorization password int enableOTA(const char *pwd, boolean safeLoad=true){return(spanOTA.init(true, safeLoad, pwd));} // enables Over-the-Air updates, with custom authorization password (overrides any password stored with the 'O' command) @@ -393,6 +425,9 @@ class Span{ TaskHandle_t getAutoPollTask(){return(pollTaskHandle);} Span& setTimeServerTimeout(uint32_t tSec){webLog.waitTime=tSec*1000;return(*this);} // sets wait time (in seconds) for optional web log time server to connect + + list>::const_iterator controllerListBegin(); + list>::const_iterator controllerListEnd(); [[deprecated("Please use reserveSocketConnections(n) method instead.")]] void setMaxConnections(uint8_t n){requestedMaxCon=n;} // sets maximum number of simultaneous HAP connections diff --git a/src/src.ino b/src/src.ino index 44be4ec..13e2f91 100644 --- a/src/src.ino +++ b/src/src.ino @@ -27,227 +27,21 @@ #include "HomeSpan.h" -CUSTOM_CHAR_DATA(TestData,333,PR+EV); - -struct HomeSpanTV : Service::Television { - - SpanCharacteristic *active = new Characteristic::Active(0); // TV On/Off (set to Off at start-up) - SpanCharacteristic *activeID = new Characteristic::ActiveIdentifier(3); // Sets HDMI 3 on start-up - SpanCharacteristic *remoteKey = new Characteristic::RemoteKey(); // Used to receive button presses from the Remote Control widget - SpanCharacteristic *settingsKey = new Characteristic::PowerModeSelection(); // Adds "View TV Setting" option to Selection Screen - SpanCharacteristic *displayOrder = new Characteristic::DisplayOrder(); - SpanCharacteristic *testData = new Characteristic::TestData(); - SpanCharacteristic *tvname; - - HomeSpanTV(const char *name) : Service::Television() { - tvname = new Characteristic::ConfiguredName(name); // Name of TV - Serial.printf("Configured TV: %s\n",name); - - TLV8 orderTLV; - uint32_t order[]={5,10,6,2,1,9,11,3,18,12}; - - for(int i=0;i0) - orderTLV.add(6); - orderTLV.add(1,sizeof(uint32_t),(uint8_t*)(order+i)); - } - - orderTLV.print(); - displayOrder->setTLV(orderTLV); - - uint8_t blob[]={1,2,3,4,5,6,7,8,9,10,11,12}; -// testData->setData(blob,sizeof(blob)); - testData->setData(blob,1); - - new SpanUserCommand('P', "- change order of inputs", changeOrder, this); - new SpanUserCommand('C', "- change name of TV", setTVName, this); - } - - boolean update() override { - - if(active->updated()){ - Serial.printf("Set TV Power to: %s\n",active->getNewVal()?"ON":"OFF"); - } - - if(activeID->updated()){ - Serial.printf("Set Input Source to HDMI-%d\n",activeID->getNewVal()); - } - - if(settingsKey->updated()){ - Serial.printf("Received request to \"View TV Settings\"\n"); - } - - if(remoteKey->updated()){ - Serial.printf("Remote Control key pressed: "); - switch(remoteKey->getNewVal()){ - case 4: - Serial.printf("UP ARROW\n"); - break; - case 5: - Serial.printf("DOWN ARROW\n"); - break; - case 6: - Serial.printf("LEFT ARROW\n"); - break; - case 7: - Serial.printf("RIGHT ARROW\n"); - break; - case 8: - Serial.printf("SELECT\n"); - break; - case 9: - Serial.printf("BACK\n"); - break; - case 11: - Serial.printf("PLAY/PAUSE\n"); - break; - case 15: - Serial.printf("INFO\n"); - break; - default: - Serial.print("UNKNOWN KEY\n"); - } - } - - return(true); - } - - static void setTVName(const char *buf, void *arg){ - HomeSpanTV *hsTV=(HomeSpanTV *)arg; - hsTV->tvname->setString("New Name"); - Serial.printf("Reset TV Name to '%s'\n",hsTV->tvname->getString()); - Serial.printf("Showing displayOrder '%s'\n",hsTV->displayOrder->getString()); - } - - static void changeOrder(const char *buf, void *arg){ - HomeSpanTV *hsTV=(HomeSpanTV *)arg; - - TLV8 orderTLV; - - hsTV->displayOrder->getTLV(orderTLV); - orderTLV.print(); - orderTLV.wipe(); - - uint8_t order[]={12,10,6,2,1,9,11,3,18,5}; - - for(int i=0;i0) - orderTLV.add(0); - orderTLV.add(1,sizeof(uint8_t),(uint8_t*)(order+i)); - } - - Serial.printf("AFTER:\n"); - orderTLV.print(); - size_t n=orderTLV.pack_size(); - Serial.printf("Size=%d\n",n); - uint8_t c[n]; - orderTLV.pack(c); - hsTV->displayOrder->setData(c,n); - } - -}; - -/////////////////////////////// - void setup() { - + Serial.begin(115200); - homeSpan.setLogLevel(2); - - homeSpan.begin(Category::Television,"HomeSpan Television"); + homeSpan.begin(Category::Lighting,"HomeSpan Light"); + + new SpanAccessory(); + new Service::AccessoryInformation(); + new Characteristic::Identify(); + new Service::LightBulb(); + new Characteristic::On(); - SPAN_ACCESSORY(); - - SpanService *hdmi1 = new Service::InputSource(); // Source included in Selection List, but excluded from Settings Screen - new Characteristic::ConfiguredName("Alpha"); - new Characteristic::Identifier(5); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *hdmi2 = new Service::InputSource(); - new Characteristic::ConfiguredName("Gamma"); - new Characteristic::Identifier(10); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *hdmi3 = new Service::InputSource(); - new Characteristic::ConfiguredName("Beta"); - new Characteristic::Identifier(6); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *hdmi4 = new Service::InputSource(); - new Characteristic::ConfiguredName("Zebra"); - new Characteristic::Identifier(2); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *hdmi5 = new Service::InputSource(); - new Characteristic::ConfiguredName("Delta"); - new Characteristic::Identifier(1); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *hdmi6 = new Service::InputSource(); - new Characteristic::ConfiguredName("Trident"); - new Characteristic::Identifier(9); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *hdmi7 = new Service::InputSource(); - new Characteristic::ConfiguredName("Netflix"); - new Characteristic::Identifier(11); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *hdmi8 = new Service::InputSource(); - new Characteristic::ConfiguredName("Alpha2"); - new Characteristic::Identifier(3); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *hdmi9 = new Service::InputSource(); - new Characteristic::ConfiguredName("Moon"); - new Characteristic::Identifier(18); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *hdmi10 = new Service::InputSource(); - new Characteristic::ConfiguredName("Gamba"); - new Characteristic::Identifier(12); - new Characteristic::IsConfigured(1); - new Characteristic::CurrentVisibilityState(0); - new Characteristic::TargetVisibilityState(0); - - SpanService *speaker = new Service::TelevisionSpeaker(); - new Characteristic::VolumeSelector(); - new Characteristic::VolumeControlType(3); - - (new HomeSpanTV("Test TV")) // Define a Television Service. Must link in InputSources! - ->addLink(hdmi1) - ->addLink(hdmi2) - ->addLink(hdmi3) - ->addLink(hdmi4) - ->addLink(hdmi5) - ->addLink(hdmi6) - ->addLink(hdmi7) - ->addLink(hdmi8) - ->addLink(hdmi9) - ->addLink(hdmi10) - ->addLink(speaker) - ; - -} +// new SpanUserCommand('k',"- list controllers",list_controllers); + homeSpan.setControllerCallback(list_controllers); +} ////////////////////////////////////// @@ -258,3 +52,17 @@ 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"); + } +}