~bluetooth/bluez/vivid-phone-overlay

« back to all changes in this revision

Viewing changes to .pc/ssp_parameter.patch/src/event.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
#define _GNU_SOURCE
 
30
#include <stdio.h>
 
31
#include <ctype.h>
 
32
#include <errno.h>
 
33
#include <unistd.h>
 
34
#include <stdlib.h>
 
35
#include <string.h>
 
36
 
 
37
#include <bluetooth/bluetooth.h>
 
38
 
 
39
#include <glib.h>
 
40
#include <dbus/dbus.h>
 
41
 
 
42
#include "log.h"
 
43
 
 
44
#include "adapter.h"
 
45
#include "manager.h"
 
46
#include "device.h"
 
47
#include "error.h"
 
48
#include "dbus-common.h"
 
49
#include "agent.h"
 
50
#include "storage.h"
 
51
#include "event.h"
 
52
 
 
53
static gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
 
54
                                        struct btd_adapter **adapter,
 
55
                                        struct btd_device **device,
 
56
                                        gboolean create)
 
57
{
 
58
        DBusConnection *conn = get_dbus_connection();
 
59
        char peer_addr[18];
 
60
 
 
61
        *adapter = manager_find_adapter(src);
 
62
        if (!*adapter) {
 
63
                error("Unable to find matching adapter");
 
64
                return FALSE;
 
65
        }
 
66
 
 
67
        ba2str(dst, peer_addr);
 
68
 
 
69
        if (create)
 
70
                *device = adapter_get_device(conn, *adapter, peer_addr);
 
71
        else
 
72
                *device = adapter_find_device(*adapter, peer_addr);
 
73
 
 
74
        if (create && !*device) {
 
75
                error("Unable to get device object!");
 
76
                return FALSE;
 
77
        }
 
78
 
 
79
        return TRUE;
 
80
}
 
81
 
 
82
/*****************************************************************
 
83
 *
 
84
 *  Section reserved to HCI commands confirmation handling and low
 
85
 *  level events(eg: device attached/dettached.
 
86
 *
 
87
 *****************************************************************/
 
88
 
 
89
static void pincode_cb(struct agent *agent, DBusError *derr,
 
90
                                const char *pincode, struct btd_device *device)
 
91
{
 
92
        struct btd_adapter *adapter = device_get_adapter(device);
 
93
        bdaddr_t dba;
 
94
        int err;
 
95
 
 
96
        device_get_address(device, &dba, NULL);
 
97
 
 
98
        if (derr) {
 
99
                err = btd_adapter_pincode_reply(adapter, &dba, NULL, 0);
 
100
                if (err < 0)
 
101
                        goto fail;
 
102
                return;
 
103
        }
 
104
 
 
105
        err = btd_adapter_pincode_reply(adapter, &dba, pincode,
 
106
                                                pincode ? strlen(pincode) : 0);
 
107
        if (err < 0)
 
108
                goto fail;
 
109
 
 
110
        return;
 
111
 
 
112
fail:
 
113
        error("Sending PIN code reply failed: %s (%d)", strerror(-err), -err);
 
114
}
 
115
 
 
116
int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba, gboolean secure)
 
117
{
 
118
        struct btd_adapter *adapter;
 
119
        struct btd_device *device;
 
120
        char pin[17];
 
121
        ssize_t pinlen;
 
122
        gboolean display = FALSE;
 
123
 
 
124
        if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
 
125
                return -ENODEV;
 
126
 
 
127
        memset(pin, 0, sizeof(pin));
 
128
        pinlen = btd_adapter_get_pin(adapter, device, pin, &display);
 
129
        if (pinlen > 0 && (!secure || pinlen == 16)) {
 
130
                if (display && device_is_bonding(device, NULL))
 
131
                        return device_request_authentication(device,
 
132
                                                AUTH_TYPE_NOTIFY_PINCODE, pin,
 
133
                                                secure, pincode_cb);
 
134
 
 
135
                btd_adapter_pincode_reply(adapter, dba, pin, pinlen);
 
136
                return 0;
 
137
        }
 
138
 
 
139
        return device_request_authentication(device, AUTH_TYPE_PINCODE, NULL,
 
140
                                                        secure, pincode_cb);
 
141
}
 
142
 
 
143
static int confirm_reply(struct btd_adapter *adapter,
 
144
                                struct btd_device *device, gboolean success)
 
145
{
 
146
        bdaddr_t bdaddr;
 
147
        uint8_t bdaddr_type;
 
148
 
 
149
        device_get_address(device, &bdaddr, &bdaddr_type);
 
150
 
 
151
        return btd_adapter_confirm_reply(adapter, &bdaddr, bdaddr_type,
 
152
                                                                success);
 
153
}
 
