All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bastien Nocera <hadess@hadess.net>
To: Johan Hedberg <johan.hedberg@gmail.com>
Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>,
	linux-bluetooth@vger.kernel.org
Subject: Re: Broken SDP parsing?
Date: Fri, 13 Mar 2009 15:37:53 +0000	[thread overview]
Message-ID: <1236958673.32264.5799.camel@cookie.hadess.net> (raw)
In-Reply-To: <20090309174644.GA4340@jh-x301>

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

On Mon, 2009-03-09 at 15:04 -0300, Johan Hedberg wrote:
<snip>
> 2. Have the new function start like:
> {
>         sdp_data_t *d;
> 
>         d = sdp_data_alloc_with_length(dtd, value, len);
>         if (!d)
>                 return -1;

FWIW, I just copied the coding style from the function 5 lines above it.

Patches attached.

[-- Attachment #2: 0001-Fix-sdp_copy_record-truncating-strings-with-NULLs.patch --]
[-- Type: text/x-patch, Size: 2647 bytes --]

>From 3922bbb56cc5e3a8602c578a793db6aee5537e94 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 13 Mar 2009 15:27:33 +0000
Subject: [PATCH] Fix sdp_copy_record truncating strings with NULLs

When a record's attribute contains embed NULLs in the string,
sdp_data_alloc() falls back to doing an strlen() on the
string, instead of taking its existing length into account.
---
 lib/sdp.c |   30 ++++++++++++++++++++++++++----
 1 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index 896c5eb..18e6450 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -97,6 +97,8 @@ static uint128_t bluetooth_base_uuid = {
 #define SDP_MAX_ATTR_LEN 65535
 
 static sdp_data_t *sdp_copy_seq(sdp_data_t *data);
+static int sdp_attr_add_new_with_length(sdp_record_t *rec,
+	uint16_t attr, uint8_t dtd, const void *value, uint32_t len);
 
 /* Message structure. */
 struct tupla {
@@ -1381,7 +1383,7 @@ static void sdp_copy_pattern(void *value, void *udata)
 	sdp_pattern_add_uuid(rec, uuid);
 }
 
-static void *sdp_data_value(sdp_data_t *data)
+static void *sdp_data_value(sdp_data_t *data, uint32_t *len)
 {
 	void *val = NULL;
 
@@ -1435,6 +1437,8 @@ static void *sdp_data_value(sdp_data_t *data)
 	case SDP_URL_STR32:
 	case SDP_TEXT_STR32:
 		val = data->val.str;
+		if (len)
+			*len = data->unitSize - 1;
 		break;
 	case SDP_ALT8:
 	case SDP_ALT16:
@@ -1457,7 +1461,7 @@ static sdp_data_t *sdp_copy_seq(sdp_data_t *data)
 		sdp_data_t *datatmp;
 		void *value;
 
-		value = sdp_data_value(tmp);
+		value = sdp_data_value(tmp, NULL);
 		datatmp = sdp_data_alloc_with_length(tmp->dtd, value,
 					tmp->unitSize);
 
@@ -1477,10 +1481,15 @@ static void sdp_copy_attrlist(void *value, void *udata)
 	sdp_data_t *data = value;
 	sdp_record_t *rec = udata;
 	void *val;
+	uint32_t len = 0;
 
-	val = sdp_data_value(data);
+	val = sdp_data_value(data, &len);
 
-	sdp_attr_add_new(rec, data->attrId, data->dtd, val);
+	if (!len)
+		sdp_attr_add_new(rec, data->attrId, data->dtd, val);
+	else
+		sdp_attr_add_new_with_length(rec, data->attrId,
+			data->dtd, val, len);
 }
 
 sdp_record_t *sdp_copy_record(sdp_record_t *rec)
@@ -2068,6 +2077,19 @@ int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd,
 	return -1;
 }
 
+static int sdp_attr_add_new_with_length(sdp_record_t *rec,
+	uint16_t attr, uint8_t dtd, const void *value, uint32_t len)
+{
+	sdp_data_t *d;
+	
+	d = sdp_data_alloc_with_length(dtd, value, len);
+	if (!d)
+		return -1;
+
+	sdp_attr_replace(rec, attr, d);
+	return 0;
+}
+
 /*
  * Set the information attributes of the service
  * pointed to by rec. The attributes are
-- 
1.6.0.6


[-- Attachment #3: 0002-Don-t-truncate-strings-with-embedded-NULLs.patch --]
[-- Type: text/x-patch, Size: 1174 bytes --]

>From b974124d58e2cf382b1c258c94c2fd92258cb25f Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 13 Mar 2009 15:30:21 +0000
Subject: [PATCH] Don't truncate strings with embedded NULLs

Instead, replace the NULLs by spaces so we don't lose data
when converting a device's SDP record to XML.
---
 common/sdp-xml.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/common/sdp-xml.c b/common/sdp-xml.c
index 0403dcd..608de76 100644
--- a/common/sdp-xml.c
+++ b/common/sdp-xml.c
@@ -239,9 +239,8 @@ static void convert_raw_data_to_xml(sdp_data_t *value, int indent_level,
 		hex = 0;
 
 		for (i = 0; i < length; i++) {
-			if (value->val.str[i] == '\0')
-				break;
-			if (!isprint(value->val.str[i])) {
+			if (!isprint(value->val.str[i]) &&
+					value->val.str[i] != '\0') {
 				hex = 1;
 				break;
 			}
@@ -304,7 +303,9 @@ static void convert_raw_data_to_xml(sdp_data_t *value, int indent_level,
 					strBuf[j++] = 'o';
 					strBuf[j++] = 't';
 				}
-				else {
+				else if (value->val.str[i] == '\0') {
+					strBuf[j++] = ' ';
+				} else {
 					strBuf[j++] = value->val.str[i];
 				}
 			}
-- 
1.6.0.6


[-- Attachment #4: 0003-Port-CUPS-discovery-to-BlueZ-4.x.patch --]
[-- Type: text/x-patch, Size: 19528 bytes --]

>From 783aa6f8de6f17a611f8b74288bd1617a9630d77 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 13 Mar 2009 15:34:57 +0000
Subject: [PATCH] Port CUPS discovery to BlueZ 4.x

Adapt CUPS printer discovery to the BlueZ 4.x API.
---
 cups/main.c |  437 ++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 256 insertions(+), 181 deletions(-)

diff --git a/cups/main.c b/cups/main.c
index d8b899e..9b102c8 100644
--- a/cups/main.c
+++ b/cups/main.c
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <signal.h>
 #include <sys/socket.h>
+#include <glib.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
@@ -42,8 +43,6 @@
 
 #include "cups.h"
 
-#define PRINTER_SERVICE_CLASS_NAME "printer"
-
 struct cups_device {
 	char *bdaddr;
 	char *name;
@@ -53,53 +52,87 @@ struct cups_device {
 static GSList *device_list = NULL;
 static GMainLoop *loop = NULL;
 static DBusConnection *conn = NULL;
+static gboolean doing_disco = FALSE;
 
 #define ATTRID_1284ID 0x0300
 
-static sdp_record_t *sdp_xml_parse_record(const char *data, int size)
-{
-	return NULL;
-}
+struct context_data {
+	gboolean found;
+	char *id;
+};
 
-static char *parse_xml_sdp(const char *xml)
+static void element_start(GMarkupParseContext *context,
+		const gchar *element_name, const gchar **attribute_names,
+		const gchar **attribute_values, gpointer user_data, GError **err)
 {
-	sdp_record_t *sdp_record;
-	sdp_list_t *l;
-	char *str = NULL;
+	struct context_data *ctx_data = user_data;
 
-	sdp_record = sdp_xml_parse_record(xml, strlen(xml));
-	if (sdp_record == NULL)
-		return NULL;
+	if (!strcmp(element_name, "record"))
+		return;
 
-	for (l = sdp_record->attrlist; l != NULL; l = l->next) {
-		sdp_data_t *data;
+	if (!strcmp(element_name, "attribute")) {
+		int i;
+		for (i = 0; attribute_names[i]; i++) {
+			if (!strcmp(attribute_names[i], "id")) {
+				if (strtol(attribute_values[i], 0, 0) == ATTRID_1284ID)
+					ctx_data->found = TRUE;
+				break;
+			}
+		}
+		return;
+	}
 
-		data = (sdp_data_t *) l->data;
-		if (data->attrId != ATTRID_1284ID)
-			continue;
-		/* Ignore the length, it's null terminated */
-		str = g_strdup(data->val.str + 2);
-		break;
+	if (ctx_data->found  && !strcmp(element_name, "text")) {
+		int i;
+		for (i = 0; attribute_names[i]; i++) {
+			if (!strcmp(attribute_names[i], "value")) {
+				ctx_data->id = g_strdup(attribute_values[i] + 2);
+				ctx_data->found = FALSE;
+			}
+		}
 	}
-	sdp_record_free(sdp_record);
+}
+
+static GMarkupParser parser = {
+	element_start, NULL, NULL, NULL, NULL
+};
 
-	return str;
+static char *sdp_xml_parse_record(const char *data)
+{
+	GMarkupParseContext *ctx;
+	struct context_data ctx_data;
+	int size;
+
+	size = strlen(data);
+	ctx_data.found = FALSE;
+	ctx_data.id = NULL;
+	ctx = g_markup_parse_context_new(&parser, 0, &ctx_data, NULL);
+
+	if (g_markup_parse_context_parse(ctx, data, size, NULL) == FALSE) {
+		g_markup_parse_context_free(ctx);
+		g_free(ctx_data.id);
+		return NULL;
+	}
+
+	g_markup_parse_context_free(ctx);
+
+	return ctx_data.id;
 }
 
-static char *device_get_ieee1284_id(const char *adapter, const char *bdaddr)
+static char *device_get_ieee1284_id(const char *adapter, const char *device)
 {
-	guint service_handle;
 	DBusMessage *message, *reply;
-	DBusMessageIter iter, reply_iter, iter_array;
+	DBusMessageIter iter, reply_iter;
+	DBusMessageIter reply_iter_entry;
 	const char *hcr_print = "00001126-0000-1000-8000-00805f9b34fb";
-	char *xml, *id;
+	const char *xml;
+	char *id;
 
 	/* Look for the service handle of the HCRP service */
-	message = dbus_message_new_method_call("org.bluez", adapter,
-						"org.bluez.Adapter",
-						"GetRemoteServiceHandles");
+	message = dbus_message_new_method_call("org.bluez", device,
+						"org.bluez.Device",
+						"DiscoverServices");
 	dbus_message_iter_init_append(message, &iter);
-	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
 	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &hcr_print);
 
 	reply = dbus_connection_send_with_reply_and_block(conn,
@@ -111,40 +144,41 @@ static char *device_get_ieee1284_id(const char *adapter, const char *bdaddr)
 		return NULL;
 
 	dbus_message_iter_init(reply, &reply_iter);
+
 	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
 		dbus_message_unref(reply);
-		return NULL;
-	}
-
-	/* Hopefully we only get one handle, or take a punt */
-	dbus_message_iter_recurse(&reply_iter, &iter_array);
-	while (dbus_message_iter_get_arg_type(&iter_array) == DBUS_TYPE_UINT32) {
-		dbus_message_iter_get_basic(&iter_array, &service_handle);
-		dbus_message_iter_next(&iter_array);
+		return FALSE;
 	}
 
-	dbus_message_unref(reply);
+	dbus_message_iter_recurse(&reply_iter, &reply_iter_entry);
 
-	/* Now get the XML for the HCRP service record */
-	message = dbus_message_new_method_call("org.bluez", adapter,
-						"org.bluez.Adapter",
-						"GetRemoteServiceRecordAsXML");
-	dbus_message_iter_init_append(message, &iter);
-	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
-	dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &service_handle);
+	/* Hopefully we only get one handle, or take a punt */
+	while (dbus_message_iter_get_arg_type(&reply_iter_entry) == DBUS_TYPE_DICT_ENTRY) {
+		guint32 key;
+		DBusMessageIter dict_entry;
 
-	reply = dbus_connection_send_with_reply_and_block(conn,
-							message, -1, NULL);
+		dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
 
-	dbus_message_unref(message);
+		/* Key ? */
+		dbus_message_iter_get_basic(&dict_entry, &key);
+		if (!key) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
 
-	if (!reply)
-		return NULL;
+		/* Try to get the value */
+		if (!dbus_message_iter_next(&dict_entry)) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
 
-	dbus_message_iter_init(reply, &reply_iter);
-	dbus_message_iter_get_basic(&reply_iter, &xml);
+		dbus_message_iter_get_basic(&dict_entry, &xml);
 
-	id = parse_xml_sdp(xml);
+		id = sdp_xml_parse_record(xml);
+		if (id != NULL)
+			break;
+		dbus_message_iter_next(&reply_iter_entry);
+	}
 
 	dbus_message_unref(reply);
 
