[PATCH 3/6] avctp: Allow to register state callback for specified audio device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



State callback can now be registered and called for specified device
only (or all devices if NULL is passed). This will allow for more
cleaner callback register/unregister in roles code.

Fix following valgrind reports:

16 bytes in 1 blocks are still reachable in loss record 43 of 223
   at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x4E7FA78: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.3)
   by 0x4E92CA2: g_slice_alloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.3)
   by 0x4E93FC2: g_slist_append (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.3)
   by 0x419ABD: avctp_add_state_cb (avctp.c:1652)
   by 0x41DD87: audio_device_register (device.c:320)
   by 0x416ECA: manager_get_audio_device (manager.c:491)
   by 0x4171A8: a2dp_sink_probe (manager.c:131)
   by 0x46A821: dev_probe (device.c:2347)
   by 0x468CBE: btd_profile_foreach (profile.c:599)
   by 0x46BBB5: device_probe_profiles (device.c:2423)
   by 0x461458: load_devices (adapter.c:2549)

16 bytes in 1 blocks are still reachable in loss record 44 of 223
   at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x4E7FA78: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.3)
   by 0x4E92CA2: g_slice_alloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.3)
   by 0x4E93FC2: g_slist_append (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.3)
   by 0x419ABD: avctp_add_state_cb (avctp.c:1652)
   by 0x417791: control_init (control.c:290)
   by 0x417097: avrcp_probe (manager.c:156)
   by 0x46A821: dev_probe (device.c:2347)
   by 0x468CBE: btd_profile_foreach (profile.c:599)
   by 0x46BBB5: device_probe_profiles (device.c:2423)
   by 0x461458: load_devices (adapter.c:2549)
   by 0x465086: read_info_complete (adapter.c:5514)

24 bytes in 1 blocks are still reachable in loss record 59 of 223
   at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x4E7FA78: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.3)
   by 0x419A92: avctp_add_state_cb (avctp.c:1647)
   by 0x41DD87: audio_device_register (device.c:320)
   by 0x416ECA: manager_get_audio_device (manager.c:491)
   by 0x4171A8: a2dp_sink_probe (manager.c:131)
   by 0x46A821: dev_probe (device.c:2347)
   by 0x468CBE: btd_profile_foreach (profile.c:599)
   by 0x46BBB5: device_probe_profiles (device.c:2423)
   by 0x461458: load_devices (adapter.c:2549)
   by 0x465086: read_info_complete (adapter.c:5514)
   by 0x4713A1: request_complete (mgmt.c:221)

24 bytes in 1 blocks are still reachable in loss record 60 of 223
   at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x4E7FA78: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3200.3)
   by 0x419A92: avctp_add_state_cb (avctp.c:1647)
   by 0x417791: control_init (control.c:290)
   by 0x417097: avrcp_probe (manager.c:156)
   by 0x46A821: dev_probe (device.c:2347)
   by 0x468CBE: btd_profile_foreach (profile.c:599)
   by 0x46BBB5: device_probe_profiles (device.c:2423)
   by 0x461458: load_devices (adapter.c:2549)
   by 0x465086: read_info_complete (adapter.c:5514)
   by 0x4713A1: request_complete (mgmt.c:221)
   by 0x47175B: received_data (mgmt.c:319)
---
 profiles/audio/avctp.c   | 9 ++++++++-
 profiles/audio/avctp.h   | 3 ++-
 profiles/audio/avrcp.c   | 2 +-
 profiles/audio/control.c | 8 ++++----
 profiles/audio/device.c  | 8 ++++----
 5 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index c276c52..7fbaacb 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
@@ -114,6 +114,7 @@ struct avc_header {
 
 struct avctp_state_callback {
 	avctp_state_cb cb;
+	struct audio_device *dev;
 	void *user_data;
 	unsigned int id;
 };
@@ -477,6 +478,10 @@ static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
 
 	for (l = callbacks; l != NULL; l = l->next) {
 		struct avctp_state_callback *cb = l->data;
+
+		if (cb->dev && cb->dev != dev)
+			continue;
+
 		cb->cb(dev, old_state, new_state, cb->user_data);
 	}
 
@@ -1639,13 +1644,15 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
 						func, user_data);
 }
 
