~bluetooth/bluez/import-mer-patches

« back to all changes in this revision

Viewing changes to .pc/reauthentication-after-link-key-rejection.patch/src/device.c

  • Committer: Simon Fels
  • Date: 2015-09-11 09:01:46 UTC
  • Revision ID: morphis@gravedo.de-20150911090146-4c0ln9s7ec3xf0nx
Import package bluez_4.101-0ubuntu25.1~overlay4 from stable phone overlay PPA

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) 2006-2010  Nokia Corporation
 
6
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
 
7
 *
 
8
 *
 
9
 *  This program is free software; you can redistribute it and/or modify
 
10
 *  it under the terms of the GNU General Public License as published by
 
11
 *  the Free Software Foundation; either version 2 of the License, or
 
12
 *  (at your option) any later version.
 
13
 *
 
14
 *  This program is distributed in the hope that it will be useful,
 
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 *  GNU General Public License for more details.
 
18
 *
 
19
 *  You should have received a copy of the GNU General Public License
 
20
 *  along with this program; if not, write to the Free Software
 
21
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
22
 *
 
23
 */
 
24
 
 
25
#ifdef HAVE_CONFIG_H
 
26
#include <config.h>
 
27
#endif
 
28
 
 
29
#include <stdio.h>
 
30
#include <stdlib.h>
 
31
#include <unistd.h>
 
32
#include <fcntl.h>
 
33
#include <sys/stat.h>
 
34
#include <sys/ioctl.h>
 
35
#include <errno.h>
 
36
 
 
37
#include <bluetooth/bluetooth.h>
 
38
#include <bluetooth/uuid.h>
 
39
#include <bluetooth/sdp.h>
 
40
#include <bluetooth/sdp_lib.h>
 
41
 
 
42
#include <glib.h>
 
43
#include <dbus/dbus.h>
 
44
#include <gdbus.h>
 
45
 
 
46
#include "log.h"
 
47
 
 
48
#include "att.h"
 
49
#include "hcid.h"
 
50
#include "adapter.h"
 
51
#include "gattrib.h"
 
52
#include "attio.h"
 
53
#include "device.h"
 
54
#include "dbus-common.h"
 
55
#include "error.h"
 
56
#include "glib-helper.h"
 
57
#include "sdp-client.h"
 
58
#include "gatt.h"
 
59
#include "agent.h"
 
60
#include "sdp-xml.h"
 
61
#include "storage.h"
 
62
#include "btio.h"
 
63
#include "attrib-server.h"
 
64
#include "attrib/client.h"
 
65
 
 
66
#define DISCONNECT_TIMER        2
 
67
#define DISCOVERY_TIMER         2
 
68
 
 
69
#define AUTO_CONNECTION_INTERVAL        5 /* Next connection attempt */
 
70
 
 
71
/* When all services should trust a remote device */
 
72
#define GLOBAL_TRUST "[all]"
 
73
 
 
74
#define APPEARANCE_CHR_UUID 0x2a01
 
75
 
 
76
struct btd_disconnect_data {
 
77
        guint id;
 
78
        disconnect_watch watch;
 
79
        void *user_data;
 
80
        GDestroyNotify destroy;
 
81
};
 
82
 
 
83
struct bonding_req {
 
84
        DBusConnection *conn;
 
85
        DBusMessage *msg;
 
86
        guint listener_id;
 
87
        struct btd_device *device;
 
88
};
 
89
 
 
90
struct authentication_req {
 
91
        auth_type_t type;
 
92
        void *cb;
 
93
        struct agent *agent;
 
94
        struct btd_device *device;
 
95
        uint32_t passkey;
 
96
        char *pincode;
 
97
        gboolean secure;
 
98
};
 
99
 
 
100
struct browse_req {
 
101
        DBusConnection *conn;
 
102
        DBusMessage *msg;
 
103
        struct btd_device *device;
 
104
        GSList *match_uuids;
 
105
        GSList *profiles_added;
 
106
        GSList *profiles_removed;
 
107
        sdp_list_t *records;
 
108
        int search_uuid;
 
109
        int reconnect_attempt;
 
110
        guint listener_id;
 
111
};
 
112
 
 
113
struct attio_data {
 
114
        guint id;
 
115
        attio_connect_cb cfunc;
 
116
        attio_disconnect_cb dcfunc;
 
117
        gpointer user_data;
 
118
};
 
119
 
 
120
typedef void (*attio_error_cb) (const GError *gerr, gpointer user_data);
 
121
typedef void (*attio_success_cb) (gpointer user_data);
 
122
 
 
123
struct att_callbacks {
 
124
        attio_error_cb error;           /* Callback for error */
 
125
        attio_success_cb success;       /* Callback for success */
 
126
        gpointer user_data;
 
127
};
 
128
 
 
129
struct btd_device {
 
130
        bdaddr_t        bdaddr;
 
131
        uint8_t         bdaddr_type;
 
132
        gchar           *path;
 
133
        char            name[MAX_NAME_LENGTH + 1];
 
134
        char            *alias;
 
135
        uint16_t        vendor_src;
 
136
        uint16_t        vendor;
 
137
        uint16_t        product;
 
138
        uint16_t        version;
 
139
        struct btd_adapter      *adapter;
 
140
        GSList          *uuids;
 
141
        GSList          *services;              /* Primary services path */
 
142
        GSList          *primaries;             /* List of primary services */
 
143
        GSList          *drivers;               /* List of device drivers */
 
144
        GSList          *watches;               /* List of disconnect_data */
 
145
        gboolean        temporary;
 
146
        struct agent    *agent;
 
147
        guint           disconn_timer;
 
148
        guint           discov_timer;
 
149
        struct browse_req *browse;              /* service discover request */
 
150
        struct bonding_req *bonding;
 
151
        struct authentication_req *authr;       /* authentication request */
 
152
        GSList          *disconnects;           /* disconnects message */
 
153
        GAttrib         *attrib;
 
154
        GSList          *attios;
 
155
        GSList          *attios_offline;
 
156
        guint           attachid;               /* Attrib server attach */
 
157
        guint           auto_id;                /* Auto connect source id */
 
158
 
 
159
        gboolean        connected;
 
160
 
 
161
        sdp_list_t      *tmp_records;
 
162
 
 
163
        gboolean        trusted;
 
164
        gboolean        paired;
 
165
        gboolean        blocked;
 
166
        gboolean        bonded;
 
167
        gboolean        auto_connect;
 
168
 
 
169
        gboolean        authorizing;
 
170
        gint            ref;
 
171
 
 
172
        GIOChannel      *att_io;
 
173
        guint           cleanup_id;
 
174
};
 
175
 
 
176
static uint16_t uuid_list[] = {
 
177
        L2CAP_UUID,
 
178
        PNP_INFO_SVCLASS_ID,
 
179
        PUBLIC_BROWSE_GROUP,
 
180
        0
 
181
};
 
182
 
 
183
static GSList *device_drivers = NULL;
 
184
 
 
185
static void browse_request_free(struct browse_req *req)
 
186
{
 
187
        if (req->listener_id)
 
188
                g_dbus_remove_watch(req->conn, req->listener_id);
 
189
        if (req->msg)
 
190
                dbus_message_unref(req->msg);
 
191
        if (req->conn)
 
192
                dbus_connection_unref(req->conn);
 
193
        if (req->device)
 
194
                btd_device_unref(req->device);
 
195
        g_slist_free_full(req->profiles_added, g_free);
 
196
        g_slist_free(req->profiles_removed);
 
197
        if (req->records)
 
198
                sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
 
199
 
 
200
        g_free(req);
 
201
}
 
202
 
 
203
static void att_cleanup(struct btd_device *device)
 
204
{
 
205
        if (device->attachid) {
 
206
                attrib_channel_detach(device->attrib, device->attachid);
 
207
                device->attachid = 0;
 
208
        }
 
209
 
 
210
        if (device->cleanup_id) {
 
211
                g_source_remove(device->cleanup_id);
 
212
                device->cleanup_id = 0;
 
213
        }
 
214
 
 
215
        if (device->att_io) {
 
216
                g_io_channel_shutdown(device->att_io, FALSE, NULL);
 
217
                g_io_channel_unref(device->att_io);
 
218
                device->att_io = NULL;
 
219
        }
 
220
 
 
221
        if (device->attrib) {
 
222
                g_attrib_unref(device->attrib);
 
223
                device->attrib = NULL;
 
224
        }
 
225
}
 
226
 
 
227
static void browse_request_cancel(struct browse_req *req)
 
228
{
 
229
        struct btd_device *device = req->device;
 
230
        struct btd_adapter *adapter = device->adapter;
 
231
        bdaddr_t src;
 
232
 
 
233
        if (device_is_creating(device, NULL))
 
234
                device_set_temporary(device, TRUE);
 
235
 
 
236
        adapter_get_address(adapter, &src);
 
237
 
 
238
        bt_cancel_discovery(&src, &device->bdaddr);
 
239
 
 
240
        att_cleanup(device);
 
241
 
 
242
        device->browse = NULL;
 
243
        browse_request_free(req);
 
244
}
 
245
 
 
246
static void device_free(gpointer user_data)
 
247
{
 
248
        struct btd_device *device = user_data;
 
249
        struct btd_adapter *adapter = device->adapter;
 
250
        struct agent *agent = adapter_get_agent(adapter);
 
251
 
 
252
        if (device->agent)
 
253
                agent_free(device->agent);
 
254
 
 
255
        if (agent && (agent_is_busy(agent, device) ||
 
256
                                agent_is_busy(agent, device->authr)))
 
257
                agent_cancel(agent);
 
258
 
 
259
        g_slist_free_full(device->services, g_free);
 
260
        g_slist_free_full(device->uuids, g_free);
 
261
        g_slist_free_full(device->primaries, g_free);
 
262
        g_slist_free_full(device->attios, g_free);
 
263
        g_slist_free_full(device->attios_offline, g_free);
 
264
 
 
265
        att_cleanup(device);
 
266
 
 
267
        if (device->tmp_records)
 
268
                sdp_list_free(device->tmp_records,
 
269
                                        (sdp_free_func_t) sdp_record_free);
 
270
 
 
271
        if (device->disconn_timer)
 
272
                g_source_remove(device->disconn_timer);
 
273
 
 
274
        if (device->discov_timer)
 
275
                g_source_remove(device->discov_timer);
 
276
 
 
277
        if (device->auto_id)
 
278
                g_source_remove(device->auto_id);
 
279
 
 
280
        DBG("%p", device);
 
281
 
 
282
        if (device->authr)
 
283
                g_free(device->authr->pincode);
 
284
        g_free(device->authr);
 
285
        g_free(device->path);
 
286
        g_free(device->alias);
 
287
        g_free(device);
 
288
}
 
289
 
 
290
gboolean device_is_bredr(struct btd_device *device)
 
291
{
 
292
        return (device->bdaddr_type == BDADDR_BREDR);
 
293
}
 
294
 
 
295
gboolean device_is_le(struct btd_device *device)
 
296
{
 
297
        return (device->bdaddr_type != BDADDR_BREDR);
 
298
}
 
299
 
 
300
gboolean device_is_paired(struct btd_device *device)
 
301
{
 
302
        return device->paired;
 
303
}
 
304
 
 
305
gboolean device_is_bonded(struct btd_device *device)
 
306
{
 
307
        return device->bonded;
 
308
}
 
309
 
 
310
gboolean device_is_trusted(struct btd_device *device)
 
311
{
 
312
        return device->trusted;
 
313
}
 
314
 
 
315
static DBusMessage *get_properties(DBusConnection *conn,
 
316
                                DBusMessage *msg, void *user_data)
 
317
{
 
318
        struct btd_device *device = user_data;
 
319
        struct btd_adapter *adapter = device->adapter;
 
320
        DBusMessage *reply;
 
321
        DBusMessageIter iter;
 
322
        DBusMessageIter dict;
 
323
        bdaddr_t src;
 
324
        char name[MAX_NAME_LENGTH + 1], srcaddr[18], dstaddr[18];
 
325
        char **str;
 
326
        const char *ptr, *icon = NULL;
 
327
        dbus_bool_t boolean;
 
328
        uint32_t class;
 
329
        uint16_t app;
 
330
        int i;
 
331
        GSList *l;
 
332
 
 
333
        ba2str(&device->bdaddr, dstaddr);
 
334
 
 
335
        reply = dbus_message_new_method_return(msg);
 
336
        if (!reply)
 
337
                return NULL;
 
338
 
 
339
        dbus_message_iter_init_append(reply, &iter);
 
340
 
 
341
        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
 
342
                        DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
 
343
                        DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
 
344
                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
 
345
 
 
346
        /* Address */
 
347
        ptr = dstaddr;
 
348
        dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr);
 
349
 
 
350
        /* Name */
 
351
        ptr = NULL;
 
352
        memset(name, 0, sizeof(name));
 
353
        adapter_get_address(adapter, &src);
 
354
        ba2str(&src, srcaddr);
 
355
 
 
356
        ptr = device->name;
 
357
        dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr);
 
358
 
 
359
        /* Alias (fallback to name or address) */
 
360
        if (device->alias != NULL)
 
361
                ptr = device->alias;
 
362
        else if (strlen(ptr) == 0) {
 
363
                g_strdelimit(dstaddr, ":", '-');
 
364
                ptr = dstaddr;
 
365
        }
 
366
 
 
367
        dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr);
 
368
 
 
369
        /* Class */
 
370
        if (read_remote_class(&src, &device->bdaddr, &class) == 0) {
 
371
                icon = class_to_icon(class);
 
372
 
 
373
                dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class);
 
374
        } else if (read_remote_appearance(&src, &device->bdaddr,
 
375
                                                device->bdaddr_type, &app) == 0)
 
376
                /* Appearance */
 
377
                icon = gap_appearance_to_icon(app);
 
378
 
 
379
        dict_append_entry(&dict, "Icon", DBUS_TYPE_STRING, &icon);
 
380
 
 
381
        /* Vendor */
 
382
        if (device->vendor)
 
383
                dict_append_entry(&dict, "Vendor", DBUS_TYPE_UINT16,
 
384
                                                        &device->vendor);
 
385
 
 
386
        /* Vendor Source*/
 
387
        if (device->vendor_src)
 
388
                dict_append_entry(&dict, "VendorSource", DBUS_TYPE_UINT16,
 
389
                                                        &device->vendor_src);
 
390
 
 
391
        /* Product */
 
392
        if (device->product)
 
393
                dict_append_entry(&dict, "Product", DBUS_TYPE_UINT16,
 
394
                                                        &device->product);
 
395
 
 
396
        /* Version */
 
397
        if (device->version)
 
398
                dict_append_entry(&dict, "Version", DBUS_TYPE_UINT16,
 
399
                                                        &device->version);
 
400
 
 
401
        /* Paired */
 
402
        boolean = device_is_paired(device);
 
403
        dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean);
 
404
 
 
405
        /* Trusted */
 
406
        boolean = device_is_trusted(device);
 
407
        dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean);
 
408
 
 
409
        /* Blocked */
 
410
        boolean = device->blocked;
 
411
        dict_append_entry(&dict, "Blocked", DBUS_TYPE_BOOLEAN, &boolean);
 
412
 
 
413
        /* Connected */
 
414
        dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN,
 
415
                                                        &device->connected);
 
