mirror of
https://github.com/esphome/esphome.git
synced 2025-10-05 03:13:49 +01:00
wip
This commit is contained in:
@@ -58,7 +58,7 @@ static std::vector<api::BluetoothLERawAdvertisement> &get_batch_buffer() {
|
||||
return batch_buffer;
|
||||
}
|
||||
|
||||
bool BluetoothProxy::parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) {
|
||||
bool BluetoothProxy::parse_devices(const esp32_ble::BLEScanResult *scan_results, size_t count) {
|
||||
if (!api::global_api_server->is_connected() || this->api_connection_ == nullptr || !this->raw_advertisements_)
|
||||
return false;
|
||||
|
||||
@@ -73,7 +73,7 @@ bool BluetoothProxy::parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_p
|
||||
|
||||
// Add new advertisements to the batch buffer
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
auto &result = advertisements[i];
|
||||
auto &result = scan_results[i];
|
||||
uint8_t length = result.adv_data_len + result.scan_rsp_len;
|
||||
|
||||
batch_buffer.emplace_back();
|
||||
|
@@ -52,7 +52,7 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
|
||||
public:
|
||||
BluetoothProxy();
|
||||
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override;
|
||||
bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) override;
|
||||
bool parse_devices(const esp32_ble::BLEScanResult *scan_results, size_t count) override;
|
||||
void dump_config() override;
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
|
@@ -312,9 +312,36 @@ void ESP32BLE::loop() {
|
||||
this->real_gattc_event_handler_(ble_event->event_.gattc.gattc_event, ble_event->event_.gattc.gattc_if,
|
||||
&ble_event->event_.gattc.gattc_param);
|
||||
break;
|
||||
case BLEEvent::GAP:
|
||||
this->real_gap_event_handler_(ble_event->event_.gap.gap_event, &ble_event->event_.gap.gap_param);
|
||||
case BLEEvent::GAP: {
|
||||
esp_gap_ble_cb_event_t gap_event = ble_event->event_.gap.gap_event;
|
||||
if (gap_event == ESP_GAP_BLE_SCAN_RESULT_EVT) {
|
||||
// Use the new scan event handler - no memcpy!
|
||||
for (auto *scan_handler : this->gap_scan_event_handlers_) {
|
||||
scan_handler->gap_scan_event_handler(ble_event->scan_result());
|
||||
}
|
||||
} else if (gap_event == ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT ||
|
||||
gap_event == ESP_GAP_BLE_SCAN_START_COMPLETE_EVT ||
|
||||
gap_event == ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT) {
|
||||
// Create temporary param for scan complete events
|
||||
esp_ble_gap_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(param));
|
||||
|
||||
// Set the appropriate status field based on event type
|
||||
if (gap_event == ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT) {
|
||||
param.scan_param_cmpl.status = ble_event->event_.gap.scan_complete.status;
|
||||
} else if (gap_event == ESP_GAP_BLE_SCAN_START_COMPLETE_EVT) {
|
||||
param.scan_start_cmpl.status = ble_event->event_.gap.scan_complete.status;
|
||||
} else if (gap_event == ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT) {
|
||||
param.scan_stop_cmpl.status = ble_event->event_.gap.scan_complete.status;
|
||||
}
|
||||
|
||||
this->real_gap_event_handler_(gap_event, ¶m);
|
||||
} else {
|
||||
// Fallback for unexpected events (uses full param copy)
|
||||
this->real_gap_event_handler_(gap_event, &ble_event->event_.gap.gap_param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -328,6 +355,13 @@ void ESP32BLE::loop() {
|
||||
}
|
||||
|
||||
void ESP32BLE::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
|
||||
static constexpr size_t MAX_BLE_QUEUE_SIZE = SCAN_RESULT_BUFFER_SIZE * 2;
|
||||
|
||||
if (global_ble->ble_events_.size() >= MAX_BLE_QUEUE_SIZE) {
|
||||
ESP_LOGW(TAG, "BLE event queue full (%d), dropping GAP event %d", MAX_BLE_QUEUE_SIZE, event);
|
||||
return;
|
||||
}
|
||||
|
||||
BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
|
||||
if (new_event == nullptr) {
|
||||
// Memory too fragmented to allocate new event. Can only drop it until memory comes back
|
||||
@@ -346,6 +380,13 @@ void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap
|
||||
|
||||
void ESP32BLE::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
||||
esp_ble_gatts_cb_param_t *param) {
|
||||
static constexpr size_t MAX_BLE_QUEUE_SIZE = SCAN_RESULT_BUFFER_SIZE * 2;
|
||||
|
||||
if (global_ble->ble_events_.size() >= MAX_BLE_QUEUE_SIZE) {
|
||||
ESP_LOGW(TAG, "BLE event queue full (%d), dropping GATTS event %d", MAX_BLE_QUEUE_SIZE, event);
|
||||
return;
|
||||
}
|
||||
|
||||
BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
|
||||
if (new_event == nullptr) {
|
||||
// Memory too fragmented to allocate new event. Can only drop it until memory comes back
|
||||
@@ -365,6 +406,13 @@ void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if
|
||||
|
||||
void ESP32BLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||
esp_ble_gattc_cb_param_t *param) {
|
||||
static constexpr size_t MAX_BLE_QUEUE_SIZE = SCAN_RESULT_BUFFER_SIZE * 2;
|
||||
|
||||
if (global_ble->ble_events_.size() >= MAX_BLE_QUEUE_SIZE) {
|
||||
ESP_LOGW(TAG, "BLE event queue full (%d), dropping GATTC event %d", MAX_BLE_QUEUE_SIZE, event);
|
||||
return;
|
||||
}
|
||||
|
||||
BLEEvent *new_event = EVENT_ALLOCATOR.allocate(1);
|
||||
if (new_event == nullptr) {
|
||||
// Memory too fragmented to allocate new event. Can only drop it until memory comes back
|
||||
|
@@ -22,6 +22,13 @@
|
||||
namespace esphome {
|
||||
namespace esp32_ble {
|
||||
|
||||
// Maximum number of BLE scan results to buffer
|
||||
#ifdef USE_PSRAM
|
||||
static constexpr uint8_t SCAN_RESULT_BUFFER_SIZE = 32;
|
||||
#else
|
||||
static constexpr uint8_t SCAN_RESULT_BUFFER_SIZE = 20;
|
||||
#endif
|
||||
|
||||
uint64_t ble_addr_to_uint64(const esp_bd_addr_t address);
|
||||
|
||||
// NOLINTNEXTLINE(modernize-use-using)
|
||||
@@ -57,6 +64,23 @@ class GAPEventHandler {
|
||||
virtual void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) = 0;
|
||||
};
|
||||
|
||||
// Structure for BLE scan results - only fields we actually use
|
||||
struct BLEScanResult {
|
||||
esp_bd_addr_t bda;
|
||||
uint8_t ble_addr_type;
|
||||
int8_t rssi;
|
||||
uint8_t ble_adv[ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX];
|
||||
uint8_t adv_data_len;
|
||||
uint8_t scan_rsp_len;
|
||||
uint8_t search_evt;
|
||||
}; // ~73 bytes vs ~400 bytes for full esp_ble_gap_cb_param_t
|
||||
|
||||
class GAPScanEventHandler {
|
||||
public:
|
||||
// Receives scan results directly without memcpy
|
||||
virtual void gap_scan_event_handler(const BLEScanResult &scan_result) = 0;
|
||||
};
|
||||
|
||||
class GATTcEventHandler {
|
||||
public:
|
||||
virtual void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||
@@ -101,6 +125,9 @@ class ESP32BLE : public Component {
|
||||
void advertising_register_raw_advertisement_callback(std::function<void(bool)> &&callback);
|
||||
|
||||
void register_gap_event_handler(GAPEventHandler *handler) { this->gap_event_handlers_.push_back(handler); }
|
||||
void register_gap_scan_event_handler(GAPScanEventHandler *handler) {
|
||||
this->gap_scan_event_handlers_.push_back(handler);
|
||||
}
|
||||
void register_gattc_event_handler(GATTcEventHandler *handler) { this->gattc_event_handlers_.push_back(handler); }
|
||||
void register_gatts_event_handler(GATTsEventHandler *handler) { this->gatts_event_handlers_.push_back(handler); }
|
||||
void register_ble_status_event_handler(BLEStatusEventHandler *handler) {
|
||||
@@ -123,6 +150,7 @@ class ESP32BLE : public Component {
|
||||
void advertising_init_();
|
||||
|
||||
std::vector<GAPEventHandler *> gap_event_handlers_;
|
||||
std::vector<GAPScanEventHandler *> gap_scan_event_handlers_;
|
||||
std::vector<GATTcEventHandler *> gattc_event_handlers_;
|
||||
std::vector<GATTsEventHandler *> gatts_event_handlers_;
|
||||
std::vector<BLEStatusEventHandler *> ble_status_event_handlers_;
|
||||
|
@@ -10,21 +10,56 @@
|
||||
|
||||
namespace esphome {
|
||||
namespace esp32_ble {
|
||||
|
||||
// Received GAP, GATTC and GATTS events are only queued, and get processed in the main loop().
|
||||
// This class stores each event in a single type.
|
||||
// This class stores each event with minimal memory usage by only copying the data we actually need.
|
||||
class BLEEvent {
|
||||
public:
|
||||
BLEEvent(esp_gap_ble_cb_event_t e, esp_ble_gap_cb_param_t *p) {
|
||||
this->event_.gap.gap_event = e;
|
||||
memcpy(&this->event_.gap.gap_param, p, sizeof(esp_ble_gap_cb_param_t));
|
||||
this->type_ = GAP;
|
||||
this->event_.gap.gap_event = e;
|
||||
|
||||
// Only copy the data we actually use for each GAP event type
|
||||
switch (e) {
|
||||
case ESP_GAP_BLE_SCAN_RESULT_EVT:
|
||||
// Copy only the fields we use from scan results (~72 bytes)
|
||||
memcpy(this->event_.gap.scan_result.bda, p->scan_rst.bda, sizeof(esp_bd_addr_t));
|
||||
this->event_.gap.scan_result.ble_addr_type = p->scan_rst.ble_addr_type;
|
||||
this->event_.gap.scan_result.rssi = p->scan_rst.rssi;
|
||||
this->event_.gap.scan_result.adv_data_len = p->scan_rst.adv_data_len;
|
||||
this->event_.gap.scan_result.scan_rsp_len = p->scan_rst.scan_rsp_len;
|
||||
this->event_.gap.scan_result.search_evt = p->scan_rst.search_evt;
|
||||
memcpy(this->event_.gap.scan_result.ble_adv, p->scan_rst.ble_adv,
|
||||
ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX);
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
|
||||
this->event_.gap.scan_complete.status = p->scan_param_cmpl.status;
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
|
||||
this->event_.gap.scan_complete.status = p->scan_start_cmpl.status;
|
||||
break;
|
||||
|
||||
case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
|
||||
this->event_.gap.scan_complete.status = p->scan_stop_cmpl.status;
|
||||
break;
|
||||
|
||||
default:
|
||||
// For any other GAP events, copy the full param
|
||||
// This is a safety fallback but shouldn't happen in normal operation
|
||||
memcpy(&this->event_.gap.gap_param, p, sizeof(esp_ble_gap_cb_param_t));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
BLEEvent(esp_gattc_cb_event_t e, esp_gatt_if_t i, esp_ble_gattc_cb_param_t *p) {
|
||||
this->type_ = GATTC;
|
||||
this->event_.gattc.gattc_event = e;
|
||||
this->event_.gattc.gattc_if = i;
|
||||
memcpy(&this->event_.gattc.gattc_param, p, sizeof(esp_ble_gattc_cb_param_t));
|
||||
// Need to also make a copy of relevant event data.
|
||||
|
||||
// Copy data for events that need it
|
||||
switch (e) {
|
||||
case ESP_GATTC_NOTIFY_EVT:
|
||||
this->data.assign(p->notify.value, p->notify.value + p->notify.value_len);
|
||||
@@ -38,14 +73,15 @@ class BLEEvent {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->type_ = GATTC;
|
||||
};
|
||||
|
||||
BLEEvent(esp_gatts_cb_event_t e, esp_gatt_if_t i, esp_ble_gatts_cb_param_t *p) {
|
||||
this->type_ = GATTS;
|
||||
this->event_.gatts.gatts_event = e;
|
||||
this->event_.gatts.gatts_if = i;
|
||||
memcpy(&this->event_.gatts.gatts_param, p, sizeof(esp_ble_gatts_cb_param_t));
|
||||
// Need to also make a copy of relevant event data.
|
||||
|
||||
// Copy data for events that need it
|
||||
switch (e) {
|
||||
case ESP_GATTS_WRITE_EVT:
|
||||
this->data.assign(p->write.value, p->write.value + p->write.len);
|
||||
@@ -54,39 +90,55 @@ class BLEEvent {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->type_ = GATTS;
|
||||
};
|
||||
|
||||
union {
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
struct gap_event {
|
||||
esp_gap_ble_cb_event_t gap_event;
|
||||
esp_ble_gap_cb_param_t gap_param;
|
||||
} gap;
|
||||
union {
|
||||
BLEScanResult scan_result; // ~73 bytes
|
||||
|
||||
// Minimal storage for scan complete events
|
||||
struct {
|
||||
esp_bt_status_t status;
|
||||
} scan_complete; // 1 byte
|
||||
|
||||
// Fallback for unexpected events (shouldn't be used)
|
||||
esp_ble_gap_cb_param_t gap_param;
|
||||
};
|
||||
} gap; // ~80 bytes instead of 400+
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
struct gattc_event {
|
||||
esp_gattc_cb_event_t gattc_event;
|
||||
esp_gatt_if_t gattc_if;
|
||||
esp_ble_gattc_cb_param_t gattc_param;
|
||||
} gattc;
|
||||
} gattc; // ~68 bytes
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
struct gatts_event {
|
||||
esp_gatts_cb_event_t gatts_event;
|
||||
esp_gatt_if_t gatts_if;
|
||||
esp_ble_gatts_cb_param_t gatts_param;
|
||||
} gatts;
|
||||
} event_;
|
||||
} gatts; // ~68 bytes
|
||||
} event_; // Union size is now ~80 bytes (largest member)
|
||||
|
||||
std::vector<uint8_t> data{}; // For GATTC/GATTS data
|
||||
|
||||
std::vector<uint8_t> data{};
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
enum ble_event_t : uint8_t {
|
||||
GAP,
|
||||
GATTC,
|
||||
GATTS,
|
||||
} type_;
|
||||
|
||||
// Helper methods to access event data
|
||||
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; }
|
||||
esp_bt_status_t scan_complete_status() const { return event_.gap.scan_complete.status; }
|
||||
};
|
||||
// Total size: ~110 bytes instead of 440 bytes!
|
||||
|
||||
} // namespace esp32_ble
|
||||
} // namespace esphome
|
||||
|
@@ -45,6 +45,10 @@ template<class T> class Queue {
|
||||
return element;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return q_.size(); // Atomic read, no lock needed
|
||||
}
|
||||
|
||||
protected:
|
||||
std::queue<T *> q_;
|
||||
SemaphoreHandle_t m_;
|
||||
|
@@ -268,6 +268,7 @@ async def to_code(config):
|
||||
|
||||
parent = await cg.get_variable(config[esp32_ble.CONF_BLE_ID])
|
||||
cg.add(parent.register_gap_event_handler(var))
|
||||
cg.add(parent.register_gap_scan_event_handler(var))
|
||||
cg.add(parent.register_gattc_event_handler(var))
|
||||
cg.add(parent.register_ble_status_event_handler(var))
|
||||
cg.add(var.set_parent(parent))
|
||||
|
@@ -50,9 +50,8 @@ void ESP32BLETracker::setup() {
|
||||
ESP_LOGE(TAG, "BLE Tracker was marked failed by ESP32BLE");
|
||||
return;
|
||||
}
|
||||
ExternalRAMAllocator<esp_ble_gap_cb_param_t::ble_scan_result_evt_param> allocator(
|
||||
ExternalRAMAllocator<esp_ble_gap_cb_param_t::ble_scan_result_evt_param>::ALLOW_FAILURE);
|
||||
this->scan_result_buffer_ = allocator.allocate(ESP32BLETracker::SCAN_RESULT_BUFFER_SIZE);
|
||||
ExternalRAMAllocator<BLEScanResult> allocator(ExternalRAMAllocator<BLEScanResult>::ALLOW_FAILURE);
|
||||
this->scan_result_buffer_ = allocator.allocate(SCAN_RESULT_BUFFER_SIZE);
|
||||
|
||||
if (this->scan_result_buffer_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Could not allocate buffer for BLE Tracker!");
|
||||
@@ -140,7 +139,24 @@ void ESP32BLETracker::loop() {
|
||||
if (this->parse_advertisements_) {
|
||||
for (size_t i = 0; i < index; i++) {
|
||||
ESPBTDevice device;
|
||||
device.parse_scan_rst(this->scan_result_buffer_[i]);
|
||||
// Convert BLEScanResult to ESP-IDF format for parse_scan_rst
|
||||
esp_ble_gap_cb_param_t::ble_scan_result_evt_param param;
|
||||
memcpy(param.bda, this->scan_result_buffer_[i].bda, sizeof(esp_bd_addr_t));
|
||||
param.ble_addr_type = this->scan_result_buffer_[i].ble_addr_type;
|
||||
param.rssi = this->scan_result_buffer_[i].rssi;
|
||||
param.adv_data_len = this->scan_result_buffer_[i].adv_data_len;
|
||||
param.scan_rsp_len = this->scan_result_buffer_[i].scan_rsp_len;
|
||||
param.search_evt = this->scan_result_buffer_[i].search_evt;
|
||||
memcpy(param.ble_adv, this->scan_result_buffer_[i].ble_adv,
|
||||
ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX);
|
||||
// Fill in fields we don't store
|
||||
param.dev_type = 0;
|
||||
param.ble_evt_type = 0;
|
||||
param.flag = 0;
|
||||
param.num_resps = 1;
|
||||
param.num_dis = 0;
|
||||
|
||||
device.parse_scan_rst(param);
|
||||
|
||||
bool found = false;
|
||||
for (auto *listener : this->listeners_) {
|
||||
@@ -371,7 +387,7 @@ void ESP32BLETracker::recalculate_advertisement_parser_types() {
|
||||
void ESP32BLETracker::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
|
||||
switch (event) {
|
||||
case ESP_GAP_BLE_SCAN_RESULT_EVT:
|
||||
this->gap_scan_result_(param->scan_rst);
|
||||
// This will be handled by gap_scan_event_handler instead
|
||||
break;
|
||||
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
|
||||
this->gap_scan_set_param_complete_(param->scan_param_cmpl);
|
||||
@@ -385,8 +401,63 @@ void ESP32BLETracker::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_ga
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (auto *client : this->clients_) {
|
||||
client->gap_event_handler(event, param);
|
||||
// Still forward non-scan events to clients
|
||||
if (event != ESP_GAP_BLE_SCAN_RESULT_EVT) {
|
||||
for (auto *client : this->clients_) {
|
||||
client->gap_event_handler(event, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ESP32BLETracker::gap_scan_event_handler(const BLEScanResult &scan_result) {
|
||||
ESP_LOGV(TAG, "gap_scan_result - event %d", scan_result.search_evt);
|
||||
|
||||
if (scan_result.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) {
|
||||
if (xSemaphoreTake(this->scan_result_lock_, 0)) {
|
||||
if (this->scan_result_index_ < SCAN_RESULT_BUFFER_SIZE) {
|
||||
// Store BLEScanResult directly in our buffer
|
||||
this->scan_result_buffer_[this->scan_result_index_++] = scan_result;
|
||||
}
|
||||
xSemaphoreGive(this->scan_result_lock_);
|
||||
}
|
||||
} else if (scan_result.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) {
|
||||
// Scan finished on its own
|
||||
if (this->scanner_state_ != ScannerState::RUNNING) {
|
||||
if (this->scanner_state_ == ScannerState::STOPPING) {
|
||||
ESP_LOGE(TAG, "Scan was not running when scan completed.");
|
||||
} else if (this->scanner_state_ == ScannerState::STARTING) {
|
||||
ESP_LOGE(TAG, "Scan was not started when scan completed.");
|
||||
} else if (this->scanner_state_ == ScannerState::FAILED) {
|
||||
ESP_LOGE(TAG, "Scan was in failed state when scan completed.");
|
||||
} else if (this->scanner_state_ == ScannerState::IDLE) {
|
||||
ESP_LOGE(TAG, "Scan was idle when scan completed.");
|
||||
} else if (this->scanner_state_ == ScannerState::STOPPED) {
|
||||
ESP_LOGE(TAG, "Scan was stopped when scan completed.");
|
||||
}
|
||||
}
|
||||
this->set_scanner_state_(ScannerState::STOPPED);
|
||||
}
|
||||
|
||||
// Forward scan results to clients - they still expect the old format
|
||||
if (scan_result.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) {
|
||||
esp_ble_gap_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(param));
|
||||
memcpy(param.scan_rst.bda, scan_result.bda, sizeof(esp_bd_addr_t));
|
||||
param.scan_rst.ble_addr_type = scan_result.ble_addr_type;
|
||||
param.scan_rst.rssi = scan_result.rssi;
|
||||
param.scan_rst.adv_data_len = scan_result.adv_data_len;
|
||||
param.scan_rst.scan_rsp_len = scan_result.scan_rsp_len;
|
||||
param.scan_rst.search_evt = scan_result.search_evt;
|
||||
memcpy(param.scan_rst.ble_adv, scan_result.ble_adv, ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX);
|
||||
param.scan_rst.dev_type = 0;
|
||||
param.scan_rst.ble_evt_type = 0;
|
||||
param.scan_rst.flag = 0;
|
||||
param.scan_rst.num_resps = 1;
|
||||
param.scan_rst.num_dis = 0;
|
||||
|
||||
for (auto *client : this->clients_) {
|
||||
client->gap_event_handler(ESP_GAP_BLE_SCAN_RESULT_EVT, ¶m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,33 +515,7 @@ void ESP32BLETracker::gap_scan_stop_complete_(const esp_ble_gap_cb_param_t::ble_
|
||||
this->set_scanner_state_(ScannerState::STOPPED);
|
||||
}
|
||||
|
||||
void ESP32BLETracker::gap_scan_result_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m) {
|
||||
ESP_LOGV(TAG, "gap_scan_result - event %d", param.search_evt);
|
||||
if (param.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) {
|
||||
if (xSemaphoreTake(this->scan_result_lock_, 0)) {
|
||||
if (this->scan_result_index_ < ESP32BLETracker::SCAN_RESULT_BUFFER_SIZE) {
|
||||
this->scan_result_buffer_[this->scan_result_index_++] = param;
|
||||
}
|
||||
xSemaphoreGive(this->scan_result_lock_);
|
||||
}
|
||||
} else if (param.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) {
|
||||
// Scan finished on its own
|
||||
if (this->scanner_state_ != ScannerState::RUNNING) {
|
||||
if (this->scanner_state_ == ScannerState::STOPPING) {
|
||||
ESP_LOGE(TAG, "Scan was not running when scan completed.");
|
||||
} else if (this->scanner_state_ == ScannerState::STARTING) {
|
||||
ESP_LOGE(TAG, "Scan was not started when scan completed.");
|
||||
} else if (this->scanner_state_ == ScannerState::FAILED) {
|
||||
ESP_LOGE(TAG, "Scan was in failed state when scan completed.");
|
||||
} else if (this->scanner_state_ == ScannerState::IDLE) {
|
||||
ESP_LOGE(TAG, "Scan was idle when scan completed.");
|
||||
} else if (this->scanner_state_ == ScannerState::STOPPED) {
|
||||
ESP_LOGE(TAG, "Scan was stopped when scan completed.");
|
||||
}
|
||||
}
|
||||
this->set_scanner_state_(ScannerState::STOPPED);
|
||||
}
|
||||
}
|
||||
// Removed - functionality moved to gap_scan_event_handler
|
||||
|
||||
void ESP32BLETracker::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||
esp_ble_gattc_cb_param_t *param) {
|
||||
|
@@ -121,9 +121,7 @@ class ESPBTDeviceListener {
|
||||
public:
|
||||
virtual void on_scan_end() {}
|
||||
virtual bool parse_device(const ESPBTDevice &device) = 0;
|
||||
virtual bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) {
|
||||
return false;
|
||||
};
|
||||
virtual bool parse_devices(const BLEScanResult *scan_results, size_t count) { return false; };
|
||||
virtual AdvertisementParserType get_advertisement_parser_type() {
|
||||
return AdvertisementParserType::PARSED_ADVERTISEMENTS;
|
||||
};
|
||||
@@ -210,6 +208,7 @@ class ESPBTClient : public ESPBTDeviceListener {
|
||||
|
||||
class ESP32BLETracker : public Component,
|
||||
public GAPEventHandler,
|
||||
public GAPScanEventHandler,
|
||||
public GATTcEventHandler,
|
||||
public BLEStatusEventHandler,
|
||||
public Parented<ESP32BLE> {
|
||||
@@ -240,6 +239,7 @@ class ESP32BLETracker : public Component,
|
||||
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
|
||||
esp_ble_gattc_cb_param_t *param) override;
|
||||
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
|
||||
void gap_scan_event_handler(const BLEScanResult &scan_result) override;
|
||||
void ble_before_disabled_event_handler() override;
|
||||
|
||||
void add_scanner_state_callback(std::function<void(ScannerState)> &&callback) {
|
||||
@@ -287,12 +287,8 @@ class ESP32BLETracker : public Component,
|
||||
bool parse_advertisements_{false};
|
||||
SemaphoreHandle_t scan_result_lock_;
|
||||
size_t scan_result_index_{0};
|
||||
#ifdef USE_PSRAM
|
||||
const static u_int8_t SCAN_RESULT_BUFFER_SIZE = 32;
|
||||
#else
|
||||
const static u_int8_t SCAN_RESULT_BUFFER_SIZE = 20;
|
||||
#endif // USE_PSRAM
|
||||
esp_ble_gap_cb_param_t::ble_scan_result_evt_param *scan_result_buffer_;
|
||||
// SCAN_RESULT_BUFFER_SIZE is now defined in esp32_ble/ble.h
|
||||
BLEScanResult *scan_result_buffer_;
|
||||
esp_bt_status_t scan_start_failed_{ESP_BT_STATUS_SUCCESS};
|
||||
esp_bt_status_t scan_set_param_failed_{ESP_BT_STATUS_SUCCESS};
|
||||
int connecting_{0};
|
||||
|
Reference in New Issue
Block a user