-unsigned int avctp_add_state_cb(avctp_state_cb cb, void *user_data)
+unsigned int avctp_add_state_cb(avctp_state_cb cb, struct audio_device *dev,
+								void *user_data)
 {
 	struct avctp_state_callback *state_cb;
 	static unsigned int id = 0;
 
 	state_cb = g_new(struct avctp_state_callback, 1);
 	state_cb->cb = cb;
+	state_cb->dev = dev;
 	state_cb->user_data = user_data;
 	state_cb->id = ++id;
 
diff --git a/profiles/audio/avctp.h b/profiles/audio/avctp.h
index 411b093..56ed672 100644
--- a/profiles/audio/avctp.h
+++ b/profiles/audio/avctp.h
@@ -92,7 +92,8 @@ typedef size_t (*avctp_browsing_pdu_cb) (struct avctp *session,
 					uint8_t *operands, size_t operand_count,
 					void *user_data);
 
-unsigned int avctp_add_state_cb(avctp_state_cb cb, void *user_data);
+unsigned int avctp_add_state_cb(avctp_state_cb cb, struct audio_device *dev,
+							void *user_data);
 gboolean avctp_remove_state_cb(unsigned int id);
 
 int avctp_register(struct btd_adapter *adapter, gboolean master);
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index abb902a..b7edc44 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -2832,7 +2832,7 @@ int avrcp_register(struct btd_adapter *adapter, GKeyFile *config)
 	servers = g_slist_append(servers, server);
 
 	if (!avctp_id)
-		avctp_id = avctp_add_state_cb(state_changed, NULL);
+		avctp_id = avctp_add_state_cb(state_changed, NULL, NULL);
 
 	return 0;
 }
diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index 18c8478..b48ff0a 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -59,11 +59,10 @@
 #include "glib-helper.h"
 #include "dbus-common.h"
 
-static unsigned int avctp_id = 0;
-
 struct control {
 	struct avctp *session;
 	gboolean target;
+	unsigned int avctp_id;
 };
 
 static void state_changed(struct audio_device *dev, avctp_state_t old_state,
@@ -250,6 +249,8 @@ static void path_unregister(void *data)
 	if (control->session)
 		avctp_disconnect(control->session);
 
+	avctp_remove_state_cb(control->avctp_id);
+
 	g_free(control);
 	dev->control = NULL;
 }
@@ -286,8 +287,7 @@ struct control *control_init(struct audio_device *dev, GSList *uuids)
 
 	control_update(control, uuids);
 
-	if (!avctp_id)
-		avctp_id = avctp_add_state_cb(state_changed, NULL);
+	control->avctp_id = avctp_add_state_cb(state_changed, dev, NULL);
 
 	return control;
 }
diff --git a/profiles/audio/device.c b/profiles/audio/device.c
index 663a341..61bd37c 100644
--- a/profiles/audio/device.c
+++ b/profiles/audio/device.c
@@ -81,10 +81,10 @@ struct dev_priv {
 	gboolean disconnecting;
 
 	unsigned int avdtp_callback_id;
+	unsigned int avctp_callback_id;
 };
 
 static unsigned int sink_callback_id = 0;
-static unsigned int avctp_callback_id = 0;
 
 static void device_free(struct audio_device *dev)
 {
@@ -100,6 +100,7 @@ static void device_free(struct audio_device *dev)
 							priv->dc_id);
 
 		avdtp_remove_state_cb(priv->avdtp_callback_id);
+		avctp_remove_state_cb(priv->avctp_callback_id);
 
 		g_free(priv);
 	}
@@ -315,9 +316,8 @@ struct audio_device *audio_device_register(struct btd_device *device)
 		sink_callback_id = sink_add_state_cb(device_sink_cb, NULL);
 
 	dev->priv->avdtp_callback_id = avdtp_add_state_cb(device_avdtp_cb, dev);
-
-	if (avctp_callback_id == 0)
-		avctp_callback_id = avctp_add_state_cb(device_avctp_cb, NULL);
+	dev->priv->avctp_callback_id = avctp_add_state_cb(device_avctp_cb, dev,
+									NULL);
 
 	return dev;
 }
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux