Move all SpanPoint code into separate HomePoint.cpp and HomePoint.h files
This enables SpanPoint to operate as a standalone library with no reliance on anything in HomeSpan. To Do: migrate all HomePeer code into SpanPoint. This will yield a universal standalone HomePoint library that can be used for BOTH the receiver and the sender (which automatically means two-way communication is always possible)
This commit is contained in:
parent
58683586bc
commit
72294bde8b
|
|
@ -0,0 +1,103 @@
|
|||
/*********************************************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-2022 Gregg E. Berman
|
||||
*
|
||||
* https://github.com/HomeSpan/HomeSpan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
#include "HomePoint.h"
|
||||
#include <WiFi.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
|
||||
SpanPoint::SpanPoint(const char *macAddress, int qLength, int nItems){
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
init(); // initialize SpanPoint
|
||||
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
|
||||
|
||||
this->qLength=qLength;
|
||||
dataQueue = xQueueCreate(nItems,qLength);
|
||||
|
||||
SpanPoints.push_back(this);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void SpanPoint::init(const char *password){
|
||||
|
||||
if(initialized)
|
||||
return;
|
||||
|
||||
if(WiFi.getMode()!=WIFI_AP_STA)
|
||||
WiFi.mode(WIFI_AP_STA); // set mode to mixed AP/STA. This does not start any servers, just configures the WiFi radio to ensure it does not sleep (required for ESP-NOW)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
boolean SpanPoint::get(void *dataBuf){
|
||||
|
||||
return(xQueueReceive(dataQueue, dataBuf, 0));
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void SpanPoint::dataReceived(const uint8_t *mac, const uint8_t *incomingData, int len){
|
||||
|
||||
auto it=SpanPoints.begin();
|
||||
for(;it!=SpanPoints.end() && memcmp((*it)->peerInfo.peer_addr,mac,6)!=0; it++);
|
||||
|
||||
if(it==SpanPoints.end())
|
||||
return;
|
||||
|
||||
if(len!=(*it)->qLength){
|
||||
Serial.printf("SpanPoint Warning! %d bytes received from %02X:%02X:%02X:%02X:%02X:%02X does not match %d-byte queue size\n",len,mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],(*it)->qLength);
|
||||
return;
|
||||
}
|
||||
|
||||
xQueueSend((*it)->dataQueue, incomingData, pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
uint8_t SpanPoint::lmk[16];
|
||||
boolean SpanPoint::initialized=false;
|
||||
vector<SpanPoint *> SpanPoint::SpanPoints;
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*********************************************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-2022 Gregg E. Berman
|
||||
*
|
||||
* https://github.com/HomeSpan/HomeSpan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <esp_now.h>
|
||||
#include <vector>
|
||||
|
||||
using std::vector;
|
||||
|
||||
class SpanPoint {
|
||||
|
||||
int qLength; // length of 1 queue item (in bytes)
|
||||
esp_now_peer_info_t peerInfo; // structure for all ESP-NOW peer data
|
||||
QueueHandle_t dataQueue; // queue to store data after it is received
|
||||
|
||||
static uint8_t lmk[16];
|
||||
static boolean initialized;
|
||||
static vector<SpanPoint *> SpanPoints;
|
||||
|
||||
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, int qLength, int nItems=1);
|
||||
static void setPassword(const char *pwd){init(pwd);};
|
||||
boolean get(void *dataBuf);
|
||||
};
|
||||
|
||||
///////////////////////////////
|
||||
|
|
@ -58,7 +58,8 @@ void Span::begin(Category catID, const char *displayName, const char *hostNameBa
|
|||
this->modelName=modelName;
|
||||
sprintf(this->category,"%d",(int)catID);
|
||||
|
||||
WiFi.mode(WIFI_AP_STA); // set mode to mixed AP/STA. This does not start any servers, just configures the WiFi radio to ensure it does not sleep (required for ESP-NOW)
|
||||
if(WiFi.getMode()!=WIFI_AP_STA)
|
||||
WiFi.mode(WIFI_AP_STA); // set mode to mixed AP/STA. This does not start any servers, just configures the WiFi radio to ensure it does not sleep (required for ESP-NOW)
|
||||
|
||||
statusLED=new Blinker(statusDevice,autoOffLED); // create Status LED, even is statusDevice is NULL
|
||||
|
||||
|
|
@ -2150,75 +2151,6 @@ void SpanOTA::error(ota_error_t err){
|
|||
else if (err == OTA_END_ERROR) Serial.println("End Failed\n");
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// SpanPoint //
|
||||
///////////////////////////////
|
||||
|
||||
SpanPoint::SpanPoint(const char *macAddress, int qLength, int nItems){
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
init(); // initialize SpanPoint
|
||||
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
|
||||
|
||||
this->qLength=qLength;
|
||||
dataQueue = xQueueCreate(nItems,qLength);
|
||||
|
||||
SpanPoints.push_back(this);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
boolean SpanPoint::get(void *dataBuf){
|
||||
|
||||
return(xQueueReceive(dataQueue, dataBuf, 0));
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void SpanPoint::dataReceived(const uint8_t *mac, const uint8_t *incomingData, int len){
|
||||
|
||||
auto it=SpanPoints.begin();
|
||||
for(;it!=SpanPoints.end() && memcmp((*it)->peerInfo.peer_addr,mac,6)!=0; it++);
|
||||
|
||||
if(it==SpanPoints.end())
|
||||
return;
|
||||
|
||||
if(len!=(*it)->qLength){
|
||||
Serial.printf("SpanPoint Warning! %d bytes received from %02X:%02X:%02X:%02X:%02X:%02X does not match %d-byte queue size\n",len,mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],(*it)->qLength);
|
||||
return;
|
||||
}
|
||||
|
||||
xQueueSend((*it)->dataQueue, incomingData, pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
// MISC //
|
||||
///////////////////////////////
|
||||
|
|
@ -2232,8 +2164,6 @@ int SpanOTA::otaPercent;
|
|||
boolean SpanOTA::safeLoad;
|
||||
boolean SpanOTA::enabled=false;
|
||||
boolean SpanOTA::auth;
|
||||
uint8_t SpanPoint::lmk[16];
|
||||
boolean SpanPoint::initialized=false;
|
||||
vector<SpanPoint *> SpanPoint::SpanPoints;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
#include <unordered_set>
|
||||
#include <nvs.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <esp_now.h>
|
||||
|
||||
#include "extras/Blinker.h"
|
||||
#include "extras/Pixel.h"
|
||||
|
|
@ -156,29 +155,6 @@ struct SpanOTA{ // manages OTA process
|
|||
// USER API CLASSES BEGINS HERE //
|
||||
//////////////////////////////////////
|
||||
|
||||
class SpanPoint {
|
||||
|
||||
friend class Span;
|
||||
|
||||
int qLength; // length of 1 queue item (in bytes)
|
||||
esp_now_peer_info_t peerInfo; // structure for all ESP-NOW peer data
|
||||
QueueHandle_t dataQueue; // queue to store data after it is received
|
||||
|
||||
static uint8_t lmk[16];
|
||||
static boolean initialized;
|
||||
static vector<SpanPoint *> SpanPoints;
|
||||
|
||||
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, int qLength, int nItems=1);
|
||||
boolean get(void *dataBuf);
|
||||
};
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
class Span{
|
||||
|
||||
friend class SpanAccessory;
|
||||
|
|
@ -191,7 +167,6 @@ class Span{
|
|||
friend class SpanOTA;
|
||||
friend class Network;
|
||||
friend class HAPClient;
|
||||
friend class SpanPoint;
|
||||
|
||||
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
|
||||
|
|
@ -308,7 +283,6 @@ class Span{
|
|||
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 setWifiCredentials(const char *ssid, const char *pwd); // sets WiFi Credentials
|
||||
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 deleteStoredValues(){processSerialCommand("V");} // deletes stored Characteristic values from NVS
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "extras/RFControl.h"
|
||||
#include "extras/Blinker.h"
|
||||
#include "extras/PwmPin.h"
|
||||
#include "HomePoint.h"
|
||||
|
||||
|
||||
#define STRING_t const char * // WORK-AROUND
|
||||
|
|
@ -50,11 +51,12 @@ void setup() {
|
|||
// homeSpan.enableAutoStartAP();
|
||||
// homeSpan.setApFunction(myWiFiAP);
|
||||
|
||||
SpanPoint::setPassword("Hello Thert");
|
||||
dev1=new SpanPoint("AC:67:B2:77:42:20",sizeof(message_t));
|
||||
|
||||
homeSpan.begin(Category::Lighting,"HomeSpan Lamp Server","homespan");
|
||||
|
||||
homeSpan.setSpanPointPassword("Hello Thert");
|
||||
|
||||
dev1=new SpanPoint("AC:67:B2:77:42:20",sizeof(message_t));
|
||||
dev2=new SpanPoint("7C:DF:A1:61:E4:A8",sizeof(message_t));
|
||||
|
||||
new SpanAccessory(); // Begin by creating a new Accessory using SpanAccessory(), which takes no arguments
|
||||
|
|
|
|||
Loading…
Reference in New Issue