summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-03-27 23:07:19 +0000
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-03-27 23:07:19 +0000
commit7299869ac79b76564cd68411acb18f4233ddbbb7 (patch)
tree6773d52943cb4e6cf04e51f5ed0702bd37dc8169 /audio
parentbec69df1c6672579961d96b718b8703650d01322 (diff)
Convert audio service into a plugin.
Diffstat (limited to 'audio')
-rw-r--r--audio/Makefile.am32
-rw-r--r--audio/a2dp.c55
-rw-r--r--audio/control.c89
-rw-r--r--audio/device.c57
-rw-r--r--audio/main.c80
-rw-r--r--audio/manager.c178
-rw-r--r--audio/manager.h6
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,