154
 
 
155
static void confirm_cb(struct agent *agent, DBusError *err, void *user_data)
 
156
{
 
157
        struct btd_device *device = user_data;
 
158
        struct btd_adapter *adapter = device_get_adapter(device);
 
159
        gboolean success = (err == NULL) ? TRUE : FALSE;
 
160
 
 
161
        confirm_reply(adapter, device, success);
 
162
}
 
163
 
 
164
static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
 
165
                        void *user_data)
 
166
{
 
167
        struct btd_device *device = user_data;
 
168
        struct btd_adapter *adapter = device_get_adapter(device);
 
169
        bdaddr_t bdaddr;
 
170
        uint8_t bdaddr_type;
 
171
 
 
172
        device_get_address(device, &bdaddr, &bdaddr_type);
 
173
 
 
174
        if (err)
 
175
                passkey = INVALID_PASSKEY;
 
176
 
 
177
        btd_adapter_passkey_reply(adapter, &bdaddr, bdaddr_type, passkey);
 
178
}
 
179
 
 
180
int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
 
181
{
 
182
        struct btd_adapter *adapter;
 
183
        struct btd_device *device;
 
184
 
 
185
        if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
 
186
                return -ENODEV;
 
187
 
 
188
        return device_request_authentication(device, AUTH_TYPE_CONFIRM,
 
189
                                                &passkey, FALSE, confirm_cb);
 
190
}
 
191
 
 
192
int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba)
 
193
{
 
194
        struct btd_adapter *adapter;
 
195
        struct btd_device *device;
 
196
 
 
197
        if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
 
198
                return -ENODEV;
 
199
 
 
200
        return device_request_authentication(device, AUTH_TYPE_PASSKEY, NULL,
 
201
                                                        FALSE, passkey_cb);
 
202
}
 
203
 
 
204
int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
 
205
{
 
206
        struct btd_adapter *adapter;
 
207
        struct btd_device *device;
 
208
 
 
209
        if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
 
210
                return -ENODEV;
 
211
 
 
212
        return device_request_authentication(device, AUTH_TYPE_NOTIFY_PASSKEY,
 
213
                                                        &passkey, FALSE, NULL);
 
214
}
 
215
 
 
216
void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer,
 
217
                                                                uint8_t status)
 
218
{
 
219
        struct btd_adapter *adapter;
 
220
        struct btd_device *device;
 
221
        gboolean create;
 
222
 
 
223
        DBG("status=%02x", status);
 
224
 
 
225
        create = status ? FALSE : TRUE;
 
226
 
 
227
        if (!get_adapter_and_device(local, peer, &adapter, &device, create))
 
228
                return;
 
229
 
 
230
        if (!device)
 
231
                return;
 
232
 
 
233
        device_simple_pairing_complete(device, status);
 
234
}
 
235
 
 
236
static void update_lastseen(bdaddr_t *sba, bdaddr_t *dba)
 
237
{
 
238
        time_t t;
 
239
        struct tm *tm;
 
240
 
 
241
        t = time(NULL);
 
242
        tm = gmtime(&t);
 
243
 
 
244
        write_lastseen_info(sba, dba, tm);
 
245
}
 
246
 
 
247
static void update_lastused(bdaddr_t *sba, bdaddr_t *dba)
 
248
{
 
249
        time_t t;
 
250
        struct tm *tm;
 
251
 
 
252
        t = time(NULL);
 
253
        tm = gmtime(&t);
 
254
 
 
255
        write_lastused_info(sba, dba, tm);
 
256
}
 
257
 
 
258
void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
 
259
                                        int8_t rssi, uint8_t confirm_name,
 
260
                                        uint8_t *data, uint8_t data_len)
 
261
{
 
262
        struct btd_adapter *adapter;
 
263
 
 
264
        adapter = manager_find_adapter(local);
 
265
        if (!adapter) {
 
266
                error("No matching adapter found");
 
267
                return;
 
268
        }
 
269
 
 
270
        update_lastseen(local, peer);
 
271
 
 
272
        if (data)
 
273
                write_remote_eir(local, peer, data, data_len);
 
274
 
 
275
        adapter_update_found_devices(adapter, peer, bdaddr_type, rssi,
 
276
                                                confirm_name, data, data_len);
 
277
}
 
278
 
 
279
void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer,
 
280
                                                        gboolean legacy)
 
281
{
 
282
        struct btd_adapter *adapter;
 
283
        struct remote_dev_info *dev;
 
284
 
 
285
        adapter = manager_find_adapter(local);
 
286
        if (!adapter) {
 
287
                error("No matching adapter found");
 
288
                return;
 
289
        }
 
290
 
 
291
        dev = adapter_search_found_devices(adapter, peer);
 
292
        if (dev)
 
293
                dev->legacy = legacy;
 
294
}
 
