diff options
| author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-04-11 17:32:52 +0000 | 
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-04-11 17:32:52 +0000 | 
| commit | 23f49566e8bb0eb0b5b0e2a9b1841c28a92080fa (patch) | |
| tree | 438ecc3ac2540849f531112e48866d06c41d4460 | |
| parent | bdfe1e3884ad855eeec021d5dca8c2c246078ef3 (diff) | |
Emit signals properly when removing a device.
| -rw-r--r-- | hcid/adapter.c | 172 | ||||
| -rw-r--r-- | hcid/adapter.h | 5 | ||||
| -rw-r--r-- | hcid/dbus-hci.c | 45 | 
3 files changed, 114 insertions, 108 deletions
| diff --git a/hcid/adapter.c b/hcid/adapter.c index 0934ad02..4097c18e 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -2310,19 +2310,106 @@ struct device *adapter_create_device(DBusConnection *conn,  	return device;  } +static DBusHandlerResult remove_bonding(DBusConnection *conn, DBusMessage *msg, +					const char *address, void *data) +{ +	struct adapter *adapter = data; +	struct device *device; +	DBusMessage *reply; +	char path[MAX_PATH_LENGTH], filename[PATH_MAX + 1]; +	char *str; +	bdaddr_t src, dst; +	GSList *l; +	int dev, err; + +	str2ba(adapter->address, &src); +	str2ba(address, &dst); + +	dev = hci_open_dev(adapter->dev_id); +	if (dev < 0 && msg) +		return error_no_such_adapter(conn, msg); + +	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, +			"linkkeys"); + +	/* textfile_del doesn't return an error when the key is not found */ +	str = textfile_caseget(filename, address); +	if (!str && msg) +		return error_bonding_does_not_exist(conn, msg); + +	/* Delete the link key from storage */ +	if (textfile_casedel(filename, address) < 0 && msg) { +		err = errno; +		return error_failed_errno(conn, msg, err); +	} + +	/* Delete the link key from the Bluetooth chip */ +	hci_delete_stored_link_key(dev, &dst, 0, 1000); + +	/* find the connection */ +	l = g_slist_find_custom(adapter->active_conn, &dst, +				active_conn_find_by_bdaddr); +	if (l) { +		struct active_conn_info *con = l->data; +		/* Send the HCI disconnect command */ +		if ((hci_disconnect(dev, htobs(con->handle), +					HCI_OE_USER_ENDED_CONNECTION, 500) < 0) +					&& msg){ +			int err = errno; +			error("Disconnect failed"); +			hci_close_dev(dev); +			return error_failed_errno(conn, msg, err); +		} +	} + +	hci_close_dev(dev); + +	if (str) { +		snprintf(path, MAX_PATH_LENGTH, BASE_PATH "/hci%d", +			adapter->dev_id); +		dbus_connection_emit_signal(conn, path, +					ADAPTER_INTERFACE, "BondingRemoved", +					DBUS_TYPE_STRING, &address, +					DBUS_TYPE_INVALID); +	} + +	device = adapter_find_device(adapter, address); +	if (!device) +		goto proceed; + +	if (str) { +		gboolean paired = FALSE; +		dbus_connection_emit_property_changed(conn, device->path, +					DEVICE_INTERFACE, "Paired", +					DBUS_TYPE_BOOLEAN, &paired); +	} + +proceed: +	if(!msg) +		goto done; + +	reply = dbus_message_new_method_return(msg); + +	return send_message_and_unref(conn, reply); + +done: +	return DBUS_HANDLER_RESULT_HANDLED; +} + +  void adapter_remove_device(DBusConnection *conn, struct adapter *adapter,  				struct device *device)  { -	char path[MAX_PATH_LENGTH];  	bdaddr_t src; +	char path[MAX_PATH_LENGTH];  	str2ba(adapter->address, &src);  	delete_entry(&src, "profiles", device->address); -	delete_entry(&src, "linkkeys", device->address); -	snprintf(path, MAX_PATH_LENGTH, "/hci%d", adapter->dev_id); +	remove_bonding(conn, NULL, device->address, adapter);  	if (!device->temporary) { +		snprintf(path, MAX_PATH_LENGTH, "/hci%d", adapter->dev_id);  		dbus_connection_emit_signal(conn, path,  				ADAPTER_INTERFACE,  				"DeviceRemoved", @@ -2630,91 +2717,20 @@ static DBusHandlerResult adapter_remove_bonding(DBusConnection *conn,  						DBusMessage *msg, void *data)  {  	struct adapter *adapter = data; -	GSList *l; -	DBusMessage *reply; -	char filename[PATH_MAX + 1]; -	char *addr_ptr, *str, *old_path, *new_path; -	bdaddr_t bdaddr; -	int dd; +	char *address;  	if (!adapter->up)  		return error_not_ready(conn, msg);  	if (!dbus_message_get_args(msg, NULL, -				DBUS_TYPE_STRING, &addr_ptr, +				DBUS_TYPE_STRING, &address,  				DBUS_TYPE_INVALID))  		return error_invalid_arguments(conn, msg, NULL); -	if (check_address(addr_ptr) < 0) +	if (check_address(address) < 0)  		return error_invalid_arguments(conn, msg, NULL); -	dd = hci_open_dev(adapter->dev_id); -	if (dd < 0) -		return error_no_such_adapter(conn, msg); - -	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, -			"linkkeys"); - -	/* textfile_del doesn't return an error when the key is not found */ -	str = textfile_caseget(filename, addr_ptr); -	if (!str) { -		hci_close_dev(dd); -		return error_bonding_does_not_exist(conn, msg); -	} - -	free(str); - -	/* Delete the link key from storage */ -	if (textfile_casedel(filename, addr_ptr) < 0) { -		int err = errno; -		hci_close_dev(dd); -		return error_failed_errno(conn, msg, err); -	} - -	str2ba(addr_ptr, &bdaddr); - -	/* Delete the link key from the Bluetooth chip */ -	hci_delete_stored_link_key(dd, &bdaddr, 0, 1000); - -	/* find the connection */ -	l = g_slist_find_custom(adapter->active_conn, &bdaddr, -			active_conn_find_by_bdaddr); -	if (l) { -		struct active_conn_info *con = l->data; -		/* Send the HCI disconnect command */ -		if (hci_disconnect(dd, htobs(con->handle), -					HCI_OE_USER_ENDED_CONNECTION, 500) < 0) { -			int err = errno; -			error("Disconnect failed"); -			hci_close_dev(dd); -			return error_failed_errno(conn, msg, err); -		} -	} - -	resolve_paths(msg, &old_path, &new_path); - -	dbus_connection_emit_signal(conn, dbus_message_get_path(msg), -					ADAPTER_INTERFACE, "BondingRemoved", -					DBUS_TYPE_STRING, &addr_ptr, -					DBUS_TYPE_INVALID); - -	if (new_path) { -		struct device *device; -		gboolean paired = FALSE; - -		device = adapter_find_device(adapter, addr_ptr); -		if (device) { -			dbus_connection_emit_property_changed(conn, -					device->path, DEVICE_INTERFACE, -					"Paired", DBUS_TYPE_BOOLEAN, &paired); -		} -	} - -	reply = dbus_message_new_method_return(msg); - -	hci_close_dev(dd); - -	return send_message_and_unref(conn, reply); +	return remove_bonding(conn, msg, address, data);  }  static DBusHandlerResult adapter_has_bonding(DBusConnection *conn, diff --git a/hcid/adapter.h b/hcid/adapter.h index 767cbde7..d715d58f 100644 --- a/hcid/adapter.h +++ b/hcid/adapter.h @@ -118,11 +118,10 @@ struct device *adapter_get_device(DBusConnection *conn,  struct device *adapter_find_device(struct adapter *adapter, const char *dest); -struct device *adapter_create_device(DBusConnection *conn, -				struct adapter *adapter, const char *address); -  void adapter_remove_device(DBusConnection *conn, struct adapter *adapter,  				struct device *device); +struct device *adapter_create_device(DBusConnection *conn, +				struct adapter *adapter, const char *address);  const char *major_class_str(uint32_t class); diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index 9b48a11f..f91c8901 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -1056,6 +1056,7 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,  	struct device *device;  	struct bonding_request_info *bonding;  	void *d; +	gboolean paired = TRUE;  	ba2str(local, local_addr);  	ba2str(peer, peer_addr); @@ -1090,17 +1091,12 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,  	send_adapter_signal(connection, adapter->dev_id, "BondingCreated",  				DBUS_TYPE_STRING, &paddr, DBUS_TYPE_INVALID); -	if (hcid_dbus_use_experimental()) { -		struct device *device; -		gboolean paired = TRUE; - -		device = adapter_get_device(connection, adapter, paddr); -		if (device) { -			device->temporary = FALSE; -			dbus_connection_emit_property_changed(connection, -				device->path, DEVICE_INTERFACE, -				"Paired", DBUS_TYPE_BOOLEAN, &paired); -		} +	device = adapter_get_device(connection, adapter, paddr); +	if (device) { +		device->temporary = FALSE; +		dbus_connection_emit_property_changed(connection, device->path, +					DEVICE_INTERFACE, "Paired", +					DBUS_TYPE_BOOLEAN, &paired);  	}  proceed: @@ -1958,9 +1954,11 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,  	char path[MAX_PATH_LENGTH], local_addr[18], peer_addr[18];  	const char *paddr = peer_addr;  	struct adapter *adapter; +	struct device *device;  	struct active_conn_info *dev;  	GSList *l;  	int id; +	gboolean connected = FALSE;  	if (status) {  		error("Disconnection failed: 0x%02x", status); @@ -2049,25 +2047,18 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,  					DBUS_TYPE_STRING, &paddr,  					DBUS_TYPE_INVALID); -	if (hcid_dbus_use_experimental()) { -		struct device *device; -		gboolean connected = FALSE; - -		device = adapter_find_device(adapter, paddr); -		if (device) { -			dbus_connection_emit_property_changed(connection, -						device->path, DEVICE_INTERFACE, -						"Connected", DBUS_TYPE_BOOLEAN, -						&connected); -			if (device->temporary) -				adapter_remove_device(connection, adapter, -							device); -		} -	} -  	adapter->active_conn = g_slist_remove(adapter->active_conn, dev);  	g_free(dev); +	device = adapter_find_device(adapter, paddr); +	if (device) { +		dbus_connection_emit_property_changed(connection, +					device->path, DEVICE_INTERFACE, +					"Connected", DBUS_TYPE_BOOLEAN, +					&connected); +		if (device->temporary) +			adapter_remove_device(connection, adapter, device); +	}  }  int set_limited_discoverable(int dd, const uint8_t *cls, gboolean limited) | 
