diff --git a/src/HomePeer.cpp b/src/HomePeer.cpp deleted file mode 100644 index b50f155..0000000 --- a/src/HomePeer.cpp +++ /dev/null @@ -1,71 +0,0 @@ - -#include "HomePeer.h" - -#include -#include -#include -#include - -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< -#include - -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; diff --git a/src/HomePoint.cpp b/src/HomePoint.cpp deleted file mode 100644 index 0650100..0000000 --- a/src/HomePoint.cpp +++ /dev/null @@ -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 -#include - -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< 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; -} - -/////////////////////////////// - -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::SpanPoints; -int SpanPoint::channel; -uint16_t SpanPoint::channelMask; -QueueHandle_t SpanPoint::statusQueue; diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index aef6360..af2f89b 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "HomeSpan.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"); } +/////////////////////////////// + +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<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::SpanPoints; +uint16_t SpanPoint::channelMask=0x3FFE; +QueueHandle_t SpanPoint::statusQueue; + /////////////////////////////// // MISC // /////////////////////////////// @@ -2161,10 +2345,6 @@ void __attribute__((weak)) loop(){ /////////////////////////////// -int SpanOTA::otaPercent; -boolean SpanOTA::safeLoad; -boolean SpanOTA::enabled=false; -boolean SpanOTA::auth; diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 7a0080b..6fd59be 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -765,13 +765,13 @@ 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 setAsHub(){isHub=true;} + static uint8_t nextChannel(); static void dataSent(const uint8_t *mac, esp_now_send_status_t status) { xQueueOverwrite( statusQueue, &status ); diff --git a/src/src.ino b/src/src.ino index 566600a..7f16cf8 100644 --- a/src/src.ino +++ b/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 + 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"); - SpanPoint::setPassword("Hello Thert"); - 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(1<<13); - 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 @@ -115,6 +115,8 @@ void setup() { } // end of setup() +unsigned long alarmTime=0; + ////////////////////////////////////// void loop(){ @@ -125,6 +127,12 @@ void loop(){ if(dev2->get(&message)) 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() //////////////////////////////////////