From 17541956196b13ee083852fd4124cd8cfd0928a4 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 9 Oct 2008 15:00:09 +0200 Subject: Add mechanism for adding new UUIDs from the driver side With this patch drivers can notify the core daemon that a device supports some UUID. This is useful in case we don't have a service record for a profile which the remote device initiates a connection for. --- audio/avdtp.c | 10 ++++++---- audio/control.c | 2 +- audio/manager.c | 51 ++++++++++++++++++++++++--------------------------- audio/manager.h | 3 +-- src/device.c | 33 ++++++++++++++++++++++++++++----- src/device.h | 1 + 6 files changed, 61 insertions(+), 39 deletions(-) diff --git a/audio/avdtp.c b/audio/avdtp.c index 1c6f8e67..affc7fe7 100644 --- a/audio/avdtp.c +++ b/audio/avdtp.c @@ -42,7 +42,9 @@ #include "logging.h" -#include "adapter.h" +#include "../src/adapter.h" +#include "../src/device.h" + #include "device.h" #include "manager.h" #include "control.h" @@ -1061,7 +1063,7 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, } avdtp_get_peers(session, &src, &dst); - dev = manager_get_device(&src, &dst, NULL); + dev = manager_get_device(&src, &dst); if (!dev) { error("Unable to get a audio device object"); goto failed; @@ -1070,7 +1072,7 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, switch (sep->info.type) { case AVDTP_SEP_TYPE_SOURCE: if (!dev->sink) - dev->sink = sink_init(dev); + btd_device_add_uuid(dev->btd_dev, A2DP_SINK_UUID); break; case AVDTP_SEP_TYPE_SINK: /* Do source_init() here when it's implemented */ @@ -2804,7 +2806,7 @@ static void avdtp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src, goto drop; } - dev = manager_get_device(src, dst, NULL); + dev = manager_get_device(src, dst); if (!dev) { error("Unable to get audio device object for %s", address); goto drop; diff --git a/audio/control.c b/audio/control.c index 8b3b2d8a..c8480197 100644 --- a/audio/control.c +++ b/audio/control.c @@ -686,7 +686,7 @@ static void avctp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src, goto drop; } - dev = manager_get_device(src, dst, NULL); + dev = manager_get_device(src, dst); if (!dev) { error("Unable to get audio device object for %s", address); goto drop; diff --git a/audio/manager.c b/audio/manager.c index bb7a457a..a73d7e0c 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -476,12 +476,12 @@ static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src, svclass = HANDSFREE_SVCLASS_ID; } - device = manager_get_device(src, dst, NULL); + device = manager_get_device(src, dst); if (!device) goto drop; if (!device->headset) - device->headset = headset_init(device, svclass, remote_uuid); + btd_device_add_uuid(device->btd_dev, remote_uuid); if (headset_get_state(device) > HEADSET_STATE_DISCONNECTED) { debug("Refusing new connection since one already exists"); @@ -666,21 +666,18 @@ static int gateway_server_init(struct audio_adapter *adapter) static int audio_probe(struct btd_device *device, GSList *uuids) { struct btd_adapter *adapter = device_get_adapter(device); - const gchar *path = device_get_path(device); bdaddr_t src, dst; struct audio_device *audio_dev; adapter_get_address(adapter, &src); device_get_address(device, &dst); - audio_dev = manager_get_device(&src, &dst, path); + audio_dev = manager_get_device(&src, &dst); if (!audio_dev) { debug("audio_probe: unable to get a device object"); return -1; } - audio_dev->btd_dev = device; - g_slist_foreach(uuids, (GFunc) handle_uuid, audio_dev); return 0; @@ -1048,44 +1045,44 @@ struct audio_device *manager_find_device(const bdaddr_t *bda, const char *interf } struct audio_device *manager_get_device(const bdaddr_t *src, - const bdaddr_t *dst, - const char *path) + const bdaddr_t *dst) { struct audio_device *dev; + struct btd_adapter *adapter; + struct btd_device *device; + char addr[18]; + const char *path; dev = manager_find_device(dst, NULL, FALSE); if (dev) return dev; - if (!path) { - struct btd_adapter *adapter; - struct btd_device *device; - char addr[18]; - ba2str(src, addr); + ba2str(src, addr); - adapter = manager_find_adapter(src); - if (!adapter) { - error("Unable to get a btd_adapter object for %s", - addr); - return NULL; - } + adapter = manager_find_adapter(src); + if (!adapter) { + error("Unable to get a btd_adapter object for %s", + addr); + return NULL; + } - ba2str(dst, addr); + ba2str(dst, addr); - device = adapter_get_device(connection, adapter, addr); - if (!device) { - error("Unable to get btd_device object for %s", addr); - return NULL; - } - - path = device_get_path(device); + device = adapter_get_device(connection, adapter, addr); + if (!device) { + error("Unable to get btd_device object for %s", addr); + return NULL; } + path = device_get_path(device); + dev = device_register(connection, path, src, dst); if (!dev) return NULL; + dev->btd_dev = device; + devices = g_slist_append(devices, dev); return dev; diff --git a/audio/manager.h b/audio/manager.h index 3d712f41..3af580ff 100644 --- a/audio/manager.h +++ b/audio/manager.h @@ -39,5 +39,4 @@ struct audio_device *manager_find_device(const bdaddr_t *bda, const char *interf gboolean connected); struct audio_device *manager_get_device(const bdaddr_t *src, - const bdaddr_t *dst, - const char *path); + const bdaddr_t *dst); diff --git a/src/device.c b/src/device.c index 3f70e647..6fba5352 100644 --- a/src/device.c +++ b/src/device.c @@ -827,10 +827,9 @@ static void discover_device_reply(struct browse_req *req, sdp_list_t *recs) dbus_message_unref(reply); } -static void services_changed(struct browse_req *req) +static void services_changed(struct btd_device *device) { DBusConnection *conn = get_dbus_connection(); - struct btd_device *device = req->device; char **uuids; GSList *l; int i; @@ -952,7 +951,7 @@ static void update_services(struct browse_req *req, sdp_list_t *recs) } } -static void store(struct btd_device *device) +static void store_profiles(struct btd_device *device) { struct btd_adapter *adapter = device->adapter; bdaddr_t src; @@ -1028,11 +1027,11 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data) device_remove_drivers(device, req->uuids_removed); /* Propagate services changes */ - services_changed(req); + services_changed(req->device); proceed: /* Store the device's profiles in the filesystem */ - store(device); + store_profiles(device); if (req->msg) { if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, @@ -1339,6 +1338,30 @@ int device_set_paired(DBusConnection *conn, struct btd_device *device, return 0; } +void btd_device_add_uuid(struct btd_device *device, const char *uuid) +{ + GSList *uuid_list; + char *new_uuid; + + if (g_slist_find_custom(device->uuids, uuid, + (GCompareFunc) strcasecmp)) + return; + + new_uuid = g_strdup(uuid); + + device->uuids = g_slist_append(device->uuids, new_uuid); + + store_profiles(device); + + uuid_list = g_slist_append(NULL, new_uuid); + + device_probe_drivers(device, uuid_list); + + g_slist_free(uuid_list); + + services_changed(device); +} + const sdp_record_t *btd_device_get_record(struct btd_device *device, const char *uuid) { diff --git a/src/device.h b/src/device.h index e0d334f6..c0d3b2bb 100644 --- a/src/device.h +++ b/src/device.h @@ -33,6 +33,7 @@ int device_browse(struct btd_device *device, DBusConnection *conn, void device_probe_drivers(struct btd_device *device, GSList *uuids); const sdp_record_t *btd_device_get_record(struct btd_device *device, const char *uuid); +void btd_device_add_uuid(struct btd_device *device, const char *uuid); struct btd_adapter *device_get_adapter(struct btd_device *device); void device_get_address(struct btd_device *adapter, bdaddr_t *bdaddr); const gchar *device_get_path(struct btd_device *device); -- cgit