~ubuntu-branches/ubuntu/wily/gnome-bluetooth/wily

« back to all changes in this revision

Viewing changes to .pc/git_add_vendor_attribute_support_49b84e8.patch/wizard/pin.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2014-07-10 16:37:02 UTC
  • Revision ID: package-import@ubuntu.com-20140710163702-obu3c4a7xs92tm9y
Tags: 3.8.2.1-0ubuntu7
* debian/control.in:
  - remove Build-Depends on nautilus-sendto.
  - add libudev-dev to Build-Depends.
* debian/gnome-bluetooth.install:
  - stop installing the nautilus-sendto plugin, it's no longer being built
    due to nautilus-sendto not providing API.
  - don't try to install gconf settings.
* debian/patches/git_add_vendor_attribute_support_49b84e8.patch,
  debian/patches/git_vendor_from_oui_helper_90423abf.patch: cherry-pick
  patches to allow specifying devices by vendor, and as such update the
  pin database.
* debian/patches/logitech_ultrathin_touch_pin.patch: specify a default PIN
  for the Logitech Ultrathin Touch mice. Thanks to Ralph Meijer for the
  patch. (LP: #1237355)
* debian/patches/pin_code_database_update.patch: update the PIN database
  from git.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *  BlueZ - Bluetooth protocol stack for Linux
 
4
 *
 
5
 *  Copyright (C) 2009  Bastien Nocera <hadess@hadess.net>
 
6
 *
 
7
 *
 
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.
 
12
 *
 
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.
 
17
 *
 
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
 
21
 *
 
22
 */
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#include <config.h>
 
26
#endif
 
27
 
 
28
#include <stdlib.h>
 
29
#include <string.h>
 
30
#include <glib.h>
 
31
#include <libudev.h>
 
32
#include <bluetooth-enums.h>
 
33
#include <bluetooth-utils.h>
 
34
 
 
35
#include "pin.h"
 
36
 
 
37
#define PIN_CODE_DB "pin-code-database.xml"
 
38
#define MAX_DIGITS_PIN_PREFIX "max:"
 
39
 
 
40
char *
 
41
oui_to_vendor (const char *oui)
 
42
{
 
43
        struct udev *udev;
 
44
        struct udev_hwdb *hwdb;
 
45
        struct udev_list_entry *list, *l;
 
46
        char *modalias;
 
47
        char *vendor = NULL;
 
48
 
 
49
        if (oui == NULL ||
 
50
            strlen (oui) < 8)
 
51
                return NULL;
 
52
 
 
53
        udev = udev_new ();
 
54
        if (udev == NULL)
 
55
                goto bail;
 
56
 
 
57
        hwdb = udev_hwdb_new (udev);
 
58
        if (hwdb == NULL)
 
59
                goto bail;
 
60
 
 
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]));
 
68
 
 
69
        list = udev_hwdb_get_properties_list_entry (hwdb, modalias, 0);
 
70
 
 
71
        udev_list_entry_foreach (l, list) {
 
72
                const char *name = udev_list_entry_get_name (l);
 
73
 
 
74
                if (g_strcmp0 (name, "ID_OUI_FROM_DATABASE") == 0) {
 
75
                        vendor = g_strdup (udev_list_entry_get_value (l));
 
76
                        break;
 
77
                }
 
78
        }
 
79
 
 
80
bail:
 
81
        g_clear_pointer (&modalias, g_free);
 
82
        g_clear_pointer (&hwdb, udev_hwdb_unref);
 
83
        g_clear_pointer (&udev, udev_unref);
 
84
 
 
85
        return vendor;
 
86
}
 
87
 
 
88
#define TYPE_IS(x, r) {                         \
 
89
        if (g_str_equal(type, x)) return r;     \
 
90
}
 
91
 
 
92
static guint string_to_type(const char *type)
 
93
{
 
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);
 
103
 
 
104
        g_warning ("unhandled type '%s'", type);
 
105
        return BLUETOOTH_TYPE_ANY;
 
106
}
 
107
 
 
108
typedef struct {
 
109
        char *ret_pin;
 
110
        guint max_digits;
 
111
        guint type;
 
112
        const char *address;
 
113
        const char *name;
 
114
} PinParseData;
 
115
 
 
116
static void
 
117
pin_db_parse_start_tag (GMarkupParseContext *ctx,
 
118
                        const gchar         *element_name,
 
119
                        const gchar        **attr_names,
 
120
                        const gchar        **attr_values,
 
121
                        gpointer             data,
 
122
                        GError             **error)
 
123
{
 
124
        PinParseData *pdata = (PinParseData *) data;
 
125
 
 
126
        if (pdata->ret_pin != NULL || pdata->max_digits != 0)
 
127
                return;
 
128
        if (g_str_equal (element_name, "device") == FALSE)
 
129
                return;
 
130
 
 
131
        while (*attr_names && *attr_values) {
 
132
                if (g_str_equal (*attr_names, "type")) {
 
133
                        guint type;
 
134
 
 
135
                        type = string_to_type (*attr_values);
 
136
                        if (type != BLUETOOTH_TYPE_ANY && type != pdata->type)
 
137
                                return;
 
138
                } else if (g_str_equal (*attr_names, "oui")) {
 
139
                        if (g_str_has_prefix (pdata->address, *attr_values) == FALSE)
 
140
                                return;
 
141
                } else if (g_str_equal (*attr_names, "name")) {
 
142
                        if (*attr_values == NULL || pdata->name == NULL)
 
143
                                return;
 
144
                        if (strstr (pdata->name, *attr_values) == NULL)
 
145
                                return;
 
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);
 
150
                        } else {
 
151
                                pdata->ret_pin = g_strdup (*attr_values);
 
152
                        }
 
153
                        return;
 
154
                }
 
155
 
 
156
                ++attr_names;
 
157
                ++attr_values;
 
158
        }
 
159
}
 
160
 
 
161
char *
 
162
get_pincode_for_device (guint type, const char *address, const char *name, guint *max_digits)
 
163
{
 
164
        GMarkupParseContext *ctx;
 
165
        GMarkupParser parser = { pin_db_parse_start_tag, NULL, NULL, NULL, NULL };
 
166
        PinParseData data;
 
167
        char *buf;
 
168
        gsize buf_len;
 
169
        GError *err = NULL;
 
170
 
 
171
        g_return_val_if_fail (address != NULL, NULL);
 
172
 
 
173
        g_debug ("Getting pincode for device '%s' (type: %s address: %s)",
 
174
                 name ? name : "", address, bluetooth_type_to_string (type));
 
175
 
 
176
        /* Load the PIN database and split it in lines */
 
177
        if (!g_file_get_contents(PIN_CODE_DB, &buf, &buf_len, NULL)) {
 
178
                char *filename;
 
179
 
 
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);
 
183
                        g_free (filename);
 
184
                        return NULL;
 
185
                }
 
186
                g_free (filename);
 
187
        }
 
188
 
 
189
        data.ret_pin = NULL;
 
190
        data.max_digits = 0;
 
191
        data.type = type;
 
192
        data.address = address;
 
193
        data.name = name;
 
194
 
 
195
        ctx = g_markup_parse_context_new (&parser, 0, &data, NULL);
 
196
 
 
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);
 
199
                g_error_free (err);
 
200
        }
 
201
 
 
202
        g_markup_parse_context_free (ctx);
 
203
        g_free (buf);
 
204
 
 
205
        if (max_digits != NULL)
 
206
                *max_digits = data.max_digits;
 
207
 
 
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));
 
211
 
 
212
        return data.ret_pin;
 
213
}
 
214