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"); + } +}