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 /hcid/adapter.c | |
| parent | bdfe1e3884ad855eeec021d5dca8c2c246078ef3 (diff) | |
Emit signals properly when removing a device.
Diffstat (limited to 'hcid/adapter.c')
| -rw-r--r-- | hcid/adapter.c | 172 | 
1 files changed, 94 insertions, 78 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, | 
