~ubuntu-branches/ubuntu/oneiric/bluez/oneiric

« back to all changes in this revision

Viewing changes to plugins/hciops.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2011-06-06 18:11:44 UTC
  • mfrom: (1.1.33 upstream) (6.3.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110606181144-28qwmmobedosb2ct
Tags: 4.94-0ubuntu1
* Resynchronize on Debian, remaining diff:
* debian/bluez.bluetooth.default:
  - Drop.  Doesn't do anything now.
* debian/control:
  - use arch: any rather than a list of architectures
* debian/bluez.bluetooth.init:
  - Drop most calls in this script as now all it serves as is to 
    workaround a problem with dbus not being ready early enough. Once dbus is 
    started by an upstart service, this should be able to be converted 
    to an upstart service too.
* debian/rules:
  - Don't build hid2hci anymore.  It's part of udev now.
  - Don't install bluez_agent.udev, doesn't work in Ubuntu.
  - Don't use simple-patchsys
* debian/source_bluez.py, debian/bluez.install:
  - apport hook made by Baptiste Mille-Mathias.      
* debian/source/format: 
  - use source format 3.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
#include "event.h"
52
52
#include "manager.h"
53
53
#include "oob.h"
 
54
#include "eir.h"
 
55
 
 
56
#define DISCOV_HALTED 0
 
57
#define DISCOV_INQ 1
 
58
#define DISCOV_SCAN 2
 
59
 
 
60
#define TIMEOUT_BR_LE_SCAN 5120 /* TGAP(100)/2 */
 
61
#define TIMEOUT_LE_SCAN 10240 /* TGAP(gen_disc_scan_min) */
 
62
 
 
63
#define LENGTH_BR_INQ 0x08
 
64
#define LENGTH_BR_LE_INQ 0x04
 
65
 
 
66
static int hciops_start_scanning(int index, int timeout);
54
67
 
55
68
static int child_pipe[2] = { -1, -1 };
56
69
 
57
70
static guint child_io_id = 0;
58
71
static guint ctl_io_id = 0;
59
72
 
 
73
enum adapter_type {
 
74
        BR_EDR,
 
75
        LE_ONLY,
 
76
        BR_EDR_LE,
 
77
        UNKNOWN,
 
78
};
 
79
 
60
80
/* Commands sent by kernel on starting an adapter */
61
81
enum {
62
82
        PENDING_BDADDR,
65
85
        PENDING_NAME,
66
86
};
67
87
 
68
 
struct uuid_info {
69
 
        uuid_t uuid;
70
 
        uint8_t svc_hint;
71
 
};
72
 
 
73
88
struct bt_conn {
74
89
        struct dev_info *dev;
75
90
        bdaddr_t bdaddr;
98
113
        char name[249];
99
114
        uint8_t eir[HCI_MAX_EIR_LENGTH];
100
115
        uint8_t features[8];
 
116
        uint8_t extfeatures[8];
101
117
        uint8_t ssp_mode;
102
118
 
103
119
        int8_t tx_power;
104
120
 
 
121
        int discov_state;
 
122
 
105
123
        uint32_t current_cod;
106
124
        uint32_t wanted_cod;
107
125
        uint32_t pending_cod;
133
151
        GSList *uuids;
134
152
 
135
153
        GSList *connections;
 
154
 
 
155
        guint stop_scan_id;
136
156
} *devs = NULL;
137
157
 
 
158
static inline int get_state(int index)
 
159
{
 
160
        struct dev_info *dev = &devs[index];
 
161
 
 
162
        return dev->discov_state;
 
163
}
 
164
 
 
165
static inline gboolean is_resolvname_enabled(void)
 
166
{
 
167
        return main_opts.name_resolv ? TRUE : FALSE;
 
168
}
 
169
 
 
170
static void set_state(int index, int state)
 
171
{
 
172
        struct btd_adapter *adapter;
 
173
        struct dev_info *dev = &devs[index];
 
174
 
 
175
        if (dev->discov_state == state)
 
176
                return;
 
177
 
 
178
        adapter = manager_find_adapter_by_id(index);
 
179
        if (!adapter) {
 
180
                error("No matching adapter found");
 
181
                return;
 
182
        }
 
183
 
 
184
        dev->discov_state = state;
 
185
 
 
186
        DBG("hci%d: new state %d", index, dev->discov_state);
 
187
 
 
188
        switch (dev->discov_state) {
 
189
        case DISCOV_HALTED:
 
190
                if (adapter_get_state(adapter) == STATE_SUSPENDED)
 
191
                        return;
 
192
 
 
193
                if (is_resolvname_enabled() &&
 
194
                                        adapter_has_discov_sessions(adapter))
 
195
                        adapter_set_state(adapter, STATE_RESOLVNAME);
 
196
                else
 
197
                        adapter_set_state(adapter, STATE_IDLE);
 
198
                break;
 
199
        case DISCOV_INQ:
 
200
        case DISCOV_SCAN:
 
201
                adapter_set_state(adapter, STATE_DISCOV);
 
202
                break;
 
203
        }
 
204
}
 
205
 
 
206
static inline gboolean is_le_capable(int index)
 
207
{
 
208
        struct dev_info *dev = &devs[index];
 
209
 
 
210
        return (main_opts.le && dev->features[4] & LMP_LE &&
 
211
                        dev->extfeatures[0] & LMP_HOST_LE) ? TRUE : FALSE;
 
212
}
 
213
 
 
214
static inline gboolean is_bredr_capable(int index)
 
215
{
 
216
        struct dev_info *dev = &devs[index];
 
217
 
 
218
        return (dev->features[4] & LMP_NO_BREDR) == 0 ? TRUE : FALSE;
 
219
}
 
220
 
 
221
static int get_adapter_type(int index)
 
222
{
 
223
        if (is_le_capable(index) && is_bredr_capable(index))
 
224
                return BR_EDR_LE;
 
225
        else if (is_le_capable(index))
 
226
                return LE_ONLY;
 
227
        else if (is_bredr_capable(index))
 
228
                return BR_EDR;
 
229
 
 
230
        return UNKNOWN;
 
231
}
 
232
 
138
233
static int ignore_device(struct hci_dev_info *di)
139
234
{
140
235
        return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR;
153
248
        dev->registered = registered;
154
249
        dev->already_up = already_up;
155
250
        dev->io_capability = 0x03; /* No Input No Output */
 
251
        dev->discov_state = DISCOV_HALTED;
156
252
 
157
253
        return dev;
158
254
}
472
568
static int hciops_stop_inquiry(int index)
473
569
{
474
570
        struct dev_info *dev = &devs[index];
475
 
        struct hci_dev_info di;
476
 
        int err;
477
571
 
478
572
        DBG("hci%d", index);
479
573
 
480
 
        if (hci_devinfo(index, &di) < 0)
 
574
        if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_INQUIRY_CANCEL, 0, 0) < 0)