416
 
 
417
        /* UUIDs */
 
418
        str = g_new0(char *, g_slist_length(device->uuids) + 1);
 
419
        for (i = 0, l = device->uuids; l; l = l->next, i++)
 
420
                str[i] = l->data;
 
421
        dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &str, i);
 
422
        g_free(str);
 
423
 
 
424
        /* Services */
 
425
        str = g_new0(char *, g_slist_length(device->services) + 1);
 
426
        for (i = 0, l = device->services; l; l = l->next, i++)
 
427
                str[i] = l->data;
 
428
        dict_append_array(&dict, "Services", DBUS_TYPE_OBJECT_PATH, &str, i);
 
429
        g_free(str);
 
430
 
 
431
        /* Adapter */
 
432
        ptr = adapter_get_path(adapter);
 
433
        dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr);
 
434
 
 
435
        dbus_message_iter_close_container(&iter, &dict);
 
436
 
 
437
        return reply;
 
438
}
 
439
 
 
440
static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
 
441
                                        const char *alias, void *data)
 
442
{
 
443
        struct btd_device *device = data;
 
444
        struct btd_adapter *adapter = device->adapter;
 
445
        char srcaddr[18], dstaddr[18];
 
446
        bdaddr_t src;
 
447
        int err;
 
448
 
 
449
        /* No change */
 
450
        if ((device->alias == NULL && g_str_equal(alias, "")) ||
 
451
                        g_strcmp0(device->alias, alias) == 0)
 
452
                return dbus_message_new_method_return(msg);
 
453
 
 
454
        adapter_get_address(adapter, &src);
 
455
        ba2str(&src, srcaddr);
 
456
        ba2str(&device->bdaddr, dstaddr);
 
457
 
 
458
        /* Remove alias if empty string */
 
459
        err = write_device_alias(srcaddr, dstaddr,
 
460
                        g_str_equal(alias, "") ? NULL : alias);
 
461
        if (err < 0)
 
462
                return btd_error_failed(msg, strerror(-err));
 
463
 
 
464
        g_free(device->alias);
 
465
        device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
 
466
 
 
467
        emit_property_changed(conn, dbus_message_get_path(msg),
 
468
                                DEVICE_INTERFACE, "Alias",
 
469
                                DBUS_TYPE_STRING, &alias);
 
470
 
 
471
        return dbus_message_new_method_return(msg);
 
472
}
 
473
 
 
474
static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
 
475
                                        gboolean value, void *data)
 
476
{
 
477
        struct btd_device *device = data;
 
478
        struct btd_adapter *adapter = device->adapter;
 
479
        char srcaddr[18], dstaddr[18];
 
480
        bdaddr_t src;
 
481
        int err;
 
482
 
 
483
        if (device->trusted == value)
 
484
                return dbus_message_new_method_return(msg);
 
485
 
 
486
        adapter_get_address(adapter, &src);
 
487
        ba2str(&src, srcaddr);
 
488
        ba2str(&device->bdaddr, dstaddr);
 
489
 
 
490
        err = write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value);
 
491
        if (err < 0)
 
492
                return btd_error_failed(msg, strerror(-err));
 
493
 
 
494
        device->trusted = value;
 
495
 
 
496
        emit_property_changed(conn, dbus_message_get_path(msg),
 
497
                                DEVICE_INTERFACE, "Trusted",
 
498
                                DBUS_TYPE_BOOLEAN, &value);
 
499
 
 
500
        return dbus_message_new_method_return(msg);
 
501
}
 
502
 
 
503
static void driver_remove(struct btd_device_driver *driver,
 
504
                                                struct btd_device *device)
 
505
{
 
506
        driver->remove(device);
 
507
 
 
508
        device->drivers = g_slist_remove(device->drivers, driver);
 
509
}
 
510
 
 
511
static gboolean do_disconnect(gpointer user_data)
 
512
{
 
513
        struct btd_device *device = user_data;
 
514
 
 
515
        device->disconn_timer = 0;
 
516
 
 
517
        btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
 
518
                                                        device->bdaddr_type);
 
519
 
 
520
        return FALSE;
 
521
}
 
522
 
 
523
int device_block(DBusConnection *conn, struct btd_device *device,
 
524
                                                gboolean update_only)
 
525
{
 
526
        int err = 0;
 
527
        bdaddr_t src;
 
528
 
 
529
        if (device->blocked)
 
530
                return 0;
 
531
 
 
532
        if (device->connected)
 
533
                do_disconnect(device);
 
534
 
 
535
        g_slist_foreach(device->drivers, (GFunc) driver_remove, device);
 
536
 
 
537
        if (!update_only)
 
538
                err = btd_adapter_block_address(device->adapter,
 
539
                                        &device->bdaddr, device->bdaddr_type);
 
540
 
 
541
        if (err < 0)
 
542
                return err;
 
543
 
 
544
        device->blocked = TRUE;
 
545
 
 
546
        adapter_get_address(device->adapter, &src);
 
547
 
 
548
        err = write_blocked(&src, &device->bdaddr, TRUE);
 
549
        if (err < 0)
 
550
                error("write_blocked(): %s (%d)", strerror(-err), -err);
 
551
 
 
552
        device_set_temporary(device, FALSE);
 
553
 
 
554
        emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Blocked",
 
555
                                        DBUS_TYPE_BOOLEAN, &device->blocked);
 
556
 
 
557
        return 0;
 
558
}
 
559
 
 
560
int device_unblock(DBusConnection *conn, struct btd_device *device,
 
561
                                gboolean silent, gboolean update_only)
 
562
{
 
563
        int err = 0;
 
564
        bdaddr_t src;
 
565
 
 
566
        if (!device->blocked)
 
567
                return 0;
 
568
 
 
569
        if (!update_only)
 
570
                err = btd_adapter_unblock_address(device->adapter,
 
571
                                        &device->bdaddr, device->bdaddr_type);
 
572
 
 
573
        if (err < 0)
 
574
                return err;
 
575
 
 
576
        device->blocked = FALSE;
 
577
 
 
578
        adapter_get_address(device->adapter, &src);
 
579
 
 
580
        err = write_blocked(&src, &device->bdaddr, FALSE);
 
581
        if (err < 0)
 
582
                error("write_blocked(): %s (%d)", strerror(-err), -err);
 
583
 
 
584
        if (!silent) {
 
585
                emit_property_changed(conn, device->path,
 
586
                                        DEVICE_INTERFACE, "Blocked",
 
587
                                        DBUS_TYPE_BOOLEAN, &device->blocked);
 
588
                device_probe_drivers(device, device->uuids);
 
589
        }
 
590
 
 
591
        return 0;
 
592
}
 
593
 
 
594
static DBusMessage *set_blocked(DBusConnection *conn, DBusMessage *msg,
 
595
                                                gboolean value, void *data)
 
596
{
 
597
        struct btd_device *device = data;
 
598
        int err;
 
599
 
 
600
        if (value)
 
601
                err = device_block(conn, device, FALSE);
 
602
        else
 
603
                err = device_unblock(conn, device, FALSE, FALSE);
 
604
 
 
605
        switch (-err) {
 
606
        case 0:
 
607
                return dbus_message_new_method_return(msg);
 
608
        case EINVAL:
 
609
                return btd_error_failed(msg, "Kernel lacks blacklist support");
 
610
        default:
 
611
                return btd_error_failed(msg, strerror(-err));
 
612
        }
 
613
}
 
614
 
 
615
static DBusMessage *set_property(DBusConnection *conn,
 
616
                                DBusMessage *msg, void *data)
 
617
{
 
618
        DBusMessageIter iter;
 
619
        DBusMessageIter sub;
 
620
        const char *property;
 
621
 
 
622
        if (!dbus_message_iter_init(msg, &iter))
 
623
                return btd_error_invalid_args(msg);
 
624
 
 
625
        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
 
626
                return btd_error_invalid_args(msg);
 
627
 
 
628
        dbus_message_iter_get_basic(&iter, &property);
 
629
        dbus_message_iter_next(&iter);
 
630
 
 
631
        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
 
632
                return btd_error_invalid_args(msg);
 
633
        dbus_message_iter_recurse(&iter, &sub);
 
634
 
 
635
        if (g_str_equal("Trusted", property)) {
 
636
                dbus_bool_t value;
 
637
                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
 
638
                        return btd_error_invalid_args(msg);
 
639
                dbus_message_iter_get_basic(&sub, &value);
 
640
 
 
641
                return set_trust(conn, msg, value, data);
 
642
        } else if (g_str_equal("Alias", property)) {
 
643
                const char *alias;
 
644
 
 
645
                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
 
646
                        return btd_error_invalid_args(msg);
 
647
                dbus_message_iter_get_basic(&sub, &alias);
 
648
 
 
649
                return set_alias(conn, msg, alias, data);
 
650
        } else if (g_str_equal("Blocked", property)) {
 
651
                dbus_bool_t value;
 
652
 
 
653
                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
 
654
                        return btd_error_invalid_args(msg);
 
655
 
 
656
                dbus_message_iter_get_basic(&sub, &value);
 
657
 
 
658
                return set_blocked(conn, msg, value, data);
 
659
        }
 
660
 
 
661
        return btd_error_invalid_args(msg);
 
662
}
 
663
 
 
664
static void discover_services_req_exit(DBusConnection *conn, void *user_data)
 
665
{
 
666
        struct browse_req *req = user_data;
 
667
 
 
668
        DBG("DiscoverServices requestor exited");
 
669
 
 
670
        browse_request_cancel(req);
 
671
}
 
672
 
 
673
static DBusMessage *discover_services(DBusConnection *conn,
 
674
                                        DBusMessage *msg, void *user_data)
 
675
{
 
676
        struct btd_device *device = user_data;
 
677
        const char *pattern;
 
678
        int err;
 
679
 
 
680
        if (device->browse)
 
681
                return btd_error_in_progress(msg);
 
682
 
 
683
        if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
 
684
                                                DBUS_TYPE_INVALID) == FALSE)
 
685
                return btd_error_invalid_args(msg);
 
686
 
 
687
        if (strlen(pattern) == 0) {
 
688
                err = device_browse_sdp(device, conn, msg, NULL, FALSE);
 
689
                if (err < 0)
 
690
                        goto fail;
 
691
        } else {
 
692
                uuid_t uuid;
 
693
 
 
694
                if (bt_string2uuid(&uuid, pattern) < 0)
 
695
                        return btd_error_invalid_args(msg);
 
696
 
 
697
                sdp_uuid128_to_uuid(&uuid);
 
698
 
 
699
                err = device_browse_sdp(device, conn, msg, &uuid, FALSE);
 
700
                if (err < 0)
 
701
                        goto fail;
 
702
        }
 
703
 
 
704
        return NULL;
 
705
 
 
706
fail:
 
707
        return btd_error_failed(msg, strerror(-err));
 
708
}
 
709
 
 
710
static const char *browse_request_get_requestor(struct browse_req *req)
 
711
{
 
712
        if (!req->msg)
 
713
                return NULL;
 
714
 
 
715
        return dbus_message_get_sender(req->msg);
 
716
}
 
717
 
 
718
static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
 
719
                                                        const char *record)
 
720
{
 
721
        DBusMessageIter entry;
 
722
 
 
723
        dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
 
724
                                                        NULL, &entry);
 
725
 
 
726
        dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
 
727
 
 
728
        dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
 
729
 
 
730
        dbus_message_iter_close_container(dict, &entry);
 
731
}
 
732
 
 
733
static void discover_services_reply(struct browse_req *req, int err,
 
734
                                                        sdp_list_t *recs)
 
735
{
 
736
        DBusMessage *reply;
 
737
        DBusMessageIter iter, dict;
 
738
        sdp_list_t *seq;
 
739
 
 
740
        if (err) {
 
741
                const char *err_if;
 
742
 
 
743
                if (err == -EHOSTDOWN)
 
744
                        err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
 
745
                else
 
746
                        err_if = ERROR_INTERFACE ".Failed";
 
747
 
 
748
                reply = dbus_message_new_error(req->msg, err_if,
 
749
                                                        strerror(-err));
 
750
                g_dbus_send_message(req->conn, reply);
 
751
                return;
 
752
        }
 
753
 
 
754
        reply = dbus_message_new_method_return(req->msg);
 
755
        if (!reply)
 
756
                return;
 
757
 
 
758
        dbus_message_iter_init_append(reply, &iter);
 
759
 
 
760
        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
 
761
                        DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
 
762
                        DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
 
763
                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
 
764
 
 
765
        for (seq = recs; seq; seq = seq->next) {
 
766
                sdp_record_t *rec = (sdp_record_t *) seq->data;
 
767
                GString *result;
 
768
 
 
769
                if (!rec)
 
770
                        break;
 
771
 
 
772
                result = g_string_new(NULL);
 
773
 
 
774
                convert_sdp_record_to_xml(rec, result,
 
775
                                (void *) g_string_append);
 
776
 
 
777
                if (result->len)
 
778
                        iter_append_record(&dict, rec->handle, result->str);
 
779
 
 
780
                g_string_free(result, TRUE);
 
781
        }
 
782
 
 
783
        dbus_message_iter_close_container(&iter, &dict);
 
784
 
 
785
        g_dbus_send_message(req->conn, reply);
 
786
}
 
787
 
 
788
static DBusMessage *cancel_discover(DBusConnection *conn,
 
789
                                        DBusMessage *msg, void *user_data)
 
790
{
 
791
        struct btd_device *device = user_data;
 
792
        const char *sender = dbus_message_get_sender(msg);
 
793
        const char *requestor;
 
794
 
 
795
        if (!device->browse)
 
796
                return btd_error_does_not_exist(msg);
 
797
 
 
798
        if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
 
799
                                        "DiscoverServices"))
 
800
                return btd_error_not_authorized(msg);
 
801
 
 
802
        requestor = browse_request_get_requestor(device->browse);
 
803
 
 
804
        /* only the discover requestor can cancel the inquiry process */
 
805
        if (!requestor || !g_str_equal(requestor, sender))
 
806
                return btd_error_not_authorized(msg);
 
807
 
 
808
        discover_services_reply(device->browse, -ECANCELED, NULL);
 
809
 
 
810
        browse_request_cancel(device->browse);
 
811
 
 
812
        return dbus_message_new_method_return(msg);
 
813
}
 
814
 
 
815
static void bonding_request_cancel(struct bonding_req *bonding)
 
816
{
 
817
        struct btd_device *device = bonding->device;
 
818
        struct btd_adapter *adapter = device->adapter;
 
819
 
 
820
        adapter_cancel_bonding(adapter, &device->bdaddr);
 
821
}
 
822
 
 
823
void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
 
824
{
 
825
        DBusConnection *conn = get_dbus_connection();
 
826
 
 
827
        if (device->bonding)
 
828
                bonding_request_cancel(device->bonding);
 
829
 
 
830
        if (device->browse) {
 
831
                discover_services_reply(device->browse, -ECANCELED, NULL);
 
832
                browse_request_cancel(device->browse);
 
833
        }
 
834
 
 
835
        if (msg)
 
836
                device->disconnects = g_slist_append(device->disconnects,
 
837
                                                dbus_message_ref(msg));
 
838
 
 
839
        if (device->disconn_timer)
 
840
                return;
 
841
 
 
842
        while (device->watches) {
 
843
                struct btd_disconnect_data *data = device->watches->data;
 
844
 
 
845
                if (data->watch)
 
846
                        /* temporary is set if device is going to be removed */
 
847
                        data->watch(device, device->temporary,
 
848
                                                        data->user_data);
 
849
 
 
850
                /* Check if the watch has been removed by callback function */
 
851
                if (!g_slist_find(device->watches, data))
 
852
                        continue;
 
853
 
 
854
                device->watches = g_slist_remove(device->watches, data);
 
855
                g_free(data);
 
856
        }
 
857
 
 
858
        device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,
 
859
                                                do_disconnect, device);
 
