mirror of
https://github.com/esphome/esphome.git
synced 2024-12-18 19:44:53 +01:00
move packet strucutr into main file
This commit is contained in:
parent
4fe0aa57eb
commit
88232ae65f
4 changed files with 118 additions and 143 deletions
|
@ -55,6 +55,43 @@ struct {
|
||||||
} __attribute__((packed)) espnow_frame_format_t;
|
} __attribute__((packed)) espnow_frame_format_t;
|
||||||
#endif
|
#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); }
|
void ESPNowProtocol::setup() { parent_->register_protocol(this); }
|
||||||
|
|
||||||
bool ESPNowProtocol::write(uint64_t mac_address, const uint8_t *data, uint8_t len) {
|
bool ESPNowProtocol::write(uint64_t mac_address, const uint8_t *data, uint8_t len) {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "esphome/core/automation.h"
|
#include "esphome/core/automation.h"
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
#include "espnow_packet.h"
|
|
||||||
#include <esp_now.h>
|
#include <esp_now.h>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -18,6 +18,86 @@
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace espnow {
|
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<typename... Args> 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_t>(size_s);
|
||||||
|
std::unique_ptr<char[]> 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;
|
class ESPNowComponent;
|
||||||
|
|
||||||
static const uint32_t ESPNOW_DEFAULT_APP_ID = 0x11CFAF;
|
static const uint32_t ESPNOW_DEFAULT_APP_ID = 0x11CFAF;
|
||||||
|
|
|
@ -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
|
|
|
@ -1,97 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined(USE_ESP32)
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#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<typename... Args> 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_t>(size_s);
|
|
||||||
std::unique_ptr<char[]> 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
|
|
Loading…
Reference in a new issue