From dd18a219db7e4d7306c4cbd088baecfd146a811d Mon Sep 17 00:00:00 2001
From: "J. Nick Koston" <nick@koston.org>
Date: Mon, 27 Jan 2025 16:57:52 -1000
Subject: [PATCH] Include Bluetooth connection slot allocations in connections
 free message (#8148)

---
 esphome/components/api/api.proto                   |  1 +
 esphome/components/api/api_pb2.cpp                 | 14 ++++++++++++++
 esphome/components/api/api_pb2.h                   |  1 +
 .../components/bluetooth_proxy/bluetooth_proxy.cpp |  5 +++++
 4 files changed, 21 insertions(+)

diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto
index 684540ffa6..534098e5fd 100644
--- a/esphome/components/api/api.proto
+++ b/esphome/components/api/api.proto
@@ -1381,6 +1381,7 @@ message BluetoothConnectionsFreeResponse {
 
   uint32 free = 1;
   uint32 limit = 2;
+  repeated uint64 allocated = 3;
 }
 
 message BluetoothGATTErrorResponse {
diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp
index 8df152881c..41016e510f 100644
--- a/esphome/components/api/api_pb2.cpp
+++ b/esphome/components/api/api_pb2.cpp
@@ -6430,6 +6430,10 @@ bool BluetoothConnectionsFreeResponse::decode_varint(uint32_t field_id, ProtoVar
       this->limit = value.as_uint32();
       return true;
     }
+    case 3: {
+      this->allocated.push_back(value.as_uint64());
+      return true;
+    }
     default:
       return false;
   }
@@ -6437,6 +6441,9 @@ bool BluetoothConnectionsFreeResponse::decode_varint(uint32_t field_id, ProtoVar
 void BluetoothConnectionsFreeResponse::encode(ProtoWriteBuffer buffer) const {
   buffer.encode_uint32(1, this->free);
   buffer.encode_uint32(2, this->limit);
+  for (auto &it : this->allocated) {
+    buffer.encode_uint64(3, it, true);
+  }
 }
 #ifdef HAS_PROTO_MESSAGE_DUMP
 void BluetoothConnectionsFreeResponse::dump_to(std::string &out) const {
@@ -6451,6 +6458,13 @@ void BluetoothConnectionsFreeResponse::dump_to(std::string &out) const {
   sprintf(buffer, "%" PRIu32, this->limit);
   out.append(buffer);
   out.append("\n");
+
+  for (const auto &it : this->allocated) {
+    out.append("  allocated: ");
+    sprintf(buffer, "%llu", it);
+    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 063c217bf7..a3fccbc641 100644
--- a/esphome/components/api/api_pb2.h
+++ b/esphome/components/api/api_pb2.h
@@ -1624,6 +1624,7 @@ class BluetoothConnectionsFreeResponse : public ProtoMessage {
  public:
   uint32_t free{0};
   uint32_t limit{0};
+  std::vector<uint64_t> allocated{};
   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 bd1c8b7ea4..a263aca456 100644
--- a/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp
+++ b/esphome/components/bluetooth_proxy/bluetooth_proxy.cpp
@@ -475,6 +475,11 @@ void BluetoothProxy::send_connections_free() {
   api::BluetoothConnectionsFreeResponse call;
   call.free = this->get_bluetooth_connections_free();
   call.limit = this->get_bluetooth_connections_limit();
+  for (auto *connection : this->connections_) {
+    if (connection->address_ != 0) {
+      call.allocated.push_back(connection->address_);
+    }
+  }
   this->api_connection_->send_bluetooth_connections_free_response(call);
 }