Created SpanPoint
Verified ESP-NOW is communicating correctly with HomeSpan. Verified encryption works. Next step - create linkages between incoming data and Services; create queue structure to transfer data.
This commit is contained in:
parent
22cfa130b4
commit
4f983051ce
|
|
@ -31,10 +31,10 @@
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <driver/ledc.h>
|
#include <driver/ledc.h>
|
||||||
#include <mbedtls/version.h>
|
#include <mbedtls/version.h>
|
||||||
|
#include <mbedtls/sha256.h>
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
#include <esp_sntp.h>
|
#include <esp_sntp.h>
|
||||||
#include <esp_ota_ops.h>
|
#include <esp_ota_ops.h>
|
||||||
#include <esp_now.h>
|
|
||||||
|
|
||||||
#include "HomeSpan.h"
|
#include "HomeSpan.h"
|
||||||
#include "HAP.h"
|
#include "HAP.h"
|
||||||
|
|
@ -140,11 +140,7 @@ void Span::begin(Category catID, const char *displayName, const char *hostNameBa
|
||||||
Serial.print(__TIME__);
|
Serial.print(__TIME__);
|
||||||
|
|
||||||
Serial.printf("\nPartition: %s",esp_ota_get_running_partition()->label);
|
Serial.printf("\nPartition: %s",esp_ota_get_running_partition()->label);
|
||||||
|
Serial.printf("\nMAC Address: %s",WiFi.macAddress().c_str());
|
||||||
if(espNowEnabled){
|
|
||||||
esp_now_init(); // initialize ESP NOW
|
|
||||||
Serial.print("\nESP-NOW: ENABLED");
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.print("\n\nDevice Name: ");
|
Serial.print("\n\nDevice Name: ");
|
||||||
Serial.print(displayName);
|
Serial.print(displayName);
|
||||||
|
|
@ -449,7 +445,6 @@ void Span::checkConnect(){
|
||||||
connected++;
|
connected++;
|
||||||
|
|
||||||
addWebLog(true,"WiFi Connected! IP Address = %s",WiFi.localIP().toString().c_str());
|
addWebLog(true,"WiFi Connected! IP Address = %s",WiFi.localIP().toString().c_str());
|
||||||
Serial.printf("MAC Address = %s, Channel = %d\n",WiFi.macAddress().c_str(),WiFi.channel());
|
|
||||||
|
|
||||||
if(connected>1) // Do not initialize everything below if this is only a reconnect
|
if(connected>1) // Do not initialize everything below if this is only a reconnect
|
||||||
return;
|
return;
|
||||||
|
|
@ -2155,6 +2150,57 @@ void SpanOTA::error(ota_error_t err){
|
||||||
else if (err == OTA_END_ERROR) Serial.println("End Failed\n");
|
else if (err == OTA_END_ERROR) Serial.println("End Failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// SpanPoint //
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
SpanPoint::SpanPoint(const char *macAddress){
|
||||||
|
|
||||||
|
if(homeSpan.Accessories.empty() || homeSpan.Accessories.back()->Services.empty()){
|
||||||
|
Serial.printf("\nFATAL ERROR! Can't create new SpanPoint(\"%s\") without a defined Service ***\n",macAddress);
|
||||||
|
Serial.printf("\n=== PROGRAM HALTED ===");
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
if(sscanf(macAddress,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",peerInfo.peer_addr,peerInfo.peer_addr+1,peerInfo.peer_addr+2,peerInfo.peer_addr+3,peerInfo.peer_addr+4,peerInfo.peer_addr+5)!=6){
|
||||||
|
Serial.printf("\nFATAL ERROR! Can't create new SpanPoint(\"%s\") - Invalid MAC Address ***\n",macAddress);
|
||||||
|
Serial.printf("\n=== PROGRAM HALTED ===");
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
peerInfo.channel=0; // 0=matches current WiFi channel
|
||||||
|
peerInfo.ifidx=WIFI_IF_STA; // must specify interface
|
||||||
|
peerInfo.encrypt=true; // turn on encryption for this peer
|
||||||
|
memcpy(peerInfo.lmk, lmk, 16); // set local key
|
||||||
|
esp_now_add_peer(&peerInfo); // add peer to ESP-NOW
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
void SpanPoint::init(const char *password){
|
||||||
|
|
||||||
|
if(initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint8_t hash[32];
|
||||||
|
mbedtls_sha256_ret((const unsigned char *)password,strlen(password),hash,0); // produce 256-bit bit hash from password
|
||||||
|
|
||||||
|
esp_now_init(); // initialize ESP-NOW
|
||||||
|
memcpy(lmk, hash, 16); // store first 16 bytes of hash for later use as local key
|
||||||
|
esp_now_set_pmk(hash+16); // set hash for primary key using last 16 bytes of hash
|
||||||
|
esp_now_register_recv_cb(dataReceived); // set callback for receiving data
|
||||||
|
|
||||||
|
initialized=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
void SpanPoint::dataReceived(const uint8_t *mac, const uint8_t *incomingData, int len){
|
||||||
|
Serial.printf("SpanPoint: %d bytes received from %02X:%02X:%02X:%02X:%02X:%02X\n",len,mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
void __attribute__((weak)) loop(){
|
void __attribute__((weak)) loop(){
|
||||||
|
|
@ -2166,5 +2212,7 @@ int SpanOTA::otaPercent;
|
||||||
boolean SpanOTA::safeLoad;
|
boolean SpanOTA::safeLoad;
|
||||||
boolean SpanOTA::enabled=false;
|
boolean SpanOTA::enabled=false;
|
||||||
boolean SpanOTA::auth;
|
boolean SpanOTA::auth;
|
||||||
|
uint8_t SpanPoint::lmk[16];
|
||||||
|
boolean SpanPoint::initialized=false;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <nvs.h>
|
#include <nvs.h>
|
||||||
#include <ArduinoOTA.h>
|
#include <ArduinoOTA.h>
|
||||||
|
#include <esp_now.h>
|
||||||
|
|
||||||
#include "extras/Blinker.h"
|
#include "extras/Blinker.h"
|
||||||
#include "extras/Pixel.h"
|
#include "extras/Pixel.h"
|
||||||
|
|
@ -155,6 +156,25 @@ struct SpanOTA{ // manages OTA process
|
||||||
// USER API CLASSES BEGINS HERE //
|
// USER API CLASSES BEGINS HERE //
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
||||||
|
class SpanPoint {
|
||||||
|
|
||||||
|
friend class Span;
|
||||||
|
|
||||||
|
esp_now_peer_info_t peerInfo;
|
||||||
|
|
||||||
|
static uint8_t lmk[16];
|
||||||
|
static boolean initialized;
|
||||||
|
|
||||||
|
static void dataReceived(const uint8_t *mac, const uint8_t *incomingData, int len);
|
||||||
|
static void init(const char *password="HomeSpan");
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SpanPoint(const char *macAddress);
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
class Span{
|
class Span{
|
||||||
|
|
||||||
friend class SpanAccessory;
|
friend class SpanAccessory;
|
||||||
|
|
@ -167,6 +187,7 @@ class Span{
|
||||||
friend class SpanOTA;
|
friend class SpanOTA;
|
||||||
friend class Network;
|
friend class Network;
|
||||||
friend class HAPClient;
|
friend class HAPClient;
|
||||||
|
friend class SpanPoint;
|
||||||
|
|
||||||
const char *displayName; // display name for this device - broadcast as part of Bonjour MDNS
|
const char *displayName; // display name for this device - broadcast as part of Bonjour MDNS
|
||||||
const char *hostNameBase; // base of hostName of this device - full host name broadcast by Bonjour MDNS will have 6-byte accessoryID as well as '.local' automatically appended
|
const char *hostNameBase; // base of hostName of this device - full host name broadcast by Bonjour MDNS will have 6-byte accessoryID as well as '.local' automatically appended
|
||||||
|
|
@ -185,7 +206,6 @@ class Span{
|
||||||
char pairingCodeCommand[12]=""; // user-specified Pairing Code - only needed if Pairing Setup Code is specified in sketch using setPairingCode()
|
char pairingCodeCommand[12]=""; // user-specified Pairing Code - only needed if Pairing Setup Code is specified in sketch using setPairingCode()
|
||||||
String lastClientIP="0.0.0.0"; // IP address of last client accessing device through encrypted channel
|
String lastClientIP="0.0.0.0"; // IP address of last client accessing device through encrypted channel
|
||||||
boolean newCode; // flag indicating new application code has been loaded (based on keeping track of app SHA256)
|
boolean newCode; // flag indicating new application code has been loaded (based on keeping track of app SHA256)
|
||||||
boolean espNowEnabled=false; // flag indicating if ESP-NOW is enabled
|
|
||||||
|
|
||||||
int connected=0; // WiFi connection status (increments upon each connect and disconnect)
|
int connected=0; // WiFi connection status (increments upon each connect and disconnect)
|
||||||
unsigned long waitTime=60000; // time to wait (in milliseconds) between WiFi connection attempts
|
unsigned long waitTime=60000; // time to wait (in milliseconds) between WiFi connection attempts
|
||||||
|
|
@ -284,8 +304,8 @@ class Span{
|
||||||
void setApFunction(void (*f)()){apFunction=f;} // sets an optional user-defined function to call when activating the WiFi Access Point
|
void setApFunction(void (*f)()){apFunction=f;} // sets an optional user-defined function to call when activating the WiFi Access Point
|
||||||
void enableAutoStartAP(){autoStartAPEnabled=true;} // enables auto start-up of Access Point when WiFi Credentials not found
|
void enableAutoStartAP(){autoStartAPEnabled=true;} // enables auto start-up of Access Point when WiFi Credentials not found
|
||||||
void setWifiCredentials(const char *ssid, const char *pwd); // sets WiFi Credentials
|
void setWifiCredentials(const char *ssid, const char *pwd); // sets WiFi Credentials
|
||||||
void enableEspNOW(){espNowEnabled=true;}; // enables ESP-NOW
|
void setSpanPointPassword(const char *pwd){SpanPoint::init(pwd);}; // sets SpanPoint password
|
||||||
|
|
||||||
void setPairingCode(const char *s){sprintf(pairingCodeCommand,"S %9s",s);} // sets the Pairing Code - use is NOT recommended. Use 'S' from CLI instead
|
void setPairingCode(const char *s){sprintf(pairingCodeCommand,"S %9s",s);} // sets the Pairing Code - use is NOT recommended. Use 'S' from CLI instead
|
||||||
void deleteStoredValues(){processSerialCommand("V");} // deletes stored Characteristic values from NVS
|
void deleteStoredValues(){processSerialCommand("V");} // deletes stored Characteristic values from NVS
|
||||||
|
|
||||||
|
|
@ -305,7 +325,7 @@ class Span{
|
||||||
void autoPoll(uint32_t stackSize=CONFIG_ARDUINO_LOOP_STACK_SIZE){xTaskCreateUniversal([](void *parms){for(;;)homeSpan.pollTask();}, "pollTask", stackSize, NULL, 1, &pollTaskHandle, 0);} // start pollTask()
|
void autoPoll(uint32_t stackSize=CONFIG_ARDUINO_LOOP_STACK_SIZE){xTaskCreateUniversal([](void *parms){for(;;)homeSpan.pollTask();}, "pollTask", stackSize, NULL, 1, &pollTaskHandle, 0);} // start pollTask()
|
||||||
|
|
||||||
void setTimeServerTimeout(uint32_t tSec){webLog.waitTime=tSec*1000;} // sets wait time (in seconds) for optional web log time server to connect
|
void setTimeServerTimeout(uint32_t tSec){webLog.waitTime=tSec*1000;} // sets wait time (in seconds) for optional web log time server to connect
|
||||||
|
|
||||||
[[deprecated("Please use reserveSocketConnections(n) method instead.")]]
|
[[deprecated("Please use reserveSocketConnections(n) method instead.")]]
|
||||||
void setMaxConnections(uint8_t n){requestedMaxCon=n;} // sets maximum number of simultaneous HAP connections
|
void setMaxConnections(uint8_t n){requestedMaxCon=n;} // sets maximum number of simultaneous HAP connections
|
||||||
};
|
};
|
||||||
|
|
@ -319,6 +339,7 @@ class SpanAccessory{
|
||||||
friend class SpanCharacteristic;
|
friend class SpanCharacteristic;
|
||||||
friend class SpanButton;
|
friend class SpanButton;
|
||||||
friend class SpanRange;
|
friend class SpanRange;
|
||||||
|
friend class SpanPoint;
|
||||||
|
|
||||||
uint32_t aid=0; // Accessory Instance ID (HAP Table 6-1)
|
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
|
int iidCount=0; // running count of iid to use for Services and Characteristics associated with this Accessory
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ void setup() {
|
||||||
|
|
||||||
homeSpan.begin(Category::Lighting,"HomeSpan Lamp Server","homespan");
|
homeSpan.begin(Category::Lighting,"HomeSpan Lamp Server","homespan");
|
||||||
|
|
||||||
|
homeSpan.setSpanPointPassword("Hello Thert");
|
||||||
|
|
||||||
new SpanAccessory(); // Begin by creating a new Accessory using SpanAccessory(), which takes no arguments
|
new SpanAccessory(); // Begin by creating a new Accessory using SpanAccessory(), which takes no arguments
|
||||||
|
|
||||||
new Service::AccessoryInformation(); // HAP requires every Accessory to implement an AccessoryInformation Service, which has 6 required Characteristics
|
new Service::AccessoryInformation(); // HAP requires every Accessory to implement an AccessoryInformation Service, which has 6 required Characteristics
|
||||||
|
|
@ -63,6 +65,7 @@ void setup() {
|
||||||
new Characteristic::Name("Light 1");
|
new Characteristic::Name("Light 1");
|
||||||
new Characteristic::ColorTemperature();
|
new Characteristic::ColorTemperature();
|
||||||
new Characteristic::Active();
|
new Characteristic::Active();
|
||||||
|
new SpanPoint("AC:67:B2:77:42:20");
|
||||||
new Service::LightBulb();
|
new Service::LightBulb();
|
||||||
new Characteristic::On(0,true);
|
new Characteristic::On(0,true);
|
||||||
(new Characteristic::Brightness(50,false))->setRange(10,100,5);
|
(new Characteristic::Brightness(50,false))->setRange(10,100,5);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue