public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [Bluez-devel] [PATCH] New RemoteDeviceDisconnectionRequested signal implementation
@ 2006-12-28 13:20 Luciano Coelho
  2006-12-28 23:10 ` Johan Hedberg
  0 siblings, 1 reply; 2+ messages in thread
From: Luciano Coelho @ 2006-12-28 13:20 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 910 bytes --]

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.

[-- Attachment #2: hcid_disconnect_signal.patch --]
[-- Type: text/x-patch, Size: 10696 bytes --]

Index: hcid/dbus-adapter.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-adapter.c,v
retrieving revision 1.141
diff -u -r1.141 dbus-adapter.c
--- hcid/dbus-adapter.c	25 Dec 2006 15:06:01 -0000	1.141
+++ hcid/dbus-adapter.c	28 Dec 2006 13:06:01 -0000
@@ -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
diff -u -r1.1 dbus-adapter.h
--- hcid/dbus-adapter.h	30 Oct 2006 18:39:38 -0000	1.1
+++ hcid/dbus-adapter.h	28 Dec 2006 13:06:01 -0000
@@ -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
diff -u -r1.91 dbus-api.txt
--- hcid/dbus-api.txt	25 Dec 2006 15:06:01 -0000	1.91
+++ hcid/dbus-api.txt	28 Dec 2006 13:06:01 -0000
@@ -679,15 +679,22 @@
 		void DisconnectRemoteDevice(string address)
 
 			This method disconnects a specific remote device by
-			terminating the low-level ACL connection. The use
-			of this method should be restricted to administrator
-			use only.
+			terminating the low-level ACL connection. The use of
+			this method should be restricted to administrator
+			use.
+
+			A RemoteDeviceDisconnectionRequested signal will be
+			sent and the actual disconnection will only happen 2
+			seconds later.  This enables upper-level applications
+			to terminate their connections gracefully before the
+			ACL connection is terminated.
 
 			Possible errors: org.bluez.Error.NotReady
 					 org.bluez.Error.Failed
 					 org.bluez.Error.NoSuchAdapter
 					 org.bluez.Error.InvalidArguments
 			                 org.bluez.Error.NotConnected
+			                 org.bluez.Error.InProgress
 
 		void CreateBonding(string address)
 
@@ -905,6 +912,20 @@
 			                 org.bluez.Error.InProgress
 			                 org.bluez.Error.Failed
 
+		array{string} ListRemoteDevices()
+
+			List addresses of all known remote devices (seen, used or bonded).
+
+			Possible errors: none
+
+		array{string} ListRecentRemoteDevices(string date)
+
+			List addresses of all used or bonded remote devices since date.
+
+			date format is "YYYY-MM-DD HH:MM:SS GMT"
+
+			Possible errors: none
+
 Signals		void ModeChanged(string mode)
 
 			If the current mode is changed with SetMode this signal
@@ -987,6 +1008,12 @@
 			This signal will be send if a low level connection
 			between two devices has been created.
 
+		void RemoteDeviceDisconnectionRequested(string address)
+
+			This signal will be sent when a low level
+			disconnection to a remote device has been requested.
+			The actual disconnection will happen 2 seconds later.
+
 		void RemoteDeviceDisconnected(string address)
 
 			This signal will be send if a low level connection
@@ -1000,20 +1027,6 @@
 
 			Signals that a bonding was removed.
 
-		array{string} ListRemoteDevices()
-
-			List addresses of all known remote devices (seen, used or bonded).
-
-			Possible errors: none
-
-		array{string} ListRecentRemoteDevices(string date)
-
-			List addresses of all used or bonded remote devices since date.
-
-			date format is "YYYY-MM-DD HH:MM:SS GMT"
-
-			Possible errors: none
-
 
 Security hierarchy
 ==================
Index: hcid/dbus-error.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-error.c,v
retrieving revision 1.33
diff -u -r1.33 dbus-error.c
--- hcid/dbus-error.c	4 Dec 2006 12:53:58 -0000	1.33
+++ hcid/dbus-error.c	28 Dec 2006 13:06:01 -0000
@@ -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
diff -u -r1.3 dbus-error.h
--- hcid/dbus-error.h	4 Dec 2006 12:53:58 -0000	1.3
+++ hcid/dbus-error.h	28 Dec 2006 13:06:01 -0000
@@ -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
diff -u -r1.5 dbus-hci.c
--- hcid/dbus-hci.c	18 Dec 2006 12:58:35 -0000	1.5
+++ hcid/dbus-hci.c	28 Dec 2006 13:06:02 -0000
@@ -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
diff -u -r1.3 apitest
--- test/apitest	10 Nov 2006 17:20:25 -0000	1.3
+++ test/apitest	28 Dec 2006 13:06:02 -0000
@@ -69,6 +69,7 @@
                 "RemoteAliasChanged"
                 "RemoteAliasCleared",
                 "RemoteDeviceConnected",
+                "RemoteDeviceDisconnectionRequested",
                 "RemoteDeviceDisconnected",
                 "BondingCreated",
                 "BondingRemoved" ]

[-- Attachment #3: Type: text/plain, Size: 347 bytes --]

-------------------------------------------------------------------------
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

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Bluez-devel] [PATCH] New RemoteDeviceDisconnectionRequested signal implementation
  2006-12-28 13:20 [Bluez-devel] [PATCH] New RemoteDeviceDisconnectionRequested signal implementation Luciano Coelho
@ 2006-12-28 23:10 ` Johan Hedberg
  0 siblings, 0 replies; 2+ messages in thread
From: Johan Hedberg @ 2006-12-28 23:10 UTC (permalink / raw)
  To: bluez-devel

Hi Luca,

On Thu, Dec 28, 2006, Luciano Coelho wrote:
> 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.

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
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-12-28 23:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-28 13:20 [Bluez-devel] [PATCH] New RemoteDeviceDisconnectionRequested signal implementation Luciano Coelho
2006-12-28 23:10 ` Johan Hedberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox