From b7317c3b5f76b4be1da70343b2dc310ba2cf8293 Mon Sep 17 00:00:00 2001 From: Gregg Date: Fri, 30 Sep 2022 22:20:32 -0500 Subject: [PATCH] Added SpanPoint::send() functionality Works as expected. Next Up: Modify send() logic so that channels are NOT scanned if device is a main HomeSpan hub. --- src/HomePoint.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++-- src/HomeSpan.cpp | 3 +- src/HomeSpan.h | 11 ++++++- src/src.ino | 10 +++++- 4 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/HomePoint.cpp b/src/HomePoint.cpp index b6030bb..0650100 100644 --- a/src/HomePoint.cpp +++ b/src/HomePoint.cpp @@ -27,6 +27,7 @@ #include "HomeSpan.h" #include +#include SpanPoint::SpanPoint(const char *macAddress, int sendSize, int receiveSize, int queueDepth){ @@ -36,10 +37,16 @@ SpanPoint::SpanPoint(const char *macAddress, int sendSize, int receiveSize, int 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 (queue depth=%d).\n", + 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 @@ -49,7 +56,8 @@ SpanPoint::SpanPoint(const char *macAddress, int sendSize, int receiveSize, int memcpy(peerInfo.lmk, lmk, 16); // set local key esp_now_add_peer(&peerInfo); // add peer to ESP-NOW - receiveQueue = xQueueCreate(queueDepth,receiveSize); + if(receiveSize>0) + receiveQueue = xQueueCreate(queueDepth,receiveSize); SpanPoints.push_back(this); } @@ -71,25 +79,84 @@ void SpanPoint::init(const char *password){ 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< 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<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; } @@ -103,6 +170,9 @@ void SpanPoint::dataReceived(const uint8_t *mac, const uint8_t *incomingData, in 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; @@ -117,3 +187,6 @@ uint8_t SpanPoint::lmk[16]; boolean SpanPoint::initialized=false; boolean SpanPoint::isHub=false; vector SpanPoint::SpanPoints; +int SpanPoint::channel; +uint16_t SpanPoint::channelMask; +QueueHandle_t SpanPoint::statusQueue; diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index e455be5..aef6360 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -60,8 +60,7 @@ void Span::begin(Category catID, const char *displayName, const char *hostNameBa 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) + 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 diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 6f8f7fc..7a0080b 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -765,16 +765,25 @@ class SpanPoint { static boolean initialized; static boolean isHub; static vector SpanPoints; + static int channel; // WiFi channel (1-13) + static uint16_t channelMask; // channel mask + 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 init(const char *password="HomeSpan"); static void setAsHub(); - + + static void dataSent(const uint8_t *mac, esp_now_send_status_t status) { + xQueueOverwrite( statusQueue, &status ); + } + public: SpanPoint(const char *macAddress, int sendSize, int receiveSize, int queueDepth=1); static void setPassword(const char *pwd){init(pwd);}; + static void setChannelMask(uint16_t mask); boolean get(void *dataBuf); + boolean send(void *data); }; ///////////////////////////////////////////////// diff --git a/src/src.ino b/src/src.ino index f99ed28..566600a 100644 --- a/src/src.ino +++ b/src/src.ino @@ -50,12 +50,20 @@ void setup() { // homeSpan.enableAutoStartAP(); // homeSpan.setApFunction(myWiFiAP); + homeSpan.enableWebLog(10,"pool.ntp.org","UTC","myLog"); // creates a web log on the URL /HomeSpan-[DEVICE-ID].local:[TCP-PORT]/myLog + + homeSpan.begin(Category::Lighting,"HomeSpan Lamp Server","homespan"); SpanPoint::setPassword("Hello Thert"); - dev1=new SpanPoint("AC:67:B2:77:42:20",0,sizeof(message_t)); + 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 Service::AccessoryInformation(); // HAP requires every Accessory to implement an AccessoryInformation Service, which has 6 required Characteristics