Diff between d311204d6d87d5aa6c93125b193f22857297dabc and 711331d28f769d3d217b520f30cf6237e2b179ee

Changed Files

File Additions Deletions Status
android/a2dp.c +82 -0 modified

Full Patch

diff --git a/android/a2dp.c b/android/a2dp.c
index 32b6aa3..936c28e 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -27,6 +27,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -34,18 +35,23 @@
 
 #include "btio/btio.h"
 #include "lib/bluetooth.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
 #include "log.h"
 #include "a2dp.h"
 #include "hal-msg.h"
 #include "ipc.h"
 #include "utils.h"
+#include "bluetooth.h"
 
 #define L2CAP_PSM_AVDTP 0x19
+#define SVC_HINT_CAPTURING 0x08
 
 static int notification_sk = -1;
 static GIOChannel *server = NULL;
 static GSList *devices = NULL;
 static bdaddr_t adapter_addr;
+static uint32_t record_id = 0;
 
 struct a2dp_device {
 	bdaddr_t	dst;
@@ -258,9 +264,71 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	signaling_connect_cb(chan, err, dev);
 }
 
+static sdp_record_t *a2dp_record(void)
+{
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid;
+	sdp_profile_desc_t profile[1];
+	sdp_list_t *aproto, *proto[2];
+	sdp_record_t *record;
+	sdp_data_t *psm, *version, *features;
+	uint16_t lp = AVDTP_UUID;
+	uint16_t a2dp_ver = 0x0103, avdtp_ver = 0x0103, feat = 0x000f;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+	root = sdp_list_append(0, &root_uuid);
+	sdp_set_browse_groups(record, root);
+
+	sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID);
+	svclass_id = sdp_list_append(0, &a2dp_uuid);
+	sdp_set_service_classes(record, svclass_id);
+
+	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
+	profile[0].version = a2dp_ver;
+	pfseq = sdp_list_append(0, &profile[0]);
+	sdp_set_profile_descs(record, pfseq);
+
+	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
+	proto[0] = sdp_list_append(0, &l2cap_uuid);
+	psm = sdp_data_alloc(SDP_UINT16, &lp);
+	proto[0] = sdp_list_append(proto[0], psm);
+	apseq = sdp_list_append(0, proto[0]);
+
+	sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID);
+	proto[1] = sdp_list_append(0, &avdtp_uuid);
+	version = sdp_data_alloc(SDP_UINT16, &avdtp_ver);
+	proto[1] = sdp_list_append(proto[1], version);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	aproto = sdp_list_append(0, apseq);
+	sdp_set_access_protos(record, aproto);
+
+	features = sdp_data_alloc(SDP_UINT16, &feat);
+	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
+
+	sdp_set_info_attr(record, "Audio Source", 0, 0);
+
+	free(psm);
+	free(version);
+	sdp_list_free(proto[0], 0);
+	sdp_list_free(proto[1], 0);
+	sdp_list_free(apseq, 0);
+	sdp_list_free(pfseq, 0);
+	sdp_list_free(aproto, 0);
+	sdp_list_free(root, 0);
+	sdp_list_free(svclass_id, 0);
+
+	return record;
+}
+
 bool bt_a2dp_register(int sk, const bdaddr_t *addr)
 {
 	GError *err = NULL;
+	sdp_record_t *rec;
 
 	DBG("");
 
@@ -277,6 +345,17 @@ bool bt_a2dp_register(int sk, const bdaddr_t *addr)
 		return false;
 	}
 
+	rec = a2dp_record();
+	if (bt_adapter_add_record(rec, SVC_HINT_CAPTURING) < 0) {
+		error("Failed to register on A2DP record");
+		sdp_record_free(rec);
+		g_io_channel_shutdown(server, TRUE, NULL);
+		g_io_channel_unref(server);
+		server = NULL;
+		return false;
+	}
+	record_id = rec->handle;
+
 	notification_sk = sk;
 
 	return true;
@@ -288,6 +367,9 @@ void bt_a2dp_unregister(void)
 
 	notification_sk = -1;
 
+	bt_adapter_remove_record(record_id);
+	record_id = 0;
+
 	if (server) {
 		g_io_channel_shutdown(server, TRUE, NULL);
 		g_io_channel_unref(server);