Moving HomePoint.h back into HomeSpan.h

Added SpanPoint::setAsHub(), which is called after homeSpan.begin() to set device as Hub so SpanPoint knows not to change WiFi channel.

Also added check to make sure there are no SpanPoint objects instantiated before a call to homeSpan.begin() (if it is called at all).
This commit is contained in:
Gregg 2022-09-30 17:27:57 -05:00
parent 72294bde8b
commit c819426dec
5 changed files with 58 additions and 69 deletions

View File

@ -25,11 +25,10 @@
*
********************************************************************************/
#include "HomePoint.h"
#include <WiFi.h>
#include "HomeSpan.h"
#include <mbedtls/sha256.h>
SpanPoint::SpanPoint(const char *macAddress, int qLength, int nItems){
SpanPoint::SpanPoint(const char *macAddress, int sendSize, int receiveSize, int queueDepth){
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);
@ -37,6 +36,12 @@ SpanPoint::SpanPoint(const char *macAddress, int qLength, int nItems){
while(1);
}
this->sendSize=sendSize;
this->receiveSize=receiveSize;
Serial.printf("SpanPoint: Created link to device with MAC Address %02X:%02X:%02X:%02X:%02X:%02X. Send size: %d bytes. Receive size: %d bytes (queue depth=%d).\n",
peerInfo.peer_addr[0],peerInfo.peer_addr[1],peerInfo.peer_addr[2],peerInfo.peer_addr[3],peerInfo.peer_addr[4],peerInfo.peer_addr[5],sendSize,receiveSize,queueDepth);
init(); // initialize SpanPoint
peerInfo.channel=0; // 0 = matches current WiFi channel
peerInfo.ifidx=WIFI_IF_STA; // must specify interface
@ -44,8 +49,7 @@ SpanPoint::SpanPoint(const char *macAddress, int qLength, int nItems){
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);
receiveQueue = xQueueCreate(queueDepth,receiveSize);
SpanPoints.push_back(this);
}
@ -75,7 +79,18 @@ void SpanPoint::init(const char *password){
boolean SpanPoint::get(void *dataBuf){
return(xQueueReceive(dataQueue, dataBuf, 0));
return(xQueueReceive(receiveQueue, dataBuf, 0));
}
///////////////////////////////
void SpanPoint::setAsHub(){
if(SpanPoints.size()>0){
Serial.printf("\nFATAL ERROR! SpanPoint objects created in main hub device must be instantiated AFTER calling homeSpan.begin() ***\n");
Serial.printf("\n=== PROGRAM HALTED ===");
while(1);
}
isHub=true;
}
///////////////////////////////
@ -88,16 +103,17 @@ void SpanPoint::dataReceived(const uint8_t *mac, const uint8_t *incomingData, in
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);
if(len!=(*it)->receiveSize){
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)->receiveSize);
return;
}
xQueueSend((*it)->dataQueue, incomingData, pdMS_TO_TICKS(1000));
xQueueSend((*it)->receiveQueue, incomingData, 0); // send to queue - do not wait if queue is full and instead fail immediately since we need to return from this function ASAP
}
///////////////////////////////
uint8_t SpanPoint::lmk[16];
boolean SpanPoint::initialized=false;
boolean SpanPoint::isHub=false;
vector<SpanPoint *> SpanPoint::SpanPoints;

View File

@ -1,54 +0,0 @@
/*********************************************************************************
* 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);
};
///////////////////////////////

View File

@ -58,6 +58,8 @@ void Span::begin(Category catID, const char *displayName, const char *hostNameBa
this->modelName=modelName;
sprintf(this->category,"%d",(int)catID);
SpanPoint::setAsHub();
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)

View File

@ -39,6 +39,7 @@
#include <unordered_set>
#include <nvs.h>
#include <ArduinoOTA.h>
#include <esp_now.h>
#include "extras/Blinker.h"
#include "extras/Pixel.h"
@ -749,6 +750,33 @@ class SpanUserCommand {
SpanUserCommand(char c, const char *s, void (*f)(const char *, void *), void *arg);
};
///////////////////////////////
class SpanPoint {
friend class Span;
int receiveSize; // size (in bytes) of messages to receive
int sendSize; // size (in bytes) of messages to send
esp_now_peer_info_t peerInfo; // structure for all ESP-NOW peer data
QueueHandle_t receiveQueue; // queue to store data after it is received
static uint8_t lmk[16];
static boolean initialized;
static boolean isHub;
static vector<SpanPoint *> SpanPoints;
static void dataReceived(const uint8_t *mac, const uint8_t *incomingData, int len);
static void init(const char *password="HomeSpan");
static void setAsHub();
public:
SpanPoint(const char *macAddress, int sendSize, int receiveSize, int queueDepth=1);
static void setPassword(const char *pwd){init(pwd);};
boolean get(void *dataBuf);
};
/////////////////////////////////////////////////
#include "Span.h"

View File

@ -8,7 +8,6 @@
#include "extras/RFControl.h"
#include "extras/Blinker.h"
#include "extras/PwmPin.h"
#include "HomePoint.h"
#define STRING_t const char * // WORK-AROUND
@ -51,13 +50,11 @@ 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");
dev2=new SpanPoint("7C:DF:A1:61:E4:A8",sizeof(message_t));
SpanPoint::setPassword("Hello Thert");
dev1=new SpanPoint("AC:67:B2:77:42:20",0,sizeof(message_t));
dev2=new SpanPoint("7C:DF:A1:61:E4:A8",0,sizeof(message_t));
new SpanAccessory(); // Begin by creating a new Accessory using SpanAccessory(), which takes no arguments