860
 
 
861
        g_dbus_emit_signal(conn, device->path,
 
862
                        DEVICE_INTERFACE, "DisconnectRequested",
 
863
                        DBUS_TYPE_INVALID);
 
864
}
 
865
 
 
866
static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
 
867
                                                        void *user_data)
 
868
{
 
869
        struct btd_device *device = user_data;
 
870
 
 
871
        if (!device->connected)
 
872
                return btd_error_not_connected(msg);
 
873
 
 
874
        device_request_disconnect(device, msg);
 
875
 
 
876
        return NULL;
 
877
}
 
878
 
 
879
static const GDBusMethodTable device_methods[] = {
 
880
        { GDBUS_METHOD("GetProperties",
 
881
                                NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
 
882
                                get_properties) },
 
883
        { GDBUS_METHOD("SetProperty",
 
884
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
 
885
                        set_property) },
 
886
        { GDBUS_ASYNC_METHOD("DiscoverServices",
 
887
                        GDBUS_ARGS({ "pattern", "s" }),
 
888
                        GDBUS_ARGS({ "services", "a{us}" }),
 
889
                        discover_services) },
 
890
        { GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
 
891
        { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, disconnect) },
 
892
        { }
 
893
};
 
894
 
 
895
static const GDBusSignalTable device_signals[] = {
 
896
        { GDBUS_SIGNAL("PropertyChanged",
 
897
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
 
898
        { GDBUS_SIGNAL("DisconnectRequested", NULL) },
 
899
        { }
 
900
};
 
901
 
 
902
gboolean device_is_connected(struct btd_device *device)
 
903
{
 
904
        return device->connected;
 
905
}
 
906
 
 
907
void device_add_connection(struct btd_device *device, DBusConnection *conn)
 
908
{
 
909
        if (device->connected) {
 
910
                char addr[18];
 
911
                ba2str(&device->bdaddr, addr);
 
912
                error("Device %s is already connected", addr);
 
913
                return;
 
914
        }
 
915
 
 
916
        device->connected = TRUE;
 
917
 
 
918
        emit_property_changed(conn, device->path,
 
919
                                        DEVICE_INTERFACE, "Connected",
 
920
                                        DBUS_TYPE_BOOLEAN, &device->connected);
 
921
}
 
922
 
 
923
void device_remove_connection(struct btd_device *device, DBusConnection *conn)
 
924
{
 
925
        if (!device->connected) {
 
926
                char addr[18];
 
927
                ba2str(&device->bdaddr, addr);
 
928
                error("Device %s isn't connected", addr);
 
929
                return;
 
930
        }
 
931
 
 
932
        device->connected = FALSE;
 
933
 
 
934
        if (device->disconn_timer > 0) {
 
935
                g_source_remove(device->disconn_timer);
 
936
                device->disconn_timer = 0;
 
937
        }
 
938
 
 
939
        while (device->disconnects) {
 
940
                DBusMessage *msg = device->disconnects->data;
 
941
 
 
942
                g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
 
943
                device->disconnects = g_slist_remove(device->disconnects, msg);
 
944
        }
 
945
 
 
946
        if (device_is_paired(device) && !device_is_bonded(device))
 
947
                device_set_paired(device, FALSE);
 
948
 
 
949
        emit_property_changed(conn, device->path,
 
950
                                        DEVICE_INTERFACE, "Connected",
 
951
                                        DBUS_TYPE_BOOLEAN, &device->connected);
 
952
}
 
953
 
 
954
guint device_add_disconnect_watch(struct btd_device *device,
 
955
                                disconnect_watch watch, void *user_data,
 
956
                                GDestroyNotify destroy)
 
957
{
 
958
        struct btd_disconnect_data *data;
 
959
        static guint id = 0;
 
960
 
 
961
        data = g_new0(struct btd_disconnect_data, 1);
 
962
        data->id = ++id;
 
963
        data->watch = watch;
 
964
        data->user_data = user_data;
 
965
        data->destroy = destroy;
 
966
 
 
967
        device->watches = g_slist_append(device->watches, data);
 
968
 
 
969
        return data->id;
 
970
}
 
971
 
 
972
void device_remove_disconnect_watch(struct btd_device *device, guint id)
 
973
{
 
974
        GSList *l;
 
975
 
 
976
        for (l = device->watches; l; l = l->next) {
 
977
                struct btd_disconnect_data *data = l->data;
 
978
 
 
979
                if (data->id == id) {
 
980
                        device->watches = g_slist_remove(device->watches,
 
981
                                                        data);
 
982
                        if (data->destroy)
 
983
                                data->destroy(data->user_data);
 
984
                        g_free(data);
 
985
                        return;
 
986
                }
 
987
        }
 
988
}
 
989
 
 
990
static void device_set_vendor(struct btd_device *device, uint16_t value)
 
991
{
 
992
        DBusConnection *conn = get_dbus_connection();
 
993
 
 
994
        if (device->vendor == value)
 
995
                return;
 
996
 
 
997
        device->vendor = value;
 
998
 
 
999
        emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Vendor",
 
1000
                                DBUS_TYPE_UINT16, &value);
 
1001
}
 
1002
 
 
1003
static void device_set_vendor_src(struct btd_device *device, uint16_t value)
 
1004
{
 
1005
        DBusConnection *conn = get_dbus_connection();
 
1006
 
 
1007
        if (device->vendor_src == value)
 
1008
                return;
 
1009
 
 
1010
        device->vendor_src = value;
 
1011
 
 
1012
        emit_property_changed(conn, device->path, DEVICE_INTERFACE,
 
1013
                                "VendorSource", DBUS_TYPE_UINT16, &value);
 
1014
}
 
1015
 
 
1016
static void device_set_product(struct btd_device *device, uint16_t value)
 
1017
{
 
1018
        DBusConnection *conn = get_dbus_connection();
 
1019
 
 
1020
        if (device->product == value)
 
1021
                return;
 
1022
 
 
1023
        device->product = value;
 
1024
 
 
1025
        emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Product",
 
1026
                                DBUS_TYPE_UINT16, &value);
 
1027
}
 
1028
 
 
1029
static void device_set_version(struct btd_device *device, uint16_t value)
 
1030
{
 
1031
        DBusConnection *conn = get_dbus_connection();
 
1032
 
 
1033
        if (device->version == value)
 
1034
                return;
 
1035
 
 
1036
        device->version = value;
 
1037
 
 
1038
        emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Version",
 
1039
                                DBUS_TYPE_UINT16, &value);
 
1040
}
 
1041
 
 
1042
struct btd_device *device_create(DBusConnection *conn,
 
1043
                                struct btd_adapter *adapter,
 
1044
                                const gchar *address, uint8_t bdaddr_type)
 
1045
{
 
1046
        gchar *address_up;
 
1047
        struct btd_device *device;
 
1048
        const gchar *adapter_path = adapter_get_path(adapter);
 
1049
        bdaddr_t src;
 
1050
        char srcaddr[18], alias[MAX_NAME_LENGTH + 1];
 
1051
        uint16_t vendor, product, version;
 
1052
 
 
1053
        device = g_try_malloc0(sizeof(struct btd_device));
 
1054
        if (device == NULL)
 
1055
                return NULL;
 
1056
 
 
1057
        address_up = g_ascii_strup(address, -1);
 
1058
        device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
 
1059
        g_strdelimit(device->path, ":", '_');
 
1060
        g_free(address_up);
 
1061
 
 
1062
        DBG("Creating device %s", device->path);
 
1063
 
 
1064
        if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE,
 
1065
                                device_methods, device_signals, NULL,
 
1066
                                device, device_free) == FALSE) {
 
1067
                device_free(device);
 
1068
                return NULL;
 
1069
        }
 
1070
 
 
1071
        str2ba(address, &device->bdaddr);
 
1072
        device->adapter = adapter;
 
1073
        device->bdaddr_type = bdaddr_type;
 
1074
        adapter_get_address(adapter, &src);
 
1075
        ba2str(&src, srcaddr);
 
1076
        read_device_name(srcaddr, address, device->name);
 
1077
        if (read_device_alias(srcaddr, address, alias, sizeof(alias)) == 0)
 
1078
                device->alias = g_strdup(alias);
 
1079
        device->trusted = read_trust(&src, address, GLOBAL_TRUST);
 
1080
 
 
1081
        if (read_blocked(&src, &device->bdaddr))
 
1082
                device_block(conn, device, FALSE);
 
1083
 
 
1084
        if (read_link_key(&src, &device->bdaddr, NULL, NULL) == 0) {
 
1085
                device_set_paired(device, TRUE);
 
1086
                device_set_bonded(device, TRUE);
 
1087
        }
 
1088
 
 
1089
        if (device_is_le(device) && has_longtermkeys(&src, &device->bdaddr,
 
1090
                                                        device->bdaddr_type)) {
 
1091
                device_set_paired(device, TRUE);
 
1092
                device_set_bonded(device, TRUE);
 
1093
        }
 
1094
 
 
1095
        if (read_device_id(srcaddr, address, NULL, &vendor, &product, &version)
 
1096
                                                                        == 0) {
 
1097
                device_set_vendor(device, vendor);
 
1098
                device_set_product(device, product);
 
1099
                device_set_version(device, version);
 
1100
        }
 
1101
 
 
1102
        return btd_device_ref(device);
 
1103
}
 
1104
 
 
1105
void device_set_name(struct btd_device *device, const char *name)
 
1106
{
 
1107
        DBusConnection *conn = get_dbus_connection();
 
1108
 
 
1109
        if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
 
1110
                return;
 
1111
 
 
1112
        strncpy(device->name, name, MAX_NAME_LENGTH);
 
1113
 
 
1114
        emit_property_changed(conn, device->path,
 
1115
                                DEVICE_INTERFACE, "Name",
 
1116
                                DBUS_TYPE_STRING, &name);
 
1117
 
 
1118
        if (device->alias != NULL)
 
1119
                return;
 
1120
 
 
1121
        emit_property_changed(conn, device->path,
 
1122
                                DEVICE_INTERFACE, "Alias",
 
1123
                                DBUS_TYPE_STRING, &name);
 
1124
}
 
1125
 
 
1126
void device_get_name(struct btd_device *device, char *name, size_t len)
 
1127
{
 
1128
        strncpy(name, device->name, len);
 
1129
}
 
1130
 
 
1131
uint16_t btd_device_get_vendor(struct btd_device *device)
 
1132
{
 
1133
        return device->vendor;
 
1134
}
 
1135
 
 
1136
uint16_t btd_device_get_vendor_src(struct btd_device *device)
 
1137
{
 
1138
        return device->vendor_src;
 
1139
}
 
1140
 
 
1141
uint16_t btd_device_get_product(struct btd_device *device)
 
1142
{
 
1143
        return device->product;
 
1144
}
 
1145
 
 
1146
uint16_t btd_device_get_version(struct btd_device *device)
 
1147
{
 
1148
        return device->version;
 
1149
}
 
1150
 
 
1151
static void device_remove_stored(struct btd_device *device)
 
1152
{
 
1153
        bdaddr_t src;
 
1154
        char key[20];
 
1155
        DBusConnection *conn = get_dbus_connection();
 
1156
 
 
1157
        adapter_get_address(device->adapter, &src);
 
1158
        ba2str(&device->bdaddr, key);
 
1159
 
 
1160
        /* key: address only */
 
1161
        delete_entry(&src, "profiles", key);
 
1162
        delete_entry(&src, "trusts", key);
 
1163
 
 
1164
        if (device_is_bonded(device)) {
 
1165
                delete_entry(&src, "linkkeys", key);
 
1166
                delete_entry(&src, "aliases", key);
 
1167
 
 
1168
                /* key: address#type */
 
1169
                sprintf(&key[17], "#%hhu", device->bdaddr_type);
 
1170
 
 
1171
                delete_entry(&src, "longtermkeys", key);
 
1172
 
 
1173
                device_set_bonded(device, FALSE);
 
1174
                device->paired = FALSE;
 
1175
                btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
 
1176
                                                        device->bdaddr_type);
 
1177
        }
 
1178
 
 
1179
        delete_all_records(&src, &device->bdaddr);
 
1180
        delete_device_service(&src, &device->bdaddr, device->bdaddr_type);
 
1181
 
 
1182
        if (device->blocked)
 
1183
                device_unblock(conn, device, TRUE, FALSE);
 
1184
}
 
1185
 
 
1186
void device_remove(struct btd_device *device, gboolean remove_stored)
 
1187
{
 
1188
 
 
1189
        DBG("Removing device %s", device->path);
 
1190
 
 
1191
        if (device->agent)
 
1192
                agent_free(device->agent);
 
1193
 
 
1194
        if (device->bonding) {
 
1195
                uint8_t status;
 
1196
 
 
1197
                if (device->connected)
 
1198
                        status = HCI_OE_USER_ENDED_CONNECTION;
 
1199
                else
 
1200
                        status = HCI_PAGE_TIMEOUT;
 
1201
 
 
1202
                device_cancel_bonding(device, status);
 
1203
        }
 
1204
 
 
1205
        if (device->browse) {
 
1206
                discover_services_reply(device->browse, -ECANCELED, NULL);
 
1207
                browse_request_cancel(device->browse);
 
1208
        }
 
1209
 
 
1210
        if (device->connected)
 
1211
                do_disconnect(device);
 
1212
 
 
1213
        if (remove_stored)
 
1214
                device_remove_stored(device);
 
1215
 
 
1216
        g_slist_foreach(device->drivers, (GFunc) driver_remove, device);
 
1217
        g_slist_free(device->drivers);
 
1218
        device->drivers = NULL;
 
1219
 
 
1220
        attrib_client_unregister(device->services);
 
1221
 
 
1222
        btd_device_unref(device);
 
1223
}
 
1224
 
 
1225
gint device_address_cmp(struct btd_device *device, const gchar *address)
 
1226
{
 
1227
        char addr[18];
 
1228
 
 
1229
        ba2str(&device->bdaddr, addr);
 
1230
        return strcasecmp(addr, address);
 
1231
}
 
1232
 
 
1233
static gboolean record_has_uuid(const sdp_record_t *rec,
 
1234
                                const char *profile_uuid)
 
1235
{
 
1236
        sdp_list_t *pat;
 
1237
 
 
1238
        for (pat = rec->pattern; pat != NULL; pat = pat->next) {
 
1239
                char *uuid;
 
1240
                int ret;
 
1241
 
 
1242
                uuid = bt_uuid2string(pat->data);
 
1243
                if (!uuid)
 
1244
                        continue;
 
1245
 
 
1246
                ret = strcasecmp(uuid, profile_uuid);
 
1247
 
 
1248
                g_free(uuid);
 
1249
 
 
1250
                if (ret == 0)
 
1251
                        return TRUE;
 
1252
        }
 
1253
 
 
1254
        return FALSE;
 
1255
}
 