@@ -161,8 +195,12 @@ static void add_device_to_list(const char *name, const char *bdaddr, const char
 		device = (struct cups_device *) l->data;
 
 		if (strcmp(device->bdaddr, bdaddr) == 0) {
-			g_free(device->name);
-			device->name = g_strdup(name);
+			if (device->name != name) {
+				g_free(device->name);
+				device->name = g_strdup(name);
+			}
+			g_free(device->id);
+			device->id = g_strdup(id);
 			return;
 		}
 	}
@@ -176,25 +214,12 @@ static void add_device_to_list(const char *name, const char *bdaddr, const char
 	device_list = g_slist_prepend(device_list, device);
 }
 
-static char *escape_name(const char *str, char orig, char dest)
-{
-	char *ret, *s;
-
-	ret = g_strdup(str);
-	while ((s = strchr(ret, orig)) != NULL)
-		s[0] = dest;
-	return ret;
-}
-
 static void print_printer_details(const char *name, const char *bdaddr, const char *id)
 {
 	char *uri, *escaped;
-	guint len;
 
-	escaped = escape_name(name, '\"', '\'');
-	len = strlen("bluetooth://") + 12 + 1;
-	uri = g_malloc(len);
-	snprintf(uri, len, "bluetooth://%c%c%c%c%c%c%c%c%c%c%c%c",
+	escaped = g_strdelimit(g_strdup(name), "\"", '\'');
+	uri = g_strdup_printf("bluetooth://%c%c%c%c%c%c%c%c%c%c%c%c",
 		 bdaddr[0], bdaddr[1],
 		 bdaddr[3], bdaddr[4],
 		 bdaddr[6], bdaddr[7],
@@ -205,53 +230,78 @@ static void print_printer_details(const char *name, const char *bdaddr, const ch
 	if (id != NULL)
 		printf(" \"%s\"\n", id);
 	else
-		printf ("\n");
+		printf("\n");
 	g_free(escaped);
 	g_free(uri);
 }
 
-static gboolean device_is_printer(const char *adapter, const char *bdaddr)
+static gboolean parse_device_properties(DBusMessageIter *reply_iter, char **name, char **bdaddr)
 {
-	char *class;
-	DBusMessage *message, *reply;
-	DBusMessageIter iter, reply_iter;
+	guint32 class = 0;
+	DBusMessageIter reply_iter_entry;
 
-	message = dbus_message_new_method_call("org.bluez", adapter,
-					       "org.bluez.Adapter",
-					       "GetRemoteMinorClass");
-	dbus_message_iter_init_append(message, &iter);
-	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
+	if (dbus_message_iter_get_arg_type(reply_iter) != DBUS_TYPE_ARRAY)
+		return FALSE;
 
-	reply = dbus_connection_send_with_reply_and_block(conn,
-							message, -1, NULL);
+	dbus_message_iter_recurse(reply_iter, &reply_iter_entry);
 
-	dbus_message_unref(message);
+	while (dbus_message_iter_get_arg_type(&reply_iter_entry) == DBUS_TYPE_DICT_ENTRY) {
+		const char *key;
+		DBusMessageIter dict_entry, iter_dict_val;
 
-	if (!reply)
-		return FALSE;
+		dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
 
-	dbus_message_iter_init(reply, &reply_iter);
-	dbus_message_iter_get_basic(&reply_iter, &class);
+		/* Key == Class ? */
+		dbus_message_iter_get_basic(&dict_entry, &key);
+		if (!key) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
 
-	if (class != NULL && strcmp(class, PRINTER_SERVICE_CLASS_NAME) == 0) {
-		dbus_message_unref(reply);
-		return TRUE;
+		if (strcmp(key, "Class") != 0 &&
+				strcmp(key, "Alias") != 0 &&
+				strcmp(key, "Address") != 0) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
+
+		/* Try to get the value */
+		if (!dbus_message_iter_next(&dict_entry)) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
+		dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
+		if (strcmp(key, "Class") == 0) {
+			dbus_message_iter_get_basic(&iter_dict_val, &class);
+		} else {
+			const char *value;
+			dbus_message_iter_get_basic(&iter_dict_val, &value);
+			if (strcmp(key, "Alias") == 0) {
+				*name = g_strdup(value);
+			} else if (bdaddr) {
+				*bdaddr = g_strdup(value);
+			}
+		}
+		dbus_message_iter_next(&reply_iter_entry);
 	}
 
+	if (class == 0)
+		return FALSE;
+	if (((class & 0x1f00) >> 8) == 0x06 && (class & 0x80))
+		return TRUE;
+
 	return FALSE;
 }
 
-static char *device_get_name(const char *adapter, const char *bdaddr)
+static gboolean device_is_printer(const char *adapter, const char *device_path, char **name, char **bdaddr)
 {
 	DBusMessage *message, *reply;
-	DBusMessageIter iter, reply_iter;
-	char *name;
+	DBusMessageIter reply_iter;
+	gboolean retval;
 
-	message = dbus_message_new_method_call("org.bluez", adapter,
-						"org.bluez.Adapter",
-						"GetRemoteName");
-	dbus_message_iter_init_append(message, &iter);
-	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
+	message = dbus_message_new_method_call("org.bluez", device_path,
+					       "org.bluez.Device",
+					       "GetProperties");
 
 	reply = dbus_connection_send_with_reply_and_block(conn,
 							message, -1, NULL);
@@ -259,56 +309,78 @@ static char *device_get_name(const char *adapter, const char *bdaddr)
 	dbus_message_unref(message);
 
 	if (!reply)
-		return NULL;
+		return FALSE;
 
 	dbus_message_iter_init(reply, &reply_iter);
-	dbus_message_iter_get_basic(&reply_iter, &name);
 
-	name = g_strdup(name);
+	retval = parse_device_properties(&reply_iter, name, bdaddr);
+
 	dbus_message_unref(reply);
 
-	return name;
+	return retval;
 }
 
-static void remote_device_found(const char *adapter, const char *bdaddr, guint class, int rssi)
+static void remote_device_found(const char *adapter, const char *bdaddr, const char *name)
 {
-	uint8_t major_index = (class >> 8) & 0x1F;
-	uint8_t minor_index;
-	uint8_t shift_minor = 0;
-	gboolean found = FALSE;
-	char *name, *id;
-
-	/* Check if we have a printer
-	 * From hcid/dbus-adapter.c minor_class_str() */
-	if (major_index != 6)
-		return;
+	DBusMessage *message, *reply, *adapter_reply;
+	DBusMessageIter iter;
+	char *object_path = NULL;
+	char *id;
 
-	minor_index = (class >> 4) & 0x0F;
-	while (shift_minor < 4) {
-		if (((minor_index >> shift_minor) & 0x01) == 0x01) {
-			if (shift_minor == 3) {
-				found = TRUE;
-				break;
-			}
-		}
-		shift_minor++;
+	adapter_reply = NULL;
+
+	if (adapter == NULL) {
+		message = dbus_message_new_method_call("org.bluez", "/",
+						       "org.bluez.Manager",
+						       "DefaultAdapter");
+
+		adapter_reply = dbus_connection_send_with_reply_and_block(conn,
+								  message, -1, NULL);
+
+		dbus_message_unref(message);
+
+		if (dbus_message_get_args(adapter_reply, NULL, DBUS_TYPE_OBJECT_PATH, &adapter, DBUS_TYPE_INVALID) == FALSE)
+			return;
 	}
 
-	if (!found)
-		return;
+	message = dbus_message_new_method_call("org.bluez", adapter,
+					       "org.bluez.Adapter",
+					       "FindDevice");
+	dbus_message_iter_init_append(message, &iter);
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
+
+	if (adapter_reply != NULL)
+		dbus_message_unref(adapter_reply);
+
+	reply = dbus_connection_send_with_reply_and_block(conn,
+							message, -1, NULL);
+
+	dbus_message_unref(message);
+
+	if (!reply) {
+		message = dbus_message_new_method_call("org.bluez", adapter,
+						       "org.bluez.Adapter",
+						       "CreateDevice");
+		dbus_message_iter_init_append(message, &iter);
+		dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
 
-	name = device_get_name(adapter, bdaddr);
-	id = device_get_ieee1284_id(adapter, bdaddr);
+		reply = dbus_connection_send_with_reply_and_block(conn,
+								  message, -1, NULL);
+
+		dbus_message_unref(message);
+
+		if (!reply)
+			return;
+	} else {
+		if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID) == FALSE)
+			return;
+	}
+
+	id = device_get_ieee1284_id(adapter, object_path);
 	add_device_to_list(name, bdaddr, id);
-	g_free(name);
 	g_free(id);
 }
 
-static void remote_name_updated(const char *bdaddr, const char *name)
-{
-	add_device_to_list(name, bdaddr, NULL);
-}
-
 static void discovery_completed(void)
 {
 	GSList *l;
@@ -317,7 +389,10 @@ static void discovery_completed(void)
 		struct cups_device *device = (struct cups_device *) l->data;
 
 		if (device->name == NULL)
-			device->name = escape_name(device->bdaddr, ':', '-');
+			device->name = g_strdelimit(g_strdup(device->bdaddr), ":", '-');
+		/* Give another try to getting an ID for the device */
+		if (device->id == NULL)
+			remote_device_found(NULL, device->bdaddr, device->name);
 		print_printer_details(device->name, device->bdaddr, device->id);
 		g_free(device->name);
 		g_free(device->bdaddr);
@@ -356,7 +431,7 @@ static gboolean list_known_printers(const char *adapter)
 
 	message = dbus_message_new_method_call ("org.bluez", adapter,
 						"org.bluez.Adapter",
-						"ListRemoteDevices");
+						"ListDevices");
 	if (message == NULL)
 		return FALSE;
 
@@ -376,18 +451,21 @@ static gboolean list_known_printers(const char *adapter)
 	}
 
 	dbus_message_iter_recurse(&reply_iter, &iter_array);
-	while (dbus_message_iter_get_arg_type(&iter_array) == DBUS_TYPE_STRING) {
-		char *bdaddr;
+	while (dbus_message_iter_get_arg_type(&iter_array) == DBUS_TYPE_OBJECT_PATH) {
+		const char *object_path;
+		char *name = NULL;
+		char *bdaddr = NULL;
 
-		dbus_message_iter_get_basic(&iter_array, &bdaddr);
-		if (device_is_printer(adapter, bdaddr)) {
-			char *name, *id;
-			name = device_get_name(adapter, bdaddr);
-			id = device_get_ieee1284_id(adapter, bdaddr);
+		dbus_message_iter_get_basic(&iter_array, &object_path);
+		if (device_is_printer(adapter, object_path, &name, &bdaddr)) {
+			char *id;
+
+			id = device_get_ieee1284_id(adapter, object_path);
 			add_device_to_list(name, bdaddr, id);
-			g_free(name);
 			g_free(id);
 		}
+		g_free(name);
+		g_free(bdaddr);
 		dbus_message_iter_next(&iter_array);
 	}
 
@@ -398,32 +476,22 @@ static gboolean list_known_printers(const char *adapter)
 
 static DBusHandlerResult filter_func(DBusConnection *connection, DBusMessage *message, void *user_data)
 {
-	const char *adapter;
-
 	if (dbus_message_is_signal(message, "org.bluez.Adapter",
-						"RemoteDeviceFound")) {
-		char *bdaddr;
-		guint class;
-		int rssi;
+						"DeviceFound")) {
+		const char *adapter, *bdaddr;
+		char *name;
+		DBusMessageIter iter;
 
-		dbus_message_get_args(message, NULL,
-					DBUS_TYPE_STRING, &bdaddr,
-					DBUS_TYPE_UINT32, &class,
-					DBUS_TYPE_INT32, &rssi,
-					DBUS_TYPE_INVALID);
-		adapter = dbus_message_get_path(message);
-		remote_device_found(adapter, bdaddr, class, rssi);
-	} else if (dbus_message_is_signal(message, "org.bluez.Adapter",
-							"RemoteNameUpdated")) {
-		char *bdaddr, *name;
+		dbus_message_iter_init(message, &iter);
+		dbus_message_iter_get_basic(&iter, &bdaddr);
+		dbus_message_iter_next(&iter);
 
-		dbus_message_get_args(message, NULL,
-					DBUS_TYPE_STRING, &bdaddr,
-					DBUS_TYPE_STRING, &name,
-					DBUS_TYPE_INVALID);
-		remote_name_updated(bdaddr, name);
+		adapter = dbus_message_get_path(message);
+		if (parse_device_properties(&iter, &name, NULL))
+			remote_device_found(adapter, bdaddr, name);
+		g_free (name);
 	} else if (dbus_message_is_signal(message, "org.bluez.Adapter",
-						"RemoteDeviceDisappeared")) {
+						"DeviceDisappeared")) {
 		char *bdaddr;
 
 		dbus_message_get_args(message, NULL,
@@ -431,8 +499,21 @@ static DBusHandlerResult filter_func(DBusConnection *connection, DBusMessage *me
 					DBUS_TYPE_INVALID);
 		remote_device_disappeared(bdaddr);
 	} else if (dbus_message_is_signal(message, "org.bluez.Adapter",
-						"DiscoveryCompleted")) {
-		discovery_completed();
+						"PropertyChanged")) {
+		DBusMessageIter iter, value_iter;
+		const char *name;
+		gboolean discovering;
+
+		dbus_message_iter_init(message, &iter);
+		dbus_message_iter_get_basic(&iter, &name);
+		dbus_message_iter_next(&iter);
+		dbus_message_iter_recurse(&iter, &value_iter);
+		dbus_message_iter_get_basic(&value_iter, &discovering);
+
+		if (discovering == FALSE && doing_disco) {
+			doing_disco = FALSE;
+			discovery_completed();
+		}
 	}
 
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -452,7 +533,6 @@ static gboolean list_printers(void)
 	DBusMessage *reply, *message;
 	DBusMessageIter reply_iter;
 	char *adapter, *match;
-	guint len;
 
 	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
 	if (conn == NULL)
@@ -486,7 +566,7 @@ static gboolean list_printers(void)
 	}
 
 	dbus_message_iter_init(reply, &reply_iter);
-	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_STRING) {
+	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_OBJECT_PATH) {
 		dbus_message_unref(reply);
 		dbus_connection_unref(conn);
 		return FALSE;
@@ -508,19 +588,17 @@ static gboolean list_printers(void)
 	"sender='org.bluez',"			\
 	"path='%s'"
 
-	len = strlen(MATCH_FORMAT) - 2 + strlen(adapter) + 1;
-	match = g_malloc(len);
-	snprintf(match, len, "type='signal',"
-				"interface='org.bluez.Adapter',"
-				"sender='org.bluez',"
-				"path='%s'",
-				adapter);
+	match = g_strdup_printf(MATCH_FORMAT, adapter);
 	dbus_bus_add_match(conn, match, &error);
 	g_free(match);
 
+	/* Add the the recent devices */
+	list_known_printers(adapter);
+
+	doing_disco = TRUE;
 	message = dbus_message_new_method_call("org.bluez", adapter,
 					"org.bluez.Adapter",
-					"DiscoverDevicesWithoutNameResolving");
+					"StartDiscovery");
 
 	if (!dbus_connection_send_with_reply(conn, message, NULL, -1)) {
 		dbus_message_unref(message);
@@ -530,9 +608,6 @@ static gboolean list_printers(void)
 	}
 	dbus_message_unref(message);
 
-	/* Also add the the recent devices */
-	g_timeout_add(0, (GSourceFunc) list_known_printers, adapter);
-
 	loop = g_main_loop_new(NULL, TRUE);
 	g_main_loop_run(loop);
 
-- 
1.6.0.6


  parent reply	other threads:[~2009-03-13 15:37 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-06  1:00 Broken SDP parsing? Bastien Nocera
2009-03-08 14:46 ` Bastien Nocera
2009-03-09 13:08   ` Luiz Augusto von Dentz
2009-03-09 14:14     ` Bastien Nocera
2009-03-09 14:32       ` Luiz Augusto von Dentz
2009-03-09 14:53         ` Luiz Augusto von Dentz
2009-03-09 15:25         ` Bastien Nocera
2009-03-09 16:40           ` Luiz Augusto von Dentz
2009-03-09 17:09             ` Bastien Nocera
2009-03-09 18:04               ` Johan Hedberg
2009-03-09 19:29                 ` Port CUPS discovery to BlueZ 4.x (Re: Broken SDP parsing?) Bastien Nocera
2009-03-13 15:37                 ` Bastien Nocera [this message]
2009-03-13 18:15                   ` Broken SDP parsing? Johan Hedberg
2009-03-14  0:39                     ` Bastien Nocera
2009-03-14 13:29                       ` 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=1236958673.32264.5799.camel@cookie.hadess.net \
    --to=hadess@hadess.net \
    --cc=johan.hedberg@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    /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.