diff options
| -rw-r--r-- | hcid/dbus-common.c | 13 | ||||
| -rw-r--r-- | hcid/dbus-hci.c | 408 | ||||
| -rw-r--r-- | hcid/dbus-hci.h | 4 | ||||
| -rw-r--r-- | hcid/main.c | 9 | ||||
| -rw-r--r-- | hcid/manager.c | 410 | ||||
| -rw-r--r-- | hcid/manager.h | 6 | 
6 files changed, 426 insertions, 424 deletions
diff --git a/hcid/dbus-common.c b/hcid/dbus-common.c index a2b25588..e779549c 100644 --- a/hcid/dbus-common.c +++ b/hcid/dbus-common.c @@ -157,7 +157,7 @@ static gboolean system_bus_reconnect(void *data)  	manager_set_default_adapter(-1);  	for (i = 0; i < dl->dev_num; i++, dr++) -		hcid_dbus_register_device(dr->dev_id); +		manager_register_adapter(dr->dev_id);  	ret_val = FALSE; @@ -192,14 +192,19 @@ void hcid_dbus_unregister(void)  		return;  	for (i = 0; children[i]; i++) { -		char dev_path[MAX_PATH_LENGTH]; +		char path[MAX_PATH_LENGTH]; +		struct adapter *adapter;  		if (children[i][0] != 'h')  			continue; -		snprintf(dev_path, sizeof(dev_path), "/%s", children[i]); +		snprintf(path, sizeof(path), "/%s", children[i]); -		unregister_adapter_path(dev_path); +		adapter = manager_find_adapter_by_path(path); +		if (!adapter) +			continue; + +		manager_unregister_adapter(adapter->dev_id);  	}  	dbus_free_string_array(children); diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index 4dbbdf34..be235882 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -305,152 +305,6 @@ static void adapter_mode_changed(struct adapter *adapter, uint8_t scan_enable)  					DBUS_TYPE_STRING, &mode);  } -/* - * HCI D-Bus services - */ -static void reply_pending_requests(const char *path, struct adapter *adapter) -{ -	DBusMessage *reply; - -	if (!path || !adapter) -		return; - -	/* pending bonding */ -	if (adapter->bonding) { -		reply = new_authentication_return(adapter->bonding->msg, -					HCI_OE_USER_ENDED_CONNECTION); -		g_dbus_send_message(connection, reply); -		remove_pending_device(adapter); - -		g_dbus_remove_watch(adapter->bonding->conn, -					adapter->bonding->listener_id); - -		if (adapter->bonding->io_id) -			g_source_remove(adapter->bonding->io_id); -		g_io_channel_close(adapter->bonding->io); -		bonding_request_free(adapter->bonding); -		adapter->bonding = NULL; -	} - -	/* If there is a pending reply for discovery cancel */ -	if (adapter->discovery_cancel) { -		reply = dbus_message_new_method_return(adapter->discovery_cancel); -		dbus_connection_send(connection, reply, NULL); -		dbus_message_unref(reply); -		dbus_message_unref(adapter->discovery_cancel); -		adapter->discovery_cancel = NULL; -	} - -	if (adapter->discov_active) { -		/* Send discovery completed signal if there isn't name -		 * to resolve */ -		g_dbus_emit_signal(connection, adapter->path, -				ADAPTER_INTERFACE, "DiscoveryCompleted", -				DBUS_TYPE_INVALID); - -		/* Cancel inquiry initiated by D-Bus client */ -		if (adapter->discov_requestor) -			cancel_discovery(adapter); -	} - -	if (adapter->pdiscov_active) { -		/* Stop periodic inquiry initiated by D-Bus client */ -		if (adapter->pdiscov_requestor) -			cancel_periodic_discovery(adapter); -	} -} - -static void do_unregister(gpointer data, gpointer user_data) -{ -	DBusConnection *conn = user_data; -	struct btd_device *device = data; - -	device_remove(conn, device); -} - -int unregister_adapter_path(const char *path) -{ -	struct adapter *adapter; - -	info("Unregister path: %s", path); - -	__remove_servers(path); - -	adapter = manager_find_adapter_by_path(path); -	if (!adapter) -		goto unreg; - -	/* check pending requests */ -	reply_pending_requests(path, adapter); - -	if (adapter->agent) { -		agent_destroy(adapter->agent, FALSE); -		adapter->agent = NULL; -	} - -	if (adapter->discov_requestor) { -		g_dbus_remove_watch(connection, adapter->discov_listener); -		adapter->discov_listener = 0; -		g_free(adapter->discov_requestor); -		adapter->discov_requestor = NULL; -	} - -	if (adapter->pdiscov_requestor) { -		g_dbus_remove_watch(connection, adapter->pdiscov_listener); -		adapter->pdiscov_listener = 0; -		g_free(adapter->pdiscov_requestor); -		adapter->pdiscov_requestor = NULL; -	} - -	if (adapter->found_devices) { -		g_slist_foreach(adapter->found_devices, -				(GFunc) g_free, NULL); -		g_slist_free(adapter->found_devices); -		adapter->found_devices = NULL; -	} - -	if (adapter->oor_devices) { -		g_slist_foreach(adapter->oor_devices, -				(GFunc) free, NULL); -		g_slist_free(adapter->oor_devices); -		adapter->oor_devices = NULL; -	} - -	if (adapter->auth_reqs) { -		g_slist_foreach(adapter->auth_reqs, -				(GFunc) g_free, NULL); -		g_slist_free(adapter->auth_reqs); -		adapter->auth_reqs = NULL; -	} - -	if (adapter->active_conn) { -		g_slist_foreach(adapter->active_conn, -				(GFunc) free, NULL); -		g_slist_free(adapter->active_conn); -		adapter->active_conn = NULL; -	} - -	if (adapter->devices) { -		g_slist_foreach(adapter->devices, do_unregister, -							connection); -		g_slist_free(adapter->devices); -	} - -	manager_remove_adapter(adapter); - -	g_free(adapter->path); -	g_free(adapter); - -unreg: -	if (!adapter_cleanup(connection, path)) { -		error("Failed to unregister adapter interface on %s object", -			path); -		return -1; -	} - -	return 0; -} -  /*****************************************************************   *   *  Section reserved to HCI commands confirmation handling and low @@ -458,268 +312,6 @@ unreg:   *   *****************************************************************/ -int hcid_dbus_register_device(uint16_t id) -{ -	char path[MAX_PATH_LENGTH]; -	struct adapter *adapter; - -	snprintf(path, sizeof(path), "/hci%d", id); - -	adapter = g_try_new0(struct adapter, 1); -	if (!adapter) { -		error("Failed to alloc memory to D-Bus path register data (%s)", -				path); -		return -1; -	} - -	adapter->dev_id = id; -	adapter->pdiscov_resolve_names = 1; - -	if (!adapter_init(connection, path, adapter)) { -		error("Adapter interface init failed on path %s", path); -		g_free(adapter); -		return -1; -	} - -	adapter->path = g_strdup(path); - -	__probe_servers(path); - -	manager_add_adapter(adapter); - -	return 0; -} - -int hcid_dbus_unregister_device(uint16_t id) -{ -	char path[MAX_PATH_LENGTH]; - -	snprintf(path, sizeof(path), "/hci%d", id); - -	return unregister_adapter_path(path); -} - -static void create_stored_device_from_profiles(char *key, char *value, -						void *user_data) -{ -	struct adapter *adapter = user_data; -	GSList *uuids = bt_string2list(value); -	struct btd_device *device; - -	device = device_create(connection, adapter, key); -	if (device) { -		device_set_temporary(device, FALSE); -		adapter->devices = g_slist_append(adapter->devices, device); -		device_probe_drivers(device, uuids); -		g_slist_free(uuids); -	} -} - -static void create_stored_device_from_linkkeys(char *key, char *value, -						void *user_data) -{ -	struct adapter *adapter = user_data; -	struct btd_device *device; - -	if (g_slist_find_custom(adapter->devices, -				key, (GCompareFunc) device_address_cmp)) -		return; - -	device = device_create(connection, adapter, key); -	if (device) { -		device_set_temporary(device, FALSE); -		adapter->devices = g_slist_append(adapter->devices, device); -	} -} - -static void register_devices(bdaddr_t *src, struct adapter *adapter) -{ -	char filename[PATH_MAX + 1]; -	char addr[18]; - -	ba2str(src, addr); - -	create_name(filename, PATH_MAX, STORAGEDIR, addr, "profiles"); -	textfile_foreach(filename, create_stored_device_from_profiles, adapter); - -	create_name(filename, PATH_MAX, STORAGEDIR, addr, "linkkeys"); -	textfile_foreach(filename, create_stored_device_from_linkkeys, adapter); -} - -int hcid_dbus_start_device(uint16_t id) -{ -	char path[MAX_PATH_LENGTH]; -	struct hci_dev_info di; -	struct adapter* adapter; -	struct hci_conn_list_req *cl = NULL; -	struct hci_conn_info *ci; -	const char *mode; -	int i, err, dd = -1, ret = -1; - -	snprintf(path, sizeof(path), "/hci%d", id); - -	if (hci_devinfo(id, &di) < 0) { -		error("Getting device info failed: hci%d", id); -		return -1; -	} - -	if (hci_test_bit(HCI_RAW, &di.flags)) -		return -1; - -	adapter = manager_find_adapter_by_path(path); -	if (!adapter) { -		error("Getting %s path data failed!", path); -		return -1; -	} - -	if (hci_test_bit(HCI_INQUIRY, &di.flags)) -		adapter->discov_active = 1; -	else -		adapter->discov_active = 0; - -	adapter->up = 1; -	adapter->discov_timeout = get_discoverable_timeout(id); -	adapter->discov_type = DISCOVER_TYPE_NONE; - -	dd = hci_open_dev(id); -	if (dd < 0) -		goto failed; - -	adapter->scan_enable = get_startup_scan(id); -	hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, -					1, &adapter->scan_enable); -	/* -	 * Get the adapter Bluetooth address -	 */ -	err = get_device_address(adapter->dev_id, adapter->address, -					sizeof(adapter->address)); -	if (err < 0) -		goto failed; - -	err = get_device_class(adapter->dev_id, adapter->class); -	if (err < 0) -		goto failed; - -	adapter->mode = get_startup_mode(id); -	if (adapter->mode == MODE_LIMITED) -		set_limited_discoverable(dd, adapter->class, TRUE); - -	/* -	 * retrieve the active connections: address the scenario where -	 * the are active connections before the daemon've started -	 */ - -	cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); - -	cl->dev_id = id; -	cl->conn_num = 10; -	ci = cl->conn_info; - -	if (ioctl(dd, HCIGETCONNLIST, cl) < 0) -		goto failed; - -	for (i = 0; i < cl->conn_num; i++, ci++) -		active_conn_append(&adapter->active_conn, -					&ci->bdaddr, ci->handle); - -	ret = 0; - -	mode = mode2str(adapter->mode); - -	dbus_connection_emit_property_changed(connection, adapter->path, -					ADAPTER_INTERFACE, "Mode", -					DBUS_TYPE_STRING, &mode); - -	if (manager_get_default_adapter() < 0) -		manager_set_default_adapter(id); - -	register_devices(&di.bdaddr, adapter); - -failed: -	if (dd >= 0) -		hci_close_dev(dd); - -	g_free(cl); - -	return ret; -} - -int hcid_dbus_stop_device(uint16_t id) -{ -	char path[MAX_PATH_LENGTH]; -	struct adapter *adapter; -	const char *mode = "off"; - -	snprintf(path, sizeof(path), "/hci%d", id); - -	adapter = manager_find_adapter_by_path(path); -	if (!adapter) { -		error("Getting %s path data failed!", path); -		return -1; -	} - -	/* cancel pending timeout */ -	if (adapter->timeout_id) { -		g_source_remove(adapter->timeout_id); -		adapter->timeout_id = 0; -	} - -	/* check pending requests */ -	reply_pending_requests(path, adapter); - -	if (adapter->discov_requestor) { -		g_dbus_remove_watch(connection, adapter->discov_listener); -		adapter->discov_listener = 0; -		g_free(adapter->discov_requestor); -		adapter->discov_requestor = NULL; -	} - -	if (adapter->pdiscov_requestor) { -		g_dbus_remove_watch(connection, adapter->pdiscov_listener); -		adapter->pdiscov_listener = 0; -		g_free(adapter->pdiscov_requestor); -		adapter->pdiscov_requestor = NULL; -	} - -	if (adapter->found_devices) { -		g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL); -		g_slist_free(adapter->found_devices); -		adapter->found_devices = NULL; -	} - -	if (adapter->oor_devices) { -		g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL); -		g_slist_free(adapter->oor_devices); -		adapter->oor_devices = NULL; -	} - -	if (adapter->auth_reqs) { -		g_slist_foreach(adapter->auth_reqs, (GFunc) g_free, NULL); -		g_slist_free(adapter->auth_reqs); -		adapter->auth_reqs = NULL; -	} - -	if (adapter->active_conn) { -		g_slist_foreach(adapter->active_conn, (GFunc) g_free, NULL); -		g_slist_free(adapter->active_conn); -		adapter->active_conn = NULL; -	} - -	dbus_connection_emit_property_changed(connection, adapter->path, -					ADAPTER_INTERFACE, "Mode", -					DBUS_TYPE_STRING, &mode); - -	adapter->up = 0; -	adapter->scan_enable = SCAN_DISABLED; -	adapter->mode = MODE_OFF; -	adapter->discov_active = 0; -	adapter->pdiscov_active = 0; -	adapter->pinq_idle = 0; -	adapter->discov_type = DISCOVER_TYPE_NONE; - -	return 0; -} -  static void pincode_cb(struct agent *agent, DBusError *err, const char *pincode,  			struct btd_device *device)  { diff --git a/hcid/dbus-hci.h b/hcid/dbus-hci.h index cb618816..f141d664 100644 --- a/hcid/dbus-hci.h +++ b/hcid/dbus-hci.h @@ -24,10 +24,6 @@  void hcid_dbus_set_experimental();  int hcid_dbus_use_experimental(); -int hcid_dbus_register_device(uint16_t id); -int hcid_dbus_unregister_device(uint16_t id); -int hcid_dbus_start_device(uint16_t id); -int hcid_dbus_stop_device(uint16_t id);  int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci);  void hcid_dbus_inquiry_start(bdaddr_t *local); diff --git a/hcid/main.c b/hcid/main.c index 8ecc5a39..2dca2065 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -56,6 +56,7 @@  #include "dbus-hci.h"  #include "device.h"  #include "agent.h" +#include "manager.h"  struct hcid_opts hcid;  struct device_opts default_device; @@ -617,7 +618,7 @@ static void device_devreg_setup(int dev_id)  		return;  	if (!hci_test_bit(HCI_RAW, &di.flags)) -		hcid_dbus_register_device(dev_id); +		manager_register_adapter(dev_id);  }  static void device_devup_setup(int dev_id) @@ -628,7 +629,7 @@ static void device_devup_setup(int dev_id)  	if (hcid.security)  		start_security_manager(dev_id);  	start_adapter(dev_id); -	hcid_dbus_start_device(dev_id); +	manager_start_adapter(dev_id);  }  static void init_all_devices(int ctl) @@ -685,7 +686,7 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si)  	case HCI_DEV_UNREG:  		info("HCI dev %d unregistered", sd->dev_id); -		hcid_dbus_unregister_device(sd->dev_id); +		manager_unregister_adapter(sd->dev_id);  		remove_adapter(sd->dev_id);  		break; @@ -696,7 +697,7 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si)  	case HCI_DEV_DOWN:  		info("HCI dev %d down", sd->dev_id); -		hcid_dbus_stop_device(sd->dev_id); +		manager_stop_adapter(sd->dev_id);  		if (hcid.security)  			stop_security_manager(sd->dev_id);  		stop_adapter(sd->dev_id); diff --git a/hcid/manager.c b/hcid/manager.c index de80c5e6..41ad9f04 100644 --- a/hcid/manager.c +++ b/hcid/manager.c @@ -57,6 +57,9 @@  #include "dbus-database.h"  #include "sdp-xml.h"  #include "oui.h" +#include "agent.h" +#include "device.h" +#include "glib-helper.h"  #include "manager.h" @@ -985,7 +988,7 @@ struct adapter *manager_find_adapter_by_id(int id)  	return match->data;  } -void manager_add_adapter(struct adapter *adapter) +static void manager_add_adapter(struct adapter *adapter)  {  	g_dbus_emit_signal(connection, "/",  			MANAGER_INTERFACE, "AdapterAdded", @@ -995,7 +998,7 @@ void manager_add_adapter(struct adapter *adapter)  	adapters = g_slist_append(adapters, adapter);  } -void manager_remove_adapter(struct adapter *adapter) +static void manager_remove_adapter(struct adapter *adapter)  {  	g_dbus_emit_signal(connection, "/",  			MANAGER_INTERFACE, "AdapterRemoved", @@ -1012,6 +1015,409 @@ void manager_remove_adapter(struct adapter *adapter)  	adapters = g_slist_remove(adapters, adapter);  } +int manager_register_adapter(int id) +{ +	char path[MAX_PATH_LENGTH]; +	struct adapter *adapter; + +	snprintf(path, sizeof(path), "/hci%d", id); + +	adapter = g_try_new0(struct adapter, 1); +	if (!adapter) { +		error("Failed to alloc memory to D-Bus path register data (%s)", +				path); +		return -1; +	} + +	adapter->dev_id = id; +	adapter->pdiscov_resolve_names = 1; + +	if (!adapter_init(connection, path, adapter)) { +		error("Adapter interface init failed on path %s", path); +		g_free(adapter); +		return -1; +	} + +	adapter->path = g_strdup(path); + +	__probe_servers(path); + +	manager_add_adapter(adapter); + +	return 0; +} + +static void reply_pending_requests(struct adapter *adapter) +{ +	DBusMessage *reply; + +	if (!adapter) +		return; + +	/* pending bonding */ +	if (adapter->bonding) { +		reply = new_authentication_return(adapter->bonding->msg, +					HCI_OE_USER_ENDED_CONNECTION); +		g_dbus_send_message(connection, reply); +		remove_pending_device(adapter); + +		g_dbus_remove_watch(adapter->bonding->conn, +					adapter->bonding->listener_id); + +		if (adapter->bonding->io_id) +			g_source_remove(adapter->bonding->io_id); +		g_io_channel_close(adapter->bonding->io); +		bonding_request_free(adapter->bonding); +		adapter->bonding = NULL; +	} + +	/* If there is a pending reply for discovery cancel */ +	if (adapter->discovery_cancel) { +		reply = dbus_message_new_method_return(adapter->discovery_cancel); +		dbus_connection_send(connection, reply, NULL); +		dbus_message_unref(reply); +		dbus_message_unref(adapter->discovery_cancel); +		adapter->discovery_cancel = NULL; +	} + +	if (adapter->discov_active) { +		/* Send discovery completed signal if there isn't name +		 * to resolve */ +		g_dbus_emit_signal(connection, adapter->path, +				ADAPTER_INTERFACE, "DiscoveryCompleted", +				DBUS_TYPE_INVALID); + +		/* Cancel inquiry initiated by D-Bus client */ +		if (adapter->discov_requestor) +			cancel_discovery(adapter); +	} + +	if (adapter->pdiscov_active) { +		/* Stop periodic inquiry initiated by D-Bus client */ +		if (adapter->pdiscov_requestor) +			cancel_periodic_discovery(adapter); +	} +} + +static void do_unregister(gpointer data, gpointer user_data) +{ +	DBusConnection *conn = user_data; +	struct btd_device *device = data; + +	device_remove(conn, device); +} + +int manager_unregister_adapter(int id) +{ +	struct adapter *adapter; + +	adapter = manager_find_adapter_by_id(id); +	if (!adapter) +		return -1; + +	info("Unregister path: %s", adapter->path); + +	__remove_servers(adapter->path); + +	/* check pending requests */ +	reply_pending_requests(adapter); + +	if (adapter->agent) { +		agent_destroy(adapter->agent, FALSE); +		adapter->agent = NULL; +	} + +	if (adapter->discov_requestor) { +		g_dbus_remove_watch(connection, adapter->discov_listener); +		adapter->discov_listener = 0; +		g_free(adapter->discov_requestor); +		adapter->discov_requestor = NULL; +	} + +	if (adapter->pdiscov_requestor) { +		g_dbus_remove_watch(connection, adapter->pdiscov_listener); +		adapter->pdiscov_listener = 0; +		g_free(adapter->pdiscov_requestor); +		adapter->pdiscov_requestor = NULL; +	} + +	if (adapter->found_devices) { +		g_slist_foreach(adapter->found_devices, +				(GFunc) g_free, NULL); +		g_slist_free(adapter->found_devices); +		adapter->found_devices = NULL; +	} + +	if (adapter->oor_devices) { +		g_slist_foreach(adapter->oor_devices, +				(GFunc) free, NULL); +		g_slist_free(adapter->oor_devices); +		adapter->oor_devices = NULL; +	} + +	if (adapter->auth_reqs) { +		g_slist_foreach(adapter->auth_reqs, +				(GFunc) g_free, NULL); +		g_slist_free(adapter->auth_reqs); +		adapter->auth_reqs = NULL; +	} + +	if (adapter->active_conn) { +		g_slist_foreach(adapter->active_conn, +				(GFunc) free, NULL); +		g_slist_free(adapter->active_conn); +		adapter->active_conn = NULL; +	} + +	if (adapter->devices) { +		g_slist_foreach(adapter->devices, do_unregister, +							connection); +		g_slist_free(adapter->devices); +	} + +	manager_remove_adapter(adapter); + +	if (!adapter_cleanup(connection, adapter->path)) { +		error("Failed to unregister adapter interface on %s object", +			adapter->path); +		return -1; +	} + +	g_free(adapter->path); +	g_free(adapter); + +	return 0; +} + +static int active_conn_append(GSList **list, bdaddr_t *bdaddr, +				uint16_t handle) +{ +	struct active_conn_info *dev; + +	dev = g_new0(struct active_conn_info, 1); + +	bacpy(&dev->bdaddr, bdaddr); +	dev->handle = handle; + +	*list = g_slist_append(*list, dev); +	return 0; +} + +static void create_stored_device_from_profiles(char *key, char *value, +						void *user_data) +{ +	struct adapter *adapter = user_data; +	GSList *uuids = bt_string2list(value); +	struct btd_device *device; + +	device = device_create(connection, adapter, key); +	if (device) { +		device_set_temporary(device, FALSE); +		adapter->devices = g_slist_append(adapter->devices, device); +		device_probe_drivers(device, uuids); +		g_slist_free(uuids); +	} +} + +static void create_stored_device_from_linkkeys(char *key, char *value, +						void *user_data) +{ +	struct adapter *adapter = user_data; +	struct btd_device *device; + +	if (g_slist_find_custom(adapter->devices, +				key, (GCompareFunc) device_address_cmp)) +		return; + +	device = device_create(connection, adapter, key); +	if (device) { +		device_set_temporary(device, FALSE); +		adapter->devices = g_slist_append(adapter->devices, device); +	} +} + +static void register_devices(bdaddr_t *src, struct adapter *adapter) +{ +	char filename[PATH_MAX + 1]; +	char addr[18]; + +	ba2str(src, addr); + +	create_name(filename, PATH_MAX, STORAGEDIR, addr, "profiles"); +	textfile_foreach(filename, create_stored_device_from_profiles, adapter); + +	create_name(filename, PATH_MAX, STORAGEDIR, addr, "linkkeys"); +	textfile_foreach(filename, create_stored_device_from_linkkeys, adapter); +} + +int manager_start_adapter(int id) +{ +	struct hci_dev_info di; +	struct adapter* adapter; +	struct hci_conn_list_req *cl = NULL; +	struct hci_conn_info *ci; +	const char *mode; +	int i, err, dd = -1, ret = -1; + +	if (hci_devinfo(id, &di) < 0) { +		error("Getting device info failed: hci%d", id); +		return -1; +	} + +	if (hci_test_bit(HCI_RAW, &di.flags)) +		return -1; + +	adapter = manager_find_adapter_by_id(id); +	if (!adapter) { +		error("Getting device data failed: hci%d", id); +		return -1; +	} + +	if (hci_test_bit(HCI_INQUIRY, &di.flags)) +		adapter->discov_active = 1; +	else +		adapter->discov_active = 0; + +	adapter->up = 1; +	adapter->discov_timeout = get_discoverable_timeout(id); +	adapter->discov_type = DISCOVER_TYPE_NONE; + +	dd = hci_open_dev(id); +	if (dd < 0) +		goto failed; + +	adapter->scan_enable = get_startup_scan(id); +	hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, +					1, &adapter->scan_enable); +	/* +	 * Get the adapter Bluetooth address +	 */ +	err = get_device_address(adapter->dev_id, adapter->address, +					sizeof(adapter->address)); +	if (err < 0) +		goto failed; + +	err = get_device_class(adapter->dev_id, adapter->class); +	if (err < 0) +		goto failed; + +	adapter->mode = get_startup_mode(id); +	if (adapter->mode == MODE_LIMITED) +		set_limited_discoverable(dd, adapter->class, TRUE); + +	/* +	 * retrieve the active connections: address the scenario where +	 * the are active connections before the daemon've started +	 */ + +	cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); + +	cl->dev_id = id; +	cl->conn_num = 10; +	ci = cl->conn_info; + +	if (ioctl(dd, HCIGETCONNLIST, cl) < 0) +		goto failed; + +	for (i = 0; i < cl->conn_num; i++, ci++) +		active_conn_append(&adapter->active_conn, +					&ci->bdaddr, ci->handle); + +	ret = 0; + +	mode = mode2str(adapter->mode); + +	dbus_connection_emit_property_changed(connection, adapter->path, +					ADAPTER_INTERFACE, "Mode", +					DBUS_TYPE_STRING, &mode); + +	if (manager_get_default_adapter() < 0) +		manager_set_default_adapter(id); + +	register_devices(&di.bdaddr, adapter); + +failed: +	if (dd >= 0) +		hci_close_dev(dd); + +	g_free(cl); + +	return ret; +} + +int manager_stop_adapter(int id) +{ +	struct adapter *adapter; +	const char *mode = "off"; + +	adapter = manager_find_adapter_by_id(id); +	if (!adapter) { +		error("Getting device data failed: hci%d", id); +		return -1; +	} + +	/* cancel pending timeout */ +	if (adapter->timeout_id) { +		g_source_remove(adapter->timeout_id); +		adapter->timeout_id = 0; +	} + +	/* check pending requests */ +	reply_pending_requests(adapter); + +	if (adapter->discov_requestor) { +		g_dbus_remove_watch(connection, adapter->discov_listener); +		adapter->discov_listener = 0; +		g_free(adapter->discov_requestor); +		adapter->discov_requestor = NULL; +	} + +	if (adapter->pdiscov_requestor) { +		g_dbus_remove_watch(connection, adapter->pdiscov_listener); +		adapter->pdiscov_listener = 0; +		g_free(adapter->pdiscov_requestor); +		adapter->pdiscov_requestor = NULL; +	} + +	if (adapter->found_devices) { +		g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL); +		g_slist_free(adapter->found_devices); +		adapter->found_devices = NULL; +	} + +	if (adapter->oor_devices) { +		g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL); +		g_slist_free(adapter->oor_devices); +		adapter->oor_devices = NULL; +	} + +	if (adapter->auth_reqs) { +		g_slist_foreach(adapter->auth_reqs, (GFunc) g_free, NULL); +		g_slist_free(adapter->auth_reqs); +		adapter->auth_reqs = NULL; +	} + +	if (adapter->active_conn) { +		g_slist_foreach(adapter->active_conn, (GFunc) g_free, NULL); +		g_slist_free(adapter->active_conn); +		adapter->active_conn = NULL; +	} + +	dbus_connection_emit_property_changed(connection, adapter->path, +					ADAPTER_INTERFACE, "Mode", +					DBUS_TYPE_STRING, &mode); + +	adapter->up = 0; +	adapter->scan_enable = SCAN_DISABLED; +	adapter->mode = MODE_OFF; +	adapter->discov_active = 0; +	adapter->pdiscov_active = 0; +	adapter->pinq_idle = 0; +	adapter->discov_type = DISCOVER_TYPE_NONE; + +	return 0; +} +  int manager_get_default_adapter()  {  	return default_adapter_id; diff --git a/hcid/manager.h b/hcid/manager.h index 2065d5ac..6942e85b 100644 --- a/hcid/manager.h +++ b/hcid/manager.h @@ -30,7 +30,9 @@ void manager_cleanup(DBusConnection *conn, const char *path);  struct adapter *manager_find_adapter(const bdaddr_t *sba);  struct adapter *manager_find_adapter_by_path(const char *path);  struct adapter *manager_find_adapter_by_id(int id); -void manager_add_adapter(struct adapter *adapter); -void manager_remove_adapter(struct adapter *adapter); +int manager_register_adapter(int id); +int manager_unregister_adapter(int id); +int manager_start_adapter(int id); +int manager_stop_adapter(int id);  int manager_get_default_adapter();  void manager_set_default_adapter(int id);  | 
