diff options
| author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-03-27 23:07:19 +0000 | 
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-03-27 23:07:19 +0000 | 
| commit | 7299869ac79b76564cd68411acb18f4233ddbbb7 (patch) | |
| tree | 6773d52943cb4e6cf04e51f5ed0702bd37dc8169 | |
| parent | bec69df1c6672579961d96b718b8703650d01322 (diff) | |
Convert audio service into a plugin.
| -rw-r--r-- | audio/Makefile.am | 32 | ||||
| -rw-r--r-- | audio/a2dp.c | 55 | ||||
| -rw-r--r-- | audio/control.c | 89 | ||||
| -rw-r--r-- | audio/device.c | 57 | ||||
| -rw-r--r-- | audio/main.c | 80 | ||||
| -rw-r--r-- | audio/manager.c | 178 | ||||
| -rw-r--r-- | audio/manager.h | 6 | 
7 files changed, 149 insertions, 348 deletions
| diff --git a/audio/Makefile.am b/audio/Makefile.am index e36c2c2d..239d78be 100644 --- a/audio/Makefile.am +++ b/audio/Makefile.am @@ -1,23 +1,20 @@  if AUDIOSERVICE -if CONFIGFILES -confdir = $(sysconfdir)/bluetooth +plugindir = $(libdir)/bluetooth/plugins -conf_DATA = audio.service audio.conf -endif - -servicedir = $(libdir)/bluetooth - -service_PROGRAMS = bluetoothd-service-audio +plugin_LTLIBRARIES = libaudio.la -bluetoothd_service_audio_SOURCES = main.c \ -	manager.h manager.c headset.h headset.c ipc.h ipc.c unix.h unix.c \ +libaudio_la_SOURCES = main.c \ +	manager.h manager.c headset.h headset.c \ +	ipc.h ipc.c unix.h unix.c \  	device.h device.c gateway.h gateway.c \ -	sink.c sink.h avdtp.c avdtp.h a2dp.c a2dp.h control.c control.h - -bluetoothd_service_audio_LDADD = $(top_builddir)/common/libhelper.a \ -				@GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ +	sink.c sink.h avdtp.c avdtp.h \ +	a2dp.c a2dp.h control.c control.h +libaudio_la_LDFLAGS = -module -avoid-version -export-symbols-regex bluetooth_plugin_desc +libaudio_la_LIBADD = $(top_builddir)/common/libhelper.a \ +		@GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ +libaudio_la_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@  if ALSA  alsadir = $(libdir)/alsa-lib @@ -54,11 +51,8 @@ libgstbluetooth_la_CFLAGS = @GSTREAMER_CFLAGS@ @SBC_CFLAGS@  endif  endif -AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ - -INCLUDES = -I$(top_srcdir)/common +INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/hcid -I$(top_srcdir)/sdpd -EXTRA_DIST = audio.service audio.conf audio-api.txt test-audio asound.conf +EXTRA_DIST = audio.conf audio-api.txt test-audio asound.conf  MAINTAINERCLEANFILES = Makefile.in - diff --git a/audio/a2dp.c b/audio/a2dp.c index e9c53c41..c3292fef 100644 --- a/audio/a2dp.c +++ b/audio/a2dp.c @@ -42,6 +42,7 @@  #include "avdtp.h"  #include "sink.h"  #include "a2dp.h" +#include "sdpd.h"  /* The duration that streams without users are allowed to stay in   * STREAMING state. */ @@ -915,31 +916,32 @@ static struct avdtp_sep_ind mpeg_ind = {  	.reconfigure		= reconf_ind  }; -static int a2dp_source_record(sdp_buf_t *buf) +static sdp_record_t *a2dp_source_record()  {  	sdp_list_t *svclass_id, *pfseq, *apseq, *root;  	uuid_t root_uuid, l2cap, avdtp, a2src;  	sdp_profile_desc_t profile[1];  	sdp_list_t *aproto, *proto[2]; -	sdp_record_t record; +	sdp_record_t *record;  	sdp_data_t *psm, *version, *features;  	uint16_t lp = AVDTP_UUID, ver = 0x0100, feat = 0x000F; -	int ret = 0; -	memset(&record, 0, sizeof(sdp_record_t)); +	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_set_browse_groups(record, root);  	sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID);  	svclass_id = sdp_list_append(0, &a2src); -	sdp_set_service_classes(&record, svclass_id); +	sdp_set_service_classes(record, svclass_id);  	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);  	profile[0].version = 0x0100;  	pfseq = sdp_list_append(0, &profile[0]); -	sdp_set_profile_descs(&record, pfseq); +	sdp_set_profile_descs(record, pfseq);  	sdp_uuid16_create(&l2cap, L2CAP_UUID);  	proto[0] = sdp_list_append(0, &l2cap); @@ -954,17 +956,12 @@ static int a2dp_source_record(sdp_buf_t *buf)  	apseq = sdp_list_append(apseq, proto[1]);  	aproto = sdp_list_append(0, apseq); -	sdp_set_access_protos(&record, aproto); +	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); +	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features); -	if (sdp_gen_record_pdu(&record, buf) < 0) -		ret = -1; -	else -		ret = 0; +	sdp_set_info_attr(record, "Audio Source", 0, 0);  	free(psm);  	free(version); @@ -975,15 +972,13 @@ static int a2dp_source_record(sdp_buf_t *buf)  	sdp_list_free(aproto, 0);  	sdp_list_free(root, 0);  	sdp_list_free(svclass_id, 0); -	sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); -	sdp_list_free(record.pattern, free); -	return ret; +	return record;  } -static int a2dp_sink_record(sdp_buf_t *buf) +static sdp_record_t *a2dp_sink_record()  { -	return -1; +	return NULL;  }  static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type, @@ -991,9 +986,9 @@ static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type,  {  	struct a2dp_sep *sep;  	GSList **l; -	int (*create_record)(sdp_buf_t *buf); +	sdp_record_t *(*create_record)(void);  	uint32_t *record_id; -	sdp_buf_t buf; +	sdp_record_t *record;  	struct avdtp_sep_ind *ind;  	sep = g_new0(struct a2dp_sep, 1); @@ -1022,22 +1017,22 @@ static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type,  	if (*record_id != 0)  		goto add; -	memset(&buf, 0, sizeof(buf)); -	if (create_record(&buf) < 0) { +	record = create_record(); +	if (!record) {  		error("Unable to allocate new service record");  		avdtp_unregister_sep(sep->sep);  		g_free(sep);  		return NULL;  	} -	*record_id = add_service_record(conn, &buf); -	free(buf.data); -	if (!*record_id) { -		error("Unable to register A2DP service record"); +	if (add_record_to_server(BDADDR_ANY, record) < 0) { +		error("Unable to register A2DP service record");\ +		sdp_record_free(record);  		avdtp_unregister_sep(sep->sep);  		g_free(sep);  		return NULL;  	} +	*record_id = record->handle;  add:  	*l = g_slist_append(*l, sep); @@ -1156,12 +1151,12 @@ void a2dp_exit()  	sources = NULL;  	if (source_record_id) { -		remove_service_record(connection, source_record_id); +		remove_record_from_server(source_record_id);  		source_record_id = 0;  	}  	if (sink_record_id) { -		remove_service_record(connection, sink_record_id); +		remove_record_from_server(sink_record_id);  		sink_record_id = 0;  	} diff --git a/audio/control.c b/audio/control.c index 63612f4a..13b4b811 100644 --- a/audio/control.c +++ b/audio/control.c @@ -53,6 +53,7 @@  #include "manager.h"  #include "avdtp.h"  #include "control.h" +#include "sdpd.h"  #define AVCTP_PSM 23 @@ -171,27 +172,28 @@ struct control {  	struct avctp *session;  }; -static int avrcp_ct_record(sdp_buf_t *buf) +static sdp_record_t *avrcp_ct_record()  {  	sdp_list_t *svclass_id, *pfseq, *apseq, *root;  	uuid_t root_uuid, l2cap, avctp, avrct;  	sdp_profile_desc_t profile[1];  	sdp_list_t *aproto, *proto[2]; -	sdp_record_t record; +	sdp_record_t *record;  	sdp_data_t *psm, *version, *features;  	uint16_t lp = AVCTP_PSM, ver = 0x0103, feat = 0x000f; -	int ret = 0; -	memset(&record, 0, sizeof(sdp_record_t)); +	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_set_browse_groups(record, root);  	/* Service Class ID List */  	sdp_uuid16_create(&avrct, AV_REMOTE_SVCLASS_ID);  	svclass_id = sdp_list_append(0, &avrct); -	sdp_set_service_classes(&record, svclass_id); +	sdp_set_service_classes(record, svclass_id);  	/* Protocol Descriptor List */  	sdp_uuid16_create(&l2cap, L2CAP_UUID); @@ -207,23 +209,18 @@ static int avrcp_ct_record(sdp_buf_t *buf)  	apseq = sdp_list_append(apseq, proto[1]);  	aproto = sdp_list_append(0, apseq); -	sdp_set_access_protos(&record, aproto); +	sdp_set_access_protos(record, aproto);  	/* Bluetooth Profile Descriptor List */  	sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);  	profile[0].version = ver;  	pfseq = sdp_list_append(0, &profile[0]); -	sdp_set_profile_descs(&record, pfseq); +	sdp_set_profile_descs(record, pfseq);  	features = sdp_data_alloc(SDP_UINT16, &feat); -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); - -	sdp_set_info_attr(&record, "AVRCP CT", 0, 0); +	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features); -	if (sdp_gen_record_pdu(&record, buf) < 0) -		ret = -1; -	else -		ret = 0; +	sdp_set_info_attr(record, "AVRCP CT", 0, 0);  	free(psm);  	free(version); @@ -234,33 +231,32 @@ static int avrcp_ct_record(sdp_buf_t *buf)  	sdp_list_free(aproto, 0);  	sdp_list_free(root, 0);  	sdp_list_free(svclass_id, 0); -	sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); -	sdp_list_free(record.pattern, free); -	return ret; +	return record;  } -static int avrcp_tg_record(sdp_buf_t *buf) +static sdp_record_t *avrcp_tg_record()  {  	sdp_list_t *svclass_id, *pfseq, *apseq, *root;  	uuid_t root_uuid, l2cap, avctp, avrtg;  	sdp_profile_desc_t profile[1];  	sdp_list_t *aproto, *proto[2]; -	sdp_record_t record; +	sdp_record_t *record;  	sdp_data_t *psm, *version, *features;  	uint16_t lp = AVCTP_PSM, ver = 0x0103, feat = 0x000f; -	int ret = 0; -	memset(&record, 0, sizeof(sdp_record_t)); +	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_set_browse_groups(record, root);  	/* Service Class ID List */  	sdp_uuid16_create(&avrtg, AV_REMOTE_TARGET_SVCLASS_ID);  	svclass_id = sdp_list_append(0, &avrtg); -	sdp_set_service_classes(&record, svclass_id); +	sdp_set_service_classes(record, svclass_id);  	/* Protocol Descriptor List */  	sdp_uuid16_create(&l2cap, L2CAP_UUID); @@ -276,23 +272,18 @@ static int avrcp_tg_record(sdp_buf_t *buf)  	apseq = sdp_list_append(apseq, proto[1]);  	aproto = sdp_list_append(0, apseq); -	sdp_set_access_protos(&record, aproto); +	sdp_set_access_protos(record, aproto);  	/* Bluetooth Profile Descriptor List */  	sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);  	profile[0].version = ver;  	pfseq = sdp_list_append(0, &profile[0]); -	sdp_set_profile_descs(&record, pfseq); +	sdp_set_profile_descs(record, pfseq);  	features = sdp_data_alloc(SDP_UINT16, &feat); -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); +	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features); -	sdp_set_info_attr(&record, "AVRCP TG", 0, 0); - -	if (sdp_gen_record_pdu(&record, buf) < 0) -		ret = -1; -	else -		ret = 0; +	sdp_set_info_attr(record, "AVRCP TG", 0, 0);  	free(psm);  	free(version); @@ -303,10 +294,8 @@ static int avrcp_tg_record(sdp_buf_t *buf)  	sdp_list_free(pfseq, 0);  	sdp_list_free(root, 0);  	sdp_list_free(svclass_id, 0); -	sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); -	sdp_list_free(record.pattern, free); -	return ret; +	return record;  }  static GIOChannel *avctp_server_socket(gboolean master) @@ -981,7 +970,7 @@ void avrcp_disconnect(struct device *dev)  int avrcp_init(DBusConnection *conn, GKeyFile *config)  { -	sdp_buf_t buf; +	sdp_record_t *record;  	gboolean tmp, master = TRUE;  	GError *err = NULL; @@ -999,31 +988,31 @@ int avrcp_init(DBusConnection *conn, GKeyFile *config)  	connection = dbus_connection_ref(conn); -	if (avrcp_tg_record(&buf) < 0) { +	record = avrcp_tg_record(); +	if (!record) {  		error("Unable to allocate new service record");  		return -1;  	} -	tg_record_id = add_service_record(conn, &buf); -	free(buf.data); - -	if (!tg_record_id) { +	if (add_record_to_server(BDADDR_ANY, record) < 0) {  		error("Unable to register AVRCP target service record"); +		sdp_record_free(record);  		return -1;  	} +	tg_record_id = record->handle; -	if (avrcp_ct_record(&buf) < 0) { +	record = avrcp_ct_record(); +	if (!record) {  		error("Unable to allocate new service record");  		return -1;  	} -	ct_record_id = add_service_record(conn, &buf); -	free(buf.data); - -	if (!ct_record_id) { +	if (add_record_to_server(BDADDR_ANY, record) < 0) {  		error("Unable to register AVRCP controller service record"); +		sdp_record_free(record);  		return -1;  	} +	ct_record_id = record->handle;  	avctp_server = avctp_server_socket(master);  	if (!avctp_server) @@ -1044,11 +1033,11 @@ void avrcp_exit(void)  	g_io_channel_unref(avctp_server);  	avctp_server = NULL; -	remove_service_record(connection, ct_record_id); +	remove_record_from_server(ct_record_id);  	ct_record_id = 0; -	remove_service_record(connection, ct_record_id); -	ct_record_id = 0; +	remove_record_from_server(tg_record_id); +	tg_record_id = 0;  	dbus_connection_unref(connection);  	connection = NULL; diff --git a/audio/device.c b/audio/device.c index 7510d9a4..7e25fe90 100644 --- a/audio/device.c +++ b/audio/device.c @@ -218,60 +218,6 @@ static void device_unregister(DBusConnection *conn, void *data)  	device_free(device);  } -char *find_adapter(DBusConnection *conn, bdaddr_t *src) -{ -	DBusMessage *msg, *reply; -	DBusError derr; -	char address[18], *addr_ptr = address; -	char *path, *ret; - -	msg = dbus_message_new_method_call("org.bluez", "/org/bluez", -						"org.bluez.Manager", -						"FindAdapter"); -	if (!msg) { -		error("Unable to allocate new method call"); -		return NULL; -	} - -	ba2str(src, address); - -	dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr, -				 DBUS_TYPE_INVALID); - -	dbus_error_init(&derr); -	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, -								&derr); - -	dbus_message_unref(msg); - -	if (dbus_error_is_set(&derr) || -				dbus_set_error_from_message(&derr, reply)) { -		error("FindAdapter(%s) failed: %s", address, derr.message); -		dbus_error_free(&derr); -		return NULL; -	} - -	dbus_error_init(&derr); -	dbus_message_get_args(reply, &derr, -				DBUS_TYPE_STRING, &path, -				DBUS_TYPE_INVALID); - -	if (dbus_error_is_set(&derr)) { -		error("Unable to get message args"); -		dbus_message_unref(reply); -		dbus_error_free(&derr); -		return FALSE; -	} - -	ret = g_strdup(path); - -	dbus_message_unref(reply); - -	debug("Got path %s for adapter with address %s", ret, address); - -	return ret; -} -  struct device *device_register(DBusConnection *conn,  					const char *path, bdaddr_t *bda)  { @@ -289,7 +235,8 @@ struct device *device_register(DBusConnection *conn,  	dev = g_new0(struct device, 1); -	dev->adapter_path = find_adapter(conn, &src); +	/* FIXME just to maintain compatibility */ +	dev->adapter_path = g_strdup_printf("/org/bluez/hci%d", dev_id);  	if (!dev->adapter_path) {  		device_free(dev);  		return NULL; diff --git a/audio/main.c b/audio/main.c index 6c6b0d79..f96b19f8 100644 --- a/audio/main.c +++ b/audio/main.c @@ -26,29 +26,21 @@  #include <config.h>  #endif -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <signal.h> +#include <errno.h> +#include <sys/socket.h> +#include <bluetooth/bluetooth.h> +#include <bluetooth/sdp.h>  #include <glib.h>  #include <dbus/dbus.h> -#include <bluetooth/bluetooth.h> -#include <bluetooth/sdp.h> +#include "plugin.h"  #include "dbus.h"  #include "logging.h"  #include "unix.h"  #include "device.h"  #include "manager.h" -static GMainLoop *main_loop = NULL; - -static void sig_term(int sig) -{ -	g_main_loop_quit(main_loop); -} -  static GKeyFile *load_config_file(const char *file)  {  	GError *err = NULL; @@ -66,64 +58,42 @@ static GKeyFile *load_config_file(const char *file)  	return keyfile;  } -int main(int argc, char *argv[]) +static DBusConnection *conn; + +static int audio_init(void)  { -	DBusConnection *conn; -	struct sigaction sa;  	GKeyFile *config; -	start_logging("audio", "Bluetooth Audio daemon"); - -	memset(&sa, 0, sizeof(sa)); -	sa.sa_flags = SA_NOCLDSTOP; -	sa.sa_handler = sig_term; -	sigaction(SIGTERM, &sa, NULL); -	sigaction(SIGINT,  &sa, NULL); - -	sa.sa_handler = SIG_IGN; -	sigaction(SIGCHLD, &sa, NULL); -	sigaction(SIGPIPE, &sa, NULL); - -	enable_debug(); +	conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); +	if (conn == NULL) +		return -EIO;  	config = load_config_file(CONFIGDIR "/audio.conf"); -	main_loop = g_main_loop_new(NULL, FALSE); - -	conn = dbus_bus_system_setup_with_main_loop(NULL, NULL, NULL); -	if (!conn) { -		g_main_loop_unref(main_loop); -		exit(1); -	} -  	if (unix_init() < 0) {  		error("Unable to setup unix socket"); -		exit(1); +		return -EIO;  	} -	if (audio_init(conn, config) < 0) { -		error("Audio init failed!"); -		exit(1); +	if (audio_manager_init(conn, config) < 0) { +		dbus_connection_unref(conn); +		return -EIO;  	} -	if (argc > 1 && !strcmp(argv[1], "-s")) -		register_external_service(conn, "audio", "Audio service", ""); -	if (config) -		g_key_file_free(config); +	g_key_file_free(config); + +	register_external_service(conn, "audio", "audio service", ""); -	g_main_loop_run(main_loop); +	return 0; +} -	audio_exit(); +static void audio_exit(void) +{ +	audio_manager_exit();  	unix_exit();  	dbus_connection_unref(conn); - -	g_main_loop_unref(main_loop); - -	info("Exit"); - -	stop_logging(); - -	return 0;  } + +BLUETOOTH_PLUGIN_DEFINE("audio", audio_init, audio_exit) diff --git a/audio/manager.c b/audio/manager.c index 4abc4571..7da74be6 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -62,6 +62,7 @@  #include "sink.h"  #include "control.h"  #include "manager.h" +#include "sdpd.h"  typedef enum {  	HEADSET	= 1 << 0, @@ -1164,33 +1165,34 @@ static void manager_unregister(DBusConnection *conn, void *data)  	}  } -static int hsp_ag_record(sdp_buf_t *buf, uint8_t ch) +static sdp_record_t *hsp_ag_record(uint8_t ch)  {  	sdp_list_t *svclass_id, *pfseq, *apseq, *root;  	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;  	uuid_t l2cap_uuid, rfcomm_uuid;  	sdp_profile_desc_t profile; +	sdp_record_t *record;  	sdp_list_t *aproto, *proto[2]; -	sdp_record_t record;  	sdp_data_t *channel; -	int ret; -	memset(&record, 0, sizeof(sdp_record_t)); +	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_set_browse_groups(record, root);  	sdp_uuid16_create(&svclass_uuid, HEADSET_AGW_SVCLASS_ID);  	svclass_id = sdp_list_append(0, &svclass_uuid);  	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);  	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); -	sdp_set_service_classes(&record, svclass_id); +	sdp_set_service_classes(record, svclass_id);  	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);  	profile.version = 0x0100;  	pfseq = sdp_list_append(0, &profile); -	sdp_set_profile_descs(&record, pfseq); +	sdp_set_profile_descs(record, pfseq);  	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);  	proto[0] = sdp_list_append(0, &l2cap_uuid); @@ -1203,14 +1205,9 @@ static int hsp_ag_record(sdp_buf_t *buf, uint8_t ch)  	apseq = sdp_list_append(apseq, proto[1]);  	aproto = sdp_list_append(0, apseq); -	sdp_set_access_protos(&record, aproto); +	sdp_set_access_protos(record, aproto); -	sdp_set_info_attr(&record, "Headset Audio Gateway", 0, 0); - -	if (sdp_gen_record_pdu(&record, buf) < 0) -		ret = -1; -	else -		ret = 0; +	sdp_set_info_attr(record, "Headset Audio Gateway", 0, 0);  	sdp_data_free(channel);  	sdp_list_free(proto[0], 0); @@ -1220,42 +1217,41 @@ static int hsp_ag_record(sdp_buf_t *buf, uint8_t ch)  	sdp_list_free(aproto, 0);  	sdp_list_free(root, 0);  	sdp_list_free(svclass_id, 0); -	sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); -	sdp_list_free(record.pattern, free); -	return ret; +	return record;  } -static int hfp_ag_record(sdp_buf_t *buf, uint8_t ch, uint32_t feat) +static sdp_record_t *hfp_ag_record(uint8_t ch, uint32_t feat)  {  	sdp_list_t *svclass_id, *pfseq, *apseq, *root;  	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;  	uuid_t l2cap_uuid, rfcomm_uuid;  	sdp_profile_desc_t profile;  	sdp_list_t *aproto, *proto[2]; -	sdp_record_t record; +	sdp_record_t *record;  	sdp_data_t *channel, *features;  	uint8_t netid = 0x01;  	uint16_t sdpfeat;  	sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); -	int ret; -	memset(&record, 0, sizeof(sdp_record_t)); +	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_set_browse_groups(record, root);  	sdp_uuid16_create(&svclass_uuid, HANDSFREE_AGW_SVCLASS_ID);  	svclass_id = sdp_list_append(0, &svclass_uuid);  	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);  	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); -	sdp_set_service_classes(&record, svclass_id); +	sdp_set_service_classes(record, svclass_id);  	sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID);  	profile.version = 0x0105;  	pfseq = sdp_list_append(0, &profile); -	sdp_set_profile_descs(&record, pfseq); +	sdp_set_profile_descs(record, pfseq);  	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);  	proto[0] = sdp_list_append(0, &l2cap_uuid); @@ -1269,19 +1265,14 @@ static int hfp_ag_record(sdp_buf_t *buf, uint8_t ch, uint32_t feat)  	sdpfeat = (uint16_t) feat & 0xF;  	features = sdp_data_alloc(SDP_UINT16, &sdpfeat); -	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); +	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);  	aproto = sdp_list_append(0, apseq); -	sdp_set_access_protos(&record, aproto); +	sdp_set_access_protos(record, aproto); -	sdp_set_info_attr(&record, "Hands-Free Audio Gateway", 0, 0); +	sdp_set_info_attr(record, "Hands-Free Audio Gateway", 0, 0); -	sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network); - -	if (sdp_gen_record_pdu(&record, buf) < 0) -		ret = -1; -	else -		ret = 0; +	sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network);  	sdp_data_free(channel);  	sdp_list_free(proto[0], 0); @@ -1291,93 +1282,8 @@ static int hfp_ag_record(sdp_buf_t *buf, uint8_t ch, uint32_t feat)  	sdp_list_free(aproto, 0);  	sdp_list_free(root, 0);  	sdp_list_free(svclass_id, 0); -	sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); -	sdp_list_free(record.pattern, free); - -	return ret; -} - -uint32_t add_service_record(DBusConnection *conn, sdp_buf_t *buf) -{ -	DBusMessage *msg, *reply; -	DBusError derr; -	dbus_uint32_t rec_id; - -	msg = dbus_message_new_method_call("org.bluez", "/org/bluez", -						"org.bluez.Database", -						"AddServiceRecord"); -	if (!msg) { -		error("Can't allocate new method call"); -		return 0; -	} - -	dbus_message_append_args(msg, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, -						&buf->data, buf->data_size, -							DBUS_TYPE_INVALID); - -	dbus_error_init(&derr); -	reply = dbus_connection_send_with_reply_and_block(connection, -							msg, -1, &derr); - -	dbus_message_unref(msg); - -	if (dbus_error_is_set(&derr) || -			dbus_set_error_from_message(&derr, reply)) { -		error("Adding service record failed: %s", derr.message); -		dbus_error_free(&derr); -		return 0; -	} - -	dbus_message_get_args(reply, &derr, DBUS_TYPE_UINT32, &rec_id, -							DBUS_TYPE_INVALID); - -	if (dbus_error_is_set(&derr)) { -		error("Invalid arguments to AddServiceRecord reply: %s", -								derr.message); -		dbus_message_unref(reply); -		dbus_error_free(&derr); -		return 0; -	} - -	dbus_message_unref(reply); - -	debug("add_service_record: got record id 0x%x", rec_id); - -	return rec_id; -} - -int remove_service_record(DBusConnection *conn, uint32_t rec_id) -{ -	DBusMessage *msg, *reply; -	DBusError derr; - -	msg = dbus_message_new_method_call("org.bluez", "/org/bluez", -						"org.bluez.Database", -						"RemoveServiceRecord"); -	if (!msg) { -		error("Can't allocate new method call"); -		return 0; -	} - -	dbus_message_append_args(msg, DBUS_TYPE_UINT32, &rec_id, -							DBUS_TYPE_INVALID); - -	dbus_error_init(&derr); -	reply = dbus_connection_send_with_reply_and_block(connection, -							msg, -1, &derr); - -	dbus_message_unref(msg); -	if (dbus_error_is_set(&derr)) { -		error("Removing service record 0x%x failed: %s", -						rec_id, derr.message); -		dbus_error_free(&derr); -		return 0; -	} - -	dbus_message_unref(reply); - -	return 0; +	return record;  }  static void auth_cb(DBusPendingCall *call, void *data) @@ -1543,7 +1449,7 @@ static GIOChannel *server_socket(uint8_t *channel, gboolean master)  static int headset_server_init(DBusConnection *conn, GKeyFile *config)  {  	uint8_t chan = DEFAULT_HS_AG_CHANNEL; -	sdp_buf_t buf; +	sdp_record_t *record;  	gboolean hfp = TRUE, master = TRUE;  	GError *err = NULL;  	uint32_t features; @@ -1577,19 +1483,20 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)  	if (!hs_server)  		return -1; -	if (hsp_ag_record(&buf, chan) < 0) { +	record = hsp_ag_record(chan); +	if (!record) {  		error("Unable to allocate new service record");  		return -1;  	} -	hs_record_id = add_service_record(conn, &buf); -	free(buf.data); -	if (!hs_record_id) { +	if (add_record_to_server(BDADDR_ANY, record) < 0) {  		error("Unable to register HS AG service record"); +		sdp_record_free(record);  		g_io_channel_unref(hs_server);  		hs_server = NULL;  		return -1;  	} +	hs_record_id = record->handle;  	g_io_add_watch(hs_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,  				(GIOFunc) ag_io_cb, NULL); @@ -1605,19 +1512,20 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)  	if (!hf_server)  		return -1; -	if (hfp_ag_record(&buf, chan, features) < 0) { +	record = hfp_ag_record(chan, features); +	if (!record) {  		error("Unable to allocate new service record");  		return -1;  	} -	hf_record_id = add_service_record(conn, &buf); -	free(buf.data); -	if (!hf_record_id) { -		error("Unable to register HS AG service record"); +	if (add_record_to_server(BDADDR_ANY, record) < 0) { +		error("Unable to register HF AG service record"); +		sdp_record_free(record);  		g_io_channel_unref(hf_server); -		hs_server = NULL; +		hf_server = NULL;  		return -1;  	} +	hf_record_id = record->handle;  	g_io_add_watch(hf_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,  			(GIOFunc) ag_io_cb, NULL); @@ -1628,7 +1536,7 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)  static void server_exit(void)  {  	if (hs_record_id) { -		remove_service_record(connection, hs_record_id); +		remove_record_from_server(hs_record_id);  		hs_record_id = 0;  	} @@ -1638,7 +1546,7 @@ static void server_exit(void)  	}  	if (hf_record_id) { -		remove_service_record(connection, hf_record_id); +		remove_record_from_server(hf_record_id);  		hf_record_id = 0;  	} @@ -1648,7 +1556,7 @@ static void server_exit(void)  	}  } -int audio_init(DBusConnection *conn, GKeyFile *config) +int audio_manager_init(DBusConnection *conn, GKeyFile *config)  {  	char *str;  	GError *err = NULL; @@ -1731,11 +1639,11 @@ int audio_init(DBusConnection *conn, GKeyFile *config)  	return 0;  failed: -	audio_exit(); +	audio_manager_exit();  	return -1;  } -void audio_exit(void) +void audio_manager_exit(void)  {  	server_exit(); diff --git a/audio/manager.h b/audio/manager.h index 4038d3b9..c8f826ee 100644 --- a/audio/manager.h +++ b/audio/manager.h @@ -36,11 +36,9 @@ struct enabled_interfaces {  typedef void (*create_dev_cb_t) (struct device *dev, void *user_data); -int audio_init(DBusConnection *conn, GKeyFile *config); -void audio_exit(void); +int audio_manager_init(DBusConnection *conn, GKeyFile *config); +void audio_manager_exit(void); -uint32_t add_service_record(DBusConnection *conn, sdp_buf_t *buf); -int remove_service_record(DBusConnection *conn, uint32_t rec_id);  gboolean server_is_enabled(uint16_t svc);  struct device *manager_find_device(bdaddr_t *bda, const char *interface, | 