1256
 
 
1257
static GSList *device_match_pattern(struct btd_device *device,
 
1258
                                        const char *match_uuid,
 
1259
                                        GSList *profiles)
 
1260
{
 
1261
        GSList *l, *uuids = NULL;
 
1262
 
 
1263
        for (l = profiles; l; l = l->next) {
 
1264
                char *profile_uuid = l->data;
 
1265
                const sdp_record_t *rec;
 
1266
 
 
1267
                rec = btd_device_get_record(device, profile_uuid);
 
1268
                if (!rec)
 
1269
                        continue;
 
1270
 
 
1271
                if (record_has_uuid(rec, match_uuid))
 
1272
                        uuids = g_slist_append(uuids, profile_uuid);
 
1273
        }
 
1274
 
 
1275
        return uuids;
 
1276
}
 
1277
 
 
1278
static GSList *device_match_driver(struct btd_device *device,
 
1279
                                        struct btd_device_driver *driver,
 
1280
                                        GSList *profiles)
 
1281
{
 
1282
        const char **uuid;
 
1283
        GSList *uuids = NULL;
 
1284
 
 
1285
        for (uuid = driver->uuids; *uuid; uuid++) {
 
1286
                GSList *match;
 
1287
 
 
1288
                /* skip duplicated uuids */
 
1289
                if (g_slist_find_custom(uuids, *uuid,
 
1290
                                (GCompareFunc) strcasecmp))
 
1291
                        continue;
 
1292
 
 
1293
                /* match profile driver */
 
1294
                match = g_slist_find_custom(profiles, *uuid,
 
1295
                                        (GCompareFunc) strcasecmp);
 
1296
                if (match) {
 
1297
                        uuids = g_slist_append(uuids, match->data);
 
1298
                        continue;
 
1299
                }
 
1300
 
 
1301
                /* match pattern driver */
 
1302
                match = device_match_pattern(device, *uuid, profiles);
 
1303
                uuids = g_slist_concat(uuids, match);
 
1304
        }
 
1305
 
 
1306
        return uuids;
 
1307
}
 
1308
 
 
1309
void device_probe_drivers(struct btd_device *device, GSList *profiles)
 
1310
{
 
1311
        GSList *list;
 
1312
        char addr[18];
 
1313
        int err;
 
1314
 
 
1315
        ba2str(&device->bdaddr, addr);
 
1316
 
 
1317
        if (device->blocked) {
 
1318
                DBG("Skipping drivers for blocked device %s", addr);
 
1319
                goto add_uuids;
 
1320
        }
 
1321
 
 
1322
        DBG("Probing drivers for %s", addr);
 
1323
 
 
1324
        for (list = device_drivers; list; list = list->next) {
 
1325
                struct btd_device_driver *driver = list->data;
 
1326
                GSList *probe_uuids;
 
1327
 
 
1328
                probe_uuids = device_match_driver(device, driver, profiles);
 
1329
 
 
1330
                if (!probe_uuids)
 
1331
                        continue;
 
1332
 
 
1333
                err = driver->probe(device, probe_uuids);
 
1334
                if (err < 0) {
 
1335
                        error("%s driver probe failed for device %s",
 
1336
                                                        driver->name, addr);
 
1337
                        g_slist_free(probe_uuids);
 
1338
                        continue;
 
1339
                }
 
1340
 
 
1341
                device->drivers = g_slist_append(device->drivers, driver);
 
1342
                g_slist_free(probe_uuids);
 
1343
        }
 
1344
 
 
1345
add_uuids:
 
1346
        for (list = profiles; list; list = list->next) {
 
1347
                GSList *l = g_slist_find_custom(device->uuids, list->data,
 
1348
                                                (GCompareFunc) strcasecmp);
 
1349
                if (l)
 
1350
                        continue;
 
1351
 
 
1352
                device->uuids = g_slist_insert_sorted(device->uuids,
 
1353
                                                g_strdup(list->data),
 
1354
                                                (GCompareFunc) strcasecmp);
 
1355
        }
 
1356
}
 
1357
 
 
1358
static void device_remove_drivers(struct btd_device *device, GSList *uuids)
 
1359
{
 
1360
        struct btd_adapter *adapter = device_get_adapter(device);
 
1361
        GSList *list, *next;
 
1362
        char srcaddr[18], dstaddr[18];
 
1363
        bdaddr_t src;
 
1364
        sdp_list_t *records;
 
1365
 
 
1366
        adapter_get_address(adapter, &src);
 
1367
        ba2str(&src, srcaddr);
 
1368
        ba2str(&device->bdaddr, dstaddr);
 
1369
 
 
1370
        records = read_records(&src, &device->bdaddr);
 
1371
 
 
1372
        DBG("Removing drivers for %s", dstaddr);
 
1373
 
 
1374
        for (list = device->drivers; list; list = next) {
 
1375
                struct btd_device_driver *driver = list->data;
 
1376
                const char **uuid;
 
1377
 
 
1378
                next = list->next;
 
1379
 
 
1380
                for (uuid = driver->uuids; *uuid; uuid++) {
 
1381
                        if (!g_slist_find_custom(uuids, *uuid,
 
1382
                                                (GCompareFunc) strcasecmp))
 
1383
                                continue;
 
1384
 
 
1385
                        DBG("UUID %s was removed from device %s",
 
1386
                                                        *uuid, dstaddr);
 
1387
 
 
1388
                        driver->remove(device);
 
1389
                        device->drivers = g_slist_remove(device->drivers,
 
1390
                                                                driver);
 
1391
                        break;
 
1392
                }
 
1393
        }
 
1394
 
 
1395
        for (list = uuids; list; list = list->next) {
 
1396
                sdp_record_t *rec;
 
1397
 
 
1398
                device->uuids = g_slist_remove(device->uuids, list->data);
 
1399
 
 
1400
                rec = find_record_in_list(records, list->data);
 
1401
                if (!rec)
 
1402
                        continue;
 
1403
 
 
1404
                delete_record(srcaddr, dstaddr, rec->handle);
 
1405
 
 
1406
                records = sdp_list_remove(records, rec);
 
1407
                sdp_record_free(rec);
 
1408
 
 
1409
        }
 
1410
 
 
1411
        if (records)
 
1412
                sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
 
1413
}
 
1414
 
 
1415
static void services_changed(struct btd_device *device)
 
1416
{
 
1417
        DBusConnection *conn = get_dbus_connection();
 
1418
        char **uuids;
 
1419
        GSList *l;
 
1420
        int i;
 
1421
 
 
1422
        uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
 
1423
        for (i = 0, l = device->uuids; l; l = l->next, i++)
 
1424
                uuids[i] = l->data;
 
1425
 
 
1426
        emit_array_property_changed(conn, device->path, DEVICE_INTERFACE,
 
1427
                                        "UUIDs", DBUS_TYPE_STRING, &uuids, i);
 
1428
 
 
1429
        g_free(uuids);
 
1430
}
 
1431
 
 
1432
static int rec_cmp(const void *a, const void *b)
 
1433
{
 
1434
        const sdp_record_t *r1 = a;
 
1435
        const sdp_record_t *r2 = b;
 
1436
 
 
1437
        return r1->handle - r2->handle;
 
1438
}
 
1439
 
 
1440
static void update_services(struct browse_req *req, sdp_list_t *recs)
 
1441
{
 
1442
        struct btd_device *device = req->device;
 
1443
        struct btd_adapter *adapter = device_get_adapter(device);
 
1444
        sdp_list_t *seq;
 
1445
        char srcaddr[18], dstaddr[18];
 
1446
        bdaddr_t src;
 
1447
 
 
1448
        adapter_get_address(adapter, &src);
 
1449
        ba2str(&src, srcaddr);
 
1450
        ba2str(&device->bdaddr, dstaddr);
 
1451
 
 
1452
        for (seq = recs; seq; seq = seq->next) {
 
1453
                sdp_record_t *rec = (sdp_record_t *) seq->data;
 
1454
                sdp_list_t *svcclass = NULL;
 
1455
                gchar *profile_uuid;
 
1456
                GSList *l;
 
1457
 
 
1458
                if (!rec)
 
1459
                        break;
 
1460
 
 
1461
                if (sdp_get_service_classes(rec, &svcclass) < 0)
 
1462
                        continue;
 
1463
 
 
1464
                /* Check for empty service classes list */
 
1465
                if (svcclass == NULL) {
 
1466
                        DBG("Skipping record with no service classes");
 
1467
                        continue;
 
1468
                }
 
1469
 
 
1470
                /* Extract the first element and skip the remainning */
 
1471
                profile_uuid = bt_uuid2string(svcclass->data);
 
1472
                if (!profile_uuid) {
 
1473
                        sdp_list_free(svcclass, free);
 
1474
                        continue;
 
1475
                }
 
1476
 
 
1477
                if (!strcasecmp(profile_uuid, PNP_UUID)) {
 
1478
                        uint16_t source, vendor, product, version;
 
1479
                        sdp_data_t *pdlist;
 
1480
 
 
1481
                        pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
 
1482
                        source = pdlist ? pdlist->val.uint16 : 0x0000;
 
1483
 
 
1484
                        pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
 
1485
                        vendor = pdlist ? pdlist->val.uint16 : 0x0000;
 
1486
 
 
1487
                        device_set_vendor(device, vendor);
 
1488
 
 
1489
                        pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
 
1490
                        product = pdlist ? pdlist->val.uint16 : 0x0000;
 
1491
 
 
1492
                        device_set_product(device, product);
 
1493
 
 
1494
                        pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
 
1495
                        version = pdlist ? pdlist->val.uint16 : 0x0000;
 
1496
 
 
1497
                        device_set_version(device, version);
 
1498
 
 
1499
                        if (source || vendor || product || version)
 
1500
                                store_device_id(srcaddr, dstaddr, source,
 
1501
                                                vendor, product, version);
 
1502
                }
 
1503
 
 
1504
                /* Check for duplicates */
 
1505
                if (sdp_list_find(req->records, rec, rec_cmp)) {
 
1506
                        g_free(profile_uuid);
 
1507
                        sdp_list_free(svcclass, free);
 
1508
                        continue;
 
1509
                }
 
1510
 
 
1511
                store_record(srcaddr, dstaddr, rec);
 
1512
 
 
1513
                /* Copy record */
 
1514
                req->records = sdp_list_append(req->records,
 
1515
                                                        sdp_copy_record(rec));
 
1516
 
 
1517
                l = g_slist_find_custom(device->uuids, profile_uuid,
 
1518
                                                        (GCompareFunc) strcmp);
 
1519
                if (!l)
 
1520
                        req->profiles_added =
 
1521
                                        g_slist_append(req->profiles_added,
 
1522
                                                        profile_uuid);
 
1523
                else {
 
1524
                        req->profiles_removed =
 
1525
                                        g_slist_remove(req->profiles_removed,
 
1526
                                                        l->data);
 
1527
                        g_free(profile_uuid);
 
1528
                }
 
1529
 
 
1530
                sdp_list_free(svcclass, free);
 
1531
        }
 
1532
}
 
1533
 
 
1534
static void store_profiles(struct btd_device *device)
 
1535
{
 
1536
        struct btd_adapter *adapter = device->adapter;
 
1537
        bdaddr_t src;
 
1538
        char *str;
 
1539
 
 
1540
        adapter_get_address(adapter, &src);
 
1541
 
 
1542
        if (!device->uuids) {
 
1543
                write_device_profiles(&src, &device->bdaddr, "");
 
1544
                return;
 
1545
        }
 
1546
 
 
1547
        str = bt_list2string(device->uuids);
 
1548
        write_device_profiles(&src, &device->bdaddr, str);
 
1549
        g_free(str);
 
1550
}
 
1551
 
 
1552
static void create_device_reply(struct btd_device *device, struct browse_req *req)
 
1553
{
 
1554
        DBusMessage *reply;
 
1555
 
 
1556
        reply = dbus_message_new_method_return(req->msg);
 
1557
        if (!reply)
 
1558
                return;
 
1559
 
 
1560
        dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
 
1561
                                        DBUS_TYPE_INVALID);
 
1562
 
 
1563
        g_dbus_send_message(req->conn, reply);
 
1564
}
 
1565
 
 
1566
GSList *device_services_from_record(struct btd_device *device, GSList *profiles)
 
1567
{
 
1568
        GSList *l, *prim_list = NULL;
 
1569
        char *att_uuid;
 
1570
        uuid_t proto_uuid;
 
1571
 
 
1572
        sdp_uuid16_create(&proto_uuid, ATT_UUID);
 
1573
        att_uuid = bt_uuid2string(&proto_uuid);
 
1574
 
 
1575
        for (l = profiles; l; l = l->next) {
 
1576
                const char *profile_uuid = l->data;
 
1577
                const sdp_record_t *rec;
 
1578
                struct gatt_primary *prim;
 
1579
                uint16_t start = 0, end = 0, psm = 0;
 
1580
                uuid_t prim_uuid;
 
1581
 
 
1582
                rec = btd_device_get_record(device, profile_uuid);
 
1583
                if (!rec)
 
1584
                        continue;
 
1585
 
 
1586
                if (!record_has_uuid(rec, att_uuid))
 
1587
                        continue;
 
1588
 
 
1589
                if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
 
1590
                        continue;
 
1591
 
 
1592
                prim = g_new0(struct gatt_primary, 1);
 
1593
                prim->range.start = start;
 
1594
                prim->range.end = end;
 
1595
                sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
 
1596
 
 
1597
                prim_list = g_slist_append(prim_list, prim);
 
1598
        }
 
1599
 
 
1600
        g_free(att_uuid);
 
1601
 
 
1602
        return prim_list;
 
1603
}
 
1604
 
 
1605
static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 
1606
{
 
1607
        struct browse_req *req = user_data;
 
1608
        struct btd_device *device = req->device;
 
1609
        char addr[18];
 
1610
 
 
1611
        ba2str(&device->bdaddr, addr);
 
1612
 
 
1613
        if (err < 0) {
 
1614
                error("%s: error updating services: %s (%d)",
 
1615
                                addr, strerror(-err), -err);
 
1616
                goto send_reply;
 
1617
        }
 
1618
 
 
1619
        update_services(req, recs);
 
1620
 
 
1621
        if (device->tmp_records)
 
1622
                sdp_list_free(device->tmp_records,
 
1623
                                        (sdp_free_func_t) sdp_record_free);
 
1624
 
 
1625
        device->tmp_records = req->records;
 
1626
        req->records = NULL;
 
1627
 
 
1628
        if (!req->profiles_added && !req->profiles_removed) {
 
1629
                DBG("%s: No service update", addr);
 
1630
                goto send_reply;
 
1631
        }
 
1632
 
 
1633
        /* Probe matching drivers for services added */
 
1634
        if (req->profiles_added) {
 
1635
                GSList *list;
 
1636
 
 
1637
                list = device_services_from_record(device, req->profiles_added);
 
1638
                if (list)
 
1639
                        device_register_services(req->conn, device, list,
 
1640
                                                                ATT_PSM);
 
1641
 
 
1642
                device_probe_drivers(device, req->profiles_added);
 
1643
        }
 
1644
 
 
1645
        /* Remove drivers for services removed */
 
1646
        if (req->profiles_removed)
 
1647
                device_remove_drivers(device, req->profiles_removed);
 
1648
 
 
1649
        /* Propagate services changes */
 
1650
        services_changed(req->device);
 
1651
 
 
1652
send_reply:
 
1653
        if (!req->msg)
 
1654
                goto cleanup;
 
1655
 
 
1656
        if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
 
1657
                                        "DiscoverServices"))
 
1658
                discover_services_reply(req, err, device->tmp_records);
 
1659
        else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE,
 
1660
                                                "CreatePairedDevice"))
 
1661
                create_device_reply(device, req);
 
1662
        else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE,
 
1663
                                                "CreateDevice")) {
 
1664
                if (err < 0) {
 
1665
                        DBusMessage *reply;
 
1666
                        reply = btd_error_failed(req->msg, strerror(-err));
 
1667
                        g_dbus_send_message(req->conn, reply);
 
1668
                        goto cleanup;
 
1669
                }
 
1670
 
 
1671
                create_device_reply(device, req);
 
1672
                device_set_temporary(device, FALSE);
 
1673
        }
 
1674
 
 
1675
cleanup:
 
1676
        if (!device->temporary) {
 
1677
                bdaddr_t sba, dba;
 
1678
 
 
1679
                adapter_get_address(device->adapter, &sba);
 
1680
                device_get_address(device, &dba, NULL);
 
1681
 
 
1682
                store_profiles(device);
 
1683
        }
 
1684
 
 
1685
        device->browse = NULL;
 
1686
        browse_request_free(req);
 
1687
}
 
1688
 
 
1689
static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
 
1690
{
 
1691
        struct browse_req *req = user_data;
 
1692
        struct btd_device *device = req->device;
 
1693
        struct btd_adapter *adapter = device->adapter;
 
1694
        bdaddr_t src;
 
1695
        uuid_t uuid;
 
1696
 
 
1697
        /* If we have a valid response and req->search_uuid == 2, then L2CAP
 
1698
         * UUID & PNP searching was successful -- we are done */
 
1699
        if (err < 0 || (req->search_uuid == 2 && req->records)) {
 
1700
                if (err == -ECONNRESET && req->reconnect_attempt < 1) {
 
1701
                        req->search_uuid--;
 
1702
                        req->reconnect_attempt++;
 
1703
                } else
 
1704
                        goto done;
 
1705
        }
 
1706
 
 
1707
        update_services(req, recs);
 
1708
 
 
1709
        adapter_get_address(adapter, &src);
 
1710
 
 
1711
        /* Search for mandatory uuids */
 
1712
        if (uuid_list[req->search_uuid]) {
 
1713
                sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
 
1714
                bt_search_service(&src, &device->bdaddr, &uuid,
 
1715
                                                browse_cb, user_data, NULL);
 
1716
                return;
 
1717
        }
 
1718
 
 
1719
done:
 
1720
        search_cb(recs, err, user_data);
 
1721
}
 
1722
 
 
1723
static void init_browse(struct browse_req *req, gboolean reverse)
 
1724
{
 
1725
        GSList *l;
 
1726
 
 
1727
        /* If we are doing reverse-SDP don't try to detect removed profiles
 
1728
         * since some devices hide their service records while they are
 
1729
         * connected
 
1730
         */
 
1731
        if (reverse)
 
1732
                return;
 
1733
 
 
1734
        for (l = req->device->uuids; l; l = l->next)
 
1735
                req->profiles_removed = g_slist_append(req->profiles_removed,
 
1736
                                                l->data);
 
1737
}
 
1738
 
 
1739
static char *primary_list_to_string(GSList *primary_list)
 
1740
{
 
1741
        GString *services;
 
1742
        GSList *l;
 
1743
 
 
1744
        services = g_string_new(NULL);
 
1745
 
 
1746
        for (l = primary_list; l; l = l->next) {
 
1747
                struct gatt_primary *primary = l->data;
 
1748
                char service[64];
 
1749
 
 
1750
                memset(service, 0, sizeof(service));
 
1751
 
 
1752
                snprintf(service, sizeof(service), "%04X#%04X#%s ",
 
1753
                                primary->range.start, primary->range.end, primary->uuid);
 
1754
 
 
1755
                services = g_string_append(services, service);
 
1756
        }
 
1757
 
 
1758
        return g_string_free(services, FALSE);
 
1759
}
 
1760
 
 
1761
static void store_services(struct btd_device *device)
 
1762
{
 
1763
        struct btd_adapter *adapter = device->adapter;
 
1764
        bdaddr_t dba, sba;
 
1765
        char *str = primary_list_to_string(device->primaries);
 
1766
 
 
1767
        adapter_get_address(adapter, &sba);
 
1768
        device_get_address(device, &dba, NULL);
 
1769
 
 
1770
        write_device_services(&sba, &dba, device->bdaddr_type, str);
 
1771
 
 
1772
        g_free(str);
 
1773
}
 
1774
 
 
1775
static void attio_connected(gpointer data, gpointer user_data)
 
1776
{
 
1777
        struct attio_data *attio = data;
 
1778
        GAttrib *attrib = user_data;
 
1779
 
 
1780
        if (attio->cfunc)
 
1781
                attio->cfunc(attrib, attio->user_data);
 
1782
}
 
1783
 
 
1784
static void attio_disconnected(gpointer data, gpointer user_data)
 
1785
{
 
1786
        struct attio_data *attio = data;
 
1787
 
 
1788
        if (attio->dcfunc)
 
1789
                attio->dcfunc(attio->user_data);
 
1790
}
 
1791
 
 
1792
static void att_connect_dispatched(gpointer user_data)
 
1793
{
 
1794
        struct btd_device *device = user_data;
 
1795
 
 
1796
        device->auto_id = 0;
 
1797
}
 
1798
 
 
1799
static gboolean att_connect(gpointer user_data);
 
1800
 
 
1801
static gboolean attrib_disconnected_cb(GIOChannel *io, GIOCondition cond,
 
1802
                                                        gpointer user_data)
 
1803
{
 
1804
        struct btd_device *device = user_data;
 
1805
        int sock, err = 0;
 
1806
        socklen_t len;
 
1807
 
 
1808
        if (device->browse)
 
1809
                goto done;
 
1810
 
 
1811
        sock = g_io_channel_unix_get_fd(io);
 
1812
        len = sizeof(err);
 
1813
        getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len);
 
1814
 
 
1815
        g_slist_foreach(device->attios, attio_disconnected, NULL);
 
1816
 
 
1817
        if (device->auto_connect == FALSE || err != ETIMEDOUT)
 
1818
                goto done;
 
1819
 
 
1820
        device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
 
1821
                                                AUTO_CONNECTION_INTERVAL,
 
1822
                                                att_connect, device,
 
1823
                                                att_connect_dispatched);
 
1824
 
 
1825
done:
 
1826
        att_cleanup(device);
 
1827
 
 
1828
        return FALSE;
 
1829
}
 
1830
 
 
1831
static void appearance_cb(guint8 status, const guint8 *pdu, guint16 plen,
 
1832
                                                        gpointer user_data)
 
1833
{
 
1834
        struct btd_device *device = user_data;
 
1835
        struct btd_adapter *adapter = device->adapter;
 
1836
        struct att_data_list *list =  NULL;
 
1837
        uint16_t app;
 
1838
        bdaddr_t src;
 
1839
        uint8_t *atval;
 
1840
 
 
1841
        if (status != 0) {
 
1842
                DBG("Read characteristics by UUID failed: %s\n",
 
1843
                                                        att_ecode2str(status));
 
1844
                goto done;
 
1845
        }
 
1846
 
 
1847
        list = dec_read_by_type_resp(pdu, plen);
 
1848
        if (list == NULL)
 
1849
                goto done;
 
1850
 
 
1851
        if (list->len != 4) {
 
1852
                DBG("Appearance value: invalid data");
 
1853
                goto done;
 
1854
        }
 
1855
 
 
1856
        /* A device shall have only one instance of the
 
1857
        Appearance characteristic. */
 
1858
        atval = list->data[0] + 2; /* skip handle value */
 
1859
        app = att_get_u16(atval);
 
1860
 
 
1861
        adapter_get_address(adapter, &src);
 
1862
        write_remote_appearance(&src, &device->bdaddr, device->bdaddr_type,
 
1863
                                                                        app);
 
1864
 
 
1865
done:
 
1866
        att_data_list_free(list);
 
1867
        if (device->attios == NULL && device->attios_offline == NULL)
 
1868
                att_cleanup(device);
 
1869
}
 
1870
 
 
1871
static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 
1872
{
 
1873
        struct browse_req *req = user_data;
 
1874
        struct btd_device *device = req->device;
 
1875
        struct gatt_primary *gap_prim = NULL;
 
1876
        GSList *l, *uuids = NULL;
 
1877
 
 
1878
        if (status) {
 
1879
                if (req->msg) {
 
1880
                        DBusMessage *reply;
 
1881
                        reply = btd_error_failed(req->msg,
 
1882
                                                        att_ecode2str(status));
 
1883
                        g_dbus_send_message(req->conn, reply);
 
1884
                }
 
1885
                goto done;
 
1886
        }
 
1887
 
 
1888
        device_set_temporary(device, FALSE);
 
1889
 
 
1890
        for (l = services; l; l = l->next) {
 
1891
                struct gatt_primary *prim = l->data;
 
1892
 
 
1893
                if (strcmp(prim->uuid, GAP_SVC_UUID) == 0)
 
1894
                        gap_prim = prim;
 
1895
 
 
1896
                uuids = g_slist_append(uuids, prim->uuid);
 
1897
        }
 
1898
 
 
1899
        device_register_services(req->conn, device, g_slist_copy(services), -1);
 
1900
        device_probe_drivers(device, uuids);
 
1901
 
 
1902
        if (gap_prim) {
 
1903
                /* Read appearance characteristic */
 
1904
                bt_uuid_t uuid;
 
1905
 
 
1906
                bt_uuid16_create(&uuid, APPEARANCE_CHR_UUID);
 
1907
 
 
1908
                gatt_read_char_by_uuid(device->attrib, gap_prim->range.start,
 
1909
                        gap_prim->range.end, &uuid, appearance_cb, device);
 
1910
        } else if (device->attios == NULL && device->attios_offline == NULL)
 
1911
                att_cleanup(device);
 
1912
 
 
1913
        g_slist_free(uuids);
 
1914
 
 
1915
        services_changed(device);
 
1916
        if (req->msg)
 
1917
                create_device_reply(device, req);
 
1918
 
 
1919
        store_services(device);
 
1920
 
 
1921
done:
 
1922
        device->browse = NULL;
 
1923
        browse_request_free(req);
 
1924
}
 
1925
 
 
1926
static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 
1927
{
 
1928
        struct att_callbacks *attcb = user_data;
 
1929
        struct btd_device *device = attcb->user_data;
 
1930
        GAttrib *attrib;
 
1931
 
 
1932
        g_io_channel_unref(device->att_io);
 
1933
        device->att_io = NULL;
 
1934
 
 
1935
        if (gerr) {
 
1936
                DBG("%s", gerr->message);
 
1937
 
 
1938
                if (attcb->error)
 
1939
                        attcb->error(gerr, user_data);
 
1940
 
 
1941
                goto done;
 
1942
        }
 
1943
 
 
1944
        attrib = g_attrib_new(io);
 
1945
        device->attachid = attrib_channel_attach(attrib);
 
1946
        if (device->attachid == 0)
 
1947
                error("Attribute server attach failure!");
 
1948
 
 
1949
        device->attrib = attrib;
 
1950
        device->cleanup_id = g_io_add_watch(io, G_IO_HUP,
 
1951
                                        attrib_disconnected_cb, device);
 
1952
 
 
1953
        if (attcb->success)
 
1954
                attcb->success(user_data);
 
1955
done:
 
1956
        g_free(attcb);
 
1957
}
 
1958
 
 
1959
static void att_error_cb(const GError *gerr, gpointer user_data)
 
1960
{
 
1961
        struct att_callbacks *attcb = user_data;
 
1962
        struct btd_device *device = attcb->user_data;
 
1963
 
 
1964
        if (device->auto_connect == FALSE)
 
1965
                return;
 
1966
 
 
1967
        device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
 
1968
                                                AUTO_CONNECTION_INTERVAL,
 
1969
                                                att_connect, device,
 
1970
                                                att_connect_dispatched);
 
1971
 
 
1972
        DBG("Enabling automatic connections");
 
1973
}
 
1974
 
 
1975
static void att_success_cb(gpointer user_data)
 
1976
{
 
1977
        struct att_callbacks *attcb = user_data;
 
1978
        struct btd_device *device = attcb->user_data;
 
1979
 
 
1980
        if (device->attios == NULL)
 
1981
                return;
 
1982
 
 
1983
        g_slist_foreach(device->attios, attio_connected, device->attrib);
 
1984
}
 
1985
 
 
1986
static gboolean att_connect(gpointer user_data)
 
1987
{
 
1988
        struct btd_device *device = user_data;
 
1989
        struct btd_adapter *adapter = device->adapter;
 
1990
        struct att_callbacks *attcb;
 
1991
        GIOChannel *io;
 
1992
        GError *gerr = NULL;
 
1993
        char addr[18];
 
1994
        bdaddr_t sba;
 
1995
 
 
1996
        adapter_get_address(adapter, &sba);
 
1997
        ba2str(&device->bdaddr, addr);
 
1998
 
 
1999
        DBG("Connection attempt to: %s", addr);
 
2000
 
 
2001
        attcb = g_new0(struct att_callbacks, 1);
 
2002
        attcb->error = att_error_cb;
 
2003
        attcb->success = att_success_cb;
 
2004
        attcb->user_data = device;
 
2005
 
 
2006
        if (device_is_bredr(device)) {
 
2007
                io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
 
2008
                                        attcb, NULL, &gerr,
 
2009
                                        BT_IO_OPT_SOURCE_BDADDR, &sba,
 
2010
                                        BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
 
2011
                                        BT_IO_OPT_PSM, ATT_PSM,
 
2012
                                        BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
 
2013
                                        BT_IO_OPT_INVALID);
 
2014
        } else {
 
2015
                io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
 
2016
                                attcb, NULL, &gerr,
 
2017
                                BT_IO_OPT_SOURCE_BDADDR, &sba,
 
2018
                                BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
 
2019
                                BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
 
2020
                                BT_IO_OPT_CID, ATT_CID,
 
2021
                                BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
 
2022
                                BT_IO_OPT_INVALID);
 
2023
        }
 
2024
 
 
2025
        if (io == NULL) {
 
2026
                error("ATT bt_io_connect(%s): %s", addr, gerr->message);
 
2027
                g_error_free(gerr);
 
2028
                g_free(attcb);
 
2029
                return FALSE;
 
2030
        }
 
2031
 
 
2032
        device->att_io = io;
 
2033
 
 
2034
        return FALSE;
 
2035
}
 
2036
 
 
2037
static void att_browse_error_cb(const GError *gerr, gpointer user_data)
 
2038
{
 
2039
        struct att_callbacks *attcb = user_data;
 
2040
        struct btd_device *device = attcb->user_data;
 
2041
        struct browse_req *req = device->browse;
 
2042
 
 
2043
        if (req->msg) {
 
2044
                DBusMessage *reply;
 
2045
 
 
2046
                reply = btd_error_failed(req->msg, gerr->message);
 
2047
                g_dbus_send_message(req->conn, reply);
 
2048
        }
 
2049
 
 
2050
        device->browse = NULL;
 
2051
        browse_request_free(req);
 
2052
}
 
2053
 
 
2054
static void att_browse_cb(gpointer user_data)
 
2055
{
 
2056
        struct att_callbacks *attcb = user_data;
 
2057
        struct btd_device *device = attcb->user_data;
 
2058
 
 
2059
        gatt_discover_primary(device->attrib, NULL, primary_cb,
 
2060
                                                        device->browse);
 
2061
}
 
2062
 
 
2063
int device_browse_primary(struct btd_device *device, DBusConnection *conn,
 
2064
                                DBusMessage *msg, gboolean secure)
 
2065
{
 
2066
        struct btd_adapter *adapter = device->adapter;
 
2067
        struct att_callbacks *attcb;
 
2068
        struct browse_req *req;
 
2069
        BtIOSecLevel sec_level;
 
2070
        bdaddr_t src;
 
2071
 
 
2072
        if (device->browse)
 
2073
                return -EBUSY;
 
2074
 
 
2075
        /* FIXME: GATT service updates (implemented in update_services() for
 
2076
         * SDP) are not supported yet. It will be supported once client side
 
2077
         * "Services Changed" characteristic handling is implemented. */
 
2078
        if (device->primaries) {
 
2079
                error("Could not update GATT services");
 
2080
                return -ENOSYS;
 
2081
        }
 
2082
 
 
2083
        req = g_new0(struct browse_req, 1);
 
2084
        req->device = btd_device_ref(device);
 
2085
        adapter_get_address(adapter, &src);
 
2086
 
 
2087
        device->browse = req;
 
2088
 
 
2089
        if (device->attrib) {
 
2090
                gatt_discover_primary(device->attrib, NULL, primary_cb, req);
 
2091
                goto done;
 
2092
        }
 
2093
 
 
2094
        sec_level = secure ? BT_IO_SEC_HIGH : BT_IO_SEC_LOW;
 
2095
 
 
2096
        attcb = g_new0(struct att_callbacks, 1);
 
2097
        attcb->error = att_browse_error_cb;
 
2098
        attcb->success = att_browse_cb;
 
2099
        attcb->user_data = device;
 
2100
 
 
2101
        device->att_io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
 
2102
                                attcb, NULL, NULL,
 
2103
                                BT_IO_OPT_SOURCE_BDADDR, &src,
 
2104
                                BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
 
2105
                                BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
 
2106
                                BT_IO_OPT_CID, ATT_CID,
 
2107
                                BT_IO_OPT_SEC_LEVEL, sec_level,
 
2108
                                BT_IO_OPT_INVALID);
 
2109
 
 
2110
        if (device->att_io == NULL) {
 
2111
                device->browse = NULL;
 
2112
                browse_request_free(req);
 
2113
                g_free(attcb);
 
2114
                return -EIO;
 
2115
        }
 
2116
 
 
2117
done:
 
2118
        if (conn == NULL)
 
2119
                conn = get_dbus_connection();
 
2120
 
 
2121
        req->conn = dbus_connection_ref(conn);
 
2122
 
 
2123
        if (msg) {
 
2124
                const char *sender = dbus_message_get_sender(msg);
 
2125
 
 
2126
                req->msg = dbus_message_ref(msg);
 
2127
                /* Track the request owner to cancel it
 
2128
                 * automatically if the owner exits */
 
2129
                req->listener_id = g_dbus_add_disconnect_watch(conn,
 
2130
                                                sender,
 
2131
                                                discover_services_req_exit,
 
2132
                                                req, NULL);
 
2133
        }
 
2134
 
 
2135
        return 0;
 
2136
}
 
2137
 
 
2138
int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
 
2139
                        DBusMessage *msg, uuid_t *search, gboolean reverse)
 
2140
{
 
2141
        struct btd_adapter *adapter = device->adapter;
 
2142
        struct browse_req *req;
 
2143
        bt_callback_t cb;
 
2144
        bdaddr_t src;
 
2145
        uuid_t uuid;
 
2146
        int err;
 
2147
 
 
2148
        if (device->browse)
 
2149
                return -EBUSY;
 
2150
 
 
2151
        adapter_get_address(adapter, &src);
 
2152
 
 
2153
        req = g_new0(struct browse_req, 1);
 
2154
        req->device = btd_device_ref(device);
 
2155
        if (search) {
 
2156
                memcpy(&uuid, search, sizeof(uuid_t));
 
2157
                cb = search_cb;
 
2158
        } else {
 
2159
                sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
 
2160
                init_browse(req, reverse);
 
2161
                cb = browse_cb;
 
2162
        }
 
2163
 
 
2164
        err = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL);
 
2165
        if (err < 0) {
 
2166
                browse_request_free(req);
 
2167
                return err;
 
2168
        }
 
2169
 
 
2170
        if (conn == NULL)
 
2171
                conn = get_dbus_connection();
 
2172
 
 
2173
        req->conn = dbus_connection_ref(conn);
 
2174
        device->browse = req;
 
2175
 
 
2176
        if (msg) {
 
2177
                const char *sender = dbus_message_get_sender(msg);
 
2178
 
 
2179
                req->msg = dbus_message_ref(msg);
 
2180
                /* Track the request owner to cancel it
 
2181
                 * automatically if the owner exits */
 
2182
                req->listener_id = g_dbus_add_disconnect_watch(conn,
 
2183
                                                sender,
 
2184
                                                discover_services_req_exit,
 
2185
                                                req, NULL);
 
2186
        }
 
2187
 
 
2188
        return err;
 
2189
}
 
2190
 
 
2191
struct btd_adapter *device_get_adapter(struct btd_device *device)
 
2192
{
 
2193
        if (!device)
 
2194
                return NULL;
 
2195
 
 
2196
        return device->adapter;
 
2197
}
 
2198
 
 
2199
void device_get_address(struct btd_device *device, bdaddr_t *bdaddr,
 
2200
                                                        uint8_t *bdaddr_type)
 
2201
{
 
2202
        bacpy(bdaddr, &device->bdaddr);
 
2203
        if (bdaddr_type != NULL)
 
2204
                *bdaddr_type = device->bdaddr_type;
 
2205
}
 
2206
 
 
2207
void device_set_addr_type(struct btd_device *device, uint8_t bdaddr_type)
 
2208
{
 
2209
        if (device == NULL)
 
2210
                return;
 
2211
 
 
2212
        device->bdaddr_type = bdaddr_type;
 
2213
}
 
2214
 
 
2215
uint8_t device_get_addr_type(struct btd_device *device)
 
2216
{
 
2217
        return device->bdaddr_type;
 
2218
}
 
2219
 
 
2220
const gchar *device_get_path(struct btd_device *device)
 
2221
{
 
2222
        if (!device)
 
2223
                return NULL;
 
2224
 
 
2225
        return device->path;
 
2226
}
 
2227
 
 
2228
struct agent *device_get_agent(struct btd_device *device)
 
2229
{
 
2230
        if (!device)
 
2231
                return NULL;
 
2232
 
 
2233
        if (device->agent)
 
2234
                return device->agent;
 
2235
 
 
2236
        return adapter_get_agent(device->adapter);
 
2237
}
 
2238
 
 
2239
gboolean device_is_busy(struct btd_device *device)
 
2240
{
 
2241
        return device->browse ? TRUE : FALSE;
 
2242
}
 
2243
 
 
2244
gboolean device_is_temporary(struct btd_device *device)
 
2245
{
 
2246
        return device->temporary;
 
2247
}
 
2248
 
 
2249
void device_set_temporary(struct btd_device *device, gboolean temporary)
 
2250
{
 
2251
        if (!device)
 
2252
                return;
 
2253
 
 
2254
        DBG("temporary %d", temporary);
 
2255
 
 
2256
        device->temporary = temporary;
 
2257
}
 
2258
 
 
2259
void device_set_bonded(struct btd_device *device, gboolean bonded)
 
2260
{
 
2261
        if (!device)
 
2262
                return;
 
2263
 
 
2264
        DBG("bonded %d", bonded);
 
2265
 
 
2266
        device->bonded = bonded;
 
2267
}
 
2268
 
 
2269
void device_set_auto_connect(struct btd_device *device, gboolean enable)
 
2270
{
 
2271
        char addr[18];
 
2272
 
 
2273
        if (!device)
 
2274
                return;
 
2275
 
 
2276
        ba2str(&device->bdaddr, addr);
 
2277
 
 
2278
        DBG("%s auto connect: %d", addr, enable);
 
2279
 
 
2280
        device->auto_connect = enable;
 
2281
 
 
2282
        /* Disabling auto connect */
 
2283
        if (enable == FALSE) {
 
2284
                if (device->auto_id)
 
2285
                        g_source_remove(device->auto_id);
 
2286
                return;
 
2287
        }
 
2288
 
 
2289
        /* Enabling auto connect */
 
2290
        if (device->auto_id != 0)
 
2291
                return;
 
2292
 
 
2293
        if (device->attrib) {
 
2294
                DBG("Already connected");
 
2295
                return;
 
2296
        }
 
2297
 
 
2298
        if (device->attios == NULL && device->attios_offline == NULL)
 
2299
                return;
 
2300
 
 
2301
        device->auto_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
 
2302
                                                att_connect, device,
 
2303
                                                att_connect_dispatched);
 
2304
}
 
2305
 
 
2306
static gboolean start_discovery(gpointer user_data)
 
2307
{
 
2308
        struct btd_device *device = user_data;
 
2309
 
 
2310
        if (device_is_bredr(device))
 
2311
                device_browse_sdp(device, NULL, NULL, NULL, TRUE);
 
2312
        else
 
2313
                device_browse_primary(device, NULL, NULL, FALSE);
 
2314
 
 
2315
        device->discov_timer = 0;
 
2316
 
 
2317
        return FALSE;
 
2318
}
 
2319
 
 
2320
static DBusMessage *new_authentication_return(DBusMessage *msg, int status)
 
2321
{
 
2322
        switch (status) {
 
2323
        case 0x00: /* success */
 
2324
                return dbus_message_new_method_return(msg);
 
2325
 
 
2326
        case 0x04: /* page timeout */
 
2327
                return dbus_message_new_error(msg,
 
2328
                                ERROR_INTERFACE ".ConnectionAttemptFailed",
 
2329
                                "Page Timeout");
 
2330
        case 0x08: /* connection timeout */
 
2331
                return dbus_message_new_error(msg,
 
2332
                                ERROR_INTERFACE ".ConnectionAttemptFailed",
 
2333
                                "Connection Timeout");
 
2334
        case 0x10: /* connection accept timeout */
 
2335
        case 0x22: /* LMP response timeout */
 
2336
        case 0x28: /* instant passed - is this a timeout? */
 
2337
                return dbus_message_new_error(msg,
 
2338
                                        ERROR_INTERFACE ".AuthenticationTimeout",
 
2339
                                        "Authentication Timeout");
 
2340
        case 0x17: /* too frequent pairing attempts */
 
2341
                return dbus_message_new_error(msg,
 
2342
                                        ERROR_INTERFACE ".RepeatedAttempts",
 
2343
                                        "Repeated Attempts");
 
2344
 
 
2345
        case 0x06:
 
2346
        case 0x18: /* pairing not allowed (e.g. gw rejected attempt) */
 
2347
                return dbus_message_new_error(msg,
 
2348
                                        ERROR_INTERFACE ".AuthenticationRejected",
 
2349
                                        "Authentication Rejected");
 
2350
 
 
2351
        case 0x07: /* memory capacity */
 
2352
        case 0x09: /* connection limit */
 
2353
        case 0x0a: /* synchronous connection limit */
 
2354
        case 0x0d: /* limited resources */
 
2355
        case 0x13: /* user ended the connection */
 
2356
        case 0x14: /* terminated due to low resources */
 
2357
        case 0x16: /* connection terminated */
 
2358
                return dbus_message_new_error(msg,
 
2359
                                        ERROR_INTERFACE ".AuthenticationCanceled",
 
2360
                                        "Authentication Canceled");
 
2361
 
 
2362
        case 0x05: /* authentication failure */
 
2363
        case 0x0E: /* rejected due to security reasons - is this auth failure? */
 
2364
        case 0x25: /* encryption mode not acceptable - is this auth failure? */
 
2365
        case 0x26: /* link key cannot be changed - is this auth failure? */
 
2366
        case 0x29: /* pairing with unit key unsupported - is this auth failure? */
 
2367
        case 0x2f: /* insufficient security - is this auth failure? */
 
2368
        default:
 
2369
                return dbus_message_new_error(msg,
 
2370
                                        ERROR_INTERFACE ".AuthenticationFailed",
 
2371
                                        "Authentication Failed");
 
2372
        }
 
2373
}
 
2374
 
 
2375
static void bonding_request_free(struct bonding_req *bonding)
 
2376
{
 
2377
        struct btd_device *device;
 
2378
 
 
2379
        if (!bonding)
 
2380
                return;
 
2381
 
 
2382
        if (bonding->listener_id)
 
2383
                g_dbus_remove_watch(bonding->conn, bonding->listener_id);
 
2384
 
 
2385
        if (bonding->msg)
 
2386
                dbus_message_unref(bonding->msg);
 
2387
 
 
2388
        if (bonding->conn)
 
2389
                dbus_connection_unref(bonding->conn);
 
2390
 
 
2391
        device = bonding->device;
 
2392
        g_free(bonding);
 
2393
 
 
2394
        if (!device)
 
2395
                return;
 
2396
 
 
2397
        device->bonding = NULL;
 
2398
 
 
2399
        if (!device->agent)
 
2400
                return;
 
2401
 
 
2402
        agent_cancel(device->agent);
 
2403
        agent_free(device->agent);
 
2404
        device->agent = NULL;
 
2405
}
 
2406
 
 
2407
void device_set_paired(struct btd_device *device, gboolean value)
 
2408
{
 
2409
        DBusConnection *conn = get_dbus_connection();
 
2410
 
 
2411
        if (device->paired == value)
 
2412
                return;
 
2413
 
 
2414
        if (!value)
 
2415
                btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
 
2416
                                                        device->bdaddr_type);
 
2417
 
 
2418
        device->paired = value;
 
2419
 
 
2420
        emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired",
 
2421
                                DBUS_TYPE_BOOLEAN, &value);
 
2422
}
 
2423
 
 
2424
static void device_agent_removed(struct agent *agent, void *user_data)
 
2425
{
 
2426
        struct btd_device *device = user_data;
 
2427
 
 
2428
        device->agent = NULL;
 
2429
 
 
2430
        if (device->authr)
 
2431
                device->authr->agent = NULL;
 
2432
}
 
2433
 
 
2434
static struct bonding_req *bonding_request_new(DBusConnection *conn,
 
2435
                                                DBusMessage *msg,
 
2436
                                                struct btd_device *device,
 
2437
                                                const char *agent_path,
 
2438
                                                uint8_t capability)
 
2439
{
 
2440
        struct bonding_req *bonding;
 
2441
        const char *name = dbus_message_get_sender(msg);
 
2442
        char addr[18];
 
2443
 
 
2444
        ba2str(&device->bdaddr, addr);
 
2445
        DBG("Requesting bonding for %s", addr);
 
2446
 
 
2447
        if (!agent_path)
 
2448
                goto proceed;
 
2449
 
 
2450
        device->agent = agent_create(device->adapter, name, agent_path,
 
2451
                                        capability,
 
2452
                                        device_agent_removed,
 
2453
                                        device);
 
2454
 
 
2455
        DBG("Temporary agent registered for %s at %s:%s",
 
2456
                        addr, name, agent_path);
 
2457
 
 
2458
proceed:
 
2459
        bonding = g_new0(struct bonding_req, 1);
 
2460
 
 
2461
        bonding->conn = dbus_connection_ref(conn);
 
2462
        bonding->msg = dbus_message_ref(msg);
 
2463
 
 
2464
        return bonding;
 
2465
}
 
2466
 
 
2467
static void create_bond_req_exit(DBusConnection *conn, void *user_data)
 
2468
{
 
2469
        struct btd_device *device = user_data;
 
2470
        char addr[18];
 
2471
 
 
2472
        ba2str(&device->bdaddr, addr);
 
2473
        DBG("%s: requestor exited before bonding was completed", addr);
 
2474
 
 
2475
        if (device->authr)
 
2476
                device_cancel_authentication(device, FALSE);
 
2477
 
 
2478
        if (device->bonding) {
 
2479
                device->bonding->listener_id = 0;
 
2480
                device_request_disconnect(device, NULL);
 
2481
        }
 
2482
}
 
2483
 
 
2484
DBusMessage *device_create_bonding(struct btd_device *device,
 
2485
                                        DBusConnection *conn,
 
2486
                                        DBusMessage *msg,
 
2487
                                        const char *agent_path,
 
2488
                                        uint8_t capability)
 
2489
{
 
2490
        struct btd_adapter *adapter = device->adapter;
 
2491
        struct bonding_req *bonding;
 
2492
        int err;
 
2493
 
 
2494
        if (device->bonding)
 
2495
                return btd_error_in_progress(msg);
 
2496
 
 
2497
        if (device_is_bonded(device))
 
2498
                return btd_error_already_exists(msg);
 
2499
 
 
2500
        if (device_is_le(device)) {
 
2501
                struct att_callbacks *attcb;
 
2502
                GError *gerr = NULL;
 
2503
                bdaddr_t sba;
 
2504
 
 
2505
                adapter_get_address(adapter, &sba);
 
2506
 
 
2507
                attcb = g_new0(struct att_callbacks, 1);
 
2508
                attcb->user_data = device;
 
2509
 
 
2510
                device->att_io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
 
2511
                                attcb, NULL, &gerr,
 
2512
                                BT_IO_OPT_SOURCE_BDADDR, &sba,
 
2513
                                BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
 
2514
                                BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
 
2515
                                BT_IO_OPT_CID, ATT_CID,
 
2516
                                BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
 
2517
                                BT_IO_OPT_INVALID);
 
2518
 
 
2519
                if (device->att_io == NULL) {
 
2520
                        DBusMessage *reply = btd_error_failed(msg,
 
2521
                                                                gerr->message);
 
2522
 
 
2523
                        error("Bonding bt_io_connect(): %s", gerr->message);
 
2524
                        g_error_free(gerr);
 
2525
                        g_free(attcb);
 
2526
                        return reply;
 
2527
                }
 
2528
        }
 
2529
 
 
2530
        err = adapter_create_bonding(adapter, &device->bdaddr,
 
2531
                                        device->bdaddr_type, capability);
 
2532
        if (err < 0)
 
2533
                return btd_error_failed(msg, strerror(-err));
 
2534
 
 
2535
        bonding = bonding_request_new(conn, msg, device, agent_path,
 
2536
                                        capability);
 
2537
 
 
2538
        bonding->listener_id = g_dbus_add_disconnect_watch(conn,
 
2539
                                                dbus_message_get_sender(msg),
 
2540
                                                create_bond_req_exit, device,
 
2541
                                                NULL);
 
2542
 
 
2543
        device->bonding = bonding;
 
2544
        bonding->device = device;
 
2545
 
 
2546
        return NULL;
 
2547
}
 
2548
 
 
2549
void device_simple_pairing_complete(struct btd_device *device, uint8_t status)
 
2550
{
 
2551
        struct authentication_req *auth = device->authr;
 
2552
 
 
2553
        if (auth && (auth->type == AUTH_TYPE_NOTIFY_PASSKEY
 
2554
                     || auth->type == AUTH_TYPE_NOTIFY_PINCODE) && auth->agent)
 
2555
                agent_cancel(auth->agent);
 
2556
}
 
2557
 
 
2558
static void device_auth_req_free(struct btd_device *device)
 
2559
{
 
2560
        if (device->authr)
 
2561
                g_free(device->authr->pincode);
 
2562
        g_free(device->authr);
 
2563
        device->authr = NULL;
 
2564
}
 
2565
 
 
2566
void device_bonding_complete(struct btd_device *device, uint8_t status)
 
2567
{
 
2568
        struct bonding_req *bonding = device->bonding;
 
2569
        struct authentication_req *auth = device->authr;
 
2570
 
 
2571
        DBG("bonding %p status 0x%02x", bonding, status);
 
2572
 
 
2573
        if (auth && (auth->type == AUTH_TYPE_NOTIFY_PASSKEY
 
2574
                     || auth->type == AUTH_TYPE_NOTIFY_PINCODE) && auth->agent)
 
2575
                agent_cancel(auth->agent);
 
2576
 
 
2577
        if (status) {
 
2578
                device_cancel_authentication(device, TRUE);
 
2579
                device_cancel_bonding(device, status);
 
2580
                return;
 
2581
        }
 
2582
 
 
2583
        device_auth_req_free(device);
 
2584
 
 
2585
        /* If we're already paired nothing more is needed */
 
2586
        if (device->paired)
 
2587
                return;
 
2588
 
 
2589
        device_set_paired(device, TRUE);
 
2590
 
 
2591
        /* If we were initiators start service discovery immediately.
 
2592
         * However if the other end was the initator wait a few seconds
 
2593
         * before SDP. This is due to potential IOP issues if the other
 
2594
         * end starts doing SDP at the same time as us */
 
2595
        if (bonding) {
 
2596
                DBG("Proceeding with service discovery");
 
2597
                /* If we are initiators remove any discovery timer and just
 
2598
                 * start discovering services directly */
 
2599
                if (device->discov_timer) {
 
2600
                        g_source_remove(device->discov_timer);
 
2601
                        device->discov_timer = 0;
 
2602
                }
 
2603
 
 
2604
                if (device_is_bredr(device))
 
2605
                        device_browse_sdp(device, bonding->conn, bonding->msg,
 
2606
                                                                NULL, FALSE);
 
2607
                else
 
2608
                        device_browse_primary(device, bonding->conn,
 
2609
                                                        bonding->msg, FALSE);
 
2610
 
 
2611
                bonding_request_free(bonding);
 
2612
        } else {
 
2613
                if (!device->browse && !device->discov_timer &&
 
2614
                                main_opts.reverse_sdp) {
 
2615
                        /* If we are not initiators and there is no currently
 
2616
                         * active discovery or discovery timer, set discovery
 
2617
                         * timer */
 
2618
                        DBG("setting timer for reverse service discovery");
 
2619
                        device->discov_timer = g_timeout_add_seconds(
 
2620
                                                        DISCOVERY_TIMER,
 
2621
                                                        start_discovery,
 
2622
                                                        device);
 
2623
                }
 
2624
        }
 
2625
}
 
2626
 
 
2627
gboolean device_is_creating(struct btd_device *device, const char *sender)
 
2628
{
 
2629
        DBusMessage *msg;
 
2630
 
 
2631
        if (device->bonding && device->bonding->msg)
 
2632
                msg = device->bonding->msg;
 
2633
        else if (device->browse && device->browse->msg)
 
2634
                msg = device->browse->msg;
 
2635
        else
 
2636
                return FALSE;
 
2637
 
 
2638
        if (!dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
 
2639
                                                "CreatePairedDevice") &&
 
2640
                        !dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
 
2641
                                                        "CreateDevice"))
 
2642
                return FALSE;
 
2643
 
 
2644
        if (sender == NULL)
 
2645
                return TRUE;
 
2646
 
 
2647
        return g_str_equal(sender, dbus_message_get_sender(msg));
 
2648
}
 
2649
 
 
2650
gboolean device_is_bonding(struct btd_device *device, const char *sender)
 
2651
{
 
2652
        struct bonding_req *bonding = device->bonding;
 
2653
 
 
2654
        if (!device->bonding)
 
2655
                return FALSE;
 
2656
 
 
2657
        if (!sender)
 
2658
                return TRUE;
 
2659
 
 
2660
        return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
 
2661
}
 
2662
 
 
2663
void device_cancel_bonding(struct btd_device *device, uint8_t status)
 
2664
{
 
2665
        struct bonding_req *bonding = device->bonding;
 
2666
        DBusMessage *reply;
 
2667
        char addr[18];
 
2668
 
 
2669
        if (!bonding)
 
2670
                return;
 
2671
 
 
2672
        ba2str(&device->bdaddr, addr);
 
2673
        DBG("Canceling bonding request for %s", addr);
 
2674
 
 
2675
        if (device->authr)
 
2676
                device_cancel_authentication(device, FALSE);
 
2677
 
 
2678
        reply = new_authentication_return(bonding->msg, status);
 
2679
        g_dbus_send_message(bonding->conn, reply);
 
2680
 
 
2681
        bonding_request_cancel(bonding);
 
2682
        bonding_request_free(bonding);
 
2683
}
 
2684
 
 
2685
static void pincode_cb(struct agent *agent, DBusError *err,
 
2686
                                        const char *pincode, void *data)
 
2687
{
 
2688
        struct authentication_req *auth = data;
 
2689
        struct btd_device *device = auth->device;
 
2690
        struct btd_adapter *adapter = device_get_adapter(device);
 
2691
        struct agent *adapter_agent = adapter_get_agent(adapter);
 
2692
 
 
2693
        if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
 
2694
                                g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
 
2695
 
 
2696
                if (auth->agent == adapter_agent || adapter_agent == NULL)
 
2697
                        goto done;
 
2698
 
 
2699
                if (agent_request_pincode(adapter_agent, device, pincode_cb,
 
2700
                                                auth->secure, auth, NULL) < 0)
 
2701
                        goto done;
 
2702
 
 
2703
                auth->agent = adapter_agent;
 
2704
                return;
 
2705
        }
 
2706
 
 
2707
done:
 
2708
        /* No need to reply anything if the authentication already failed */
 
2709
        if (auth->cb == NULL)
 
2710
                return;
 
2711
 
 
2712
        ((agent_pincode_cb) auth->cb)(agent, err, pincode, device);
 
2713
 
 
2714
        device->authr->cb = NULL;
 
2715
        device->authr->agent = NULL;
 
2716
}
 
2717
 
 
2718
static void confirm_cb(struct agent *agent, DBusError *err, void *data)
 
2719
{
 
2720
        struct authentication_req *auth = data;
 
2721
        struct btd_device *device = auth->device;
 
2722
        struct btd_adapter *adapter = device_get_adapter(device);
 
2723
        struct agent *adapter_agent = adapter_get_agent(adapter);
 
2724
 
 
2725
        if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
 
2726
                                g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
 
2727
 
 
2728
                if (auth->agent == adapter_agent || adapter_agent == NULL)
 
2729
                        goto done;
 
2730
 
 
2731
                if (agent_request_confirmation(adapter_agent, device,
 
2732
                                                auth->passkey, confirm_cb,
 
2733
                                                auth, NULL) < 0)
 
2734
                        goto done;
 
2735
 
 
2736
                auth->agent = adapter_agent;
 
2737
                return;
 
2738
        }
 
2739
 
 
2740
done:
 
2741
        /* No need to reply anything if the authentication already failed */
 
2742
        if (auth->cb == NULL)
 
2743
                return;
 
2744
 
 
2745
        ((agent_cb) auth->cb)(agent, err, device);
 
2746
 
 
2747
        device->authr->cb = NULL;
 
2748
        device->authr->agent = NULL;
 
2749
}
 
2750
 
 
2751
static void passkey_cb(struct agent *agent, DBusError *err,
 
2752
                                                uint32_t passkey, void *data)
 
2753
{
 
2754
        struct authentication_req *auth = data;
 
2755
        struct btd_device *device = auth->device;
 
2756
        struct btd_adapter *adapter = device_get_adapter(device);
 
2757
        struct agent *adapter_agent = adapter_get_agent(adapter);
 
2758
 
 
2759
        if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
 
2760
                                g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
 
2761
 
 
2762
                if (auth->agent == adapter_agent || adapter_agent == NULL)
 
2763
                        goto done;
 
2764
 
 
2765
                if (agent_request_passkey(adapter_agent, device, passkey_cb,
 
2766
                                                        auth, NULL) < 0)
 
2767
                        goto done;
 
2768
 
 
2769
                auth->agent = adapter_agent;
 
2770
                return;
 
2771
        }
 
2772
 
 
2773
done:
 
2774
        /* No need to reply anything if the authentication already failed */
 
2775
        if (auth->cb == NULL)
 
2776
                return;
 
2777
 
 
2778
        ((agent_passkey_cb) auth->cb)(agent, err, passkey, device);
 
2779
 
 
2780
        device->authr->cb = NULL;
 
2781
        device->authr->agent = NULL;
 
2782
}
 
2783
 
 
2784
static void display_pincode_cb(struct agent *agent, DBusError *err, void *data)
 
2785
{
 
2786
        struct authentication_req *auth = data;
 
2787
        struct btd_device *device = auth->device;
 
2788
        struct btd_adapter *adapter = device_get_adapter(device);
 
2789
        struct agent *adapter_agent = adapter_get_agent(adapter);
 
2790
 
 
2791
        if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) ||
 
2792
                                g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) {
 
2793
 
 
2794
                /* Request a pincode if we fail to display one */
 
2795
                if (auth->agent == adapter_agent || adapter_agent == NULL) {
 
2796
                        if (agent_request_pincode(agent, device, pincode_cb,
 
2797
                                                auth->secure, auth, NULL) < 0)
 
2798
                                goto done;
 
2799
                        return;
 
2800
                }
 
2801
 
 
2802
                if (agent_display_pincode(adapter_agent, device, auth->pincode,
 
2803
                                        display_pincode_cb, auth, NULL) < 0)
 
2804
                        goto done;
 
2805
 
 
2806
                auth->agent = adapter_agent;
 
2807
                return;
 
2808
        }
 
2809
 
 
2810
done:
 
2811
        /* No need to reply anything if the authentication already failed */
 
2812
        if (auth->cb == NULL)
 
2813
                return;
 
2814
 
 
2815
        ((agent_pincode_cb) auth->cb)(agent, err, auth->pincode, device);
 
2816
 
 
2817
        g_free(device->authr->pincode);
 
2818
        device->authr->pincode = NULL;
 
2819
        device->authr->cb = NULL;
 
2820
        device->authr->agent = NULL;
 
2821
}
 
2822
 
 
2823
 
 
2824
static struct authentication_req *new_auth(struct btd_device *device,
 
2825
                                           auth_type_t type, gboolean secure,
 
2826
                                           void *cb)
 
