9 namespace bluetooth_proxy {
11 static const char *
const TAG =
"bluetooth_proxy";
12 static const int DONE_SENDING_SERVICES = -2;
16 return std::vector<uint64_t>{((uint64_t) uuid.uuid.uuid128[15] << 56) | ((uint64_t) uuid.uuid.uuid128[14] << 48) |
17 ((uint64_t) uuid.uuid.uuid128[13] << 40) | ((uint64_t) uuid.uuid.uuid128[12] << 32) |
18 ((uint64_t) uuid.uuid.uuid128[11] << 24) | ((uint64_t) uuid.uuid.uuid128[10] << 16) |
19 ((uint64_t) uuid.uuid.uuid128[9] << 8) | ((uint64_t) uuid.uuid.uuid128[8]),
20 ((uint64_t) uuid.uuid.uuid128[7] << 56) | ((uint64_t) uuid.uuid.uuid128[6] << 48) |
21 ((uint64_t) uuid.uuid.uuid128[5] << 40) | ((uint64_t) uuid.uuid.uuid128[4] << 32) |
22 ((uint64_t) uuid.uuid.uuid128[3] << 24) | ((uint64_t) uuid.uuid.uuid128[2] << 16) |
23 ((uint64_t) uuid.uuid.uuid128[1] << 8) | ((uint64_t) uuid.uuid.uuid128[0])};
32 ESP_LOGV(TAG,
"Proxying packet from %s - %s. RSSI: %d dB", device.
get_name().c_str(), device.
address_str().c_str(),
43 for (
size_t i = 0; i < count; i++) {
44 auto &result = advertisements[i];
47 adv.
rssi = result.rssi;
50 uint8_t
length = result.adv_data_len + result.scan_rsp_len;
51 adv.
data.reserve(length);
52 for (uint16_t i = 0; i <
length; i++) {
53 adv.
data.push_back(result.ble_adv[i]);
58 ESP_LOGV(TAG,
"Proxying %d packets", count);
74 service_data.
uuid = data.uuid.to_string();
75 service_data.
data.assign(data.data.begin(), data.data.end());
80 manufacturer_data.
uuid = data.uuid.to_string();
81 manufacturer_data.
data.assign(data.data.begin(), data.data.end());
88 ESP_LOGCONFIG(TAG,
"Bluetooth Proxy:");
89 ESP_LOGCONFIG(TAG,
" Active: %s", YESNO(this->
active_));
95 if (connection->address_ == 0) {
97 ESP_LOGV(TAG,
"[%d] Free connection", connection->get_connection_index());
99 ESP_LOGV(TAG,
"[%d] Used connection by [%s]", connection->get_connection_index(),
100 connection->address_str().c_str());
109 if (connection->get_address() != 0) {
110 connection->disconnect();
116 if (connection->send_service_ == connection->service_count_) {
117 connection->send_service_ = DONE_SENDING_SERVICES;
119 if (connection->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE ||
120 connection->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE) {
121 connection->release_services();
123 }
else if (connection->send_service_ >= 0) {
124 esp_gattc_service_elem_t service_result;
125 uint16_t service_count = 1;
126 esp_gatt_status_t service_status =
127 esp_ble_gattc_get_service(connection->get_gattc_if(), connection->get_conn_id(),
nullptr, &service_result,
128 &service_count, connection->send_service_);
129 connection->send_service_++;
130 if (service_status != ESP_GATT_OK) {
131 ESP_LOGE(TAG,
"[%d] [%s] esp_ble_gattc_get_service error at offset=%d, status=%d",
132 connection->get_connection_index(), connection->address_str().c_str(), connection->send_service_ - 1,
136 if (service_count == 0) {
137 ESP_LOGE(TAG,
"[%d] [%s] esp_ble_gattc_get_service missing, service_count=%d",
138 connection->get_connection_index(), connection->address_str().c_str(), service_count);
142 resp.
address = connection->get_address();
145 service_resp.
handle = service_result.start_handle;
146 uint16_t char_offset = 0;
147 esp_gattc_char_elem_t char_result;
149 uint16_t char_count = 1;
150 esp_gatt_status_t char_status = esp_ble_gattc_get_all_char(
151 connection->get_gattc_if(), connection->get_conn_id(), service_result.start_handle,
152 service_result.end_handle, &char_result, &char_count, char_offset);
153 if (char_status == ESP_GATT_INVALID_OFFSET || char_status == ESP_GATT_NOT_FOUND) {
156 if (char_status != ESP_GATT_OK) {
157 ESP_LOGE(TAG,
"[%d] [%s] esp_ble_gattc_get_all_char error, status=%d", connection->get_connection_index(),
158 connection->address_str().c_str(), char_status);
161 if (char_count == 0) {
166 characteristic_resp.
handle = char_result.char_handle;
167 characteristic_resp.
properties = char_result.properties;
169 uint16_t desc_offset = 0;
170 esp_gattc_descr_elem_t desc_result;
172 uint16_t desc_count = 1;
173 esp_gatt_status_t desc_status =
174 esp_ble_gattc_get_all_descr(connection->get_gattc_if(), connection->get_conn_id(),
175 char_result.char_handle, &desc_result, &desc_count, desc_offset);
176 if (desc_status == ESP_GATT_INVALID_OFFSET || desc_status == ESP_GATT_NOT_FOUND) {
179 if (desc_status != ESP_GATT_OK) {
180 ESP_LOGE(TAG,
"[%d] [%s] esp_ble_gattc_get_all_descr error, status=%d", connection->get_connection_index(),
181 connection->address_str().c_str(), desc_status);
184 if (desc_count == 0) {
189 descriptor_resp.
handle = desc_result.handle;
190 characteristic_resp.
descriptors.push_back(std::move(descriptor_resp));
193 service_resp.
characteristics.push_back(std::move(characteristic_resp));
195 resp.
services.push_back(std::move(service_resp));
209 if (connection->get_address() == address)
216 for (
auto *connection : this->connections_) {
217 if (connection->get_address() == 0) {
219 connection->set_address(address);
238 if (connection ==
nullptr) {
239 ESP_LOGW(TAG,
"No free connections available");
244 connection->state() == espbt::ClientState::ESTABLISHED) {
245 ESP_LOGW(TAG,
"[%d] [%s] Connection already established", connection->get_connection_index(),
246 connection->address_str().c_str());
250 }
else if (connection->state() == espbt::ClientState::SEARCHING) {
251 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, already searching for device",
252 connection->get_connection_index(), connection->address_str().c_str());
254 }
else if (connection->state() == espbt::ClientState::DISCOVERED) {
255 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, device already discovered",
256 connection->get_connection_index(), connection->address_str().c_str());
258 }
else if (connection->state() == espbt::ClientState::READY_TO_CONNECT) {
259 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, waiting in line to connect",
260 connection->get_connection_index(), connection->address_str().c_str());
262 }
else if (connection->state() == espbt::ClientState::CONNECTING) {
263 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, already connecting", connection->get_connection_index(),
264 connection->address_str().c_str());
266 }
else if (connection->state() == espbt::ClientState::DISCONNECTING) {
267 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, device is disconnecting",
268 connection->get_connection_index(), connection->address_str().c_str());
271 ESP_LOGW(TAG,
"[%d] [%s] Connection already in progress", connection->get_connection_index(),
272 connection->address_str().c_str());
276 connection->set_connection_type(espbt::ConnectionType::V3_WITH_CACHE);
277 ESP_LOGI(TAG,
"[%d] [%s] Connecting v3 with cache", connection->get_connection_index(),
278 connection->address_str().c_str());
280 connection->set_connection_type(espbt::ConnectionType::V3_WITHOUT_CACHE);
281 ESP_LOGI(TAG,
"[%d] [%s] Connecting v3 without cache", connection->get_connection_index(),
282 connection->address_str().c_str());
284 connection->set_connection_type(espbt::ConnectionType::V1);
285 ESP_LOGI(TAG,
"[%d] [%s] Connecting v1", connection->get_connection_index(), connection->address_str().c_str());
289 connection->set_remote_addr_type(static_cast<esp_ble_addr_type_t>(msg.
address_type));
290 connection->set_state(espbt::ClientState::DISCOVERED);
292 connection->set_state(espbt::ClientState::SEARCHING);
299 if (connection ==
nullptr) {
305 connection->disconnect();
307 connection->set_address(0);
315 if (connection !=
nullptr) {
316 if (!connection->is_paired()) {
317 auto err = connection->pair();
328 esp_bd_addr_t address;
330 esp_err_t ret = esp_ble_remove_bond_device(address);
335 esp_bd_addr_t address;
337 esp_err_t ret = esp_ble_gattc_cache_clean(address);
352 if (connection ==
nullptr) {
353 ESP_LOGW(TAG,
"Cannot read GATT characteristic, not connected");
358 auto err = connection->read_characteristic(msg.
handle);
366 if (connection ==
nullptr) {
367 ESP_LOGW(TAG,
"Cannot write GATT characteristic, not connected");
380 if (connection ==
nullptr) {
381 ESP_LOGW(TAG,
"Cannot read GATT descriptor, not connected");
386 auto err = connection->read_descriptor(msg.
handle);
394 if (connection ==
nullptr) {
395 ESP_LOGW(TAG,
"Cannot write GATT descriptor, not connected");
400 auto err = connection->write_descriptor(msg.
handle, msg.
data,
true);
408 if (connection ==
nullptr || !connection->connected()) {
409 ESP_LOGW(TAG,
"Cannot get GATT services, not connected");
413 if (!connection->service_count_) {
414 ESP_LOGW(TAG,
"[%d] [%s] No GATT services found", connection->connection_index_, connection->address_str().c_str());
418 if (connection->send_service_ ==
419 DONE_SENDING_SERVICES)
420 connection->send_service_ = 0;
425 if (connection ==
nullptr) {
426 ESP_LOGW(TAG,
"Cannot notify GATT characteristic, not connected");
431 auto err = connection->notify_characteristic(msg.
handle, msg.
enable);
439 ESP_LOGE(TAG,
"Only one API subscription is allowed at a time");
449 ESP_LOGV(TAG,
"API connection is not subscribed");
void send_connections_free()
void send_device_pairing(uint64_t address, bool paired, esp_err_t error=ESP_OK)
std::vector< BluetoothGATTCharacteristic > characteristics
BluetoothConnection * get_connection_(uint64_t address, bool reserve)
uint64_t ble_addr_to_uint64(const esp_bd_addr_t address)
void dump_config() override
int get_bluetooth_connections_limit()
bool parse_devices(esp_ble_gap_cb_param_t::ble_scan_result_evt_param *advertisements, size_t count) override
std::vector< BluetoothGATTService > services
std::vector< BluetoothLERawAdvertisement > advertisements
void send_device_unpairing(uint64_t address, bool success, esp_err_t error=ESP_OK)
ESP32BLETracker * parent_
bool send_bluetooth_gatt_error_response(const BluetoothGATTErrorResponse &msg)
api::APIConnection * api_connection_
void recalculate_advertisement_parser_types()
std::string address_str() const
std::vector< BluetoothServiceData > service_data
bool send_bluetooth_device_connection_response(const BluetoothDeviceConnectionResponse &msg)
const std::vector< ServiceData > & get_manufacturer_datas() const
const std::vector< ESPBTUUID > & get_service_uuids() const
bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
void bluetooth_device_request(const api::BluetoothDeviceRequest &msg)
BluetoothProxy * global_bluetooth_proxy
static ESPBTUUID from_uuid(esp_bt_uuid_t uuid)
std::vector< BluetoothGATTDescriptor > descriptors
std::vector< uint64_t > uuid
bool send_bluetooth_gatt_get_services_response(const BluetoothGATTGetServicesResponse &msg)
esp32_ble_tracker::AdvertisementParserType get_advertisement_parser_type() override
bool send_bluetooth_device_unpairing_response(const BluetoothDeviceUnpairingResponse &msg)
void bluetooth_gatt_read(const api::BluetoothGATTReadRequest &msg)
std::vector< uint64_t > uuid
void send_device_connection(uint64_t address, bool connected, uint16_t mtu=0, esp_err_t error=ESP_OK)
static void uint64_to_bd_addr(uint64_t address, esp_bd_addr_t bd_addr)
enums::BluetoothDeviceRequestType request_type
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override
void bluetooth_gatt_write(const api::BluetoothGATTWriteRequest &msg)
std::vector< uint64_t > get_128bit_uuid_vec(esp_bt_uuid_t uuid_source)
const std::vector< ServiceData > & get_service_datas() const
void bluetooth_gatt_write_descriptor(const api::BluetoothGATTWriteDescriptorRequest &msg)
esp_ble_addr_type_t get_address_type() const
void unsubscribe_api_connection(api::APIConnection *api_connection)
uint64_t address_uint64() const
void bluetooth_gatt_notify(const api::BluetoothGATTNotifyRequest &msg)
int get_bluetooth_connections_free()
bool send_bluetooth_connections_free_response(const BluetoothConnectionsFreeResponse &msg)
std::vector< BluetoothConnection * > connections_
std::vector< uint64_t > uuid
void send_api_packet_(const esp32_ble_tracker::ESPBTDevice &device)
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
void bluetooth_gatt_read_descriptor(const api::BluetoothGATTReadDescriptorRequest &msg)
void send_gatt_error(uint64_t address, uint16_t handle, esp_err_t error)
std::vector< BluetoothServiceData > manufacturer_data
const std::string & get_name() const
std::vector< std::string > service_uuids
void subscribe_api_connection(api::APIConnection *api_connection, uint32_t flags)
bool send_bluetooth_device_pairing_response(const BluetoothDevicePairingResponse &msg)
bool send_bluetooth_gatt_get_services_done_response(const BluetoothGATTGetServicesDoneResponse &msg)
ESPBTUUID as_128bit() const
bool send_bluetooth_device_clear_cache_response(const BluetoothDeviceClearCacheResponse &msg)
bool send_bluetooth_le_advertisement(const BluetoothLEAdvertisementResponse &msg)
bool send_bluetooth_le_raw_advertisements_response(const BluetoothLERawAdvertisementsResponse &msg)
APIServer * global_api_server
void bluetooth_gatt_send_services(const api::BluetoothGATTGetServicesRequest &msg)
esp_bt_uuid_t get_uuid() const
void send_gatt_services_done(uint64_t address)