mirror of
https://github.com/esphome/esphome.git
synced 2025-09-15 09:42:19 +01:00
adjust
This commit is contained in:
@@ -306,11 +306,11 @@ void ESP32BLE::loop() {
|
|||||||
switch (ble_event->type_) {
|
switch (ble_event->type_) {
|
||||||
case BLEEvent::GATTS:
|
case BLEEvent::GATTS:
|
||||||
this->real_gatts_event_handler_(ble_event->event_.gatts.gatts_event, ble_event->event_.gatts.gatts_if,
|
this->real_gatts_event_handler_(ble_event->event_.gatts.gatts_event, ble_event->event_.gatts.gatts_if,
|
||||||
&ble_event->event_.gatts.gatts_param);
|
ble_event->event_.gatts.gatts_param);
|
||||||
break;
|
break;
|
||||||
case BLEEvent::GATTC:
|
case BLEEvent::GATTC:
|
||||||
this->real_gattc_event_handler_(ble_event->event_.gattc.gattc_event, ble_event->event_.gattc.gattc_if,
|
this->real_gattc_event_handler_(ble_event->event_.gattc.gattc_event, ble_event->event_.gattc.gattc_if,
|
||||||
&ble_event->event_.gattc.gattc_param);
|
ble_event->event_.gattc.gattc_param);
|
||||||
break;
|
break;
|
||||||
case BLEEvent::GAP: {
|
case BLEEvent::GAP: {
|
||||||
esp_gap_ble_cb_event_t gap_event = ble_event->event_.gap.gap_event;
|
esp_gap_ble_cb_event_t gap_event = ble_event->event_.gap.gap_event;
|
||||||
@@ -341,6 +341,7 @@ void ESP32BLE::loop() {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Destructor will clean up external allocations for GATTC/GATTS
|
||||||
ble_event->~BLEEvent();
|
ble_event->~BLEEvent();
|
||||||
EVENT_ALLOCATOR.deallocate(ble_event, 1);
|
EVENT_ALLOCATOR.deallocate(ble_event, 1);
|
||||||
ble_event = this->ble_events_.pop();
|
ble_event = this->ble_events_.pop();
|
||||||
|
@@ -14,12 +14,25 @@ namespace esphome {
|
|||||||
namespace esp32_ble {
|
namespace esp32_ble {
|
||||||
|
|
||||||
// Received GAP, GATTC and GATTS events are only queued, and get processed in the main loop().
|
// Received GAP, GATTC and GATTS events are only queued, and get processed in the main loop().
|
||||||
// This class stores each event with minimal memory usage by only copying the data we actually need.
|
// This class stores each event with minimal memory usage.
|
||||||
|
// GAP events (99% of traffic) don't have the vector overhead.
|
||||||
|
// GATTC/GATTS events use external storage for their param and data.
|
||||||
class BLEEvent {
|
class BLEEvent {
|
||||||
public:
|
public:
|
||||||
|
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||||
|
enum ble_event_t : uint8_t {
|
||||||
|
GAP,
|
||||||
|
GATTC,
|
||||||
|
GATTS,
|
||||||
|
};
|
||||||
|
|
||||||
|
BLEEvent() = default;
|
||||||
|
|
||||||
|
// Constructor for GAP events - no external allocations needed
|
||||||
BLEEvent(esp_gap_ble_cb_event_t e, esp_ble_gap_cb_param_t *p) {
|
BLEEvent(esp_gap_ble_cb_event_t e, esp_ble_gap_cb_param_t *p) {
|
||||||
this->type_ = GAP;
|
this->type_ = GAP;
|
||||||
this->event_.gap.gap_event = e;
|
this->event_.gap.gap_event = e;
|
||||||
|
this->event_.gap.ext_data = nullptr; // GAP events don't use external data
|
||||||
|
|
||||||
// Only copy the data we actually use for each GAP event type
|
// Only copy the data we actually use for each GAP event type
|
||||||
switch (e) {
|
switch (e) {
|
||||||
@@ -49,97 +62,117 @@ class BLEEvent {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
// We only handle 4 GAP event types, others are dropped
|
// We only handle 4 GAP event types, others are dropped
|
||||||
// This should never happen in normal operation
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Constructor for GATTC events - uses external storage
|
||||||
BLEEvent(esp_gattc_cb_event_t e, esp_gatt_if_t i, esp_ble_gattc_cb_param_t *p) {
|
BLEEvent(esp_gattc_cb_event_t e, esp_gatt_if_t i, esp_ble_gattc_cb_param_t *p) {
|
||||||
this->type_ = GATTC;
|
this->type_ = GATTC;
|
||||||
this->event_.gattc.gattc_event = e;
|
this->event_.gattc.gattc_event = e;
|
||||||
this->event_.gattc.gattc_if = i;
|
this->event_.gattc.gattc_if = i;
|
||||||
memcpy(&this->event_.gattc.gattc_param, p, sizeof(esp_ble_gattc_cb_param_t));
|
|
||||||
|
// Allocate external storage for param and data
|
||||||
|
this->event_.gattc.gattc_param = new esp_ble_gattc_cb_param_t(*p);
|
||||||
|
|
||||||
// Copy data for events that need it
|
// Copy data for events that need it
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case ESP_GATTC_NOTIFY_EVT:
|
case ESP_GATTC_NOTIFY_EVT:
|
||||||
this->data.assign(p->notify.value, p->notify.value + p->notify.value_len);
|
this->event_.gattc.data = new std::vector<uint8_t>(p->notify.value, p->notify.value + p->notify.value_len);
|
||||||
this->event_.gattc.gattc_param.notify.value = this->data.data();
|
this->event_.gattc.gattc_param->notify.value = this->event_.gattc.data->data();
|
||||||
break;
|
break;
|
||||||
case ESP_GATTC_READ_CHAR_EVT:
|
case ESP_GATTC_READ_CHAR_EVT:
|
||||||
case ESP_GATTC_READ_DESCR_EVT:
|
case ESP_GATTC_READ_DESCR_EVT:
|
||||||
this->data.assign(p->read.value, p->read.value + p->read.value_len);
|
this->event_.gattc.data = new std::vector<uint8_t>(p->read.value, p->read.value + p->read.value_len);
|
||||||
this->event_.gattc.gattc_param.read.value = this->data.data();
|
this->event_.gattc.gattc_param->read.value = this->event_.gattc.data->data();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
this->event_.gattc.data = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Constructor for GATTS events - uses external storage
|
||||||
BLEEvent(esp_gatts_cb_event_t e, esp_gatt_if_t i, esp_ble_gatts_cb_param_t *p) {
|
BLEEvent(esp_gatts_cb_event_t e, esp_gatt_if_t i, esp_ble_gatts_cb_param_t *p) {
|
||||||
this->type_ = GATTS;
|
this->type_ = GATTS;
|
||||||
this->event_.gatts.gatts_event = e;
|
this->event_.gatts.gatts_event = e;
|
||||||
this->event_.gatts.gatts_if = i;
|
this->event_.gatts.gatts_if = i;
|
||||||
memcpy(&this->event_.gatts.gatts_param, p, sizeof(esp_ble_gatts_cb_param_t));
|
|
||||||
|
// Allocate external storage for param and data
|
||||||
|
this->event_.gatts.gatts_param = new esp_ble_gatts_cb_param_t(*p);
|
||||||
|
|
||||||
// Copy data for events that need it
|
// Copy data for events that need it
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case ESP_GATTS_WRITE_EVT:
|
case ESP_GATTS_WRITE_EVT:
|
||||||
this->data.assign(p->write.value, p->write.value + p->write.len);
|
this->event_.gatts.data = new std::vector<uint8_t>(p->write.value, p->write.value + p->write.len);
|
||||||
this->event_.gatts.gatts_param.write.value = this->data.data();
|
this->event_.gatts.gatts_param->write.value = this->event_.gatts.data->data();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this->event_.gatts.data = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor to clean up external allocations
|
||||||
|
~BLEEvent() {
|
||||||
|
switch (this->type_) {
|
||||||
|
case GATTC:
|
||||||
|
delete this->event_.gattc.gattc_param;
|
||||||
|
delete this->event_.gattc.data;
|
||||||
|
break;
|
||||||
|
case GATTS:
|
||||||
|
delete this->event_.gatts.gatts_param;
|
||||||
|
delete this->event_.gatts.data;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Disable copy to prevent double-delete
|
||||||
|
BLEEvent(const BLEEvent &) = delete;
|
||||||
|
BLEEvent &operator=(const BLEEvent &) = delete;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||||
struct gap_event {
|
struct gap_event {
|
||||||
esp_gap_ble_cb_event_t gap_event;
|
esp_gap_ble_cb_event_t gap_event;
|
||||||
|
void *ext_data; // Always nullptr for GAP, just for alignment
|
||||||
union {
|
union {
|
||||||
BLEScanResult scan_result; // ~73 bytes
|
BLEScanResult scan_result; // 73 bytes
|
||||||
|
|
||||||
// Minimal storage for scan complete events
|
|
||||||
struct {
|
struct {
|
||||||
esp_bt_status_t status;
|
esp_bt_status_t status;
|
||||||
} scan_complete; // 1 byte
|
} scan_complete; // 1 byte
|
||||||
|
|
||||||
// We only handle 4 GAP event types, no need for full fallback
|
|
||||||
// If we ever get an unexpected event, we'll just drop it in ble.cpp
|
|
||||||
};
|
};
|
||||||
} gap; // ~73 bytes (size of BLEScanResult)
|
} gap; // 80 bytes (with alignment)
|
||||||
|
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||||
struct gattc_event {
|
struct gattc_event {
|
||||||
esp_gattc_cb_event_t gattc_event;
|
esp_gattc_cb_event_t gattc_event;
|
||||||
esp_gatt_if_t gattc_if;
|
esp_gatt_if_t gattc_if;
|
||||||
esp_ble_gattc_cb_param_t gattc_param;
|
esp_ble_gattc_cb_param_t *gattc_param; // External allocation
|
||||||
} gattc; // ~68 bytes
|
std::vector<uint8_t> *data; // External allocation
|
||||||
|
} gattc; // 16 bytes (4 + 4 + 4 + 4)
|
||||||
|
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||||
struct gatts_event {
|
struct gatts_event {
|
||||||
esp_gatts_cb_event_t gatts_event;
|
esp_gatts_cb_event_t gatts_event;
|
||||||
esp_gatt_if_t gatts_if;
|
esp_gatt_if_t gatts_if;
|
||||||
esp_ble_gatts_cb_param_t gatts_param;
|
esp_ble_gatts_cb_param_t *gatts_param; // External allocation
|
||||||
} gatts; // ~68 bytes
|
std::vector<uint8_t> *data; // External allocation
|
||||||
} event_; // Union size is now ~73 bytes (BLEScanResult is largest)
|
} gatts; // 16 bytes (4 + 4 + 4 + 4)
|
||||||
|
} event_; // Union size is 80 bytes (largest member is gap)
|
||||||
|
|
||||||
std::vector<uint8_t> data{}; // For GATTC/GATTS data
|
ble_event_t type_;
|
||||||
|
|
||||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
|
||||||
enum ble_event_t : uint8_t {
|
|
||||||
GAP,
|
|
||||||
GATTC,
|
|
||||||
GATTS,
|
|
||||||
} type_;
|
|
||||||
|
|
||||||
// Helper methods to access event data
|
// Helper methods to access event data
|
||||||
|
ble_event_t type() const { return type_; }
|
||||||
esp_gap_ble_cb_event_t gap_event_type() const { return event_.gap.gap_event; }
|
esp_gap_ble_cb_event_t gap_event_type() const { return event_.gap.gap_event; }
|
||||||
const BLEScanResult &scan_result() const { return event_.gap.scan_result; }
|
const BLEScanResult &scan_result() const { return event_.gap.scan_result; }
|
||||||
esp_bt_status_t scan_complete_status() const { return event_.gap.scan_complete.status; }
|
esp_bt_status_t scan_complete_status() const { return event_.gap.scan_complete.status; }
|
||||||
};
|
};
|
||||||
// Total size: ~100 bytes instead of 440 bytes!
|
// Total size for GAP events: ~84 bytes (was 296 bytes - 71.6% reduction!)
|
||||||
|
// GATTC/GATTS events use external storage, keeping the queue size minimal
|
||||||
|
|
||||||
} // namespace esp32_ble
|
} // namespace esp32_ble
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
Reference in New Issue
Block a user