Re: Wizard patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 2008-06-28 at 00:23 +0200, Marcel Holtmann wrote:
> looks nice. However you have to break this up into pieces for. Sent
> small patches and I can quickly review and commit them.

Here's a patch to add support for connecting to devices via the client code.  This patch depends on the callback patch.

It finds known services on startup (in setup_services()).  Bastien
suggested that we don't need to call setup_services() since those
services are enabled by default, but I'm not quite sure what he meant.
We need to call it to get the service bus IDs so that we can then get
DBusGProxies for them.

It adds the function bluetooth_client_available_services() which gives
back a type mask for services that were detected.  Basically which
devices are likely to succeed from a bluetooth_client_connect() call.

bluetooth_client_connect() does device-specific connection handling.
It only handles a few types right now (input and headset).

-mt
diff -upr ../bluez-gnome-callback/common/client.c ./common/client.c
--- ../bluez-gnome-callback/common/client.c	2008-06-30 09:04:57.000000000 -0400
+++ ./common/client.c	2008-06-30 09:35:52.000000000 -0400
@@ -48,6 +48,8 @@ struct _BluetoothClientPrivate {
 
 	DBusGConnection *conn;
 	DBusGProxy *manager_object;
+	DBusGProxy *input_service;
+	DBusGProxy *audio_service;
 	GtkTreeStore *store;
 	gchar *default_adapter;
 };
@@ -935,6 +937,33 @@ static void setup_manager(BluetoothClien
 		g_error_free(error);
 }
 
