3
* BlueZ - Bluetooth protocol stack for Linux
5
* Copyright (C) 2009 Bastien Nocera <hadess@hadess.net>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31
#include <bluetooth-enums.h>
32
#include <bluetooth-utils.h>
36
#define PIN_CODE_DB "pin-code-database.xml"
37
#define MAX_DIGITS_PIN_PREFIX "max:"
39
#define TYPE_IS(x, r) { \
40
if (g_str_equal(type, x)) return r; \
43
static guint string_to_type(const char *type)
45
TYPE_IS ("any", BLUETOOTH_TYPE_ANY);
46
TYPE_IS ("mouse", BLUETOOTH_TYPE_MOUSE);
47
TYPE_IS ("tablet", BLUETOOTH_TYPE_TABLET);
48
TYPE_IS ("keyboard", BLUETOOTH_TYPE_KEYBOARD);
49
TYPE_IS ("headset", BLUETOOTH_TYPE_HEADSET);
50
TYPE_IS ("headphones", BLUETOOTH_TYPE_HEADPHONES);
51
TYPE_IS ("audio", BLUETOOTH_TYPE_OTHER_AUDIO);
52
TYPE_IS ("printer", BLUETOOTH_TYPE_PRINTER);
53
TYPE_IS ("network", BLUETOOTH_TYPE_NETWORK);
55
g_warning ("unhandled type '%s'", type);
56
return BLUETOOTH_TYPE_ANY;
69
pin_db_parse_start_tag (GMarkupParseContext *ctx,
70
const gchar *element_name,
71
const gchar **attr_names,
72
const gchar **attr_values,
76
PinParseData *pdata = (PinParseData *) data;
78
if (pdata->ret_pin != NULL || pdata->max_digits != 0)
80
if (g_str_equal (element_name, "device") == FALSE)
83
while (*attr_names && *attr_values) {
84
if (g_str_equal (*attr_names, "type")) {
87
type = string_to_type (*attr_values);
88
if (type != BLUETOOTH_TYPE_ANY && type != pdata->type)
90
} else if (g_str_equal (*attr_names, "oui")) {
91
if (g_str_has_prefix (pdata->address, *attr_values) == FALSE)
93
} else if (g_str_equal (*attr_names, "name")) {
94
if (*attr_values == NULL || pdata->name == NULL)
96
if (strstr (pdata->name, *attr_values) == NULL)
98
pdata->confirm = FALSE;
99
} else if (g_str_equal (*attr_names, "pin")) {
100
if (g_str_has_prefix (*attr_values, MAX_DIGITS_PIN_PREFIX) != FALSE) {
101
pdata->max_digits = strtoul (*attr_values + strlen (MAX_DIGITS_PIN_PREFIX), NULL, 0);
102
g_assert (pdata->max_digits > 0 && pdata->max_digits < PIN_NUM_DIGITS);
104
pdata->ret_pin = g_strdup (*attr_values);
115
get_pincode_for_device (guint type,
121
GMarkupParseContext *ctx;
122
GMarkupParser parser = { pin_db_parse_start_tag, NULL, NULL, NULL, NULL };
128
g_return_val_if_fail (address != NULL, NULL);
130
g_debug ("Getting pincode for device '%s' (type: %s address: %s)",
131
name ? name : "", address, bluetooth_type_to_string (type));
133
/* Load the PIN database and split it in lines */
134
if (!g_file_get_contents(PIN_CODE_DB, &buf, &buf_len, NULL)) {
137
filename = g_build_filename(PKGDATADIR, PIN_CODE_DB, NULL);
138
if (!g_file_get_contents(filename, &buf, &buf_len, NULL)) {
139
g_warning("Could not load "PIN_CODE_DB);
149
data.address = address;
153
ctx = g_markup_parse_context_new (&parser, 0, &data, NULL);
155
if (!g_markup_parse_context_parse (ctx, buf, buf_len, &err)) {
156
g_warning ("Failed to parse '%s': %s\n", PIN_CODE_DB, err->message);
160
g_markup_parse_context_free (ctx);
163
if (max_digits != NULL)
164
*max_digits = data.max_digits;
166
*confirm = data.confirm;
168
g_debug ("Got pin '%s' (max digits: %d) for device '%s' (type: %s address: %s)",
169
data.ret_pin, data.max_digits,
170
name ? name : "", bluetooth_type_to_string (type), address);