diff options
| -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); | 
