Completed all SpanPoint code
Allows for bi-directional transmission between main HomeSpan device and one or more remote devices. To Do: Create and test with Temperature Sensor Example
This commit is contained in:
parent
b7317c3b5f
commit
23afdb3711
|
|
@ -1,71 +0,0 @@
|
||||||
|
|
||||||
#include "HomePeer.h"
|
|
||||||
|
|
||||||
#include <WiFi.h>
|
|
||||||
#include <esp_wifi.h>
|
|
||||||
#include <mbedtls/sha256.h>
|
|
||||||
#include <esp_now.h>
|
|
||||||
|
|
||||||
void SpanPeer::start(const char *macAddress, const char *password){
|
|
||||||
|
|
||||||
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("*** ERROR: Can't start HomeSpan NOW! Bad MAC Address '%s'\n\n",macAddress);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
statusQueue = xQueueCreate(1,sizeof(esp_now_send_status_t));
|
|
||||||
|
|
||||||
WiFi.mode(WIFI_AP_STA);
|
|
||||||
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
|
|
||||||
esp_now_init();
|
|
||||||
esp_now_register_send_cb(onDataSent);
|
|
||||||
|
|
||||||
uint8_t lmk[32];
|
|
||||||
uint8_t mac[6];
|
|
||||||
|
|
||||||
mbedtls_sha256_ret((const unsigned char *)password,strlen(password),lmk,0);
|
|
||||||
esp_now_set_pmk(lmk+16);
|
|
||||||
|
|
||||||
peerInfo.channel=0;
|
|
||||||
peerInfo.ifidx=WIFI_IF_STA;
|
|
||||||
peerInfo.encrypt = true;
|
|
||||||
memcpy(peerInfo.lmk, lmk, 16);
|
|
||||||
esp_now_add_peer(&peerInfo);
|
|
||||||
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
|
|
||||||
|
|
||||||
Serial.printf("Started HomePeer: MAC Address = %s HomeSpan Address = %X:%X:%X:%X:%X:%X\n",WiFi.macAddress().c_str(),
|
|
||||||
peerInfo.peer_addr[0],peerInfo.peer_addr[1],peerInfo.peer_addr[2],peerInfo.peer_addr[3],peerInfo.peer_addr[4],peerInfo.peer_addr[5]);
|
|
||||||
started=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean SpanPeer::send(uint8_t *data, size_t len){
|
|
||||||
|
|
||||||
if(!started){
|
|
||||||
Serial.printf("*** ERROR: Can't send data until HomePeer has been started.\n\n");
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_now_send_status_t status = ESP_NOW_SEND_FAIL;
|
|
||||||
|
|
||||||
for(int c=0;c<13;c++){
|
|
||||||
if((1<<channel) & channelMask){
|
|
||||||
for(int i=1;i<=3;i++){
|
|
||||||
Serial.printf("Sending on channel %d, attempt #%d\n",channel,i);
|
|
||||||
esp_now_send(peerInfo.peer_addr, data, len);
|
|
||||||
xQueueReceive(statusQueue, &status, pdMS_TO_TICKS(2000));
|
|
||||||
if(status==ESP_NOW_SEND_SUCCESS)
|
|
||||||
return(true);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
channel++;
|
|
||||||
if(channel==14)
|
|
||||||
channel=1;
|
|
||||||
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
|
|
||||||
}
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
QueueHandle_t SpanPeer::statusQueue;
|
|
||||||
|
|
||||||
SpanPeer homePeer;
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <esp_now.h>
|
|
||||||
|
|
||||||
class SpanPeer {
|
|
||||||
|
|
||||||
esp_now_peer_info_t peerInfo;
|
|
||||||
boolean started=false;
|
|
||||||
static QueueHandle_t statusQueue;
|
|
||||||
int channel=1;
|
|
||||||
uint16_t channelMask=0x3FFE;
|
|
||||||
|
|
||||||
static void onDataSent(const uint8_t *mac, esp_now_send_status_t status) {
|
|
||||||
xQueueOverwrite( statusQueue, &status );
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void setChannelMask(uint16_t cm){channelMask = cm & 0x3FFE;}
|
|
||||||
void start(const char *macAddress, const char *password="HomeSpan");
|
|
||||||
boolean send(uint8_t *data, size_t len);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
extern SpanPeer homePeer;
|
|
||||||
|
|
@ -1,192 +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 "HomeSpan.h"
|
|
||||||
#include <mbedtls/sha256.h>
|
|
||||||
#include <esp_wifi.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
Serial.printf("\n=== PROGRAM HALTED ===");
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sendSize<0 || sendSize>200 || receiveSize<0 || receiveSize>200 || queueDepth<1 || (sendSize==0 && receiveSize==0)){
|
|
||||||
Serial.printf("\nFATAL ERROR! Can't create new SpanPoint(\"%s\",%d,%d,%d) - one or more invalid parameters ***\n",macAddress,sendSize,receiveSize,queueDepth);
|
|
||||||
Serial.printf("\n=== PROGRAM HALTED ===");
|
|
||||||
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 with 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
|
|
||||||
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
|
|
||||||
|
|
||||||
if(receiveSize>0)
|
|
||||||
receiveQueue = xQueueCreate(queueDepth,receiveSize);
|
|
||||||
|
|
||||||
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
|
|
||||||
esp_now_register_send_cb(dataSent); // set callback for sending data
|
|
||||||
|
|
||||||
statusQueue = xQueueCreate(1,sizeof(esp_now_send_status_t)); // create statusQueue even if not needed
|
|
||||||
setChannelMask(0x3FFE); // default channel mask uses channels 1-13
|
|
||||||
|
|
||||||
initialized=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
void SpanPoint::setChannelMask(uint16_t mask){
|
|
||||||
channelMask = mask & 0x3FFE;
|
|
||||||
|
|
||||||
channel=0;
|
|
||||||
|
|
||||||
for(int i=1;i<=13 && channel==0;i++)
|
|
||||||
channel=(channelMask & (1<<i))?i:0;
|
|
||||||
|
|
||||||
if(channel==0){
|
|
||||||
Serial.printf("\nFATAL ERROR! SpanPoint::setChannelMask(0x%04X) - one or more invalid parameters ***\n",mask);
|
|
||||||
Serial.printf("\n=== PROGRAM HALTED ===");
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isHub) // if this is NOT the main HomeSpan device
|
|
||||||
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); // set the WiFi channel
|
|
||||||
|
|
||||||
Serial.printf("ChannelMask=0x%04X => channel=%d\n",channelMask,channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
boolean SpanPoint::get(void *dataBuf){
|
|
||||||
|
|
||||||
if(receiveSize==0)
|
|
||||||
return(false);
|
|
||||||
|
|
||||||
return(xQueueReceive(receiveQueue, dataBuf, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
boolean SpanPoint::send(void *data){
|
|
||||||
|
|
||||||
if(sendSize==0)
|
|
||||||
return(false);
|
|
||||||
|
|
||||||
esp_now_send_status_t status = ESP_NOW_SEND_FAIL;
|
|
||||||
|
|
||||||
for(int c=0;c<13;c++){
|
|
||||||
if((1<<channel) & channelMask){
|
|
||||||
for(int i=1;i<=3;i++){
|
|
||||||
Serial.printf("Sending on channel %d, attempt #%d\n",channel,i);
|
|
||||||
esp_now_send(peerInfo.peer_addr, (uint8_t *) data, sendSize);
|
|
||||||
xQueueReceive(statusQueue, &status, pdMS_TO_TICKS(2000));
|
|
||||||
if(status==ESP_NOW_SEND_SUCCESS)
|
|
||||||
return(true);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
channel++;
|
|
||||||
if(channel==14)
|
|
||||||
channel=1;
|
|
||||||
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
|
|
||||||
}
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
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((*it)->receiveSize==0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
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)->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;
|
|
||||||
int SpanPoint::channel;
|
|
||||||
uint16_t SpanPoint::channelMask;
|
|
||||||
QueueHandle_t SpanPoint::statusQueue;
|
|
||||||
188
src/HomeSpan.cpp
188
src/HomeSpan.cpp
|
|
@ -35,6 +35,7 @@
|
||||||
#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_wifi.h>
|
||||||
|
|
||||||
#include "HomeSpan.h"
|
#include "HomeSpan.h"
|
||||||
#include "HAP.h"
|
#include "HAP.h"
|
||||||
|
|
@ -2152,6 +2153,189 @@ 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
int SpanOTA::otaPercent;
|
||||||
|
boolean SpanOTA::safeLoad;
|
||||||
|
boolean SpanOTA::enabled=false;
|
||||||
|
boolean SpanOTA::auth;
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// SpanPoint //
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
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);
|
||||||
|
Serial.printf("\n=== PROGRAM HALTED ===");
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sendSize<0 || sendSize>200 || receiveSize<0 || receiveSize>200 || queueDepth<1 || (sendSize==0 && receiveSize==0)){
|
||||||
|
Serial.printf("\nFATAL ERROR! Can't create new SpanPoint(\"%s\",%d,%d,%d) - one or more invalid parameters ***\n",macAddress,sendSize,receiveSize,queueDepth);
|
||||||
|
Serial.printf("\n=== PROGRAM HALTED ===");
|
||||||
|
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 with 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
|
||||||
|
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
|
||||||
|
|
||||||
|
if(receiveSize>0)
|
||||||
|
receiveQueue = xQueueCreate(queueDepth,receiveSize);
|
||||||
|
|
||||||
|
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
|
||||||
|
esp_now_register_send_cb(dataSent); // set callback for sending data
|
||||||
|
|
||||||
|
statusQueue = xQueueCreate(1,sizeof(esp_now_send_status_t)); // create statusQueue even if not needed
|
||||||
|
setChannelMask(channelMask); // default channel mask at start-up uses channels 1-13
|
||||||
|
|
||||||
|
initialized=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
void SpanPoint::setChannelMask(uint16_t mask){
|
||||||
|
channelMask = mask & 0x3FFE;
|
||||||
|
|
||||||
|
if(isHub)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint8_t channel=0;
|
||||||
|
|
||||||
|
for(int i=1;i<=13 && channel==0;i++) // find first "allowed" channel based on mask
|
||||||
|
channel=(channelMask & (1<<i))?i:0;
|
||||||
|
|
||||||
|
if(channel==0){
|
||||||
|
Serial.printf("\nFATAL ERROR! SpanPoint::setChannelMask(0x%04X) - mask must allow for at least one channel ***\n",mask);
|
||||||
|
Serial.printf("\n=== PROGRAM HALTED ===");
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
uint8_t SpanPoint::nextChannel(){
|
||||||
|
|
||||||
|
uint8_t channel;
|
||||||
|
wifi_second_chan_t channel2;
|
||||||
|
esp_wifi_get_channel(&channel,&channel2); // get current channel
|
||||||
|
|
||||||
|
if(isHub || channelMask==(1<<channel)) // do not change channel if device is either a hub, or channel mask does not allow for any other channels
|
||||||
|
return(channel);
|
||||||
|
|
||||||
|
do {
|
||||||
|
channel=(channel<13)?channel+1:1; // advance to next channel
|
||||||
|
} while(!(channelMask & (1<<channel))); // until we find next valid one
|
||||||
|
|
||||||
|
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); // set the WiFi channel
|
||||||
|
|
||||||
|
return(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
boolean SpanPoint::get(void *dataBuf){
|
||||||
|
|
||||||
|
if(receiveSize==0)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
return(xQueueReceive(receiveQueue, dataBuf, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
boolean SpanPoint::send(void *data){
|
||||||
|
|
||||||
|
if(sendSize==0)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
uint8_t channel;
|
||||||
|
wifi_second_chan_t channel2;
|
||||||
|
esp_wifi_get_channel(&channel,&channel2); // get current channel
|
||||||
|
uint8_t startingChannel=channel; // set starting channel to current channel
|
||||||
|
|
||||||
|
esp_now_send_status_t status = ESP_NOW_SEND_FAIL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
for(int i=1;i<=3;i++){
|
||||||
|
|
||||||
|
LOG1("SpanPoint: Sending %d bytes to MAC Address %02X:%02X:%02X:%02X:%02X:%02X using channel %hhu...\n",
|
||||||
|
sendSize,peerInfo.peer_addr[0],peerInfo.peer_addr[1],peerInfo.peer_addr[2],peerInfo.peer_addr[3],peerInfo.peer_addr[4],peerInfo.peer_addr[5],channel);
|
||||||
|
|
||||||
|
esp_now_send(peerInfo.peer_addr, (uint8_t *) data, sendSize);
|
||||||
|
xQueueReceive(statusQueue, &status, pdMS_TO_TICKS(2000));
|
||||||
|
if(status==ESP_NOW_SEND_SUCCESS)
|
||||||
|
return(true);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
channel=nextChannel();
|
||||||
|
} while(channel!=startingChannel);
|
||||||
|
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
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((*it)->receiveSize==0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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)->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;
|
||||||
|
uint16_t SpanPoint::channelMask=0x3FFE;
|
||||||
|
QueueHandle_t SpanPoint::statusQueue;
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// MISC //
|
// MISC //
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
@ -2161,10 +2345,6 @@ void __attribute__((weak)) loop(){
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
int SpanOTA::otaPercent;
|
|
||||||
boolean SpanOTA::safeLoad;
|
|
||||||
boolean SpanOTA::enabled=false;
|
|
||||||
boolean SpanOTA::auth;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -765,13 +765,13 @@ class SpanPoint {
|
||||||
static boolean initialized;
|
static boolean initialized;
|
||||||
static boolean isHub;
|
static boolean isHub;
|
||||||
static vector<SpanPoint *> SpanPoints;
|
static vector<SpanPoint *> SpanPoints;
|
||||||
static int channel; // WiFi channel (1-13)
|
|
||||||
static uint16_t channelMask; // channel mask
|
static uint16_t channelMask; // channel mask
|
||||||
static QueueHandle_t statusQueue; // queue for communication between SpanPoint::dataSend and SpanPoint::send
|
static QueueHandle_t statusQueue; // queue for communication between SpanPoint::dataSend and SpanPoint::send
|
||||||
|
|
||||||
static void dataReceived(const uint8_t *mac, const uint8_t *incomingData, int len);
|
static void dataReceived(const uint8_t *mac, const uint8_t *incomingData, int len);
|
||||||
static void init(const char *password="HomeSpan");
|
static void init(const char *password="HomeSpan");
|
||||||
static void setAsHub();
|
static void setAsHub(){isHub=true;}
|
||||||
|
static uint8_t nextChannel();
|
||||||
|
|
||||||
static void dataSent(const uint8_t *mac, esp_now_send_status_t status) {
|
static void dataSent(const uint8_t *mac, esp_now_send_status_t status) {
|
||||||
xQueueOverwrite( statusQueue, &status );
|
xQueueOverwrite( statusQueue, &status );
|
||||||
|
|
|
||||||
22
src/src.ino
22
src/src.ino
|
|
@ -52,17 +52,17 @@ void setup() {
|
||||||
|
|
||||||
homeSpan.enableWebLog(10,"pool.ntp.org","UTC","myLog"); // creates a web log on the URL /HomeSpan-[DEVICE-ID].local:[TCP-PORT]/myLog
|
homeSpan.enableWebLog(10,"pool.ntp.org","UTC","myLog"); // creates a web log on the URL /HomeSpan-[DEVICE-ID].local:[TCP-PORT]/myLog
|
||||||
|
|
||||||
|
SpanPoint::setPassword("Hello Thert");
|
||||||
|
|
||||||
|
homeSpan.setLogLevel(1);
|
||||||
|
|
||||||
|
dev1=new SpanPoint("AC:67:B2:77:42:20",sizeof(int),0);
|
||||||
|
dev2=new SpanPoint("7C:DF:A1:61:E4:A8",sizeof(int),sizeof(message_t));
|
||||||
|
|
||||||
homeSpan.begin(Category::Lighting,"HomeSpan Lamp Server","homespan");
|
homeSpan.begin(Category::Lighting,"HomeSpan Lamp Server","homespan");
|
||||||
|
|
||||||
SpanPoint::setPassword("Hello Thert");
|
SpanPoint::setChannelMask(1<<13);
|
||||||
dev1=new SpanPoint("AC:67:B2:77:42:20",4,0);
|
|
||||||
dev2=new SpanPoint("7C:DF:A1:61:E4:A8",0,sizeof(message_t));
|
|
||||||
|
|
||||||
SpanPoint::setChannelMask(0x3FFE);
|
|
||||||
dev2->setChannelMask(1<<1);
|
|
||||||
dev2->setChannelMask(1<<3 | 1<<8 | 1<<13);
|
|
||||||
dev2->setChannelMask(1<<13);
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
@ -115,6 +115,8 @@ void setup() {
|
||||||
|
|
||||||
} // end of setup()
|
} // end of setup()
|
||||||
|
|
||||||
|
unsigned long alarmTime=0;
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
||||||
void loop(){
|
void loop(){
|
||||||
|
|
@ -125,6 +127,12 @@ void loop(){
|
||||||
if(dev2->get(&message))
|
if(dev2->get(&message))
|
||||||
Serial.printf("DEV2: '%s' %d %f %d\n",message.a,message.b,message.c,message.d);
|
Serial.printf("DEV2: '%s' %d %f %d\n",message.a,message.b,message.c,message.d);
|
||||||
|
|
||||||
|
if(millis()-alarmTime>5000){
|
||||||
|
alarmTime=millis();
|
||||||
|
boolean success = dev2->send(&alarmTime);
|
||||||
|
Serial.printf("Success = %d\n",success);
|
||||||
|
}
|
||||||
|
|
||||||
} // end of loop()
|
} // end of loop()
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue