diff options
| -rw-r--r-- | src/adapter.c | 16 | ||||
| -rw-r--r-- | src/adapter.h | 3 | ||||
| -rw-r--r-- | src/dbus-common.c | 3 | ||||
| -rw-r--r-- | src/main.c | 18 | ||||
| -rw-r--r-- | src/manager.c | 90 | ||||
| -rw-r--r-- | src/manager.h | 2 | 
6 files changed, 77 insertions, 55 deletions
| diff --git a/src/adapter.c b/src/adapter.c index 5eaf729a..dc6f8e9c 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -120,6 +120,7 @@ struct btd_adapter {  	gboolean pairable;		/* pairable state */  	gboolean initialized; +	gboolean already_up;		/* adapter was already up on init */  };  static void adapter_set_pairable_timeout(struct btd_adapter *adapter, @@ -2912,7 +2913,8 @@ static void adapter_free(gpointer user_data)  	return;  } -struct btd_adapter *adapter_create(DBusConnection *conn, int id) +struct btd_adapter *adapter_create(DBusConnection *conn, int id, +				gboolean devup)  {  	char path[MAX_PATH_LENGTH];  	struct btd_adapter *adapter; @@ -2933,6 +2935,7 @@ struct btd_adapter *adapter_create(DBusConnection *conn, int id)  	adapter->dev_id = id;  	adapter->state |= RESOLVE_NAME;  	adapter->path = g_strdup(path); +	adapter->already_up = devup;  	if (!g_dbus_register_interface(conn, path, ADAPTER_INTERFACE,  			adapter_methods, adapter_signals, NULL, @@ -2958,6 +2961,17 @@ void adapter_remove(struct btd_adapter *adapter)  		device_remove(connection, l->data);  	g_slist_free(adapter->devices); +	/* Return adapter to down state if it was not up on init */ +	if (adapter->up && !adapter->already_up) { +		int dd = hci_open_dev(adapter->dev_id); +		if (dd < 0) +			goto done; + +		ioctl(dd, HCIDEVDOWN, adapter->dev_id); +		hci_close_dev(dd); +	} + +done:  	g_dbus_unregister_interface(connection, path, ADAPTER_INTERFACE);  	g_free(path); diff --git a/src/adapter.h b/src/adapter.h index 118ec4f9..d6f8b6c7 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -129,7 +129,8 @@ void adapter_remove_auth_request(struct btd_adapter *adapter, bdaddr_t *dba);  struct pending_auth_info *adapter_new_auth_request(struct btd_adapter *adapter,  							bdaddr_t *dba,  							auth_type_t type); -struct btd_adapter *adapter_create(DBusConnection *conn, int id); +struct btd_adapter *adapter_create(DBusConnection *conn, int id, +				gboolean devup);  void adapter_remove(struct btd_adapter *adapter);  uint16_t adapter_get_dev_id(struct btd_adapter *adapter);  const gchar *adapter_get_path(struct btd_adapter *adapter); diff --git a/src/dbus-common.c b/src/dbus-common.c index de42769e..e4587256 100644 --- a/src/dbus-common.c +++ b/src/dbus-common.c @@ -143,8 +143,9 @@ static gboolean system_bus_reconnect(void *data)  	/* reset the default device */  	manager_set_default_adapter(-1); +	/* FIXME: it shouldn't be needed to register adapters again */  	for (i = 0; i < dl->dev_num; i++, dr++) -		manager_register_adapter(dr->dev_id); +		manager_register_adapter(dr->dev_id, TRUE);  	ret_val = FALSE; @@ -474,7 +474,7 @@ fail:  	exit(1);  } -static void device_devreg_setup(int dev_id) +static void device_devreg_setup(int dev_id, gboolean devup)  {  	struct hci_dev_info di; @@ -484,7 +484,7 @@ static void device_devreg_setup(int dev_id)  		return;  	if (!hci_test_bit(HCI_RAW, &di.flags)) -		manager_register_adapter(dev_id); +		manager_register_adapter(dev_id, devup);  }  static void device_devup_setup(int dev_id) @@ -521,9 +521,13 @@ static void init_all_devices(int ctl)  	}  	for (i = 0; i < dl->dev_num; i++, dr++) { +		gboolean devup; + +		devup = hci_test_bit(HCI_UP, &dr->dev_opt); +  		info("HCI dev %d registered", dr->dev_id); -		device_devreg_setup(dr->dev_id); -		if (hci_test_bit(HCI_UP, &dr->dev_opt)) { +		device_devreg_setup(dr->dev_id, devup); +		if (devup) {  			info("HCI dev %d already up", dr->dev_id);  			device_devup_setup(dr->dev_id);  		} @@ -553,7 +557,7 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si)  	switch (sd->event) {  	case HCI_DEV_REG:  		info("HCI dev %d registered", sd->dev_id); -		device_devreg_setup(sd->dev_id); +		device_devreg_setup(sd->dev_id, FALSE);  		break;  	case HCI_DEV_UNREG: @@ -767,14 +771,14 @@ int main(int argc, char *argv[])  	hcid_dbus_unregister(); +	hcid_dbus_exit(); +  	plugin_cleanup();  	stop_sdp_server();  	agent_exit(); -	hcid_dbus_exit(); -  	g_main_loop_unref(event_loop);  	if (config) diff --git a/src/manager.c b/src/manager.c index f9263ae8..b0ba429c 100644 --- a/src/manager.c +++ b/src/manager.c @@ -326,8 +326,52 @@ dbus_bool_t manager_init(DBusConnection *conn, const char *path)  			NULL, NULL, NULL);  } +static void manager_update_adapters(void) +{ +	GSList *list; +	char **array; +	int i; + +	array = g_new0(char *, g_slist_length(adapters) + 1); +	for (i = 0, list = adapters; list; list = list->next, i++) { +		struct btd_adapter *adapter = list->data; +		array[i] = (char *) adapter_get_path(adapter); +	} + +	emit_array_property_changed(connection, "/", +					MANAGER_INTERFACE, "Adapters", +					DBUS_TYPE_OBJECT_PATH, &array); + +	g_free(array); +} + +static void manager_remove_adapter(struct btd_adapter *adapter) +{ +	uint16_t dev_id = adapter_get_dev_id(adapter); +	const gchar *path = adapter_get_path(adapter); + +	manager_update_adapters(); + +	g_dbus_emit_signal(connection, "/", +			MANAGER_INTERFACE, "AdapterRemoved", +			DBUS_TYPE_OBJECT_PATH, &path, +			DBUS_TYPE_INVALID); + +	if (default_adapter_id == dev_id || default_adapter_id < 0) { +		int new_default = hci_get_route(NULL); + +		manager_set_default_adapter(new_default); +	} + +	adapters = g_slist_remove(adapters, adapter); +	adapter_remove(adapter); +} +  void manager_cleanup(DBusConnection *conn, const char *path)  { +	g_slist_foreach(adapters, (GFunc) manager_remove_adapter, NULL); +	g_slist_free(adapters); +  	g_dbus_unregister_interface(conn, "/", MANAGER_INTERFACE);  } @@ -403,25 +447,6 @@ GSList *manager_get_adapters(void)  	return adapters;  } -static void manager_update_adapters(void) -{ -	GSList *list; -	char **array; -	int i; - -	array = g_new0(char *, g_slist_length(adapters) + 1); -	for (i = 0, list = adapters; list; list = list->next, i++) { -		struct btd_adapter *adapter = list->data; -		array[i] = (char *) adapter_get_path(adapter); -	} - -	emit_array_property_changed(connection, "/", -					MANAGER_INTERFACE, "Adapters", -					DBUS_TYPE_OBJECT_PATH, &array); - -	g_free(array); -} -  static void manager_add_adapter(struct btd_adapter *adapter)  {  	const gchar *path = adapter_get_path(adapter); @@ -442,30 +467,9 @@ static void manager_add_adapter(struct btd_adapter *adapter)  	manager_update_adapters();  } -static void manager_remove_adapter(struct btd_adapter *adapter) -{ -	uint16_t dev_id = adapter_get_dev_id(adapter); -	const gchar *path = adapter_get_path(adapter); - -	manager_update_adapters(); - -	g_dbus_emit_signal(connection, "/", -			MANAGER_INTERFACE, "AdapterRemoved", -			DBUS_TYPE_OBJECT_PATH, &path, -			DBUS_TYPE_INVALID); - -	if (default_adapter_id == dev_id || default_adapter_id < 0) { -		int new_default = hci_get_route(NULL); - -		manager_set_default_adapter(new_default); -	} - -	adapters = g_slist_remove(adapters, adapter); -} - -int manager_register_adapter(int id) +int manager_register_adapter(int id, gboolean devup)  { -	struct btd_adapter *adapter = adapter_create(connection, id); +	struct btd_adapter *adapter = adapter_create(connection, id, devup);  	if (!adapter)  		return -1; @@ -490,8 +494,6 @@ int manager_unregister_adapter(int id)  	manager_remove_adapter(adapter); -	adapter_remove(adapter); -  	return 0;  } diff --git a/src/manager.h b/src/manager.h index d0e30a89..eb087b95 100644 --- a/src/manager.h +++ b/src/manager.h @@ -32,7 +32,7 @@ struct btd_adapter *manager_find_adapter(const bdaddr_t *sba);  struct btd_adapter *manager_find_adapter_by_path(const char *path);  struct btd_adapter *manager_find_adapter_by_id(int id);  GSList *manager_get_adapters(void); -int manager_register_adapter(int id); +int manager_register_adapter(int id, gboolean devup);  int manager_unregister_adapter(int id);  int manager_start_adapter(int id);  int manager_stop_adapter(int id); | 
