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 raw packet from %02X:%02X:%02X:%02X:%02X:%02X, length %d. RSSI: %d dB", result.bda[0],
59 result.bda[1], result.bda[2], result.bda[3], result.bda[4], result.bda[5], length, result.rssi);
61 ESP_LOGV(TAG,
"Proxying %d packets", count);
77 service_data.
uuid = data.uuid.to_string();
78 service_data.
data.assign(data.data.begin(), data.data.end());
83 manufacturer_data.
uuid = data.uuid.to_string();
84 manufacturer_data.
data.assign(data.data.begin(), data.data.end());
91 ESP_LOGCONFIG(TAG,
"Bluetooth Proxy:");
92 ESP_LOGCONFIG(TAG,
" Active: %s", YESNO(this->
active_));
93 ESP_LOGCONFIG(TAG,
" Connections: %d", this->
connections_.size());
100 if (connection->address_ == 0) {
102 ESP_LOGV(TAG,
"[%d] Free connection", connection->get_connection_index());
104 ESP_LOGV(TAG,
"[%d] Used connection by [%s]", connection->get_connection_index(),
105 connection->address_str().c_str());
114 if (connection->get_address() != 0) {
115 connection->disconnect();
121 if (connection->send_service_ == connection->service_count_) {
122 connection->send_service_ = DONE_SENDING_SERVICES;
124 if (connection->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE ||
125 connection->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE) {
126 connection->release_services();
128 }
else if (connection->send_service_ >= 0) {
129 esp_gattc_service_elem_t service_result;
130 uint16_t service_count = 1;
131 esp_gatt_status_t service_status =
132 esp_ble_gattc_get_service(connection->get_gattc_if(), connection->get_conn_id(),
nullptr, &service_result,
133 &service_count, connection->send_service_);
134 connection->send_service_++;
135 if (service_status != ESP_GATT_OK) {
136 ESP_LOGE(TAG,
"[%d] [%s] esp_ble_gattc_get_service error at offset=%d, status=%d",
137 connection->get_connection_index(), connection->address_str().c_str(), connection->send_service_ - 1,
141 if (service_count == 0) {
142 ESP_LOGE(TAG,
"[%d] [%s] esp_ble_gattc_get_service missing, service_count=%d",
143 connection->get_connection_index(), connection->address_str().c_str(), service_count);
147 resp.
address = connection->get_address();
150 service_resp.
handle = service_result.start_handle;
151 uint16_t char_offset = 0;
152 esp_gattc_char_elem_t char_result;
154 uint16_t char_count = 1;
155 esp_gatt_status_t char_status = esp_ble_gattc_get_all_char(
156 connection->get_gattc_if(), connection->get_conn_id(), service_result.start_handle,
157 service_result.end_handle, &char_result, &char_count, char_offset);
158 if (char_status == ESP_GATT_INVALID_OFFSET || char_status == ESP_GATT_NOT_FOUND) {
161 if (char_status != ESP_GATT_OK) {
162 ESP_LOGE(TAG,
"[%d] [%s] esp_ble_gattc_get_all_char error, status=%d", connection->get_connection_index(),
163 connection->address_str().c_str(), char_status);
166 if (char_count == 0) {
171 characteristic_resp.
handle = char_result.char_handle;
172 characteristic_resp.
properties = char_result.properties;
174 uint16_t desc_offset = 0;
175 esp_gattc_descr_elem_t desc_result;
177 uint16_t desc_count = 1;
178 esp_gatt_status_t desc_status =
179 esp_ble_gattc_get_all_descr(connection->get_gattc_if(), connection->get_conn_id(),
180 char_result.char_handle, &desc_result, &desc_count, desc_offset);
181 if (desc_status == ESP_GATT_INVALID_OFFSET || desc_status == ESP_GATT_NOT_FOUND) {
184 if (desc_status != ESP_GATT_OK) {
185 ESP_LOGE(TAG,
"[%d] [%s] esp_ble_gattc_get_all_descr error, status=%d", connection->get_connection_index(),
186 connection->address_str().c_str(), desc_status);
189 if (desc_count == 0) {
194 descriptor_resp.
handle = desc_result.handle;
195 characteristic_resp.
descriptors.push_back(std::move(descriptor_resp));
198 service_resp.
characteristics.push_back(std::move(characteristic_resp));
200 resp.
services.push_back(std::move(service_resp));
214 if (connection->get_address() ==
address)
221 for (
auto *connection : this->connections_) {
222 if (connection->get_address() == 0) {
224 connection->set_address(address);
243 if (connection ==
nullptr) {
244 ESP_LOGW(TAG,
"No free connections available");
249 connection->state() == espbt::ClientState::ESTABLISHED) {
250 ESP_LOGW(TAG,
"[%d] [%s] Connection already established", connection->get_connection_index(),
251 connection->address_str().c_str());
255 }
else if (connection->state() == espbt::ClientState::SEARCHING) {
256 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, already searching for device",
257 connection->get_connection_index(), connection->address_str().c_str());
259 }
else if (connection->state() == espbt::ClientState::DISCOVERED) {
260 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, device already discovered",
261 connection->get_connection_index(), connection->address_str().c_str());
263 }
else if (connection->state() == espbt::ClientState::READY_TO_CONNECT) {
264 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, waiting in line to connect",
265 connection->get_connection_index(), connection->address_str().c_str());
267 }
else if (connection->state() == espbt::ClientState::CONNECTING) {
268 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, already connecting", connection->get_connection_index(),
269 connection->address_str().c_str());
271 }
else if (connection->state() == espbt::ClientState::DISCONNECTING) {
272 ESP_LOGW(TAG,
"[%d] [%s] Connection request ignored, device is disconnecting",
273 connection->get_connection_index(), connection->address_str().c_str());
276 ESP_LOGW(TAG,
"[%d] [%s] Connection already in progress", connection->get_connection_index(),
277 connection->address_str().c_str());
281 connection->set_connection_type(espbt::ConnectionType::V3_WITH_CACHE);
282 ESP_LOGI(TAG,
"[%d] [%s] Connecting v3 with cache", connection->get_connection_index(),
283 connection->address_str().c_str());
285 connection->set_connection_type(espbt::ConnectionType::V3_WITHOUT_CACHE);
286 ESP_LOGI(TAG,
"[%d] [%s] Connecting v3 without cache", connection->get_connection_index(),
287 connection->address_str().c_str());
289 connection->set_connection_type(espbt::ConnectionType::V1);
290 ESP_LOGI(TAG,
"[%d] [%s] Connecting v1", connection->get_connection_index(), connection->address_str().c_str());
294 connection->set_remote_addr_type(static_cast<esp_ble_addr_type_t>(msg.
address_type));
295 connection->set_state(espbt::ClientState::DISCOVERED);
297 connection->set_state(espbt::ClientState::SEARCHING);
304 if (connection ==
nullptr) {
310 connection->disconnect();
312 connection->set_address(0);
320 if (connection !=
nullptr) {
321 if (!connection->is_paired()) {
322 auto err = connection->pair();
335 esp_err_t ret = esp_ble_remove_bond_device(address);
342 esp_err_t ret = esp_ble_gattc_cache_clean(address);
357 if (connection ==
nullptr) {
358 ESP_LOGW(TAG,
"Cannot read GATT characteristic, not connected");
363 auto err = connection->read_characteristic(msg.
handle);
371 if (connection ==
nullptr) {
372 ESP_LOGW(TAG,
"Cannot write GATT characteristic, not connected");
385 if (connection ==
nullptr) {
386 ESP_LOGW(TAG,
"Cannot read GATT descriptor, not connected");
391 auto err = connection->read_descriptor(msg.
handle);
399 if (connection ==
nullptr) {
400 ESP_LOGW(TAG,
"Cannot write GATT descriptor, not connected");
405 auto err = connection->write_descriptor(msg.
handle, msg.
data,
true);
413 if (connection ==
nullptr || !connection->connected()) {
414 ESP_LOGW(TAG,
"Cannot get GATT services, not connected");
418 if (!connection->service_count_) {
419 ESP_LOGW(TAG,
"[%d] [%s] No GATT services found", connection->connection_index_, connection->address_str().c_str());
423 if (connection->send_service_ ==
424 DONE_SENDING_SERVICES)
425 connection->send_service_ = 0;
430 if (connection ==
nullptr) {
431 ESP_LOGW(TAG,
"Cannot notify GATT characteristic, not connected");
436 auto err = connection->notify_characteristic(msg.
handle, msg.
enable);
444 ESP_LOGE(TAG,
"Only one API subscription is allowed at a time");
454 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)
Implementation of SPI Controller mode.
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)