All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luciano Coelho <luciano.coelho@nokia.com>
To: BlueZ development <bluez-devel@lists.sourceforge.net>
Subject: [Bluez-devel] [PATCH] New RemoteDeviceDisconnectionRequested signal implementation
Date: Thu, 28 Dec 2006 15:20:00 +0200	[thread overview]
Message-ID: <4593C480.5080806@nokia.com> (raw)

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

             reply	other threads:[~2006-12-28 13:20 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-12-28 13:20 Luciano Coelho [this message]
2006-12-28 23:10 ` [Bluez-devel] [PATCH] New RemoteDeviceDisconnectionRequested signal implementation Johan Hedberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4593C480.5080806@nokia.com \
    --to=luciano.coelho@nokia.com \
    --cc=bluez-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.