diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-01-03 12:14:01 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-01-03 12:14:01 +0000 |
commit | 6033ee0c9966238f3732e945841d85ddb5162cc2 (patch) | |
tree | 76d609cb63074d1038187bb29833105493a4517e /hcid/dbus-adapter.c | |
parent | d21f13975ab07dcf9ec8b51fd764d1c5a9b76f92 (diff) |
Add disconnection delay and RemoteDeviceDisconnectRequested signal for the DisconnectRemoteDevice method
Diffstat (limited to 'hcid/dbus-adapter.c')
-rw-r--r-- | hcid/dbus-adapter.c | 92 |
1 files changed, 72 insertions, 20 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c index a36ab4fa..a4ca8712 100644 --- a/hcid/dbus-adapter.c +++ b/hcid/dbus-adapter.c @@ -1680,18 +1680,61 @@ static DBusHandlerResult adapter_last_used(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static DBusHandlerResult adapter_dc_remote_device(DBusConnection *conn, - DBusMessage *msg, void *data) + +gboolean dc_pending_timeout_handler(void *data) { + int dd; + struct adapter *adapter = data; + struct pending_dc_info *pending_dc = adapter->pending_dc; DBusMessage *reply; + dd = hci_open_dev(adapter->dev_id); + + if (dd < 0) { + error_no_such_adapter(pending_dc->conn, + pending_dc->msg); + dc_pending_timeout_cleanup(adapter); + return FALSE; + } + + /* Send the HCI disconnect command */ + if (hci_disconnect(dd, pending_dc->conn_handle, + HCI_OE_USER_ENDED_CONNECTION, + 500) < 0) { + int err = errno; + error("Disconnect failed"); + error_failed(pending_dc->conn, pending_dc->msg, err); + } else { + reply = dbus_message_new_method_return(pending_dc->msg); + if (!reply) + error("Failed to allocate disconnect reply"); + else + send_message_and_unref(pending_dc->conn, reply); + } + + hci_close_dev(dd); + dc_pending_timeout_cleanup(adapter); + + return FALSE; +} + +void dc_pending_timeout_cleanup(struct adapter *adapter) +{ + dbus_connection_unref(adapter->pending_dc->conn); + dbus_message_unref(adapter->pending_dc->msg); + free(adapter->pending_dc); + adapter->pending_dc = NULL; +} + +static DBusHandlerResult adapter_dc_remote_device(DBusConnection *conn, + DBusMessage *msg, void *data) +{ struct adapter *adapter = data; struct slist *l = adapter->active_conn; const char *peer_addr; bdaddr_t peer_bdaddr; - int dd; - struct active_conn_info *dev; + DBusMessage *signal; if (!adapter->up) return error_not_ready(conn, msg); @@ -1710,29 +1753,38 @@ static DBusHandlerResult adapter_dc_remote_device(DBusConnection *conn, if (!l) return error_not_connected(conn, msg); - dev = l->data; + if(adapter->pending_dc) + return error_disconnect_in_progress(conn, msg); - dd = hci_open_dev(adapter->dev_id); - if (dd < 0) - return error_no_such_adapter(conn, msg); + adapter->pending_dc = malloc(sizeof(*adapter->pending_dc)); + if(!adapter->pending_dc) + return DBUS_HANDLER_RESULT_NEED_MEMORY; - /* Send the HCI disconnect command */ - if (hci_disconnect(dd, dev->handle, HCI_OE_USER_ENDED_CONNECTION, - 500) < 0) { - int err = errno; - error("Disconnect failed"); - hci_close_dev(dd); - return error_failed(conn, msg, err); + /* Start waiting... */ + adapter->pending_dc->timeout_id = + g_timeout_add(DC_PENDING_TIMEOUT, + dc_pending_timeout_handler, + adapter); + + if(!adapter->pending_dc->timeout_id) { + free(adapter->pending_dc); + adapter->pending_dc = NULL; + return DBUS_HANDLER_RESULT_NEED_MEMORY; } - hci_close_dev(dd); + adapter->pending_dc->conn = dbus_connection_ref(conn); + adapter->pending_dc->msg = dbus_message_ref(msg); + adapter->pending_dc->conn_handle = + ((struct active_conn_info *) l->data)->handle; - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + /* ...and send a signal */ + signal = dev_signal_factory(adapter->dev_id, "RemoteDeviceDisconnectRequested", + DBUS_TYPE_STRING, &peer_addr, + DBUS_TYPE_INVALID); + send_message_and_unref(conn, signal); - return send_message_and_unref(conn, reply); + return DBUS_HANDLER_RESULT_HANDLED; } static void reply_authentication_failure(struct bonding_request_info *bonding) |