2827
{
 
2828
        struct authentication_req *auth;
 
2829
        struct agent *agent;
 
2830
        char addr[18];
 
2831
 
 
2832
        ba2str(&device->bdaddr, addr);
 
2833
        DBG("Requesting agent authentication for %s", addr);
 
2834
 
 
2835
        if (device->authr) {
 
2836
                error("Authentication already requested for %s", addr);
 
2837
                return NULL;
 
2838
        }
 
2839
 
 
2840
        agent = device_get_agent(device);
 
2841
        if (!agent) {
 
2842
                error("No agent available for request type %d", type);
 
2843
                return NULL;
 
2844
        }
 
2845
 
 
2846
        auth = g_new0(struct authentication_req, 1);
 
2847
        auth->agent = agent;
 
2848
        auth->device = device;
 
2849
        auth->cb = cb;
 
2850
        auth->type = type;
 
2851
        auth->secure = secure;
 
2852
        device->authr = auth;
 
2853
 
 
2854
        return auth;
 
2855
}
 
2856
 
 
2857
int device_request_pincode(struct btd_device *device, gboolean secure,
 
2858
                           void *cb)
 
2859
{
 
2860
        struct authentication_req *auth;
 
2861
        int err;
 
2862
 
 
2863
        auth = new_auth(device, AUTH_TYPE_PINCODE, secure, cb);
 
2864
        if (!auth)
 
2865
                return -EPERM;
 
2866
 
 
2867
        err = agent_request_pincode(auth->agent, device, pincode_cb, secure,
 
2868
                                    auth, NULL);
 
2869
        if (err < 0) {
 
2870
                error("Failed requesting authentication");
 
2871
                device_auth_req_free(device);
 
2872
        }
 
2873
 
 
2874
        return err;
 
2875
}
 
2876
 
 
2877
int device_request_passkey(struct btd_device *device, void *cb)
 
2878
{
 
2879
        struct authentication_req *auth;
 
2880
        int err;
 
2881
 
 
2882
        auth = new_auth(device, AUTH_TYPE_PASSKEY, FALSE, cb);
 
2883
        if (!auth)
 
2884
                return -EPERM;
 
2885
 
 
2886
        err = agent_request_passkey(auth->agent, device, passkey_cb, auth,
 
2887
                                    NULL);
 
2888
        if (err < 0) {
 
2889
                error("Failed requesting authentication");
 
2890
                device_auth_req_free(device);
 
2891
        }
 
2892
 
 
2893
        return err;
 
2894
}
 
2895
 
 
2896
int device_confirm_passkey(struct btd_device *device, uint32_t passkey,
 
2897
                           void *cb)
 
2898
{
 
2899
        struct authentication_req *auth;
 
2900
        int err;
 
2901
 
 
2902
        auth = new_auth(device, AUTH_TYPE_CONFIRM, FALSE, cb);
 
2903
        if (!auth)
 
2904
                return -EPERM;
 
2905
 
 
2906
        auth->passkey = passkey;
 
2907
 
 
2908
        err = agent_request_confirmation(auth->agent, device, passkey,
 
2909
                                         confirm_cb, auth, NULL);
 
2910
        if (err < 0) {
 
2911
                error("Failed requesting authentication");
 
2912
                device_auth_req_free(device);
 
2913
        }
 
2914
 
 
2915
        return err;
 
2916
}
 
2917
 
 
2918
int device_notify_passkey(struct btd_device *device, uint32_t passkey,
 
2919
                          uint8_t entered)
 
2920
{
 
2921
        struct authentication_req *auth;
 
2922
        int err;
 
2923
 
 
2924
        if (device->authr) {
 
2925
                auth = device->authr;
 
2926
                if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY)
 
2927
                        return -EPERM;
 
2928
        } else {
 
2929
                auth = new_auth(device, AUTH_TYPE_NOTIFY_PASSKEY, FALSE, NULL);
 
2930
                if (!auth)
 
2931
                        return -EPERM;
 
2932
        }
 
2933
 
 
2934
        err = agent_display_passkey(auth->agent, device, passkey, entered);
 
2935
        if (err < 0) {
 
2936
                error("Failed requesting authentication");
 
2937
                device_auth_req_free(device);
 
2938
        }
 
2939
 
 
2940
        return err;
 
2941
}
 
2942
 
 
2943
int device_notify_pincode(struct btd_device *device, gboolean secure,
 
2944
                          const char *pincode, void *cb)
 
2945
{
 
2946
        struct authentication_req *auth;
 
2947
        int err;
 
2948
 
 
2949
        auth = new_auth(device, AUTH_TYPE_NOTIFY_PINCODE, secure, cb);
 
2950
        if (!auth)
 
2951
                return -EPERM;
 
2952
 
 
2953
        auth->pincode = g_strdup(pincode);
 
2954
 
 
2955
        err = agent_display_pincode(auth->agent, device, pincode,
 
2956
                                    display_pincode_cb, auth, NULL);
 
2957
        if (err < 0) {
 
2958
                error("Failed requesting authentication");
 
2959
                device_auth_req_free(device);
 
2960
        }
 
2961
 
 
2962
        return err;
 
2963
}
 
2964
 
 
2965
static void cancel_authentication(struct authentication_req *auth)
 
2966
{
 
2967
        struct btd_device *device;
 
2968
        struct agent *agent;
 
2969
        DBusError err;
 
2970
 
 
2971
        if (!auth || !auth->cb)
 
2972
                return;
 
2973
 
 
2974
        device = auth->device;
 
2975
        agent = auth->agent;
 
2976
 
 
2977
        dbus_error_init(&err);
 
2978
        dbus_set_error_const(&err, "org.bluez.Error.Canceled", NULL);
 
2979
 
 
2980
        switch (auth->type) {
 
2981
        case AUTH_TYPE_PINCODE:
 
2982
                ((agent_pincode_cb) auth->cb)(agent, &err, NULL, device);
 
2983
                break;
 
2984
        case AUTH_TYPE_CONFIRM:
 
2985
                ((agent_cb) auth->cb)(agent, &err, device);
 
2986
                break;
 
2987
        case AUTH_TYPE_PASSKEY:
 
2988
                ((agent_passkey_cb) auth->cb)(agent, &err, 0, device);
 
2989
                break;
 
2990
        case AUTH_TYPE_NOTIFY_PASSKEY:
 
2991
                /* User Notify doesn't require any reply */
 
2992
                break;
 
2993
        case AUTH_TYPE_NOTIFY_PINCODE:
 
2994
                ((agent_pincode_cb) auth->cb)(agent, &err, NULL, device);
 
2995
                break;
 
2996
        }
 
2997
 
 
2998
        dbus_error_free(&err);
 
2999
        auth->cb = NULL;
 
3000
}
 
3001
 
 
3002
void device_cancel_authentication(struct btd_device *device, gboolean aborted)
 
3003
{
 
3004
        struct authentication_req *auth = device->authr;
 
3005
        char addr[18];
 
3006
 
 
3007
        if (!auth)
 
3008
                return;
 
3009
 
 
3010
        ba2str(&device->bdaddr, addr);
 
3011
        DBG("Canceling authentication request for %s", addr);
 
3012
 
 
3013
        if (auth->agent)
 
3014
                agent_cancel(auth->agent);
 
3015
 
 
3016
        if (!aborted)
 
3017
                cancel_authentication(auth);
 
3018
 
 
3019
        device_auth_req_free(device);
 
3020
}
 
3021
 
 
3022
gboolean device_is_authenticating(struct btd_device *device)
 
3023
{
 
3024
        return (device->authr != NULL);
 
3025
}
 
3026
 
 
3027
gboolean device_is_authorizing(struct btd_device *device)
 
3028
{
 
3029
        return device->authorizing;
 
3030
}
 
3031
 
 
3032
void device_set_authorizing(struct btd_device *device, gboolean auth)
 
3033
{
 
3034
        device->authorizing = auth;
 
3035
}
 
3036
 
 
3037
void device_register_services(DBusConnection *conn, struct btd_device *device,
 
3038
                                                GSList *prim_list, int psm)
 
3039
{
 
3040
        device->primaries = g_slist_concat(device->primaries, prim_list);
 
3041
        device->services = attrib_client_register(conn, device, psm, NULL,
 
3042
                                                                prim_list);
 
3043
}
 
3044
 
 
3045
GSList *btd_device_get_primaries(struct btd_device *device)
 
3046
{
 
3047
        return device->primaries;
 
3048
}
 
3049
 
 
3050
void btd_device_add_uuid(struct btd_device *device, const char *uuid)
 
3051
{
 
3052
        GSList *uuid_list;
 
3053
        char *new_uuid;
 
3054
 
 
3055
        if (g_slist_find_custom(device->uuids, uuid,
 
3056
                                (GCompareFunc) strcasecmp))
 
3057
                return;
 
3058
 
 
3059
        new_uuid = g_strdup(uuid);
 
3060
        uuid_list = g_slist_append(NULL, new_uuid);
 
3061
 
 
3062
        device_probe_drivers(device, uuid_list);
 
3063
 
 
3064
        g_free(new_uuid);
 
3065
        g_slist_free(uuid_list);
 
3066
 
 
3067
        store_profiles(device);
 
3068
        services_changed(device);
 
3069
}
 
3070
 
 
3071
const sdp_record_t *btd_device_get_record(struct btd_device *device,
 
3072
                                                        const char *uuid)
 
3073
{
 
3074
        bdaddr_t src;
 
3075
 
 
3076
        if (device->tmp_records) {
 
3077
                const sdp_record_t *record;
 
3078
 
 
3079
                record = find_record_in_list(device->tmp_records, uuid);
 
3080
                if (record != NULL)
 
3081
                        return record;
 
3082
        }
 
3083
 
 
3084
        adapter_get_address(device->adapter, &src);
 
3085
 
 
3086
        device->tmp_records = read_records(&src, &device->bdaddr);
 
3087
        if (!device->tmp_records)
 
3088
                return NULL;
 
3089
 
 
3090
        return find_record_in_list(device->tmp_records, uuid);
 
3091
}
 
3092
 
 
3093
int btd_register_device_driver(struct btd_device_driver *driver)
 
3094
{
 
3095
        device_drivers = g_slist_append(device_drivers, driver);
 
3096
 
 
3097
        return 0;
 
3098
}
 
3099
 
 
3100
void btd_unregister_device_driver(struct btd_device_driver *driver)
 
3101
{
 
3102
        device_drivers = g_slist_remove(device_drivers, driver);
 
3103
}
 
3104
 
 
3105
struct btd_device *btd_device_ref(struct btd_device *device)
 
3106
{
 
3107
        device->ref++;
 
3108
 
 
3109
        DBG("%p: ref=%d", device, device->ref);
 
3110
 
 
3111
        return device;
 
3112
}
 
3113
 
 
3114
void btd_device_unref(struct btd_device *device)
 
3115
{
 
3116
        DBusConnection *conn = get_dbus_connection();
 
3117
        gchar *path;
 
3118
 
 
3119
        device->ref--;
 
3120
 
 
3121
        DBG("%p: ref=%d", device, device->ref);
 
3122
 
 
3123
        if (device->ref > 0)
 
3124
                return;
 
3125
 
 
3126
        path = g_strdup(device->path);
 
3127
 
 
3128
        g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE);
 
3129
 
 
3130
        g_free(path);
 
3131
}
 
3132
 
 
3133
void device_set_class(struct btd_device *device, uint32_t value)
 
3134
{
 
3135
        DBusConnection *conn = get_dbus_connection();
 
3136
 
 
3137
        emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Class",
 
3138
                                DBUS_TYPE_UINT32, &value);
 
3139
}
 
3140
 
 
3141
static gboolean notify_attios(gpointer user_data)
 
3142
{
 
3143
        struct btd_device *device = user_data;
 
3144
 
 
3145
        if (device->attrib == NULL)
 
3146
                return FALSE;
 
3147
 
 
3148
        g_slist_foreach(device->attios_offline, attio_connected, device->attrib);
 
3149
        device->attios = g_slist_concat(device->attios, device->attios_offline);
 
3150
        device->attios_offline = NULL;
 
3151
 
 
3152
        return FALSE;
 
3153
}
 
3154
 
 
3155
guint btd_device_add_attio_callback(struct btd_device *device,
 
3156
                                                attio_connect_cb cfunc,
 
3157
                                                attio_disconnect_cb dcfunc,
 
3158
                                                gpointer user_data)
 
3159
{
 
3160
        struct attio_data *attio;
 
3161
        static guint attio_id = 0;
 
3162
 
 
3163
        DBG("%p registered ATT connection callback", device);
 
3164
 
 
3165
        attio = g_new0(struct attio_data, 1);
 
3166
        attio->id = ++attio_id;
 
3167
        attio->cfunc = cfunc;
 
3168
        attio->dcfunc = dcfunc;
 
3169
        attio->user_data = user_data;
 
3170
 
 
3171
        if (device->attrib && cfunc) {
 
3172
                device->attios_offline = g_slist_append(device->attios_offline,
 
3173
                                                                        attio);
 
3174
                g_idle_add(notify_attios, device);
 
3175
                return attio->id;
 
3176
        }
 
3177
 
 
3178
        device->attios = g_slist_append(device->attios, attio);
 
3179
 
 
3180
        if (device->auto_id == 0)
 
3181
                device->auto_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
 
3182
                                                att_connect, device,
 
3183
                                                att_connect_dispatched);
 
3184
 
 
3185
        return attio->id;
 
3186
}
 
3187
 
 
3188
static int attio_id_cmp(gconstpointer a, gconstpointer b)
 
3189
{
 
3190
        const struct attio_data *attio = a;
 
3191
        guint id = GPOINTER_TO_UINT(b);
 
3192
 
 
3193
        return attio->id - id;
 
3194
}
 
3195
 
 
3196
gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
 
3197
{
 
3198
        struct attio_data *attio;
 
3199
        GSList *l;
 
3200
 
 
3201
        l = g_slist_find_custom(device->attios, GUINT_TO_POINTER(id),
 
3202
                                                                attio_id_cmp);
 
3203
        if (l) {
 
3204
                attio = l->data;
 
3205
                device->attios = g_slist_remove(device->attios, attio);
 
3206
        } else {
 
3207
                l = g_slist_find_custom(device->attios_offline,
 
3208
                                        GUINT_TO_POINTER(id), attio_id_cmp);
 
3209
                if (!l)
 
3210
                        return FALSE;
 
3211
 
 
3212
                attio = l->data;
 
3213
                device->attios_offline = g_slist_remove(device->attios_offline,
 
3214
                                                                        attio);
 
3215
        }
 
3216
 
 
3217
        g_free(attio);
 
3218
 
 
3219
        if (device->attios != NULL || device->attios_offline != NULL)
 
3220
                return TRUE;
 
3221
 
 
3222
        if (device->auto_id) {
 
3223
                g_source_remove(device->auto_id);
 
3224
                device->auto_id = 0;
 
3225
        }
 
3226
 
 
3227
        att_cleanup(device);
 
3228
 
 
3229
        return TRUE;
 
3230
}
 
3231
 
 
3232
void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
 
3233
                        uint16_t vendor_id, uint16_t product_id,
 
3234
                        uint16_t product_ver)
 
3235
{
 
3236
        device_set_vendor(device, vendor_id);
 
3237
        device_set_vendor_src(device, vendor_id_src);
 
3238
        device_set_product(device, product_id);
 
3239
        device_set_version(device, product_ver);
 
3240
}