diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-08-05 23:36:14 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-08-05 23:36:14 +0200 |
commit | 32cf081aa948793869822c9634751bced245f01c (patch) | |
tree | bd6281604d6d256625c615b98cf2a3d19fe0be0e | |
parent | 161915e640404db7a46321e59127a666b992b0df (diff) | |
parent | 00acfa685e3e73c619146b7ca39068eb304f1ce8 (diff) |
Merge branch 'bluez4' of git://git.infradead.org/users/vudentz/bluez-utils
-rw-r--r-- | audio/manager.c | 1 | ||||
-rw-r--r-- | input/manager.c | 1 | ||||
-rw-r--r-- | network/manager.c | 1 | ||||
-rw-r--r-- | serial/manager.c | 1 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/agent.c | 323 | ||||
-rw-r--r-- | src/device.c | 28 | ||||
-rw-r--r-- | src/device.h | 14 | ||||
-rw-r--r-- | src/driver.c | 82 | ||||
-rw-r--r-- | src/driver.h | 54 | ||||
-rw-r--r-- | src/manager.c | 19 |
11 files changed, 344 insertions, 184 deletions
diff --git a/audio/manager.c b/audio/manager.c index b1da8426..695c6ba0 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -51,6 +51,7 @@ #include "glib-helper.h" #include "../src/adapter.h" #include "../src/device.h" +#include "../src/driver.h" #include "dbus-service.h" #include "logging.h" diff --git a/input/manager.c b/input/manager.c index 08609601..b18da8e0 100644 --- a/input/manager.c +++ b/input/manager.c @@ -46,6 +46,7 @@ #include "textfile.h" #include "../src/adapter.h" #include "../src/device.h" +#include "../src/driver.h" #include "device.h" #include "server.h" diff --git a/network/manager.c b/network/manager.c index 22a6e70c..c0af5d34 100644 --- a/network/manager.c +++ b/network/manager.c @@ -47,6 +47,7 @@ #include "adapter.h" #include "device.h" +#include "driver.h" #include "error.h" #include "bridge.h" #include "manager.h" diff --git a/serial/manager.c b/serial/manager.c index 79d7cb8e..9df3caaa 100644 --- a/serial/manager.c +++ b/serial/manager.c @@ -54,6 +54,7 @@ #include "../src/dbus-common.h" #include "adapter.h" #include "device.h" +#include "driver.h" #include "logging.h" #include "textfile.h" diff --git a/src/Makefile.am b/src/Makefile.am index 473c86f9..4b504add 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,11 +18,11 @@ sbin_PROGRAMS = bluetoothd bluetoothd_SOURCES = main.c hcid.h sdpd.h \ sdpd-server.c sdpd-request.c sdpd-service.c \ sdpd-database.c security.c storage.c \ - server.h server.c manager.h manager.c error.h error.c \ + manager.h manager.c error.h error.c \ adapter.h adapter.c device.h device.c plugin.h plugin.c \ dbus-common.c dbus-common.h dbus-hci.h dbus-hci.c \ dbus-database.c dbus-database.h dbus-service.c dbus-service.h \ - telephony.h telephony.c agent.h agent.c + telephony.h telephony.c agent.h agent.c driver.h driver.c bluetoothd_LDADD = $(top_builddir)/common/libhelper.a \ @GDBUS_LIBS@ @GMODULE_LIBS@ @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ diff --git a/src/agent.c b/src/agent.c index 3cae00a5..f0a6a44d 100644 --- a/src/agent.c +++ b/src/agent.c @@ -75,6 +75,7 @@ struct agent { struct agent_request { agent_request_type_t type; struct agent *agent; + DBusMessage *msg; DBusPendingCall *call; void *cb; void *user_data; @@ -82,6 +83,9 @@ struct agent_request { static DBusConnection *connection = NULL; +static int request_fallback(struct agent_request *req, + DBusPendingCallNotifyFunction function); + static void agent_release(struct agent *agent) { DBusMessage *message; @@ -127,6 +131,8 @@ static int send_cancel_request(struct agent_request *req) static void agent_request_free(struct agent_request *req) { + if (req->msg) + dbus_message_unref(req->msg); if (req->call) dbus_pending_call_unref(req->call); if (req->agent && req->agent->request) @@ -251,36 +257,6 @@ int agent_cancel(struct agent *agent) return 0; } -static DBusPendingCall *agent_call_authorize(struct agent *agent, - const char *device_path, - const char *uuid) -{ - DBusMessage *message; - DBusPendingCall *call; - - message = dbus_message_new_method_call(agent->name, agent->path, - "org.bluez.Agent", "Authorize"); - if (!message) { - error("Couldn't allocate D-Bus message"); - return NULL; - } - - dbus_message_append_args(message, - DBUS_TYPE_OBJECT_PATH, &device_path, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - - if (dbus_connection_send_with_reply(connection, message, - &call, REQUEST_TIMEOUT) == FALSE) { - error("D-Bus send failed"); - dbus_message_unref(message); - return NULL; - } - - dbus_message_unref(message); - return call; -} - static void simple_agent_reply(DBusPendingCall *call, void *user_data) { struct agent_request *req = user_data; @@ -295,6 +271,12 @@ static void simple_agent_reply(DBusPendingCall *call, void *user_data) dbus_error_init(&err); if (dbus_set_error_from_message(&err, message)) { + if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) || + g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) && + request_fallback(req, simple_agent_reply) == 0) { + dbus_error_free(&err); + return; + } error("Agent replied with an error: %s, %s", err.name, err.message); @@ -320,6 +302,34 @@ done: agent_request_free(req); } +static int agent_call_authorize(struct agent_request *req, + const char *device_path, + const char *uuid) +{ + struct agent *agent = req->agent; + + req->msg = dbus_message_new_method_call(agent->name, agent->path, + "org.bluez.Agent", "Authorize"); + if (!req->msg) { + error("Couldn't allocate D-Bus message"); + return -ENOMEM; + } + + dbus_message_append_args(req->msg, + DBUS_TYPE_OBJECT_PATH, &device_path, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); + + if (dbus_connection_send_with_reply(connection, req->msg, + &req->call, REQUEST_TIMEOUT) == FALSE) { + error("D-Bus send failed"); + return -EIO; + } + + dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL); + return 0; +} + int agent_authorize(struct agent *agent, const char *path, const char *uuid, @@ -327,19 +337,19 @@ int agent_authorize(struct agent *agent, void *user_data) { struct agent_request *req; + int err; if (agent->request) return -EBUSY; req = agent_request_new(agent, AGENT_REQUEST_AUTHORIZE, cb, user_data); - req->call = agent_call_authorize(agent, path, uuid); - if (!req->call) { + err = agent_call_authorize(req, path, uuid); + if (err < 0) { agent_request_free(req); return DBUS_HANDLER_RESULT_NEED_MEMORY; } - dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL); agent->request = req; debug("authorize request was sent for %s", path); @@ -347,34 +357,6 @@ int agent_authorize(struct agent *agent, return 0; } -static DBusPendingCall *pincode_request_new(struct agent *agent, - const char *device_path, - dbus_bool_t numeric) -{ - DBusMessage *message; - DBusPendingCall *call; - - message = dbus_message_new_method_call(agent->name, agent->path, - "org.bluez.Agent", "RequestPinCode"); - if (message == NULL) { - error("Couldn't allocate D-Bus message"); - return NULL; - } - - dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &device_path, - DBUS_TYPE_INVALID); - - if (dbus_connection_send_with_reply(connection, message, - &call, REQUEST_TIMEOUT) == FALSE) { - error("D-Bus send failed"); - dbus_message_unref(message); - return NULL; - } - - dbus_message_unref(message); - return call; -} - static void pincode_reply(DBusPendingCall *call, void *user_data) { struct agent_request *req = user_data; @@ -394,6 +376,13 @@ static void pincode_reply(DBusPendingCall *call, void *user_data) dbus_error_init(&err); if (dbus_set_error_from_message(&err, message)) { + if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) || + g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) && + request_fallback(req, pincode_reply) == 0) { + dbus_error_free(&err); + return; + } + error("Agent replied with an error: %s, %s", err.name, err.message); @@ -435,68 +424,91 @@ done: dbus_message_unref(message); dbus_pending_call_cancel(req->call); + agent->request = NULL; agent_request_free(req); } +static int pincode_request_new(struct agent_request *req, const char *device_path, + dbus_bool_t numeric) +{ + struct agent *agent = req->agent; + + req->msg = dbus_message_new_method_call(agent->name, agent->path, + "org.bluez.Agent", "RequestPinCode"); + if (req->msg == NULL) { + error("Couldn't allocate D-Bus message"); + return -ENOMEM; + } + + dbus_message_append_args(req->msg, DBUS_TYPE_OBJECT_PATH, &device_path, + DBUS_TYPE_INVALID); + + if (dbus_connection_send_with_reply(connection, req->msg, + &req->call, REQUEST_TIMEOUT) == FALSE) { + error("D-Bus send failed"); + return -EIO; + } + + dbus_pending_call_set_notify(req->call, pincode_reply, req, NULL); + return 0; +} + int agent_request_pincode(struct agent *agent, struct btd_device *device, agent_pincode_cb cb, void *user_data) { struct agent_request *req; const gchar *dev_path = device_get_path(device); + int err; if (agent->request) return -EBUSY; req = agent_request_new(agent, AGENT_REQUEST_PINCODE, cb, user_data); - req->call = pincode_request_new(agent, dev_path, FALSE); - if (!req->call) + err = pincode_request_new(req, dev_path, FALSE); + if (err < 0) goto failed; - dbus_pending_call_set_notify(req->call, pincode_reply, req, NULL); - agent->request = req; return 0; failed: g_free(req); - return -1; + return err; } -static DBusPendingCall *confirm_mode_change_request_new(struct agent *agent, - const char *mode) +static int confirm_mode_change_request_new(struct agent_request *req, + const char *mode) { - DBusMessage *message; - DBusPendingCall *call; + struct agent *agent = req->agent; - message = dbus_message_new_method_call(agent->name, agent->path, + req->msg = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.Agent", "ConfirmModeChange"); - if (message == NULL) { + if (req->msg == NULL) { error("Couldn't allocate D-Bus message"); - return NULL; + return -ENOMEM; } - dbus_message_append_args(message, + dbus_message_append_args(req->msg, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID); - if (dbus_connection_send_with_reply(connection, message, - &call, REQUEST_TIMEOUT) == FALSE) { + if (dbus_connection_send_with_reply(connection, req->msg, + &req->call, REQUEST_TIMEOUT) == FALSE) { error("D-Bus send failed"); - dbus_message_unref(message); - return NULL; + return -EIO; } - dbus_message_unref(message); - - return call; + dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL); + return 0; } int agent_confirm_mode_change(struct agent *agent, const char *new_mode, agent_cb cb, void *user_data) { struct agent_request *req; + int err; if (agent->request) return -EBUSY; @@ -507,46 +519,17 @@ int agent_confirm_mode_change(struct agent *agent, const char *new_mode, req = agent_request_new(agent, AGENT_REQUEST_CONFIRM_MODE, cb, user_data); - req->call = confirm_mode_change_request_new(agent, new_mode); - if (!req->call) + err = confirm_mode_change_request_new(req, new_mode); + if (err < 0) goto failed; - dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL); - agent->request = req; return 0; failed: agent_request_free(req); - return -1; -} - -static DBusPendingCall *passkey_request_new(struct agent *agent, - const char *device_path) -{ - DBusMessage *message; - DBusPendingCall *call; - - message = dbus_message_new_method_call(agent->name, agent->path, - "org.bluez.Agent", "RequestPasskey"); - if (message == NULL) { - error("Couldn't allocate D-Bus message"); - return NULL; - } - - dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &device_path, - DBUS_TYPE_INVALID); - - if (dbus_connection_send_with_reply(connection, message, - &call, REQUEST_TIMEOUT) == FALSE) { - error("D-Bus send failed"); - dbus_message_unref(message); - return NULL; - } - - dbus_message_unref(message); - return call; + return err; } static void passkey_reply(DBusPendingCall *call, void *user_data) @@ -564,6 +547,13 @@ static void passkey_reply(DBusPendingCall *call, void *user_data) dbus_error_init(&err); if (dbus_set_error_from_message(&err, message)) { + if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) || + g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) && + request_fallback(req, passkey_reply) == 0) { + dbus_error_free(&err); + return; + } + error("Agent replied with an error: %s, %s", err.name, err.message); cb(agent, &err, 0, req->user_data); @@ -588,14 +578,41 @@ done: dbus_message_unref(message); dbus_pending_call_cancel(req->call); + agent->request = NULL; agent_request_free(req); } +static int passkey_request_new(struct agent_request *req, + const char *device_path) +{ + struct agent *agent = req->agent; + + req->msg = dbus_message_new_method_call(agent->name, agent->path, + "org.bluez.Agent", "RequestPasskey"); + if (req->msg == NULL) { + error("Couldn't allocate D-Bus message"); + return -ENOMEM; + } + + dbus_message_append_args(req->msg, DBUS_TYPE_OBJECT_PATH, &device_path, + DBUS_TYPE_INVALID); + + if (dbus_connection_send_with_reply(connection, req->msg, + &req->call, REQUEST_TIMEOUT) == FALSE) { + error("D-Bus send failed"); + return -EIO; + } + + dbus_pending_call_set_notify(req->call, passkey_reply, req, NULL); + return 0; +} + int agent_request_passkey(struct agent *agent, struct btd_device *device, agent_passkey_cb cb, void *user_data) { struct agent_request *req; const gchar *dev_path = device_get_path(device); + int err; if (agent->request) return -EBUSY; @@ -605,50 +622,46 @@ int agent_request_passkey(struct agent *agent, struct btd_device *device, req = agent_request_new(agent, AGENT_REQUEST_PASSKEY, cb, user_data); - req->call = passkey_request_new(agent, dev_path); - if (!req->call) + err = passkey_request_new(req, dev_path); + if (err < 0) goto failed; - dbus_pending_call_set_notify(req->call, passkey_reply, req, NULL); - agent->request = req; return 0; failed: agent_request_free(req); - return -1; + return err; } -static DBusPendingCall *confirmation_request_new(struct agent *agent, - const char *device_path, - uint32_t passkey) +static int confirmation_request_new(struct agent_request *req, + const char *device_path, + uint32_t passkey) { - DBusMessage *message; - DBusPendingCall *call; + struct agent *agent = req->agent; - message = dbus_message_new_method_call(agent->name, agent->path, + req->msg = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.Agent", "RequestConfirmation"); - if (message == NULL) { + if (req->msg == NULL) { error("Couldn't allocate D-Bus message"); - return NULL; + return -ENOMEM; } - dbus_message_append_args(message, + dbus_message_append_args(req->msg, DBUS_TYPE_OBJECT_PATH, &device_path, DBUS_TYPE_UINT32, &passkey, DBUS_TYPE_INVALID); - if (dbus_connection_send_with_reply(connection, message, - &call, REQUEST_TIMEOUT) == FALSE) { + if (dbus_connection_send_with_reply(connection, req->msg, + &req->call, REQUEST_TIMEOUT) == FALSE) { error("D-Bus send failed"); - dbus_message_unref(message); - return NULL; + return -EIO; } - dbus_message_unref(message); + dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL); - return call; + return 0; } int agent_request_confirmation(struct agent *agent, struct btd_device *device, @@ -657,6 +670,7 @@ int agent_request_confirmation(struct agent *agent, struct btd_device *device, { struct agent_request *req; const gchar *dev_path = device_get_path(device); + int err; if (agent->request) return -EBUSY; @@ -667,19 +681,52 @@ int agent_request_confirmation(struct agent *agent, struct btd_device *device, req = agent_request_new(agent, AGENT_REQUEST_CONFIRMATION, cb, user_data); - req->call = confirmation_request_new(agent, dev_path, passkey); - if (!req->call) + err = confirmation_request_new(req, dev_path, passkey); + if (err < 0) goto failed; - dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL); - agent->request = req; return 0; failed: agent_request_free(req); - return -1; + return err; +} + +static int request_fallback(struct agent_request *req, + DBusPendingCallNotifyFunction function) +{ + struct adapter *adapter = req->agent->adapter; + DBusMessage *msg; + + if (req->agent == adapter->agent || adapter->agent == NULL) + return -EINVAL; + + dbus_pending_call_cancel(req->call); + + msg = dbus_message_copy(req->msg); + + dbus_message_set_destination(msg, adapter->agent->name); + dbus_message_set_path(msg, adapter->agent->path); + + if (dbus_connection_send_with_reply(connection, msg, + &req->call, REQUEST_TIMEOUT) == FALSE) { + error("D-Bus send failed"); + dbus_message_unref(msg); + return -EIO; + } + + req->agent->request = NULL; + req->agent = adapter->agent; + req->agent->request = req; + + dbus_message_unref(req->msg); + req->msg = msg; + + dbus_pending_call_set_notify(req->call, function, req, NULL); + + return 0; } int agent_display_passkey(struct agent *agent, struct btd_device *device, diff --git a/src/device.c b/src/device.c index 4ef90803..ac578f2b 100644 --- a/src/device.c +++ b/src/device.c @@ -57,11 +57,11 @@ #include "device.h" #include "dbus-common.h" #include "dbus-hci.h" -#include "dbus-service.h" #include "error.h" #include "glib-helper.h" #include "agent.h" #include "sdp-xml.h" +#include "driver.h" #define DEFAULT_XML_BUF_SIZE 1024 #define DISCONNECT_TIMER 2 @@ -101,8 +101,6 @@ struct browse_req { gboolean browse; }; -static GSList *drivers = NULL; - static uint16_t uuid_list[] = { PUBLIC_BROWSE_GROUP, HID_SVCLASS_ID, @@ -620,13 +618,13 @@ sdp_record_t *get_record(sdp_list_t *recs, const char *uuid) void device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs) { - GSList *list; + GSList *list = btd_get_device_drivers(); const char **uuid; int err; debug("Probe drivers for %s", device->path); - for (list = drivers; list; list = list->next) { + for (; list; list = list->next) { struct btd_device_driver *driver = list->data; GSList *records = NULL; @@ -1085,23 +1083,3 @@ uint8_t device_get_auth(struct btd_device *device) { return device->auth; } - -int btd_register_device_driver(struct btd_device_driver *driver) -{ - const char **uuid; - - /* FIXME: hack to make hci to resolve service_req_auth symbol*/ - service_req_auth(NULL, NULL, NULL, NULL, NULL); - drivers = g_slist_append(drivers, driver); - - for (uuid = driver->uuids; *uuid; uuid++) { - debug("name %s uuid %s", driver->name, *uuid); - } - - return 0; -} - -void btd_unregister_device_driver(struct btd_device_driver *driver) -{ - drivers = g_slist_remove(drivers, driver); -} diff --git a/src/device.h b/src/device.h index 31480a66..c29d670b 100644 --- a/src/device.h +++ b/src/device.h @@ -42,17 +42,3 @@ void device_set_temporary(struct btd_device *device, gboolean temporary); void device_set_cap(struct btd_device *device, uint8_t cap); void device_set_auth(struct btd_device *device, uint8_t auth); uint8_t device_get_auth(struct btd_device *device); - -#define BTD_UUIDS(args...) ((const char *[]) { args, NULL } ) - -struct btd_device_driver { - const char *name; - const char **uuids; - int (*probe) (struct btd_device_driver *driver, - struct btd_device *device, GSList *records); - void (*remove) (struct btd_device_driver *driver, - struct btd_device *device); -}; - -int btd_register_device_driver(struct btd_device_driver *driver); -void btd_unregister_device_driver(struct btd_device_driver *driver); diff --git a/src/driver.c b/src/driver.c new file mode 100644 index 00000000..5c47a250 --- /dev/null +++ b/src/driver.c @@ -0,0 +1,82 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2006-2007 Nokia Corporation + * Copyright (C) 2004-2008 Marcel Holtmann <marcel@holtmann.org> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <bluetooth/bluetooth.h> + +#include <dbus/dbus.h> +#include <glib.h> + +#include "logging.h" + +#include "driver.h" +#include "dbus-service.h" + +static GSList *device_drivers = NULL; +static GSList *adapter_drivers = NULL; + +int btd_register_device_driver(struct btd_device_driver *driver) +{ + const char **uuid; + + /* FIXME: hack to make hci to resolve service_req_auth symbol*/ + service_req_auth(NULL, NULL, NULL, NULL, NULL); + device_drivers = g_slist_append(device_drivers, driver); + + for (uuid = driver->uuids; *uuid; uuid++) { + debug("name %s uuid %s", driver->name, *uuid); + } + + return 0; +} + +void btd_unregister_device_driver(struct btd_device_driver *driver) +{ + device_drivers = g_slist_remove(device_drivers, driver); +} + +GSList *btd_get_device_drivers() +{ + return device_drivers; +} + +int btd_register_adapter_driver(struct btd_adapter_driver *driver) +{ + adapter_drivers = g_slist_append(adapter_drivers, driver); + + return 0; +} + +void btd_unregister_adapter_driver(struct btd_adapter_driver *driver) +{ + adapter_drivers = g_slist_remove(adapter_drivers, driver); +} + +GSList *btd_get_adapter_drivers() +{ + return adapter_drivers; +} diff --git a/src/driver.h b/src/driver.h new file mode 100644 index 00000000..6ed56d53 --- /dev/null +++ b/src/driver.h @@ -0,0 +1,54 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2006-2007 Nokia Corporation + * Copyright (C) 2004-2008 Marcel Holtmann <marcel@holtmann.org> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define BTD_UUIDS(args...) ((const char *[]) { args, NULL } ) + +struct btd_device; + +struct btd_device_driver { + const char *name; + const char **uuids; + int (*probe) (struct btd_device_driver *driver, + struct btd_device *device, GSList *records); + void (*remove) (struct btd_device_driver *driver, + struct btd_device *device); +}; + +int btd_register_device_driver(struct btd_device_driver *driver); +void btd_unregister_device_driver(struct btd_device_driver *driver); +GSList *btd_get_device_drivers(void); + +struct btd_adapter; + +struct btd_adapter_driver { + const char *name; + int (*probe) (struct btd_adapter_driver *driver, + struct btd_adapter *adapter); + void (*remove) (struct btd_adapter_driver *driver, + struct btd_adapter *adapter); +}; + +int btd_register_adapter_driver(struct btd_adapter_driver *driver); +void btd_unregister_adapter_driver(struct btd_adapter_driver *driver); +GSList *btd_get_adapter_drivers(void); diff --git a/src/manager.c b/src/manager.c index cda45f4c..fc0c8738 100644 --- a/src/manager.c +++ b/src/manager.c @@ -59,7 +59,7 @@ #include "oui.h" #include "agent.h" #include "device.h" -#include "glib-helper.h" +#include "driver.h" #include "manager.h" @@ -443,14 +443,17 @@ static void manager_remove_adapter(struct adapter *adapter) int manager_register_adapter(int id) { struct adapter *adapter = adapter_create(connection, id); - const gchar *path; + GSList *l = btd_get_adapter_drivers(); if (!adapter) return -1; - path = adapter_get_path(adapter); + for (; l; l = l->next) { + struct btd_adapter_driver *driver = l->data; - __probe_servers(path); + if (driver->probe) + driver->probe(driver, (struct btd_adapter *) adapter); + } manager_add_adapter(adapter); @@ -461,6 +464,7 @@ int manager_unregister_adapter(int id) { struct adapter *adapter; const gchar *path; + GSList *l = btd_get_adapter_drivers(); adapter = manager_find_adapter_by_id(id); if (!adapter) @@ -470,7 +474,12 @@ int manager_unregister_adapter(int id) info("Unregister path: %s", path); - __remove_servers(path); + for (; l; l = l->next) { + struct btd_adapter_driver *driver = l->data; + + if (driver->remove) + driver->remove(driver, (struct btd_adapter *) adapter); + } adapter_stop(adapter); |