295
 
 
296
void btd_event_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class)
 
297
{
 
298
        struct btd_adapter *adapter;
 
299
        struct btd_device *device;
 
300
        uint32_t old_class = 0;
 
301
 
 
302
        read_remote_class(local, peer, &old_class);
 
303
 
 
304
        if (old_class == class)
 
305
                return;
 
306
 
 
307
        write_remote_class(local, peer, class);
 
308
 
 
309
        if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
 
310
                return;
 
311
 
 
312
        if (!device)
 
313
                return;
 
314
 
 
315
        device_set_class(device, class);
 
316
}
 
317
 
 
318
void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
 
319
{
 
320
        struct btd_adapter *adapter;
 
321
        struct btd_device *device;
 
322
        struct remote_dev_info *dev_info;
 
323
 
 
324
        if (!g_utf8_validate(name, -1, NULL)) {
 
325
                int i;
 
326
 
 
327
                /* Assume ASCII, and replace all non-ASCII with spaces */
 
328
                for (i = 0; name[i] != '\0'; i++) {
 
329
                        if (!isascii(name[i]))
 
330
                                name[i] = ' ';
 
331
                }
 
332
                /* Remove leading and trailing whitespace characters */
 
333
                g_strstrip(name);
 
334
        }
 
335
 
 
336
        write_device_name(local, peer, name);
 
337
 
 
338
        if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
 
339
                return;
 
340
 
 
341
        dev_info = adapter_search_found_devices(adapter, peer);
 
342
        if (dev_info) {
 
343
                g_free(dev_info->name);
 
344
                dev_info->name = g_strdup(name);
 
345
                adapter_emit_device_found(adapter, dev_info);
 
346
        }
 
347
 
 
348
        if (device)
 
349
                device_set_name(device, name);
 
350
}
 
351
 
 
352
static char *buf2str(uint8_t *data, int datalen)
 
353
{
 
354
        char *buf;
 
355
        int i;
 
356
 
 
357
        buf = g_try_new0(char, (datalen * 2) + 1);
 
358
        if (buf == NULL)
 
359
                return NULL;
 
360
 
 
361
        for (i = 0; i < datalen; i++)
 
362
                sprintf(buf + (i * 2), "%2.2x", data[i]);
 
363
 
 
364
        return buf;
 
365
}
 
366
 
 
367
static int store_longtermkey(bdaddr_t *local, bdaddr_t *peer,
 
368
                                uint8_t bdaddr_type, unsigned char *key,
 
369
                                uint8_t master, uint8_t authenticated,
 
370
                                uint8_t enc_size, uint16_t ediv, uint8_t rand[8])
 
371
{
 
372
        GString *newkey;
 
373
        char *val, *str;
 
374
        int err;
 
375
 
 
376
        val = buf2str(key, 16);
 
377
        if (val == NULL)
 
378
                return -ENOMEM;
 
379
 
 
380
        newkey = g_string_new(val);
 
381
        g_free(val);
 
382
 
 
383
        g_string_append_printf(newkey, " %d %d %d %d ", authenticated, master,
 
384
                                                                enc_size, ediv);
 
385
 
 
386
        str = buf2str(rand, 8);
 
387
        if (str == NULL) {
 
388
                g_string_free(newkey, TRUE);
 
389
                return -ENOMEM;
 
390
        }
 
391
 
 
392
        newkey = g_string_append(newkey, str);
 
393
        g_free(str);
 
394
 
 
395
        err = write_longtermkeys(local, peer, bdaddr_type, newkey->str);
 
396
 
 
397
        g_string_free(newkey, TRUE);
 
398
 
 
399
        return err;
 
400
}
 
401
 
 
402
int btd_event_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
 
403
                                uint8_t *key, uint8_t key_type,
 
404
                                uint8_t pin_length)
 
405
{
 
406
        struct btd_adapter *adapter;
 
407
        struct btd_device *device;
 
408
        int ret;
 
409
 
 
410
        if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
 
411
                return -ENODEV;
 
412
 
 
413
        DBG("storing link key of type 0x%02x", key_type);
 
414
 
 
415
        ret = write_link_key(local, peer, key, key_type, pin_length);
 
416
 
 
417
        if (ret == 0) {
 
418
                device_set_bonded(device, TRUE);
 
419
 
 
420
                if (device_is_temporary(device))
 
421
                        device_set_temporary(device, FALSE);
 
422
        }
 
423
 
 
424
        return ret;
 
425
}
 
426
 
 
427
int btd_event_ltk_notify(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
 
428
                                        uint8_t *key, uint8_t master,
 
429
                                        uint8_t authenticated, uint8_t enc_size,
 
430
                                        uint16_t ediv, uint8_t rand[8])
 
