mirror of
https://github.com/esphome/esphome.git
synced 2025-02-01 18:50:55 +00:00
make use of std::shared_ptr for the packet struct
This commit is contained in:
parent
020d331f7d
commit
9f5643f75e
@ -11,7 +11,7 @@ ESPNowComponent = espnow_ns.class_("ESPNowComponent", cg.Component)
|
||||
ESPNowListener = espnow_ns.class_("ESPNowListener")
|
||||
|
||||
ESPNowPacket = espnow_ns.class_("ESPNowPacket")
|
||||
ESPNowPacketPtrConst = ESPNowPacket.operator("ptr") # .operator("const")
|
||||
|
||||
|
||||
ESPNowInterface = espnow_ns.class_(
|
||||
"ESPNowInterface", cg.Component, cg.Parented.template(ESPNowComponent)
|
||||
@ -92,19 +92,21 @@ async def to_code(config):
|
||||
for conf in config.get(CONF_ON_SENT, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(
|
||||
trigger, [(ESPNowPacketPtrConst, "packet"), (bool, "status")], conf
|
||||
trigger,
|
||||
[(cg.std_shared_ptr.template(ESPNowPacket), "packet"), (bool, "status")],
|
||||
conf,
|
||||
)
|
||||
|
||||
for conf in config.get(CONF_ON_RECEIVE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(
|
||||
trigger, [(ESPNowPacketPtrConst, "packet")], conf
|
||||
trigger, [(cg.std_shared_ptr.template(ESPNowPacket), "packet")], conf
|
||||
)
|
||||
|
||||
for conf in config.get(CONF_ON_NEW_PEER, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(
|
||||
trigger, [(ESPNowPacketPtrConst, "packet")], conf
|
||||
trigger, [(cg.std_shared_ptr.template(ESPNowPacket), "packet")], conf
|
||||
)
|
||||
|
||||
for conf in config.get(CONF_PEERS, []):
|
||||
|
@ -39,7 +39,7 @@ std::string format_mac_addr(const uint8_t *mac) {
|
||||
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
return buf;
|
||||
}
|
||||
void show_packet(std::string title, ESPNowPacket *packet) {
|
||||
void show_packet(std::string title, ESPNowPacketPtr packet) {
|
||||
ESP_LOGVV(TAG, "%s packet: M:%s H:%cx%cx%c P:%c%c%c 0x%02x S:%02x C:ox%02x~0x%02x S:%02d V:%s", "test",
|
||||
format_mac_addr(packet->peer_as_bytes()).c_str(), packet->content_at(0), packet->content_at(1),
|
||||
packet->content_at(2), packet->content_at(3), packet->content_at(4), packet->content_at(5),
|
||||
@ -50,22 +50,20 @@ void show_packet(std::string title, ESPNowPacket *packet) {
|
||||
/* ESPNowPacket ********************************************************************** */
|
||||
|
||||
ESPNowPacket::ESPNowPacket(uint64_t peer, const uint8_t *data, uint8_t size, uint32_t protocol) : ESPNowPacket() {
|
||||
assert(size <= MAX_ESPNOW_DATA_SIZE);
|
||||
this->set_peer(peer);
|
||||
|
||||
this->is_broadcast =
|
||||
(std::memcmp((const void *) this->peer_as_bytes(), (const void *) &ESPNOW_BROADCAST_ADDR, 6) == 0);
|
||||
this->set_protocol(protocol);
|
||||
this->payload()->put_bytes(data, size);
|
||||
this->update_payload_();
|
||||
std::memcpy((uint8_t *) &this->content.payload, data, size);
|
||||
this->update_payload();
|
||||
}
|
||||
|
||||
ESPNowPacket::ESPNowPacket(uint64_t peer, const uint8_t *data, uint8_t size) : ESPNowPacket() {
|
||||
this->set_peer(peer);
|
||||
std::memcpy(&(this->content), data, this->prefix_size());
|
||||
size -= this->prefix_size();
|
||||
this->payload()->put_bytes(data + this->prefix_size(), size - 1);
|
||||
this->update_payload_();
|
||||
this->content.payload[this->size] = *(data + size);
|
||||
std::memcpy((uint8_t *) &this->content, data, size);
|
||||
this->size = size - 1;
|
||||
}
|
||||
|
||||
bool ESPNowPacket::is_valid() {
|
||||
@ -80,7 +78,7 @@ bool ESPNowPacket::is_valid() {
|
||||
/* ESPNowProtocol ********************************************************************** */
|
||||
|
||||
bool ESPNowProtocol::write(uint64_t peer, const uint8_t *data, uint8_t len) {
|
||||
ESPNowPacket *packet = new ESPNowPacket(peer, data, len, this->get_protocol_id());
|
||||
ESPNowPacketPtr packet = std::make_shared<ESPNowPacket>(peer, data, len, this->get_protocol_id());
|
||||
packet->set_sequents(this->get_next_sequents());
|
||||
return this->parent_->write(packet);
|
||||
}
|
||||
@ -217,21 +215,21 @@ ESPNowProtocol *ESPNowComponent::get_protocol_(uint32_t protocol) {
|
||||
return this->protocols_[protocol];
|
||||
}
|
||||
|
||||
void ESPNowComponent::on_receive_(ESPNowPacket *packet) {
|
||||
void ESPNowComponent::on_receive_(ESPNowPacketPtr packet) {
|
||||
ESPNowProtocol *protocol = this->get_protocol_(packet->get_protocol());
|
||||
if (protocol != nullptr) {
|
||||
protocol->on_receive(packet);
|
||||
}
|
||||
}
|
||||
|
||||
void ESPNowComponent::on_sent_(ESPNowPacket *packet, bool status) {
|
||||
void ESPNowComponent::on_sent_(ESPNowPacketPtr packet, bool status) {
|
||||
ESPNowProtocol *protocol = this->get_protocol_(packet->get_protocol());
|
||||
if (protocol != nullptr) {
|
||||
protocol->on_sent(packet, status);
|
||||
}
|
||||
}
|
||||
|
||||
void ESPNowComponent::on_new_peer_(ESPNowPacket *packet) {
|
||||
void ESPNowComponent::on_new_peer_(ESPNowPacketPtr packet) {
|
||||
ESPNowProtocol *protocol = this->get_protocol_(packet->get_protocol());
|
||||
if (protocol != nullptr) {
|
||||
protocol->on_new_peer(packet);
|
||||
@ -257,7 +255,7 @@ void ESPNowComponent::on_data_received(const uint8_t *addr, const uint8_t *data,
|
||||
(wifi_promiscuous_pkt_t *) (data - sizeof(wifi_pkt_rx_ctrl_t) - 39); // = sizeof (espnow_frame_format_t)
|
||||
rx_ctrl = &promiscuous_pkt->rx_ctrl;
|
||||
#endif
|
||||
ESPNowPacket *packet = new ESPNowPacket((uint64_t) *addr, data, (uint8_t) size);
|
||||
ESPNowPacketPtr packet = std::make_shared<ESPNowPacket>((uint64_t) *addr, data, (uint8_t) size);
|
||||
packet->is_broadcast = broadcast;
|
||||
if (rx_ctrl != nullptr) {
|
||||
packet->rssi = rx_ctrl->rssi;
|
||||
@ -268,13 +266,13 @@ void ESPNowComponent::on_data_received(const uint8_t *addr, const uint8_t *data,
|
||||
show_packet("Receive", packet);
|
||||
|
||||
if (packet->is_valid()) {
|
||||
xQueueSendToBack(global_esp_now->receive_queue_, packet, 10);
|
||||
xQueueSendToBack(global_esp_now->receive_queue_, packet.get(), 10);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Invalid ESP-NOW packet received (CRC)");
|
||||
}
|
||||
}
|
||||
|
||||
bool ESPNowComponent::write(ESPNowPacket *packet) {
|
||||
bool ESPNowComponent::write(ESPNowPacketPtr packet) {
|
||||
uint8_t *mac = packet->peer_as_bytes();
|
||||
show_packet("Write", packet);
|
||||
if (this->is_failed()) {
|
||||
@ -286,7 +284,7 @@ bool ESPNowComponent::write(ESPNowPacket *packet) {
|
||||
} else if (!packet->is_valid()) {
|
||||
ESP_LOGW(TAG, "Packet is invalid. maybe you need to ::calc_crc(). the packat before writing.");
|
||||
} else if (this->use_sent_check_) {
|
||||
xQueueSendToBack(this->send_queue_, packet, 10);
|
||||
xQueueSendToBack(this->send_queue_, packet.get(), 10);
|
||||
ESP_LOGVV(TAG, "Send to 0x%12llx (%d.%d): Buffer Used: %d", packet->peer, packet->get_sequents(), packet->attempts,
|
||||
this->send_queue_used());
|
||||
|
||||
@ -303,12 +301,11 @@ bool ESPNowComponent::write(ESPNowPacket *packet) {
|
||||
}
|
||||
|
||||
void ESPNowComponent::runner() {
|
||||
ESPNowPacket *packet{nullptr};
|
||||
ESPNowPacketPtr packet{nullptr};
|
||||
|
||||
for (;;) {
|
||||
delete packet;
|
||||
packet = new ESPNowPacket();
|
||||
if (xQueueReceive(this->receive_queue_, packet, (TickType_t) 1) == pdTRUE) {
|
||||
packet = std::make_shared<ESPNowPacket>();
|
||||
if (xQueueReceive(this->receive_queue_, packet.get(), (TickType_t) 1) == pdTRUE) {
|
||||
uint8_t *mac = packet->peer_as_bytes();
|
||||
|
||||
if (!esp_now_is_peer_exist(mac)) {
|
||||
@ -321,9 +318,8 @@ void ESPNowComponent::runner() {
|
||||
}
|
||||
this->defer([this, packet]() { this->on_receive_(packet); });
|
||||
}
|
||||
delete packet;
|
||||
packet = new ESPNowPacket();
|
||||
if (xQueueReceive(this->send_queue_, packet, (TickType_t) 1) == pdTRUE) {
|
||||
packet = std::make_shared<ESPNowPacket>();
|
||||
if (xQueueReceive(this->send_queue_, packet.get(), (TickType_t) 1) == pdTRUE) {
|
||||
if (packet->attempts > MAX_NUMBER_OF_RETRYS) {
|
||||
ESP_LOGW(TAG, "To many send retries. Packet dropped. 0x%04x", packet->get_sequents());
|
||||
this->unlock();
|
||||
@ -349,18 +345,18 @@ void ESPNowComponent::runner() {
|
||||
this->unlock();
|
||||
}
|
||||
}
|
||||
xQueueSendToFront(this->send_queue_, packet, 10 / portTICK_PERIOD_MS);
|
||||
xQueueSendToFront(this->send_queue_, packet.get(), 10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ESPNowComponent::on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) {
|
||||
ESPNowPacket *packet = new ESPNowPacket();
|
||||
ESPNowPacketPtr packet = std::make_shared<ESPNowPacket>();
|
||||
if (!global_esp_now->use_sent_check_) {
|
||||
return;
|
||||
}
|
||||
uint64_t mac64 = (uint64_t) *mac_addr;
|
||||
if (xQueuePeek(global_esp_now->send_queue_, packet, 10 / portTICK_PERIOD_MS) == pdTRUE) {
|
||||
if (xQueuePeek(global_esp_now->send_queue_, packet.get(), 10 / portTICK_PERIOD_MS) == pdTRUE) {
|
||||
if (status != ESP_OK) {
|
||||
ESP_LOGE(TAG, "sent packet failed (0x%04x.%d)", packet->get_sequents(), packet->attempts);
|
||||
} else if (packet->peer != mac64) {
|
||||
@ -369,10 +365,11 @@ void ESPNowComponent::on_data_sent(const uint8_t *mac_addr, esp_now_send_status_
|
||||
} else {
|
||||
ESP_LOGV(TAG, "Confirm sent (0x%04x.%d)", packet->get_sequents(), packet->attempts);
|
||||
global_esp_now->defer([packet]() {
|
||||
packet->reload();
|
||||
global_esp_now->on_sent_(packet, true);
|
||||
delete packet;
|
||||
ESPNowPacket tmp;
|
||||
xQueueReceive(global_esp_now->send_queue_, &tmp, 10 / portTICK_PERIOD_MS);
|
||||
auto tmp = std::make_shared<ESPNowPacket>();
|
||||
|
||||
xQueueReceive(global_esp_now->send_queue_, tmp.get(), 10 / portTICK_PERIOD_MS);
|
||||
|
||||
global_esp_now->unlock();
|
||||
});
|
||||
@ -380,9 +377,9 @@ void ESPNowComponent::on_data_sent(const uint8_t *mac_addr, esp_now_send_status_
|
||||
}
|
||||
global_esp_now->defer([packet]() {
|
||||
global_esp_now->on_sent_(packet, false);
|
||||
ESPNowPacket tmp;
|
||||
xQueueReceive(global_esp_now->send_queue_, &tmp, 10 / portTICK_PERIOD_MS);
|
||||
xQueueSendToFront(global_esp_now->send_queue_, &tmp, 10 / portTICK_PERIOD_MS);
|
||||
auto tmp = std::make_shared<ESPNowPacket>();
|
||||
xQueueReceive(global_esp_now->send_queue_, tmp.get(), 10 / portTICK_PERIOD_MS);
|
||||
xQueueSendToFront(global_esp_now->send_queue_, tmp.get(), 10 / portTICK_PERIOD_MS);
|
||||
|
||||
global_esp_now->unlock();
|
||||
});
|
||||
|
@ -58,7 +58,7 @@ struct ESPNowPacket {
|
||||
// Load received packet's.
|
||||
ESPNowPacket(uint64_t peer, const uint8_t *data, uint8_t size);
|
||||
|
||||
~ESPNowPacket() {} // this->payload_buffer_ = nullptr;
|
||||
~ESPNowPacket() { this->payload_buffer_.reset(); } // this->payload_buffer_ = nullptr;
|
||||
|
||||
uint8_t *peer_as_bytes() { return (uint8_t *) &(this->peer); }
|
||||
void set_peer(uint64_t peer) {
|
||||
@ -72,35 +72,35 @@ struct ESPNowPacket {
|
||||
inline uint8_t prefix_size() { return sizeof(this->content) - sizeof(this->content.payload); }
|
||||
|
||||
uint8_t get_size() {
|
||||
this->update_payload_();
|
||||
this->update_payload();
|
||||
return this->size;
|
||||
};
|
||||
|
||||
inline uint32_t get_protocol() { return this->content.protocol; }
|
||||
void set_protocol(uint32_t protocol) {
|
||||
this->content.protocol = protocol;
|
||||
this->update_payload_();
|
||||
this->update_payload();
|
||||
}
|
||||
|
||||
inline uint8_t get_sequents() { return this->content.sequents; }
|
||||
void set_sequents(uint8_t sequents) {
|
||||
this->content.sequents = sequents;
|
||||
this->update_payload_();
|
||||
this->update_payload();
|
||||
}
|
||||
|
||||
uint8_t content_at(uint8_t pos) {
|
||||
this->update_payload_();
|
||||
this->update_payload();
|
||||
assert(pos < this->size);
|
||||
return *(((uint8_t *) &this->content) + pos);
|
||||
}
|
||||
|
||||
uint8_t *content_bytes() {
|
||||
this->update_payload_();
|
||||
this->update_payload();
|
||||
return (uint8_t *) &(this->content);
|
||||
}
|
||||
|
||||
uint8_t crc() {
|
||||
// this->update_payload_();
|
||||
// this->update_payload();
|
||||
return this->content.payload[this->size];
|
||||
}
|
||||
uint8_t calc_crc() {
|
||||
@ -113,32 +113,43 @@ struct ESPNowPacket {
|
||||
bool is_valid();
|
||||
|
||||
std::shared_ptr<ByteBuffer> payload() {
|
||||
if (!this->payload_buffer_) {
|
||||
this->reload();
|
||||
}
|
||||
this->payload_buffer_->set_position(this->payload_buffer_->get_used_space());
|
||||
return this->payload_buffer_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<ByteBuffer> payload_buffer_;
|
||||
void reload() {
|
||||
this->payload_buffer_ = std::make_shared<ByteBuffer>(MAX_ESPNOW_DATA_SIZE);
|
||||
this->payload_buffer_->put_bytes((const uint8_t *) &this->content.payload, this->size - (this->prefix_size() + 1));
|
||||
this->payload_buffer_->is_changed();
|
||||
}
|
||||
|
||||
void update_payload_() {
|
||||
if (this->payload_buffer_->is_changed()) {
|
||||
void update_payload() {
|
||||
if (this->payload_buffer_ && this->payload_buffer_->is_changed()) {
|
||||
this->payload_buffer_->flip();
|
||||
this->payload_buffer_->get_bytes((uint8_t *) &(this->content.payload), this->payload_buffer_->get_used_space());
|
||||
this->size = this->payload_buffer_->get_used_space() + this->prefix_size();
|
||||
}
|
||||
this->content.payload[this->size] = this->calc_crc();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ByteBuffer> payload_buffer_;
|
||||
};
|
||||
|
||||
using ESPNowPacketPtr = std::shared_ptr<ESPNowPacket>;
|
||||
|
||||
class ESPNowComponent;
|
||||
|
||||
class ESPNowProtocol : public Parented<ESPNowComponent> {
|
||||
public:
|
||||
ESPNowProtocol(){};
|
||||
|
||||
virtual void on_receive(ESPNowPacket *packet){};
|
||||
virtual void on_sent(ESPNowPacket *packet, bool status){};
|
||||
virtual void on_new_peer(ESPNowPacket *packet){};
|
||||
virtual void on_receive(ESPNowPacketPtr packet){};
|
||||
virtual void on_sent(ESPNowPacketPtr packet, bool status){};
|
||||
virtual void on_new_peer(ESPNowPacketPtr packet){};
|
||||
|
||||
virtual uint32_t get_protocol_id() = 0;
|
||||
uint8_t get_next_sequents() {
|
||||
@ -165,29 +176,30 @@ class ESPNowProtocol : public Parented<ESPNowComponent> {
|
||||
protected:
|
||||
uint8_t next_sequents_{255};
|
||||
};
|
||||
|
||||
class ESPNowDefaultProtocol : public ESPNowProtocol {
|
||||
public:
|
||||
uint32_t get_protocol_id() override { return ESPNOW_MAIN_PROTOCOL_ID; };
|
||||
|
||||
void add_on_receive_callback(std::function<void(ESPNowPacket *)> &&callback) {
|
||||
void add_on_receive_callback(std::function<void(ESPNowPacketPtr)> &&callback) {
|
||||
this->on_receive_.add(std::move(callback));
|
||||
}
|
||||
void on_receive(ESPNowPacket *packet) override { this->on_receive_.call(packet); };
|
||||
void on_receive(ESPNowPacketPtr packet) override { this->on_receive_.call(packet); };
|
||||
|
||||
void add_on_sent_callback(std::function<void(ESPNowPacket *, bool status)> &&callback) {
|
||||
void add_on_sent_callback(std::function<void(ESPNowPacketPtr, bool status)> &&callback) {
|
||||
this->on_sent_.add(std::move(callback));
|
||||
}
|
||||
void on_sent(ESPNowPacket *packet, bool status) override { this->on_sent_.call(packet, status); };
|
||||
void on_sent(ESPNowPacketPtr packet, bool status) override { this->on_sent_.call(packet, status); };
|
||||
|
||||
void add_on_peer_callback(std::function<void(ESPNowPacket *)> &&callback) {
|
||||
void add_on_peer_callback(std::function<void(ESPNowPacketPtr)> &&callback) {
|
||||
this->on_new_peer_.add(std::move(callback));
|
||||
}
|
||||
void on_new_peer(ESPNowPacket *packet) override { this->on_new_peer_.call(packet); };
|
||||
void on_new_peer(ESPNowPacketPtr packet) override { this->on_new_peer_.call(packet); };
|
||||
|
||||
protected:
|
||||
CallbackManager<void(ESPNowPacket *, bool)> on_sent_;
|
||||
CallbackManager<void(ESPNowPacket *)> on_receive_;
|
||||
CallbackManager<void(ESPNowPacket *)> on_new_peer_;
|
||||
CallbackManager<void(ESPNowPacketPtr, bool)> on_sent_;
|
||||
CallbackManager<void(ESPNowPacketPtr)> on_receive_;
|
||||
CallbackManager<void(ESPNowPacketPtr)> on_new_peer_;
|
||||
};
|
||||
|
||||
class ESPNowComponent : public Component {
|
||||
@ -214,7 +226,7 @@ class ESPNowComponent : public Component {
|
||||
|
||||
void runner();
|
||||
|
||||
bool write(ESPNowPacket *packet);
|
||||
bool write(ESPNowPacketPtr packet);
|
||||
|
||||
void register_protocol(ESPNowProtocol *protocol) {
|
||||
protocol->set_parent(this);
|
||||
@ -245,9 +257,9 @@ class ESPNowComponent : public Component {
|
||||
bool use_sent_check_{true};
|
||||
bool lock_{false};
|
||||
|
||||
void on_receive_(ESPNowPacket *packet);
|
||||
void on_sent_(ESPNowPacket *packet, bool status);
|
||||
void on_new_peer_(ESPNowPacket *packet);
|
||||
void on_receive_(ESPNowPacketPtr packet);
|
||||
void on_sent_(ESPNowPacketPtr packet, bool status);
|
||||
void on_new_peer_(ESPNowPacketPtr packet);
|
||||
|
||||
QueueHandle_t receive_queue_{};
|
||||
QueueHandle_t send_queue_{};
|
||||
@ -312,25 +324,25 @@ template<typename... Ts> class DelPeerAction : public Action<Ts...>, public Pare
|
||||
TemplatableValue<uint64_t, Ts...> mac_{};
|
||||
};
|
||||
|
||||
class ESPNowSentTrigger : public Trigger<ESPNowPacket *, bool> {
|
||||
class ESPNowSentTrigger : public Trigger<ESPNowPacketPtr, bool> {
|
||||
public:
|
||||
explicit ESPNowSentTrigger(ESPNowComponent *parent) {
|
||||
parent->get_default_protocol()->add_on_sent_callback(
|
||||
[this](ESPNowPacket *packet, bool status) { this->trigger(packet, status); });
|
||||
[this](ESPNowPacketPtr packet, bool status) { this->trigger(packet, status); });
|
||||
}
|
||||
};
|
||||
|
||||
class ESPNowReceiveTrigger : public Trigger<ESPNowPacket *> {
|
||||
class ESPNowReceiveTrigger : public Trigger<ESPNowPacketPtr> {
|
||||
public:
|
||||
explicit ESPNowReceiveTrigger(ESPNowComponent *parent) {
|
||||
parent->get_default_protocol()->add_on_receive_callback([this](ESPNowPacket *packet) { this->trigger(packet); });
|
||||
parent->get_default_protocol()->add_on_receive_callback([this](ESPNowPacketPtr packet) { this->trigger(packet); });
|
||||
}
|
||||
};
|
||||
|
||||
class ESPNowNewPeerTrigger : public Trigger<ESPNowPacket *> {
|
||||
class ESPNowNewPeerTrigger : public Trigger<ESPNowPacketPtr> {
|
||||
public:
|
||||
explicit ESPNowNewPeerTrigger(ESPNowComponent *parent) {
|
||||
parent->get_default_protocol()->add_on_peer_callback([this](ESPNowPacket *packet) { this->trigger(packet); });
|
||||
parent->get_default_protocol()->add_on_peer_callback([this](ESPNowPacketPtr packet) { this->trigger(packet); });
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user