481
575
                return -errno;
482
576
 
483
 
        if (hci_test_bit(HCI_INQUIRY, &di.flags))
484
 
                err = hci_send_cmd(dev->sk, OGF_LINK_CTL,
485
 
                                                OCF_INQUIRY_CANCEL, 0, 0);
486
 
        else
487
 
                err = hci_send_cmd(dev->sk, OGF_LINK_CTL,
488
 
                                        OCF_EXIT_PERIODIC_INQUIRY, 0, 0);
489
 
        if (err < 0)
490
 
                err = -errno;
491
 
 
492
 
        return err;
 
577
        return 0;
493
578
}
494
579
 
495
580
static gboolean init_adapter(int index)
873
958
                /* Some buggy controller combinations generate a changed
874
959
                 * combination key for legacy pairing even when there's no
875
960
                 * previous key */
876
 
                if ((!conn || conn->rem_auth == 0xff) && old_key_type == 0xff)
 
961
                if (conn->rem_auth == 0xff && old_key_type == 0xff)
877
962
                        key_type = 0x00;
878
963
                else if (old_key_type != 0xff)
879
964
                        key_type = old_key_type;
1271
1356
        hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba);
1272
1357
}
1273
1358
 
1274
 
static void start_inquiry(bdaddr_t *local, uint8_t status, gboolean periodic)
1275
 
{
1276
 
        struct btd_adapter *adapter;
1277
 
        int state;
1278
 
 
1279
 
        /* Don't send the signal if the cmd failed */
1280
 
        if (status) {
1281
 
                error("Inquiry Failed with status 0x%02x", status);
1282
 
                return;
1283
 
        }
1284
 
 
1285
 
        adapter = manager_find_adapter(local);
1286
 
        if (!adapter) {
1287
 
                error("Unable to find matching adapter");
1288
 
                return;
1289
 
        }
1290
 
 
1291
 
        state = adapter_get_state(adapter);
1292
 
 
1293
 
        if (periodic)
1294
 
                state |= STATE_PINQ;
1295
 
        else
1296
 
                state |= STATE_STDINQ;
1297
 
 
1298
 
        adapter_set_state(adapter, state);
1299
 
}
1300
 
 
1301
 
static void inquiry_complete(bdaddr_t *local, uint8_t status,
1302
 
                                                        gboolean periodic)
1303
 
{
1304
 
        struct btd_adapter *adapter;
1305
 
        int state;
1306
 
 
1307
 
        /* Don't send the signal if the cmd failed */
1308
 
        if (status) {
1309
 
                error("Inquiry Failed with status 0x%02x", status);
1310
 
                return;
1311
 
        }
1312
 
 
1313
 
        adapter = manager_find_adapter(local);
1314
 
        if (!adapter) {
1315
 
                error("Unable to find matching adapter");
1316
 
                return;
1317
 
        }
1318
 
 
1319
 
        state = adapter_get_state(adapter);
1320
 
        state &= ~(STATE_STDINQ | STATE_PINQ);
1321
 
        adapter_set_state(adapter, state);
1322
 
}
1323
 
 
1324
1359
static inline void remote_features_notify(int index, void *ptr)
1325
1360
{
1326
1361
        struct dev_info *dev = &devs[index];
1396
1431
                init_adapter(index);
1397
1432
}
1398
1433
 
1399
 
#define SIZEOF_UUID128 16
1400
 
 
1401
 
static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
1402
 
{
1403
 
        int i, k, uuid_count = 0;
1404
 
        uint16_t len = *eir_len;
1405
 
        uint8_t *uuid128;
1406
 
        gboolean truncated = FALSE;
1407
 
 
1408
 
        /* Store UUIDs in place, skip 2 bytes to write type and length later */
1409
 
        uuid128 = ptr + 2;
1410
 
 
1411
 
        for (; list; list = list->next) {
1412
 
                struct uuid_info *uuid = list->data;
1413
 
                uint8_t *uuid128_data = uuid->uuid.value.uuid128.data;
1414
 
 
1415
 
                if (uuid->uuid.type != SDP_UUID128)
1416
 
                        continue;
1417
 
 
1418
 
                /* Stop if not enough space to put next UUID128 */
1419
 
                if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) {
1420
 
                        truncated = TRUE;
1421
 
                        break;
1422
 
                }
1423
 
 
1424
 
                /* Check for duplicates, EIR data is Little Endian */
1425
 
                for (i = 0; i < uuid_count; i++) {
1426
 
                        for (k = 0; k < SIZEOF_UUID128; k++) {
1427
 
                                if (uuid128[i * SIZEOF_UUID128 + k] !=
1428
 
                                        uuid128_data[SIZEOF_UUID128 - 1 - k])
1429
 
                                        break;
1430
 
                        }
1431
 
                        if (k == SIZEOF_UUID128)
1432
 
                                break;
1433
 
                }
1434
 
 
1435
 
                if (i < uuid_count)
1436
 
                        continue;
1437
 
 
1438
 
                /* EIR data is Little Endian */
1439
 
                for (k = 0; k < SIZEOF_UUID128; k++)
1440
 
                        uuid128[uuid_count * SIZEOF_UUID128 + k] =
1441
 
                                uuid128_data[SIZEOF_UUID128 - 1 - k];
1442
 
 
1443
 
                len += SIZEOF_UUID128;
1444
 
                uuid_count++;
1445
 
        }
1446
 
 
1447
 
        if (uuid_count > 0 || truncated) {
1448
 
                /* EIR Data length */
1449
 
                ptr[0] = (uuid_count * SIZEOF_UUID128) + 1;
1450
 
                /* EIR Data type */
1451
 
                ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL;
1452
 
                len += 2;
1453
 
                *eir_len = len;
1454
 
        }
1455
 
}
1456
 
 
1457
 
static void create_ext_inquiry_response(int index, uint8_t *data)
1458
 