+static void setup_services(BluetoothClient *client)
+{
+	BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+	gchar *busname = NULL;
+
+	priv->input_service = NULL;
+	priv->audio_service = NULL;
+
+	if (dbus_g_proxy_call(priv->manager_object, "ActivateService", NULL,
+	                      G_TYPE_STRING, "input", G_TYPE_INVALID,
+	                      G_TYPE_STRING, &busname, G_TYPE_INVALID)) {
+		priv->input_service = dbus_g_proxy_new_for_name(priv->conn, busname,
+		                                                "/org/bluez/input",
+		                                                "org.bluez.input.Manager");
+		g_free(busname);
+	}
+
+	if (dbus_g_proxy_call(priv->manager_object, "ActivateService", NULL,
+	                      G_TYPE_STRING, "audio", G_TYPE_INVALID,
+	                      G_TYPE_STRING, &busname, G_TYPE_INVALID)) {
+		priv->audio_service = dbus_g_proxy_new_for_name(priv->conn, busname,
+		                                                "/org/bluez/audio",
+		                                                "org.bluez.audio.Manager");
+		g_free(busname);
+	}
+}
+
 static void name_owner_changed(DBusGProxy *object, const char *name,
 			const char *prev, const char *new, gpointer user_data)
 {
@@ -984,6 +1013,8 @@ static void bluetooth_client_finalize(GO
 	g_free(priv->default_adapter);
 	g_object_unref(G_OBJECT(priv->store));
 	g_object_unref (priv->manager_object);
+	g_object_unref (priv->input_service);
+	g_object_unref (priv->audio_service);
 }
 
 static void bluetooth_client_init(BluetoothClient *client)
@@ -1000,6 +1031,8 @@ static void bluetooth_client_init(Blueto
 	setup_dbus(client);
 
 	setup_manager(client);
+
+	setup_services(client);
 }
 
 static void bluetooth_client_set_property(GObject *object, guint prop_id,
@@ -1085,6 +1118,19 @@ BluetoothClient *bluetooth_client_new(vo
 	}
 }
 
+int bluetooth_client_available_services(BluetoothClient *client)
+{
+	BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+	int rv = 0;
+
+	if (priv->input_service)
+		rv |= BLUETOOTH_TYPE_INPUT;
+	if (priv->audio_service)
+		rv |= BLUETOOTH_TYPE_HEADSET;
+
+	return rv;
+}
+
 gboolean bluetooth_client_register_passkey_agent(BluetoothClient *client,
 		const char *path, const char *address, const void *info)
 {
@@ -1131,6 +1177,89 @@ static void call_reply_s(DBusGProxy *pro
 	call_reply(proxy, error, userdata);
 }
 
+static gboolean connect_to_service(BluetoothClient *client, DBusGProxy *object,
+						const gchar *address, guint type,
+						gpointer userdata)
+{
+	BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+	DBusGProxyCall *call = NULL;
+
+	/* Special case the few types we can handle */
+	if (type & BLUETOOTH_TYPE_INPUT)
+		call = input_create_secure_device_async(priv->input_service, address,
+					call_reply_s, userdata);
+	else if (type & BLUETOOTH_TYPE_HEADSET)
+		call = audio_create_headset_async(priv->audio_service, address,
+					call_reply_s, userdata);
+
+	g_object_set_data(G_OBJECT(object), "call", call);
+	return call != NULL;
+}
+
+gboolean bluetooth_client_connect(BluetoothClient *client, guint type,
+					gchar *adapter, const gchar *address,
+					bluetooth_client_call_reply callback,
+					gpointer userdata)
+{
+	BluetoothClientPrivate *priv = BLUETOOTH_CLIENT_GET_PRIVATE(client);
+	GtkTreeIter iter;
+	gboolean cont;
+
+	if (adapter == NULL)
+		adapter = priv->default_adapter;
+
+	if (adapter == NULL)
+		return FALSE;
+
+	cont = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->store), &iter);
+
+	while (cont == TRUE) {
+		DBusGProxy *object;
+		gchar *path;
+
+		gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &iter,
+						COLUMN_PATH, &path,
+						COLUMN_OBJECT, &object, -1);
+
+		if (g_ascii_strcasecmp(path, adapter) == 0) {
+			DBusGAsyncData *stuff;
+			gboolean cont;
+			GtkTreeIter child;
+
+			stuff = g_new (DBusGAsyncData, 1);
+			stuff->cb = G_CALLBACK (callback);
+			stuff->userdata = userdata;
+
+			/* If caller didn't specify a forced type, determine it from device info */
+			if (type == 0 || type == BLUETOOTH_TYPE_ANY) {
+				cont = gtk_tree_model_iter_children(GTK_TREE_MODEL(priv->store),
+										&child, &iter);
+
+				while (cont == TRUE) {
+					gchar *value;
+
+					gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &child,
+									COLUMN_ADDRESS, &value, -1);
+
+					if (g_ascii_strcasecmp(address, value) == 0) {
+						gtk_tree_model_get(GTK_TREE_MODEL(priv->store), &child,
+									COLUMN_TYPE, &type, -1);
+						break;
+					}
+
+					cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store), &child);
+				}
+			}
+
+			return connect_to_service(client, object, address, type, stuff);
+		}
+
+		cont = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->store), &iter);
+	}
+
+	return FALSE;
+}
+
 gboolean bluetooth_client_create_bonding(BluetoothClient *client,
 					gchar *adapter, const gchar *address,
 					bluetooth_client_call_reply callback,
diff -upr ../bluez-gnome-callback/common/client.h ./common/client.h
--- ../bluez-gnome-callback/common/client.h	2008-06-30 09:03:44.000000000 -0400
+++ ./common/client.h	2008-06-30 09:43:13.000000000 -0400
@@ -101,8 +101,16 @@ gboolean bluetooth_client_register_passk
 
 typedef void (*bluetooth_client_call_reply) (GError *error, gpointer data);
 
+int bluetooth_client_available_services(BluetoothClient *self);
+
 gboolean bluetooth_client_cancel_call(BluetoothClient *self,
 					gchar *adapter, const gchar *address);
+
+/* Set 'type' to non-zero to force a certain type connection -- useful for dumb devices */
+gboolean bluetooth_client_connect(BluetoothClient *self, guint type,
+					gchar *adapter, const gchar *address,
+					bluetooth_client_call_reply callback,
+					gpointer data);
 gboolean bluetooth_client_create_bonding(BluetoothClient *self,
 					gchar *adapter, const gchar *address,
 					bluetooth_client_call_reply callback,
diff -upr ../bluez-gnome-callback/common/dbus.xml ./common/dbus.xml
--- ../bluez-gnome-callback/common/dbus.xml	2008-06-30 08:55:31.000000000 -0400
+++ ./common/dbus.xml	2008-06-30 09:38:59.000000000 -0400
@@ -98,4 +98,20 @@
       <arg type="s" name="address"/>
     </method>
   </interface>
+
+  <interface name="input">
+    <method name="CreateSecureDevice">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="address"/>
+      <arg type="s" direction="out"/>
+    </method>
+  </interface>
+
+  <interface name="audio">
+    <method name="CreateHeadset">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="address"/>
+      <arg type="s" direction="out"/>
+    </method>
+  </interface>
 </node>

Attachment: signature.asc
Description: This is a digitally signed message part

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Bluez-devel mailing list
Bluez-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/bluez-devel

[Index of Archives]     [Linux Bluetooth Devel]     [Linux USB Devel]     [Network Devel]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux