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
32
#include <bluetooth-enums.h>
33
#include <bluetooth-utils.h>
37
#define PIN_CODE_DB "pin-code-database.xml"
38
#define MAX_DIGITS_PIN_PREFIX "max:"
41
oui_to_vendor (const char *oui)
44
struct udev_hwdb *hwdb;
45
struct udev_list_entry *list, *l;
57
hwdb = udev_hwdb_new (udev);
61
modalias = g_strdup_printf ("OUI:%c%c%c%c%c%c",
62
g_ascii_toupper (oui[0]),
63
g_ascii_toupper (oui[1]),
64
g_ascii_toupper (oui[3]),
65
g_ascii_toupper (oui[4]),
66
g_ascii_toupper (oui[6]),
67
g_ascii_toupper (oui[7]));
69
list = udev_hwdb_get_properties_list_entry (hwdb, modalias, 0);
71
udev_list_entry_foreach (l, list) {
72
const char *name = udev_list_entry_get_name (l);
74
if (g_strcmp0 (name, "ID_OUI_FROM_DATABASE") == 0) {
75
vendor = g_strdup (udev_list_entry_get_value (l));
81
g_clear_pointer (&modalias, g_free);
82
g_clear_pointer (&hwdb, udev_hwdb_unref);
83
g_clear_pointer (&udev, udev_unref);
88
#define TYPE_IS(x, r) { \
89
if (g_str_equal(type, x)) return r; \
92
static guint string_to_type(const char *type)
94
TYPE_IS ("any", BLUETOOTH_TYPE_ANY);
95
TYPE_IS ("mouse", BLUETOOTH_TYPE_MOUSE);
96
TYPE_IS ("tablet", BLUETOOTH_TYPE_TABLET);
97
TYPE_IS ("keyboard", BLUETOOTH_TYPE_KEYBOARD);
98
TYPE_IS ("headset", BLUETOOTH_TYPE_HEADSET);
99
TYPE_IS ("headphones", BLUETOOTH_TYPE_HEADPHONES);
100
TYPE_IS ("audio", BLUETOOTH_TYPE_OTHER_AUDIO);
101
TYPE_IS ("printer", BLUETOOTH_TYPE_PRINTER);
102
TYPE_IS ("network", BLUETOOTH_TYPE_NETWORK);
104
g_warning ("unhandled type '%s'", type);
105
return BLUETOOTH_TYPE_ANY;
117
pin_db_parse_start_tag (GMarkupParseContext *ctx,
118
const gchar *element_name,
119
const gchar **attr_names,
120
const gchar **attr_values,
124
PinParseData *pdata = (PinParseData *) data;
126
if (pdata->ret_pin != NULL || pdata->max_digits != 0)
128
if (g_str_equal (element_name, "device") == FALSE)
131
while (*attr_names && *attr_values) {
132
if (g_str_equal (*attr_names, "type")) {
135
type = string_to_type (*attr_values);
136
if (type != BLUETOOTH_TYPE_ANY && type != pdata->type)
138
} else if (g_str_equal (*attr_names, "oui")) {
139
if (g_str_has_prefix (pdata->address, *attr_values) == FALSE)
141
} else if (g_str_equal (*attr_names, "name")) {
142
if (*attr_values == NULL || pdata->name == NULL)
144
if (strstr (pdata->name, *attr_values) == NULL)
146
} else if (g_str_equal (*attr_names, "pin")) {
147
if (g_str_has_prefix (*attr_values, MAX_DIGITS_PIN_PREFIX) != FALSE) {
148
pdata->max_digits = strtoul (*attr_values + strlen (MAX_DIGITS_PIN_PREFIX), NULL, 0);
149
g_assert (pdata->max_digits > 0 && pdata->max_digits < PIN_NUM_DIGITS);
151
pdata->ret_pin = g_strdup (*attr_values);
162
get_pincode_for_device (guint type, const char *address, const char *name, guint *max_digits)
164
GMarkupParseContext *ctx;
165
GMarkupParser parser = { pin_db_parse_start_tag, NULL, NULL, NULL, NULL };
171
g_return_val_if_fail (address != NULL, NULL);
173
g_debug ("Getting pincode for device '%s' (type: %s address: %s)",
174
name ? name : "", address, bluetooth_type_to_string (type));
176
/* Load the PIN database and split it in lines */
177
if (!g_file_get_contents(PIN_CODE_DB, &buf, &buf_len, NULL)) {
180
filename = g_build_filename(PKGDATADIR, PIN_CODE_DB, NULL);
181
if (!g_file_get_contents(filename, &buf, &buf_len, NULL)) {
182
g_warning("Could not load "PIN_CODE_DB);
192
data.address = address;
195
ctx = g_markup_parse_context_new (&parser, 0, &data, NULL);
197
if (!g_markup_parse_context_parse (ctx, buf, buf_len, &err)) {
198
g_warning ("Failed to parse '%s': %s\n", PIN_CODE_DB, err->message);
202
g_markup_parse_context_free (ctx);
205
if (max_digits != NULL)
206
*max_digits = data.max_digits;
208
g_debug ("Got pin '%s' (max digits: %d) for device '%s' (type: %s address: %s)",
209
data.ret_pin, data.max_digits,
210
name ? name : "", address, bluetooth_type_to_string (type));