[gnome-bluetooth] Bug 583651 – Pin code for Sony CMT-DH5BT too long



commit bd08d3a4dd12da21343fad83785606975a14e598
Author: Bastien Nocera <hadess hadess net>
Date:   Sat May 23 17:09:49 2009 +0100

    Bug 583651 â?? Pin code for Sony CMT-DH5BT too long
    
    Add a way to force the number of digits in the PIN code for a
    particular device.
    
    The Sony CMT-DH5BT can enter random pincodes, but with a maximum of
    4 digits. Add a quirk for that, and remove the hardcoding of 6 pin
    digits (replacing it with a #define in pin.h)
---
 wizard/main.c                |   22 ++++++++++++++++------
 wizard/pin-code-database.xml |    7 +++++++
 wizard/pin.c                 |   19 ++++++++++++++++---
 wizard/pin.h                 |    4 +++-
 4 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/wizard/main.c b/wizard/main.c
index ca2a5e1..5092ed3 100644
--- a/wizard/main.c
+++ b/wizard/main.c
@@ -25,6 +25,7 @@
 #include <config.h>
 #endif
 
+#include <math.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
@@ -285,7 +286,7 @@ void prepare_callback(GtkWidget *assistant,
 		g_object_ref(agent);
 
 		/* Do we pair, or don't we? */
-		pin_ret = get_pincode_for_device (target_type, target_address, target_name);
+		pin_ret = get_pincode_for_device (target_type, target_address, target_name, NULL);
 		if (pin_ret != NULL && g_str_equal (pin_ret, "NULL"))
 			path = NULL;
 		g_free (pin_ret);
@@ -301,11 +302,19 @@ void prepare_callback(GtkWidget *assistant,
 		if (user_pincode != NULL && *user_pincode != '\0') {
 			pincode = g_strdup (user_pincode);
 		} else {
-			pincode = get_pincode_for_device(target_type, target_address, target_name);
-			if (pincode == NULL)
-				pincode = g_strdup(target_pincode);
-			else
+			guint max_digits;
+
+			pincode = get_pincode_for_device(target_type, target_address, target_name, &max_digits);
+			if (pincode == NULL) {
+				/* Truncate the default pincode if the device doesn't like long
+				 * PIN codes */
+				if (max_digits != PIN_NUM_DIGITS && max_digits > 0)
+					pincode = g_strndup(target_pincode, max_digits);
+				else
+					pincode = g_strdup(target_pincode);
+			} else {
 				automatic_pincode = TRUE;
+			}
 		}
 
 		if (automatic_pincode == FALSE) {
@@ -624,7 +633,8 @@ int main(int argc, char *argv[])
 
 	gtk_window_set_default_icon_name("bluetooth");
 
-	target_pincode = g_strdup_printf("%d", g_random_int_range(100000, 999999));
+	target_pincode = g_strdup_printf("%d", g_random_int_range(pow (10, PIN_NUM_DIGITS - 1),
+								  pow (10, PIN_NUM_DIGITS) - 1));
 
 	client = bluetooth_client_new();
 
diff --git a/wizard/pin-code-database.xml b/wizard/pin-code-database.xml
index 20260c8..6877764 100644
--- a/wizard/pin-code-database.xml
+++ b/wizard/pin-code-database.xml
@@ -27,6 +27,10 @@
   connected to and marked as trusted. This is for devices such as mice
   and joypads where there is no encryption
 
+  If a device can use a random PIN but is limited in the number of digits that
+  can be entered, then set the "pin" attribute should be set to "max:X" where X
+  is the maximum number of digits, for example max:4 for 4 digits.
+
   [1]: So specific devices should be at the top, and generic ones at the bottom,
   so settings for specific devices are overridden as expected.
 -->
@@ -131,6 +135,9 @@
 	<!-- http://bugzilla.gnome.org/show_bug.cgi?id=561325 -->
 	<device type="network" oui="00:06:66:" name="OBDPros scantool" pin="1234"/>
 
+	<!-- http://bugzilla.gnome.org/show_bug.cgi?id=583651 -->
+	<device type="audio" oui="00:1A:80:" name="CMT-DH5BT" pin="max:4"/>
+
 <!-- Generic types -->
 
 	<!-- Printers -->
diff --git a/wizard/pin.c b/wizard/pin.c
index 8522804..c7192de 100644
--- a/wizard/pin.c
+++ b/wizard/pin.c
@@ -25,12 +25,15 @@
 #include <config.h>
 #endif
 
+#include <stdlib.h>
+#include <string.h>
 #include <glib.h>
 #include <bluetooth-enums.h>
 
 #include "pin.h"
 
 #define PIN_CODE_DB "pin-code-database.xml"
+#define MAX_DIGITS_PIN_PREFIX "max:"
 
 #define TYPE_IS(x, r) {				\
 	if (g_str_equal(type, x)) return r;	\
@@ -53,6 +56,7 @@ static guint string_to_type(const char *type)
 
 typedef struct {
 	char *ret_pin;
+	guint max_digits;
 	guint type;
 	const char *address;
 	const char *name;
@@ -68,7 +72,7 @@ pin_db_parse_start_tag (GMarkupParseContext *ctx,
 {
 	PinParseData *pdata = (PinParseData *) data;
 
-	if (pdata->ret_pin != NULL)
+	if (pdata->ret_pin != NULL || pdata->max_digits != 0)
 		return;
 	if (g_str_equal (element_name, "device") == FALSE)
 		return;
@@ -87,7 +91,12 @@ pin_db_parse_start_tag (GMarkupParseContext *ctx,
 			if (g_str_equal (*attr_values, pdata->name) == FALSE)
 				return;
 		} else if (g_str_equal (*attr_names, "pin")) {
-			pdata->ret_pin = g_strdup (*attr_values);
+			if (g_str_has_prefix (MAX_DIGITS_PIN_PREFIX, *attr_values) != FALSE) {
+				pdata->max_digits = strtoul (*attr_values + strlen (MAX_DIGITS_PIN_PREFIX), NULL, 0);
+				g_assert (pdata->max_digits > 0 && pdata->max_digits < PIN_NUM_DIGITS);
+			} else {
+				pdata->ret_pin = g_strdup (*attr_values);
+			}
 			return;
 		}
 
@@ -97,7 +106,7 @@ pin_db_parse_start_tag (GMarkupParseContext *ctx,
 }
 
 char *
-get_pincode_for_device (guint type, const char *address, const char *name)
+get_pincode_for_device (guint type, const char *address, const char *name, guint *max_digits)
 {
 	GMarkupParseContext *ctx;
 	GMarkupParser parser = { pin_db_parse_start_tag, NULL, NULL, NULL, NULL };
@@ -120,6 +129,7 @@ get_pincode_for_device (guint type, const char *address, const char *name)
 	}
 
 	data.ret_pin = NULL;
+	data.max_digits = 0;
 	data.type = type;
 	data.address = address;
 	data.name = name;
@@ -134,6 +144,9 @@ get_pincode_for_device (guint type, const char *address, const char *name)
 	g_markup_parse_context_free (ctx);
 	g_free (buf);
 
+	if (max_digits != NULL)
+		*max_digits = data.max_digits;
+
 	return data.ret_pin;
 }
 
diff --git a/wizard/pin.h b/wizard/pin.h
index d5fe0d1..aae8601 100644
--- a/wizard/pin.h
+++ b/wizard/pin.h
@@ -23,5 +23,7 @@
 
 #include <glib.h>
 
-char *get_pincode_for_device (guint type, const char *address, const char *name);
+#define PIN_NUM_DIGITS 6
+
+char *get_pincode_for_device (guint type, const char *address, const char *name, guint *max_digits);
 



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