{
1459
 
        struct dev_info *dev = &devs[index];
1460
 
        GSList *l;
1461
 
        uint8_t *ptr = data;
1462
 
        uint16_t eir_len = 0;
1463
 
        uint16_t uuid16[EIR_DATA_LENGTH / 2];
1464
 
        int i, uuid_count = 0;
1465
 
        gboolean truncated = FALSE;
1466
 
        size_t name_len;
1467
 
 
1468
 
        name_len = strlen(dev->name);
1469
 
 
1470
 
        if (name_len > 0) {
1471
 
                /* EIR Data type */
1472
 
                if (name_len > 48) {
1473
 
                        name_len = 48;
1474
 
                        ptr[1] = EIR_NAME_SHORT;
1475
 
                } else
1476
 
                        ptr[1] = EIR_NAME_COMPLETE;
1477
 
 
1478
 
                /* EIR Data length */
1479
 
                ptr[0] = name_len + 1;
1480
 
 
1481
 
                memcpy(ptr + 2, dev->name, name_len);
1482
 
 
1483
 
                eir_len += (name_len + 2);
1484
 
                ptr += (name_len + 2);
1485
 
        }
1486
 
 
1487
 
        if (dev->tx_power != 0) {
1488
 
                *ptr++ = 2;
1489
 
                *ptr++ = EIR_TX_POWER;
1490
 
                *ptr++ = (uint8_t) dev->tx_power;
1491
 
                eir_len += 3;
1492
 
        }
1493
 
 
1494
 
        if (dev->did_vendor != 0x0000) {
1495
 
                uint16_t source = 0x0002;
1496
 
                *ptr++ = 9;
1497
 
                *ptr++ = EIR_DEVICE_ID;
1498
 
                *ptr++ = (source & 0x00ff);
1499
 
                *ptr++ = (source & 0xff00) >> 8;
1500
 
                *ptr++ = (dev->did_vendor & 0x00ff);
1501
 
                *ptr++ = (dev->did_vendor & 0xff00) >> 8;
1502
 
                *ptr++ = (dev->did_product & 0x00ff);
1503
 
                *ptr++ = (dev->did_product & 0xff00) >> 8;
1504
 
                *ptr++ = (dev->did_version & 0x00ff);
1505
 
                *ptr++ = (dev->did_version & 0xff00) >> 8;
1506
 
                eir_len += 10;
1507
 
        }
1508
 
 
1509
 
        /* Group all UUID16 types */
1510
 
        for (l = dev->uuids; l != NULL; l = g_slist_next(l)) {
1511
 
                struct uuid_info *uuid = l->data;
1512
 
 
1513
 
                if (uuid->uuid.type != SDP_UUID16)
1514
 
                        continue;
1515
 
 
1516
 
                if (uuid->uuid.value.uuid16 < 0x1100)
1517
 
                        continue;
1518
 
 
1519
 
                if (uuid->uuid.value.uuid16 == PNP_INFO_SVCLASS_ID)
1520
 
                        continue;
1521
 
 
1522
 
                /* Stop if not enough space to put next UUID16 */
1523
 
                if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) {
1524
 
                        truncated = TRUE;
1525
 
                        break;
1526
 
                }
1527
 
 
1528
 
                /* Check for duplicates */
1529
 
                for (i = 0; i < uuid_count; i++)
1530
 
                        if (uuid16[i] == uuid->uuid.value.uuid16)
1531
 
                                break;
1532
 
 
1533
 
                if (i < uuid_count)
1534
 
                        continue;
1535
 
 
1536
 
                uuid16[uuid_count++] = uuid->uuid.value.uuid16;
1537
 
                eir_len += sizeof(uint16_t);
1538
 
        }
1539
 
 
1540
 
        if (uuid_count > 0) {
1541
 
                /* EIR Data length */
1542
 
                ptr[0] = (uuid_count * sizeof(uint16_t)) + 1;
1543
 
                /* EIR Data type */
1544
 
                ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
1545
 
 
1546
 
                ptr += 2;
1547
 
                eir_len += 2;
1548
 
 
1549
 
                for (i = 0; i < uuid_count; i++) {
1550
 
                        *ptr++ = (uuid16[i] & 0x00ff);
1551
 
                        *ptr++ = (uuid16[i] & 0xff00) >> 8;
1552
 
                }
1553
 
        }
1554
 
 
1555
 
        /* Group all UUID128 types */
1556
 
        if (eir_len <= EIR_DATA_LENGTH - 2)
1557
 
                eir_generate_uuid128(dev->uuids, ptr, &eir_len);
1558
 
}
1559
 
 
1560
1434
static void update_ext_inquiry_response(int index)
1561
1435
{
1562
1436
        struct dev_info *dev = &devs[index];
1575
1449
 
1576
1450
        memset(&cp, 0, sizeof(cp));
1577
1451
 
1578
 
        create_ext_inquiry_response(index, cp.data);
 
1452
        eir_create(dev->name, dev->tx_power, dev->did_vendor, dev->did_product,
 
1453
                                        dev->did_version, dev->uuids, cp.data);
1579
1454
 
1580
1455
        if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0)
1581
1456
                return;
1671
1546
static void read_local_ext_features_complete(int index,
1672
1547
                                const read_local_ext_features_rp *rp)
1673
1548
{
1674
 
        struct btd_adapter *adapter;
 
1549
        struct dev_info *dev = &devs[index];
1675
1550
 
1676
1551
        DBG("hci%d status %u", index, rp->status);
1677
1552
 
1678
1553
        if (rp->status)
1679
1554
                return;
1680
1555
 
1681
 
        adapter = manager_find_adapter_by_id(index);
1682
 
        if (!adapter) {
1683
 
                error("No matching adapter found");
1684
 
                return;
1685
 
        }
1686
 
 
1687
1556
        /* Local Extended feature page number is 1 */
1688
1557
        if (rp->page_num != 1)
1689
1558
                return;
1690
1559
 
1691
 
        btd_adapter_update_local_ext_features(adapter, rp->features);
 
1560
        memcpy(dev->extfeatures, rp->features, sizeof(dev->extfeatures));
1692
1561
}
1693
1562
 
1694
1563
static void read_bd_addr_complete(int index, read_bd_addr_rp *rp)
1713
1582
                init_adapter(index);
1714
1583
}
1715
1584
 
 
1585
static inline void cs_inquiry_evt(int index, uint8_t status)
 
1586
{
 
1587
        if (status) {
 
1588
                error("Inquiry Failed with status 0x%02x", status);
 
1589
                return;
 
1590
        }
 
1591
 
 
1592
        set_state(index, DISCOV_INQ);
 
1593
}
 
1594
 
1716
1595
static inline void cmd_status(int index, void *ptr)
1717
1596
{
1718
 
        struct dev_info *dev = &devs[index];
1719
1597
        evt_cmd_status *evt = ptr;
1720
1598
        uint16_t opcode = btohs(evt->opcode);
1721
1599
 
1722
1600
        if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY))
1723
 
                start_inquiry(&dev->bdaddr, evt->status, FALSE);
 
1601
                cs_inquiry_evt(index, evt->status);
1724
1602
}
1725
1603
 
1726
1604
static void read_scan_complete(int index, uint8_t status, void *ptr)
1841
1719
                oob_read_local_data_complete(adapter, rp->hash, rp->randomizer);
1842
1720
}
1843
1721
 
 
1722
static inline void inquiry_complete_evt(int index, uint8_t status)
 
1723
{
 
1724
        int adapter_type;
 
1725
        struct btd_adapter *adapter;
 
1726
 
 
1727
        if (status) {
 
1728
                error("Inquiry Failed with status 0x%02x", status);
 
1729
                return;
 
1730
        }
 
1731
 
 
1732
        adapter = manager_find_adapter_by_id(index);
 
1733
        if (!adapter) {
 
1734
                error("No matching adapter found");
 
1735
                return;
 
1736
        }
 
1737
 
 
1738
        adapter_type = get_adapter_type(index);
 
1739
 
 
1740
        if (adapter_type == BR_EDR_LE &&
 
1741
                                        adapter_has_discov_sessions(adapter)) {
 
1742
                int err = hciops_start_scanning(index, TIMEOUT_BR_LE_SCAN);
 
1743
                if (err < 0)
 
1744
                        set_state(index, DISCOV_HALTED);
 
1745
        } else {
 
1746
                set_state(index, DISCOV_HALTED);
 
1747
        }
 
1748
}
 
1749
 
 
1750
static inline void cc_inquiry_cancel(int index, uint8_t status)
 
1751
{
 
1752
        if (status) {
 
1753
                error("Inquiry Cancel Failed with status 0x%02x", status);
 
1754
                return;
 
1755
        }
 
1756
 
 
1757
        set_state(index, DISCOV_HALTED);
 
1758
}
 
1759
 
 
1760
static inline void cc_le_set_scan_enable(int index, uint8_t status)
 
1761
{
 
1762
        int state;
 
1763
 
 
1764
        if (status) {
 
1765
                error("LE Set Scan Enable Failed with status 0x%02x", status);
 
1766
                return;
 
1767
        }
 
1768
 
 
1769
        state = get_state(index);
 
1770
        if (state == DISCOV_SCAN)
 
1771
                set_state(index, DISCOV_HALTED);
 
1772
        else
 
1773
                set_state(index, DISCOV_SCAN);
 
1774
}
 
1775
 
1844
1776
static inline void cmd_complete(int index, void *ptr)
1845
1777
{
1846
1778
        struct dev_info *dev = &devs[index];
1865
1797
                ptr += sizeof(evt_cmd_complete);
1866
1798
                read_bd_addr_complete(index, ptr);
1867
1799
                break;
1868
 
        case cmd_opcode_pack(OGF_LINK_CTL, OCF_PERIODIC_INQUIRY):
1869
 
                start_inquiry(&dev->bdaddr, status, TRUE);
1870
 
                break;
1871
 
        case cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY):
1872
 
                inquiry_complete(&dev->bdaddr, status, TRUE);
1873
 
                break;
1874
1800
        case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL):
1875
 
                inquiry_complete(&dev->bdaddr, status, FALSE);
 
1801
                cc_inquiry_cancel(index, status);
1876
1802
                break;
1877
1803
        case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_LE_HOST_SUPPORTED):
1878
1804
                write_le_host_complete(index, status);
1879
1805
                break;
1880
1806
        case cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE):
1881
 
                btd_event_le_set_scan_enable_complete(&dev->bdaddr, status);
 
1807
                cc_le_set_scan_enable(index, status);
1882
1808
                break;
1883
1809
        case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME):
1884
1810
                if (!status)
1963
1889
        uint8_t num = *(uint8_t *) ptr++;
1964
1890
        int i;
1965
1891
 
 
1892
        /* Skip if it is not in Inquiry state */
 
1893
        if (get_state(index) != DISCOV_INQ)
 
1894
                return;
 
1895
 
1966
1896
        for (i = 0; i < num; i++) {
1967
1897
                inquiry_info *info = ptr;
1968
1898
                uint32_t class = info->dev_class[0] |
2241
2171
{
2242
2172
        struct dev_info *dev = &devs[index];
2243
2173
        le_advertising_info *info;
2244
 
        uint8_t num_reports;
 
2174
        uint8_t num_reports, rssi, eir[HCI_MAX_EIR_LENGTH];
2245
2175
        const uint8_t RSSI_SIZE = 1;
2246
2176
 
2247
2177
        num_reports = meta->data[0];
2248
2178
 
2249
2179
        info = (le_advertising_info *) &meta->data[1];
2250
 
        btd_event_advertising_report(&dev->bdaddr, info);
 
2180
        rssi = *(info->data + info->length);
 
2181
 
 
2182
        memset(eir, 0, sizeof(eir));
 
2183
        memcpy(eir, info->data, info->length);
 
2184
 
 
2185
        btd_event_device_found(&dev->bdaddr, &info->bdaddr, 0, rssi, eir);
 
2186
 
2251
2187
        num_reports--;
2252
2188
 
2253
2189
        while (num_reports--) {
2254
2190
                info = (le_advertising_info *) (info->data + info->length +
2255
2191
                                                                RSSI_SIZE);
2256
 
                btd_event_advertising_report(&dev->bdaddr, info);
 
2192
                rssi = *(info->data + info->length);
 
2193
 
 
2194
                memset(eir, 0, sizeof(eir));
 
2195
                memcpy(eir, info->data, info->length);
 
2196
 
 
2197
                btd_event_device_found(&dev->bdaddr, &info->bdaddr, 0, rssi,
 
2198
                                                                        eir);
2257
2199
        }
2258
2200
}
2259
2201
 
2286
2228
        if (dev->watch_id > 0)
2287
2229
                g_source_remove(dev->watch_id);
2288
2230
 
 
2231
        if (dev->stop_scan_id > 0)
 
2232
                g_source_remove(dev->stop_scan_id);
 
2233
 
2289
2234
        if (dev->io != NULL)
2290
2235
                g_io_channel_unref(dev->io);
2291
2236
 
2373
2318
 
2374
2319
        case EVT_INQUIRY_COMPLETE:
2375
2320
                evt = (evt_cmd_status *) ptr;
2376
 
                inquiry_complete(&dev->bdaddr, evt->status, FALSE);
 
2321
                inquiry_complete_evt(index, evt->status);
2377
2322
                break;
2378
2323
 
2379
2324
        case EVT_INQUIRY_RESULT:
2657
2602
        struct dev_info *dev = &devs[index];
2658
2603
        struct hci_conn_list_req *cl;
2659
2604
        struct hci_conn_info *ci;
2660
 
        int err, i;
 
2605
        int i;
2661
2606
 
2662
2607
        DBG("hci%d", index);
2663
2608
 
2683
2628
                conn->handle = ci->handle;
2684
2629
        }
2685
2630
 
2686
 
        err = 0;
2687
 
 
2688
2631
failed:
2689
2632
        g_free(cl);
2690
2633
}
2976
2919
        return err;
2977
2920
}
2978
2921
 
2979
 
static int hciops_start_inquiry(int index, uint8_t length, gboolean periodic)
 
2922
static int hciops_start_inquiry(int index, uint8_t length)
2980
2923
{
2981
2924
        struct dev_info *dev = &devs[index];
2982
2925
        uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
2983
 
        int err;
2984
 
 
2985
 
        DBG("hci%d length %u periodic %d", index, length, periodic);
2986
 
 
2987
 
        if (periodic) {
2988
 
                periodic_inquiry_cp cp;
2989
 
 
2990
 
                memset(&cp, 0, sizeof(cp));
2991
 
                memcpy(&cp.lap, lap, 3);
2992
 
                cp.max_period = htobs(24);
2993
 
                cp.min_period = htobs(16);
2994
 
                cp.length  = length;
2995
 
                cp.num_rsp = 0x00;
2996
 
 
2997
 
                err = hci_send_cmd(dev->sk, OGF_LINK_CTL,
2998
 
                                                OCF_PERIODIC_INQUIRY,
2999
 
                                                PERIODIC_INQUIRY_CP_SIZE, &cp);
3000
 
        } else {
3001
 
                inquiry_cp inq_cp;
3002
 
 
3003
 
                memset(&inq_cp, 0, sizeof(inq_cp));
3004
 
                memcpy(&inq_cp.lap, lap, 3);
3005
 
                inq_cp.length = length;
3006
 
                inq_cp.num_rsp = 0x00;
3007
 
 
3008
 
                err = hci_send_cmd(dev->sk, OGF_LINK_CTL,
3009
 
                                        OCF_INQUIRY, INQUIRY_CP_SIZE, &inq_cp);
3010
 
        }
3011
 
 
3012
 
        if (err < 0)
3013
 
                err = -errno;
3014
 
 
3015
 
        return err;
 
2926
        inquiry_cp inq_cp;
 
2927
 
 
2928
        DBG("hci%d length %u", index, length);
 
2929
 
 
2930
        memset(&inq_cp, 0, sizeof(inq_cp));
 
2931
        memcpy(&inq_cp.lap, lap, 3);
 
2932
        inq_cp.length = length;
 
2933
        inq_cp.num_rsp = 0x00;
 
2934
 
 
2935
        if (hci_send_cmd(dev->sk, OGF_LINK_CTL,
 
2936
                        OCF_INQUIRY, INQUIRY_CP_SIZE, &inq_cp) < 0)
 
2937
                return -errno;
 
2938
 
 
2939
        return 0;
3016
2940
}
3017
2941
 
3018
2942
static int le_set_scan_enable(int index, uint8_t enable)
3033
2957
        return 0;
3034
2958
}
3035
2959
 
3036
 
static int hciops_start_scanning(int index)
 
2960
static gboolean stop_le_scan_cb(gpointer user_data)
 
2961
{
 
2962
        struct dev_info *dev = user_data;
 
2963
        int err;
 
2964
 
 
2965
        err = le_set_scan_enable(dev->id, 0);
 
2966
        if (err < 0)
 
2967
                return TRUE;
 
2968
 
 
2969
        dev->stop_scan_id = 0;
 
2970
 
 
2971
        return FALSE;
 
2972
}
 
2973
 
 
2974
static int hciops_start_scanning(int index, int timeout)
3037
2975
{
3038
2976
        struct dev_info *dev = &devs[index];
3039
2977
        le_set_scan_parameters_cp cp;
 
2978
        int err;
3040
2979
 
3041
2980
        DBG("hci%d", index);
3042
2981
 
3053
2992
                                LE_SET_SCAN_PARAMETERS_CP_SIZE, &cp) < 0)
3054
2993
                return -errno;
3055
2994
 
3056
 
        return le_set_scan_enable(index, 1);
 
2995
        err = le_set_scan_enable(index, 1);
 
2996
        if (err < 0)
 
2997
                return err;
 
2998
 
 
2999
        /* Schedule a le scan disable in 'timeout' milliseconds */
 
3000
        dev->stop_scan_id = g_timeout_add(timeout, stop_le_scan_cb, dev);
 
3001
 
 
3002
        return 0;
3057
3003
}
3058
3004
 
3059
3005
static int hciops_stop_scanning(int index)
3060
3006
{
 
3007
        struct dev_info *dev = &devs[index];
 
3008
 
3061
3009
        DBG("hci%d", index);
3062
3010
 
 
3011
        if (dev->stop_scan_id > 0) {
 
3012
                g_source_remove(dev->stop_scan_id);
 
3013
                dev->stop_scan_id = 0;
 
3014
        }
 
3015
 
3063
3016
        return le_set_scan_enable(index, 0);
3064
3017
}
3065
3018
 
3122
3075
        return 0;
3123
3076
}
3124
3077
 
 
3078
static int hciops_start_discovery(int index)
 
3079
{
 
3080
        int adapter_type = get_adapter_type(index);
 
3081
 
 
3082
        switch (adapter_type) {
 
3083
        case BR_EDR_LE:
 
3084
                return hciops_start_inquiry(index, LENGTH_BR_LE_INQ);
 
3085
        case BR_EDR:
 
3086
                return hciops_start_inquiry(index, LENGTH_BR_INQ);
 
3087
        case LE_ONLY:
 
3088
                return hciops_start_scanning(index, TIMEOUT_LE_SCAN);
 
3089
        default:
 
3090
                return -EINVAL;
 
3091
        }
 
3092
}
 
3093
 
 
3094
static int hciops_stop_discovery(int index)
 
3095
{
 
3096
        struct dev_info *dev = &devs[index];
 
3097
 
 
3098
        DBG("index %d", index);
 
3099
 
 
3100
        switch (dev->discov_state) {
 
3101
        case DISCOV_INQ:
 
3102
                return hciops_stop_inquiry(index);
 
3103
        case DISCOV_SCAN:
 
3104
                return hciops_stop_scanning(index);
 
3105
        default:
 
3106
                return -EINVAL;
 
3107
        }
 
3108
}
 
3109
 
3125
3110
static int hciops_fast_connectable(int index, gboolean enable)
3126
3111
{
3127
3112
        struct dev_info *dev = &devs[index];
3276
3261
        return 0;
3277
3262
}
3278
3263
 
3279
 
static int hciops_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin)
 
3264
static int hciops_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin,
 
3265
                                                                size_t pin_len)
3280
3266
{
3281
3267
        struct dev_info *dev = &devs[index];
3282
3268
        char addr[18];
3287
3273
 
3288
3274
        if (pin) {
3289
3275
                pin_code_reply_cp pr;
3290
 
                size_t len = strlen(pin);
3291
3276
 
3292
 
                dev->pin_length = len;
 
3277
                dev->pin_length = pin_len;
3293
3278
 
3294
3279
                memset(&pr, 0, sizeof(pr));
3295
3280
                bacpy(&pr.bdaddr, bdaddr);
3296
 
                memcpy(pr.pin_code, pin, len);
3297
 
                pr.pin_len = len;
 
3281
                memcpy(pr.pin_code, pin, pin_len);
 
3282
                pr.pin_len = pin_len;
3298
3283
                err = hci_send_cmd(dev->sk, OGF_LINK_CTL,
3299
3284
                                                OCF_PIN_CODE_REPLY,
3300
3285
                                                PIN_CODE_REPLY_CP_SIZE, &pr);
3671
3656
        .set_discoverable = hciops_set_discoverable,
3672
3657
        .set_pairable = hciops_set_pairable,
3673
3658
        .set_limited_discoverable = hciops_set_limited_discoverable,
3674
 
        .start_inquiry = hciops_start_inquiry,
3675
 
        .stop_inquiry = hciops_stop_inquiry,
3676
 
        .start_scanning = hciops_start_scanning,
3677
 
        .stop_scanning = hciops_stop_scanning,
 
3659
        .start_discovery = hciops_start_discovery,
 
3660
        .stop_discovery = hciops_stop_discovery,
3678
3661
        .resolve_name = hciops_resolve_name,
3679
3662
        .cancel_resolve_name = hciops_cancel_resolve_name,
3680
3663
        .set_name = hciops_set_name,