diff --git a/esphome/components/espnow/espnow.cpp b/esphome/components/espnow/espnow.cpp index a6220d9786..7d95d1e267 100644 --- a/esphome/components/espnow/espnow.cpp +++ b/esphome/components/espnow/espnow.cpp @@ -55,6 +55,43 @@ struct { } __attribute__((packed)) espnow_frame_format_t; #endif +ESPNowPacket::ESPNowPacket(uint64_t mac64, const uint8_t *data, uint8_t size, uint32_t app_id) + : mac64(mac64), size(size), app_id(app_id), retrys(0) { + if (this->mac64 == 0) + this->mac64 = ESPNOW_BROADCAST_ADDR; + this->is_broadcast = this->mac64 == ESPNOW_BROADCAST_ADDR; + + this->ref_id = 0; + + this->size = std::min(MAX_ESPNOW_DATA_SIZE, size); + std::memcpy(&this->data, (uint8_t *) data, this->size); + + this->data[this->size + 1] = 0; + this->recalc(); + this->info("create"); +} + +inline void ESPNowPacket::info(std::string place) { + ESP_LOGVV(TAG, "%s: M:%s A:0x%06x R:0x%02x C:0x%04x S:%02x", place.c_str(), this->to_str().c_str(), this->app_id, + this->ref_id, this->random, this->size); +} + +bool ESPNowPacket::is_valid() { + uint16_t crc = this->crc16; + recalc(); + bool valid = (std::memcmp(&header, &TRANSPORT_HEADER, 3) == 0); + valid &= (this->app_id != 0); + valid &= (this->crc16 == crc); + if (!valid) { + ESP_LOGV("Packet", "Invalid H:%02x%02x%02x A:%06x R:%02x C:%04x ipv. %04x, %d&%d&%d=%d\n", this->header[0], + this->header[1], this->header[2], this->app_id, this->ref_id, crc, this->crc16, + std::memcmp(&header, &TRANSPORT_HEADER, 3) == 0, (this->app_id != 0), (this->crc16 == crc), valid); + } + + this->crc16 = crc; + return valid; +} + void ESPNowProtocol::setup() { parent_->register_protocol(this); } bool ESPNowProtocol::write(uint64_t mac_address, const uint8_t *data, uint8_t len) { diff --git a/esphome/components/espnow/espnow.h b/esphome/components/espnow/espnow.h index 6e8eca2bbb..2ed5e99460 100644 --- a/esphome/components/espnow/espnow.h +++ b/esphome/components/espnow/espnow.h @@ -5,7 +5,7 @@ #include "esphome/core/automation.h" #include "esphome/core/component.h" #include "esphome/core/helpers.h" -#include "espnow_packet.h" + #include #include @@ -18,6 +18,86 @@ namespace esphome { namespace espnow { +typedef uint8_t espnow_addr_t[6]; + +static const uint64_t ESPNOW_BROADCAST_ADDR = 0xFFFFFFFFFFFF; +static espnow_addr_t ESPNOW_ADDR_SELF = {0}; +static const uint8_t MAX_ESPNOW_DATA_SIZE = 240; + +static const uint32_t TRANSPORT_HEADER = 0xC19983; + +template std::string string_format(const std::string &format, Args... args) { + int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' + if (size_s <= 0) { + return ("Error during formatting."); + } + auto size = static_cast(size_s); + std::unique_ptr buf(new char[size]); + std::snprintf(buf.get(), size, format.c_str(), args...); + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside +} + +static uint8_t last_ref_id = 0; + +struct ESPNowPacket { + uint64_t mac64 = 0; + uint8_t size = 0; + uint8_t rssi = 0; + uint8_t retrys : 4; + uint8_t is_broadcast : 1; + uint8_t dummy : 3; + uint32_t timestamp = 0; + + union { + uint8_t content[MAX_ESPNOW_DATA_SIZE + 11]; + struct { + uint8_t header[3] = {0xC1, 0x99, 0x83}; + uint32_t app_id = 0xFFFFFF; + uint8_t ref_id = 0x99; + uint16_t crc16 = 0x1234; + uint8_t data[MAX_ESPNOW_DATA_SIZE]; + uint8_t space = 0; + } __attribute__((packed)); + }; + + ESPNowPacket() ESPHOME_ALWAYS_INLINE : retrys(0) {} + ESPNowPacket(uint64_t mac64, const uint8_t *data, uint8_t size, uint32_t app_id); + + inline void info(std::string place); + + inline void get_mac(espnow_addr_t *mac_addres) { std::memcpy(mac_addres, &mac64, 6); } + inline void set_mac(espnow_addr_t *mac_addres) { this->mac64 = this->to_mac64(mac_addres); } + + uint64_t to_mac64(espnow_addr_t *mac_addres) { + uint64_t result; + std::memcpy(&result, mac_addres, 6); + return result; + } + + void retry() { + if (this->retrys < 7) { + retrys = retrys + 1; + } + } + + inline void recalc() { + crc16 = 0; + crc16 = esp_crc16_le(ref_id, (uint8_t *) &content, 10 + size); + } + + bool is_valid(); + + inline std::string to_str(uint64_t mac64 = 0) { + espnow_addr_t mac; + if (mac64 == 0) + mac64 = this->mac64; + memcpy((void *) &mac, &mac64, 6); + return string_format("{\"%02x:%02x:%02x:%02x:%02x:%02x\"}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + } + + inline uint8_t *dataptr() { return (uint8_t *) &content; } +}; + class ESPNowComponent; static const uint32_t ESPNOW_DEFAULT_APP_ID = 0x11CFAF; diff --git a/esphome/components/espnow/espnow_packet.c b/esphome/components/espnow/espnow_packet.c deleted file mode 100644 index 3dbcdda2b5..0000000000 --- a/esphome/components/espnow/espnow_packet.c +++ /dev/null @@ -1,45 +0,0 @@ - -#if defined(USE_ESP32) -#include "espnow_packet.h" -#include "esphome/core/log.h" - -static const char *const TAG = "espnow_packet"; - -ESPNowPacket::ESPNowPacket(uint64_t mac64, const uint8_t *data, uint8_t size, uint32_t app_id) - : mac64(mac64), size(size), app_id(app_id), retrys(0) { - if (this->mac64 == 0) - this->mac64 = ESPNOW_BROADCAST_ADDR; - this->is_broadcast = this->mac64 == ESPNOW_BROADCAST_ADDR; - - this->ref_id = 0; - - this->size = std::min(MAX_ESPNOW_DATA_SIZE, size); - std::memcpy(&this->data, (uint8_t *) data, this->size); - - this->data[this->size + 1] = 0; - this->recalc(); - this->info("create"); -} - -inline void ESPNowPacket::info(std::string place) { - ESP_LOGVV(TAG, "%s: M:%s A:0x%06x R:0x%02x C:0x%04x S:%02x", place.c_str(), this->to_str().c_str(), this->app_id, - this->ref_id, this->random, this->size); -} - -bool ESPNowPacket::is_valid() { - uint16_t crc = this->crc16; - recalc(); - bool valid = (std::memcmp(&header, &TRANSPORT_HEADER, 3) == 0); - valid &= (this->app_id != 0); - valid &= (this->crc16 == crc); - if (!valid) { - ESP_LOGV("Packet", "Invalid H:%02x%02x%02x A:%06x R:%02x C:%04x ipv. %04x, %d&%d&%d=%d\n", this->header[0], - this->header[1], this->header[2], this->app_id, this->ref_id, crc, this->crc16, - std::memcmp(&header, &TRANSPORT_HEADER, 3) == 0, (this->app_id != 0), (this->crc16 == crc), valid); - } - - this->crc16 = crc; - return valid; -} - -#endif diff --git a/esphome/components/espnow/espnow_packet.h b/esphome/components/espnow/espnow_packet.h deleted file mode 100644 index e288cfa394..0000000000 --- a/esphome/components/espnow/espnow_packet.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#if defined(USE_ESP32) - -#include -#include -#include "esphome/core/helpers.h" - -#include "esp_crc.h" - -namespace esphome { -namespace espnow { - -typedef uint8_t espnow_addr_t[6]; - -static const uint64_t ESPNOW_BROADCAST_ADDR = 0xFFFFFFFFFFFF; -static espnow_addr_t ESPNOW_ADDR_SELF = {0}; -static const uint8_t MAX_ESPNOW_DATA_SIZE = 240; - -static const uint32_t TRANSPORT_HEADER = 0xC19983; - -template std::string string_format(const std::string &format, Args... args) { - int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' - if (size_s <= 0) { - return ("Error during formatting."); - } - auto size = static_cast(size_s); - std::unique_ptr buf(new char[size]); - std::snprintf(buf.get(), size, format.c_str(), args...); - return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside -} - -static uint8_t last_ref_id = 0; - -struct ESPNowPacket { - uint64_t mac64 = 0; - uint8_t size = 0; - uint8_t rssi = 0; - uint8_t retrys : 4; - uint8_t is_broadcast : 1; - uint8_t dummy : 3; - uint32_t timestamp = 0; - - union { - uint8_t content[MAX_ESPNOW_DATA_SIZE + 11]; - struct { - uint8_t header[3] = {0xC1, 0x99, 0x83}; - uint32_t app_id = 0xFFFFFF; - uint8_t ref_id = 0x99; - uint16_t crc16 = 0x1234; - uint8_t data[MAX_ESPNOW_DATA_SIZE]; - uint8_t space = 0; - } __attribute__((packed)); - }; - - ESPNowPacket() ESPHOME_ALWAYS_INLINE : retrys(0) {} - ESPNowPacket(uint64_t mac64, const uint8_t *data, uint8_t size, uint32_t app_id); - - inline void info(std::string place); - - inline void get_mac(espnow_addr_t *mac_addres) { std::memcpy(mac_addres, &mac64, 6); } - inline void set_mac(espnow_addr_t *mac_addres) { this->mac64 = this->to_mac64(mac_addres); } - - uint64_t to_mac64(espnow_addr_t *mac_addres) { - uint64_t result; - std::memcpy(&result, mac_addres, 6); - return result; - } - - void retry() { - if (this->retrys < 7) { - retrys = retrys + 1; - } - } - - inline void recalc() { - crc16 = 0; - crc16 = esp_crc16_le(ref_id, (uint8_t *) &content, 10 + size); - } - - bool is_valid(); - - inline std::string to_str(uint64_t mac64 = 0) { - espnow_addr_t mac; - if (mac64 == 0) - mac64 = this->mac64; - memcpy((void *) &mac, &mac64, 6); - return string_format("{\"%02x:%02x:%02x:%02x:%02x:%02x\"}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - } - - inline uint8_t *dataptr() { return (uint8_t *) &content; } -}; - -} // namespace espnow -} // namespace esphome - -#endif