431
{
 
432
        struct btd_adapter *adapter;
 
433
        struct btd_device *device;
 
434
        int ret;
 
435
 
 
436
        if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
 
437
                return -ENODEV;
 
438
 
 
439
        ret = store_longtermkey(local, peer, bdaddr_type, key, master,
 
440
                                        authenticated, enc_size, ediv, rand);
 
441
        if (ret == 0) {
 
442
                device_set_bonded(device, TRUE);
 
443
 
 
444
                if (device_is_temporary(device))
 
445
                        device_set_temporary(device, FALSE);
 
446
        }
 
447
 
 
448
        return ret;
 
449
}
 
450
 
 
451
void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
 
452
                                                char *name, uint8_t *dev_class)
 
453
{
 
454
        struct btd_adapter *adapter;
 
455
        struct btd_device *device;
 
456
 
 
457
        if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
 
458
                return;
 
459
 
 
460
        update_lastused(local, peer);
 
461
 
 
462
        if (dev_class != NULL) {
 
463
                uint32_t class = dev_class[0] | (dev_class[1] << 8) |
 
464
                                                        (dev_class[2] << 16);
 
465
 
 
466
                if (class != 0)
 
467
                        write_remote_class(local, peer, class);
 
468
        }
 
469
 
 
470
        device_set_addr_type(device, bdaddr_type);
 
471
 
 
472
        adapter_add_connection(adapter, device);
 
473
 
 
474
        if (name != NULL)
 
475
                btd_event_remote_name(local, peer, name);
 
476
}
 
477
 
 
478
void btd_event_conn_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status)
 
479
{
 
480
        struct btd_adapter *adapter;
 
481
        struct btd_device *device;
 
482
        DBusConnection *conn = get_dbus_connection();
 
483
 
 
484
        DBG("status 0x%02x", status);
 
485
 
 
486
        if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
 
487
                return;
 
488
 
 
489
        if (!device)
 
490
                return;
 
491
 
 
492
        if (device_is_bonding(device, NULL))
 
493
                device_cancel_bonding(device, status);
 
494
 
 
495
        if (device_is_temporary(device))
 
496
                adapter_remove_device(conn, adapter, device, TRUE);
 
497
}
 
498
 
 
499
void btd_event_disconn_complete(bdaddr_t *local, bdaddr_t *peer)
 
500
{
 
501
        struct btd_adapter *adapter;
 
502
        struct btd_device *device;
 
503
 
 
504
        DBG("");
 
505
 
 
506
        if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
 
507
                return;
 
508
 
 
509
        if (!device)
 
510
                return;
 
511
 
 
512
        adapter_remove_connection(adapter, device);
 
513
}
 
514
 
 
515
void btd_event_device_blocked(bdaddr_t *local, bdaddr_t *peer)
 
516
{
 
517
        struct btd_adapter *adapter;
 
518
        struct btd_device *device;
 
519
 
 
520
        DBusConnection *conn = get_dbus_connection();
 
521
 
 
522
        if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
 
523
                return;
 
524
 
 
525
        if (device)
 
526
                device_block(conn, device, TRUE);
 
527
}
 
528
 
 
529
void btd_event_device_unblocked(bdaddr_t *local, bdaddr_t *peer)
 
530
{
 
531
        struct btd_adapter *adapter;
 
532
        struct btd_device *device;
 
533
 
 
534
        DBusConnection *conn = get_dbus_connection();
 
535
 
 
536
        if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
 
537
                return;
 
538
 
 
539
        if (device)
 
540
                device_unblock(conn, device, FALSE, TRUE);
 
541
}
 
542
 
 
543
void btd_event_device_unpaired(bdaddr_t *local, bdaddr_t *peer)
 
544
{
 
545
        struct btd_adapter *adapter;
 
546
        struct btd_device *device;
 
547
        DBusConnection *conn = get_dbus_connection();
 
548
 
 
549
        if (!get_adapter_and_device(local, peer, &adapter, &device, FALSE))
 
550
                return;
 
551
 
 
552
        device_set_temporary(device, TRUE);
 
553
 
 
554
        if (device_is_connected(device))
 
555
                device_request_disconnect(device, NULL);
 
556
        else
 
557
                adapter_remove_device(conn, adapter, device, TRUE);
 
558
}
 
559
 
 
560
/* Section reserved to device HCI callbacks */
 
561
 
 
562
void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer)
 
563
{
 
564
        struct btd_adapter *adapter;
 
565
        struct btd_device *device;
 
566
 
 
567
        if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
 
568
                return;
 
569
 
 
570
        device_set_paired(device, TRUE);
 
571
}