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.
This commit is contained in:
parent
ee2e850505
commit
74d27485d5
|
|
@ -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.logLevel<minLogLevel)
|
||||
return;
|
||||
|
|
@ -1356,7 +1356,7 @@ void HAPClient::hexPrintColumn(uint8_t *buf, int n, int minLogLevel){
|
|||
|
||||
//////////////////////////////////////
|
||||
|
||||
void HAPClient::hexPrintRow(uint8_t *buf, int n, int minLogLevel){
|
||||
void HAPClient::hexPrintRow(const uint8_t *buf, int n, int minLogLevel){
|
||||
|
||||
if(homeSpan.logLevel<minLogLevel)
|
||||
return;
|
||||
|
|
@ -1367,7 +1367,7 @@ void HAPClient::hexPrintRow(uint8_t *buf, int n, int minLogLevel){
|
|||
|
||||
//////////////////////////////////////
|
||||
|
||||
void HAPClient::charPrintRow(uint8_t *buf, int n, int minLogLevel){
|
||||
void HAPClient::charPrintRow(const uint8_t *buf, int n, int minLogLevel){
|
||||
|
||||
if(homeSpan.logLevel<minLogLevel)
|
||||
return;
|
||||
|
|
@ -1503,6 +1503,9 @@ void HAPClient::printControllers(int minLogLevel){
|
|||
|
||||
void HAPClient::saveControllers(){
|
||||
|
||||
if(homeSpan.controllerCallback)
|
||||
homeSpan.controllerCallback();
|
||||
|
||||
if(controllerList.empty()){
|
||||
nvs_erase_key(homeSpan.hapNVS,"CONTROLLERS");
|
||||
return;
|
||||
|
|
|
|||
26
src/HAP.h
26
src/HAP.h
|
|
@ -63,26 +63,6 @@ struct Nonce {
|
|||
void inc();
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Paired Controller Structure for Permanently-Stored Data
|
||||
|
||||
struct Controller {
|
||||
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[hap_controller_IDBYTES]; // Pairing ID
|
||||
uint8_t LTPK[crypto_sign_PUBLICKEYBYTES]; // Long Term Ed2519 Public Key
|
||||
|
||||
Controller(){}
|
||||
|
||||
Controller(uint8_t *id, uint8_t *ltpk, boolean ad){
|
||||
allocated=true;
|
||||
admin=ad;
|
||||
memcpy(ID,id,hap_controller_IDBYTES);
|
||||
memcpy(LTPK,ltpk,crypto_sign_PUBLICKEYBYTES);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Accessory Structure for Permanently-Stored Data
|
||||
|
||||
|
|
@ -150,9 +130,9 @@ struct HAPClient {
|
|||
|
||||
static void init(); // initialize HAP after start-up
|
||||
|
||||
static void hexPrintColumn(uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as HEX, one byte per row, subject to specified minimum log level
|
||||
static void hexPrintRow(uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as HEX, all on one row, subject to specified minimum log level
|
||||
static void charPrintRow(uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as CHAR, all on one row, subject to specified minimum log level
|
||||
static void hexPrintColumn(const uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as HEX, one byte per row, subject to specified minimum log level
|
||||
static void hexPrintRow(const uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as HEX, all on one row, subject to specified minimum log level
|
||||
static void charPrintRow(const uint8_t *buf, int n, int minLogLevel=0); // prints 'n' bytes of *buf as CHAR, all on one row, subject to specified minimum log level
|
||||
|
||||
static Controller *findController(uint8_t *id); // returns pointer to controller with matching ID (or NULL if no match)
|
||||
static tagError addController(uint8_t *id, uint8_t *ltpk, boolean admin); // stores data for new Controller with specified data. Returns tagError (if any)
|
||||
|
|
|
|||
|
|
@ -611,8 +611,8 @@ void Span::processSerialCommand(const char *c){
|
|||
|
||||
if(hap[i]->cPair){
|
||||
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<Controller, Mallocator<Controller>>::const_iterator Span::controllerListBegin(){
|
||||
return(HAPClient::controllerList.cbegin());
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
list<Controller, Mallocator<Controller>>::const_iterator Span::controllerListEnd(){
|
||||
return(HAPClient::controllerList.cend());
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// SpanAccessory //
|
||||
///////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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<Controller, Mallocator<Controller>>::const_iterator controllerListBegin();
|
||||
list<Controller, Mallocator<Controller>>::const_iterator controllerListEnd();
|
||||
|
||||
[[deprecated("Please use reserveSocketConnections(n) method instead.")]]
|
||||
void setMaxConnections(uint8_t n){requestedMaxCon=n;} // sets maximum number of simultaneous HAP connections
|
||||
|
|
|
|||
242
src/src.ino
242
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;i<sizeof(order)/sizeof(uint32_t);i++){
|
||||
if(i>0)
|
||||
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;i<sizeof(order)/sizeof(uint8_t);i++){
|
||||
if(i>0)
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue