New RemoteDeviceDisconnectionRequested signal implementation
PATCH 1/1 New RemoteDeviceDisconnectionRequested signal implementation
Hi Marcel (and others),
As agreed last week, I've implemented a new D-Bus signal in hcid that allows upper-level applications to disconnect gracefuly before the ACL connection is terminated as a result of a call to RemoteDeviceDisconnect.
So, this is how it works: when the RemoteDeviceDisconnect is called, we send the new signal RemoteDeviceDisconnectionRequested(string bdaddr) and wait for 2 seconds before sending the disconnection command to the controller. This enables the service implementations to disconnect in a nicer way, as specified in the profile specs (eg. in SIM Access Profile, a SIM_DISCONNECT_REQ can be sent by the client).
The change is not very big and should be backwards compatible, except for the fact that disconnections will take 2 seconds longer than before.
I also updated the documentation and the apitest script.
Please let me know what you think.
Cheers,
Luca.
Index: hcid/dbus-adapter.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-adapter.c,v retrieving revision 1.141
dbus-adapter.c +73 -21
@@ -1680,18 +1680,61 @@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 @@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); - - reply =dbus_message_new_method_return (msg); -if (!reply) -return DBUS_HANDLER_RESULT_NEED_MEMORY ; + 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; + +/* ...and send a signal */ + signal =dev_signal_factory (adapter->dev_id,"RemoteDeviceDisconnectionRequested" , +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)
Index: hcid/dbus-adapter.h
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-adapter.h,v retrieving revision 1.1
dbus-adapter.h +12 -0
@@ -34,6 +34,8 @@#define BONDING_TIMEOUT 45000/* 45 sec */ +#define DC_PENDING_TIMEOUT 2000/* 2 secs */ +/* Discover types */ #define DISCOVER_TYPE_NONE 0x00#define STD_INQUIRY 0x01
@@ -77,6 +79,13 @@uint16_t handle; }; +struct pending_dc_info { +DBusConnection *conn; +DBusMessage *msg; +uint16_t conn_handle; +guint timeout_id; +}; +struct adapter {uint16_t dev_id;int up;
@@ -100,6 +109,7 @@struct slist *active_conn;struct bonding_request_info *bonding;struct slist *pin_reqs; +struct pending_dc_info *pending_dc; };DBusHandlerResult handle_adapter_method (DBusConnection *conn,DBusMessage *msg,void *data);
@@ -112,4 +122,6 @@int pending_remote_name_cancel (struct adapter *adapter); +void dc_pending_timeout_cleanup (struct adapter *adapter); +#endif /* __ADAPTER_H */
Index: hcid/dbus-api.txt
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-api.txt,v retrieving revision 1.91
dbus-api.txt +30 -17
77 lines not on this page · raw message
Index: hcid/dbus-error.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-error.c,v retrieving revision 1.33
dbus-error.c +5 -0
@@ -278,6 +278,11 @@return error_does_not_exist (conn, msg,"Trusted device does not exist" ); } +DBusHandlerResult error_disconnect_in_progress (DBusConnection *conn,DBusMessage *msg) +{ +return error_in_progress (conn, msg,"Disconnection in progress" ); +} +static const char *strsdperror (int err) {
Index: hcid/dbus-error.h
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-error.h,v retrieving revision 1.3
dbus-error.h +1 -0
@@ -65,5 +65,6 @@DBusHandlerResult error_audit_already_exists (DBusConnection *conn,DBusMessage *msg);DBusHandlerResult error_trusted_device_already_exists (DBusConnection *conn,DBusMessage *msg);DBusHandlerResult error_trusted_device_does_not_exists (DBusConnection *conn,DBusMessage *msg); +DBusHandlerResult error_disconnect_in_progress (DBusConnection *conn,DBusMessage *msg);#endif /* __BLUEZ_DBUS_ERROR_H */
Index: hcid/dbus-hci.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-hci.c,v
retrieving revision 1.5
dbus-hci.c +22 -0
@@ -473,6 +473,14 @@ adapter->active_conn =NULL ; } +/* Check if there is a pending RemoteDeviceDisconnect request */ +if (adapter->pending_dc) { +error_no_such_adapter (adapter->pending_dc->conn, + adapter->pending_dc->msg); +g_timeout_remove (adapter->pending_dc->timeout_id); +dc_pending_timeout_cleanup (adapter); + } +free (adapter); unreg:
@@ -1742,6 +1750,20 @@ adapter->bonding =NULL ; } +/* Check if there is a pending RemoteDeviceDisconnect request */ +if (adapter->pending_dc) { +DBusMessage *reply; + + reply =dbus_message_new_method_return (adapter->pending_dc->msg); +if (!reply) +error ("Failed to allocate disconnect reply" ); +else +send_message_and_unref (adapter->pending_dc->conn, reply); + +g_timeout_remove (adapter->pending_dc->timeout_id); +dc_pending_timeout_cleanup (adapter); + } +/* Send the remote device disconnected signal */ message = dev_signal_factory(adapter->dev_id, "RemoteDeviceDisconnected",
Index: test/apitest
===================================================================
RCS file: /cvsroot/bluez/utils/test/apitest,v
retrieving revision 1.3
apitest +1 -0
@@ -69,6 +69,7 @@ "RemoteAliasChanged" "RemoteAliasCleared", "RemoteDeviceConnected", + "RemoteDeviceDisconnectionRequested", "RemoteDeviceDisconnected", "BondingCreated", "BondingRemoved" ]
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
Hi Luca,
Quoted 11 lines · Luciano Coelho
As agreed last week, I've implemented a new D-Bus signal in hcid that allows upper-level applications to disconnect gracefuly before the ACL connection is terminated as a result of a call to RemoteDeviceDisconnect.
So, this is how it works: when the RemoteDeviceDisconnect is called, we send the new signal RemoteDeviceDisconnectionRequested(string bdaddr) and wait for 2 seconds before sending the disconnection command to the controller. This enables the service implementations to disconnect in a nicer way, as specified in the profile specs (eg. in SIM Access Profile, a
SIM_DISCONNECT_REQcan be sent by the client).
Quoted 6 lines
The change is not very big and should be backwards compatible, except for the fact that disconnections will take 2 seconds longer than before.
I also updated the documentation and the apitest script.
Please let me know what you think.
Looks good to me.
Johan
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel