diff mbox series

[BlueZ,2/3] vcp: fix memory & connection management

Message ID 20250110145019.2380299-3-michal.dzik@streamunlimited.com
State New
Headers show
Series connect VCP profile to MediaTransport volume | expand

Commit Message

Michal Dzik Jan. 10, 2025, 2:50 p.m. UTC
Those changes are mandatory to be able to connect to the same VCP
renderer more than once without need to restart bluez.
- use vcp_disconnect() to close client connection and reset vcs members
- call bt_vcp_detach() the same way as bt_vcp_attach - from btd_profile
  callback
- vcs members are cleared during disconnect, because they are expected
  to be null when connecting
---
 profiles/audio/vcp.c |  9 +++++++++
 src/shared/vcp.c     | 23 +++++++++++++++++++----
 2 files changed, 28 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/profiles/audio/vcp.c b/profiles/audio/vcp.c
index 83e568f22..0203673bf 100644
--- a/profiles/audio/vcp.c
+++ b/profiles/audio/vcp.c
@@ -72,7 +72,16 @@  static void vcp_debug(const char *str, void *user_data)
 
 static int vcp_disconnect(struct btd_service *service)
 {
+	struct vcp_data *data = btd_service_get_user_data(service);
 	DBG("");
+
+	if (!data) {
+		error("VCP service not handled by profile");
+		return -EINVAL;
+	}
+	bt_vcp_detach(data->vcp);
+
+	btd_service_disconnecting_complete(service, 0);
 	return 0;
 }
 
diff --git a/src/shared/vcp.c b/src/shared/vcp.c
index 489cd2b97..c92eb00d4 100644
--- a/src/shared/vcp.c
+++ b/src/shared/vcp.c
@@ -389,13 +389,24 @@  static void vcp_detached(void *data, void *user_data)
 
 void bt_vcp_detach(struct bt_vcp *vcp)
 {
+	struct bt_vcs *vcs;
 	if (!queue_remove(sessions, vcp))
 		return;
 
-	bt_gatt_client_unref(vcp->client);
-	vcp->client = NULL;
+	if (vcp->client) {
+		bt_gatt_client_unref(vcp->client);
+		vcp->client = NULL;
+	}
 
-	queue_foreach(vcp_cbs, vcp_detached, vcp);
+	if (vcp->rdb) {
+		vcs = vcp_get_vcs(vcp);
+		vcs->service = NULL;
+		vcs->vs = NULL;
+		vcs->vs_ccc = NULL;
+		vcs->vol_cp = NULL;
+		vcs->vf = NULL;
+		vcs->vf_ccc = NULL;
+	}
 }
 
 static void vcp_db_free(void *data)
@@ -489,6 +500,7 @@  static void vcp_debug(struct bt_vcp *vcp, const char *format, ...)
 
 static void vcp_disconnected(int err, void *user_data)
 {
+	// called only when this device is acting a a server
 	struct bt_vcp *vcp = user_data;
 
 	DBG(vcp, "vcp %p disconnected err %d", vcp, err);
@@ -508,12 +520,15 @@  static struct bt_vcp *vcp_get_session(struct bt_att *att, struct gatt_db *db)
 			return vcp;
 	}
 
+	// called only when this device is acting a a server
 	vcp = bt_vcp_new(db, NULL);
 	vcp->att = att;
 
 	bt_att_register_disconnect(att, vcp_disconnected, vcp, NULL);
 
-	bt_vcp_attach(vcp, NULL);
+	if (!sessions)
+		sessions = queue_new();
+	queue_push_tail(sessions, vcp);
 
 	return vcp;