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, |