Message ID | 20250110145019.2380299-3-michal.dzik@streamunlimited.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | connect VCP profile to MediaTransport volume | expand |
Context | Check | Description |
---|---|---|
tedd_an/pre-ci_am | success | Success |
Hi Michal, On Fri, Jan 10, 2025 at 9:54 AM Michal Dzik <michal.dzik@streamunlimited.com> wrote: > > 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 --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; You shouldn't need to clean up the found attributes, these are stored in the gatt_db and are persisted on reconnection. > + } > } > > 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 Use C style comments (/*) rather than C++. > 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; > > -- > 2.34.1 > >
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;