Fix bulk and single Bluetooth parser coexistence (#5073)

This commit is contained in:
J. Nick Koston 2023-07-09 11:08:46 -10:00 committed by GitHub
parent f9fc438de8
commit e6834f25ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 13 deletions

View file

@ -275,6 +275,10 @@ esp_err_t BluetoothConnection::notify_characteristic(uint16_t handle, bool enabl
return ESP_OK; return ESP_OK;
} }
esp32_ble_tracker::AdvertisementParserType BluetoothConnection::get_advertisement_parser_type() {
return this->proxy_->get_advertisement_parser_type();
}
} // namespace bluetooth_proxy } // namespace bluetooth_proxy
} // namespace esphome } // namespace esphome

View file

@ -14,6 +14,7 @@ class BluetoothConnection : public esp32_ble_client::BLEClientBase {
bool gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, bool gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t *param) override; 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_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
esp32_ble_tracker::AdvertisementParserType get_advertisement_parser_type() override;
esp_err_t read_characteristic(uint16_t handle); esp_err_t read_characteristic(uint16_t handle);
esp_err_t write_characteristic(uint16_t handle, const std::string &data, bool response); esp_err_t write_characteristic(uint16_t handle, const std::string &data, bool response);

View file

@ -198,6 +198,12 @@ void BluetoothProxy::loop() {
} }
} }
esp32_ble_tracker::AdvertisementParserType BluetoothProxy::get_advertisement_parser_type() {
if (this->raw_advertisements_)
return esp32_ble_tracker::AdvertisementParserType::RAW_ADVERTISEMENTS;
return esp32_ble_tracker::AdvertisementParserType::PARSED_ADVERTISEMENTS;
}
BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool reserve) { BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool reserve) {
for (auto *connection : this->connections_) { for (auto *connection : this->connections_) {
if (connection->get_address() == address) if (connection->get_address() == address)
@ -435,6 +441,7 @@ void BluetoothProxy::subscribe_api_connection(api::APIConnection *api_connection
} }
this->api_connection_ = api_connection; this->api_connection_ = api_connection;
this->raw_advertisements_ = flags & BluetoothProxySubscriptionFlag::SUBSCRIPTION_RAW_ADVERTISEMENTS; this->raw_advertisements_ = flags & BluetoothProxySubscriptionFlag::SUBSCRIPTION_RAW_ADVERTISEMENTS;
this->parent_->recalculate_advertisement_parser_types();
} }
void BluetoothProxy::unsubscribe_api_connection(api::APIConnection *api_connection) { void BluetoothProxy::unsubscribe_api_connection(api::APIConnection *api_connection) {
@ -444,6 +451,7 @@ void BluetoothProxy::unsubscribe_api_connection(api::APIConnection *api_connecti
} }
this->api_connection_ = nullptr; this->api_connection_ = nullptr;
this->raw_advertisements_ = false; this->raw_advertisements_ = false;
this->parent_->recalculate_advertisement_parser_types();
} }
void BluetoothProxy::send_device_connection(uint64_t address, bool connected, uint16_t mtu, esp_err_t error) { void BluetoothProxy::send_device_connection(uint64_t address, bool connected, uint16_t mtu, esp_err_t error) {

View file

@ -51,6 +51,7 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) override; bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) override;
void dump_config() override; void dump_config() override;
void loop() override; void loop() override;
esp32_ble_tracker::AdvertisementParserType get_advertisement_parser_type() override;
void register_connection(BluetoothConnection *connection) { void register_connection(BluetoothConnection *connection) {
this->connections_.push_back(connection); this->connections_.push_back(connection);

View file

@ -107,16 +107,16 @@ void ESP32BLETracker::loop() {
ESP_LOGW(TAG, "Too many BLE events to process. Some devices may not show up."); ESP_LOGW(TAG, "Too many BLE events to process. Some devices may not show up.");
} }
bool bulk_parsed = false; if (this->raw_advertisements_) {
for (auto *listener : this->listeners_) { for (auto *listener : this->listeners_) {
bulk_parsed |= listener->parse_devices(this->scan_result_buffer_, this->scan_result_index_); listener->parse_devices(this->scan_result_buffer_, this->scan_result_index_);
} }
for (auto *client : this->clients_) { for (auto *client : this->clients_) {
bulk_parsed |= client->parse_devices(this->scan_result_buffer_, this->scan_result_index_); client->parse_devices(this->scan_result_buffer_, this->scan_result_index_);
}
} }
if (!bulk_parsed) { if (this->parse_advertisements_) {
for (size_t i = 0; i < index; i++) { for (size_t i = 0; i < index; i++) {
ESPBTDevice device; ESPBTDevice device;
device.parse_scan_rst(this->scan_result_buffer_[i]); device.parse_scan_rst(this->scan_result_buffer_[i]);
@ -284,6 +284,32 @@ void ESP32BLETracker::end_of_scan_() {
void ESP32BLETracker::register_client(ESPBTClient *client) { void ESP32BLETracker::register_client(ESPBTClient *client) {
client->app_id = ++this->app_id_; client->app_id = ++this->app_id_;
this->clients_.push_back(client); this->clients_.push_back(client);
this->recalculate_advertisement_parser_types();
}
void ESP32BLETracker::register_listener(ESPBTDeviceListener *listener) {
listener->set_parent(this);
this->listeners_.push_back(listener);
this->recalculate_advertisement_parser_types();
}
void ESP32BLETracker::recalculate_advertisement_parser_types() {
this->raw_advertisements_ = false;
this->parse_advertisements_ = false;
for (auto *listener : this->listeners_) {
if (listener->get_advertisement_parser_type() == AdvertisementParserType::PARSED_ADVERTISEMENTS) {
this->parse_advertisements_ = true;
} else {
this->raw_advertisements_ = true;
}
}
for (auto *client : this->clients_) {
if (client->get_advertisement_parser_type() == AdvertisementParserType::PARSED_ADVERTISEMENTS) {
this->parse_advertisements_ = true;
} else {
this->raw_advertisements_ = true;
}
}
} }
void ESP32BLETracker::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { void ESP32BLETracker::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {

View file

@ -27,6 +27,11 @@ using namespace esp32_ble;
using adv_data_t = std::vector<uint8_t>; using adv_data_t = std::vector<uint8_t>;
enum AdvertisementParserType {
PARSED_ADVERTISEMENTS,
RAW_ADVERTISEMENTS,
};
struct ServiceData { struct ServiceData {
ESPBTUUID uuid; ESPBTUUID uuid;
adv_data_t data; adv_data_t data;
@ -116,6 +121,9 @@ class ESPBTDeviceListener {
virtual bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) { virtual bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) {
return false; return false;
}; };
virtual AdvertisementParserType get_advertisement_parser_type() {
return AdvertisementParserType::PARSED_ADVERTISEMENTS;
};
void set_parent(ESP32BLETracker *parent) { parent_ = parent; } void set_parent(ESP32BLETracker *parent) { parent_ = parent; }
protected: protected:
@ -184,12 +192,9 @@ class ESP32BLETracker : public Component, public GAPEventHandler, public GATTcEv
void loop() override; void loop() override;
void register_listener(ESPBTDeviceListener *listener) { void register_listener(ESPBTDeviceListener *listener);
listener->set_parent(this);
this->listeners_.push_back(listener);
}
void register_client(ESPBTClient *client); void register_client(ESPBTClient *client);
void recalculate_advertisement_parser_types();
void print_bt_device_info(const ESPBTDevice &device); void print_bt_device_info(const ESPBTDevice &device);
@ -231,6 +236,8 @@ class ESP32BLETracker : public Component, public GAPEventHandler, public GATTcEv
bool scan_continuous_; bool scan_continuous_;
bool scan_active_; bool scan_active_;
bool scanner_idle_; bool scanner_idle_;
bool raw_advertisements_{false};
bool parse_advertisements_{false};
SemaphoreHandle_t scan_result_lock_; SemaphoreHandle_t scan_result_lock_;
SemaphoreHandle_t scan_end_lock_; SemaphoreHandle_t scan_end_lock_;
size_t scan_result_index_{0}; size_t scan_result_index_{0};