diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index 623ab6b009..3a6f514f91 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -1141,6 +1141,8 @@ message BluetoothLEAdvertisementResponse { repeated string service_uuids = 4; repeated BluetoothServiceData service_data = 5; repeated BluetoothServiceData manufacturer_data = 6; + + uint32 address_type = 7; } enum BluetoothDeviceRequestType { @@ -1157,6 +1159,8 @@ message BluetoothDeviceRequest { uint64 address = 1; BluetoothDeviceRequestType request_type = 2; + bool has_address_type = 3; + uint32 address_type = 4; } message BluetoothDeviceConnectionResponse { diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index bbe1da3209..e82a77974e 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -4993,6 +4993,10 @@ bool BluetoothLEAdvertisementResponse::decode_varint(uint32_t field_id, ProtoVar this->rssi = value.as_sint32(); return true; } + case 7: { + this->address_type = value.as_uint32(); + return true; + } default: return false; } @@ -5032,6 +5036,7 @@ void BluetoothLEAdvertisementResponse::encode(ProtoWriteBuffer buffer) const { for (auto &it : this->manufacturer_data) { buffer.encode_message(6, it, true); } + buffer.encode_uint32(7, this->address_type); } #ifdef HAS_PROTO_MESSAGE_DUMP void BluetoothLEAdvertisementResponse::dump_to(std::string &out) const { @@ -5068,6 +5073,11 @@ void BluetoothLEAdvertisementResponse::dump_to(std::string &out) const { it.dump_to(out); out.append("\n"); } + + out.append(" address_type: "); + sprintf(buffer, "%u", this->address_type); + out.append(buffer); + out.append("\n"); out.append("}"); } #endif @@ -5081,6 +5091,14 @@ bool BluetoothDeviceRequest::decode_varint(uint32_t field_id, ProtoVarInt value) this->request_type = value.as_enum(); return true; } + case 3: { + this->has_address_type = value.as_bool(); + return true; + } + case 4: { + this->address_type = value.as_uint32(); + return true; + } default: return false; } @@ -5088,6 +5106,8 @@ bool BluetoothDeviceRequest::decode_varint(uint32_t field_id, ProtoVarInt value) void BluetoothDeviceRequest::encode(ProtoWriteBuffer buffer) const { buffer.encode_uint64(1, this->address); buffer.encode_enum(2, this->request_type); + buffer.encode_bool(3, this->has_address_type); + buffer.encode_uint32(4, this->address_type); } #ifdef HAS_PROTO_MESSAGE_DUMP void BluetoothDeviceRequest::dump_to(std::string &out) const { @@ -5101,6 +5121,15 @@ void BluetoothDeviceRequest::dump_to(std::string &out) const { out.append(" request_type: "); out.append(proto_enum_to_string(this->request_type)); out.append("\n"); + + out.append(" has_address_type: "); + out.append(YESNO(this->has_address_type)); + out.append("\n"); + + out.append(" address_type: "); + sprintf(buffer, "%u", this->address_type); + out.append(buffer); + out.append("\n"); out.append("}"); } #endif diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index 3aee31b1bf..67ffa5c2dd 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -1257,6 +1257,7 @@ class BluetoothLEAdvertisementResponse : public ProtoMessage { std::vector service_uuids{}; std::vector service_data{}; std::vector manufacturer_data{}; + uint32_t address_type{0}; void encode(ProtoWriteBuffer buffer) const override; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; @@ -1270,6 +1271,8 @@ class BluetoothDeviceRequest : public ProtoMessage { public: uint64_t address{0}; enums::BluetoothDeviceRequestType request_type{}; + bool has_address_type{false}; + uint32_t address_type{0}; void encode(ProtoWriteBuffer buffer) const override; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; diff --git a/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp b/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp index 602edc2fa6..567874e5a2 100644 --- a/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +++ b/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp @@ -26,6 +26,7 @@ bool BluetoothProxy::parse_device(const esp32_ble_tracker::ESPBTDevice &device) void BluetoothProxy::send_api_packet_(const esp32_ble_tracker::ESPBTDevice &device) { api::BluetoothLEAdvertisementResponse resp; resp.address = device.address_uint64(); + resp.address_type = device.get_address_type(); if (!device.get_name().empty()) resp.name = device.get_name(); resp.rssi = device.get_rssi(); @@ -190,7 +191,18 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest connection->address_str().c_str()); return; } - connection->set_state(espbt::ClientState::SEARCHING); + if (msg.has_address_type) { + connection->remote_bda_[0] = (msg.address >> 40) & 0xFF; + connection->remote_bda_[1] = (msg.address >> 32) & 0xFF; + connection->remote_bda_[2] = (msg.address >> 24) & 0xFF; + connection->remote_bda_[3] = (msg.address >> 16) & 0xFF; + connection->remote_bda_[4] = (msg.address >> 8) & 0xFF; + connection->remote_bda_[5] = (msg.address >> 0) & 0xFF; + connection->set_remote_addr_type(static_cast(msg.address_type)); + connection->set_state(espbt::ClientState::DISCOVERED); + } else { + connection->set_state(espbt::ClientState::SEARCHING); + } api::global_api_server->send_bluetooth_connections_free(this->get_bluetooth_connections_free(), this->get_bluetooth_connections_limit()); break; diff --git a/esphome/components/esp32_ble_client/ble_client_base.h b/esphome/components/esp32_ble_client/ble_client_base.h index c97f3c2747..7dd740b703 100644 --- a/esphome/components/esp32_ble_client/ble_client_base.h +++ b/esphome/components/esp32_ble_client/ble_client_base.h @@ -68,6 +68,7 @@ class BLEClientBase : public espbt::ESPBTClient, public Component { int get_gattc_if() const { return this->gattc_if_; } uint8_t *get_remote_bda() { return this->remote_bda_; } esp_ble_addr_type_t get_remote_addr_type() const { return this->remote_addr_type_; } + void set_remote_addr_type(esp_ble_addr_type_t address_type) { this->remote_addr_type_ = address_type; } uint16_t get_conn_id() const { return this->conn_id_; } uint64_t get_address() const { return this->address_; }