|
13 | 13 | #include <toolchain.h> |
14 | 14 | #include <bluetooth/bluetooth.h> |
15 | 15 | #include <bluetooth/conn.h> |
| 16 | +#include <bluetooth/gatt.h> |
16 | 17 | #include <bluetooth/hci.h> |
17 | 18 |
|
18 | 19 | #include <sys/byteorder.h> |
@@ -41,6 +42,52 @@ static struct bt_le_oob oob_sc_local = { 0 }; |
41 | 42 | static struct bt_le_oob oob_sc_remote = { 0 }; |
42 | 43 | #endif /* !defined(CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY) */ |
43 | 44 |
|
| 45 | +#if defined(CONFIG_BT_PRIVACY) |
| 46 | +static struct { |
| 47 | + bt_addr_le_t addr; |
| 48 | + bool supported; |
| 49 | +} cars[CONFIG_BT_MAX_PAIRED]; |
| 50 | + |
| 51 | +static uint8_t read_car_cb(struct bt_conn *conn, uint8_t err, |
| 52 | + struct bt_gatt_read_params *params, const void *data, |
| 53 | + uint16_t length); |
| 54 | + |
| 55 | +static struct bt_gatt_read_params read_car_params = { |
| 56 | + .func = read_car_cb, |
| 57 | + .by_uuid.uuid = BT_UUID_CENTRAL_ADDR_RES, |
| 58 | + .by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE, |
| 59 | + .by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE, |
| 60 | +}; |
| 61 | + |
| 62 | +static uint8_t read_car_cb(struct bt_conn *conn, uint8_t err, |
| 63 | + struct bt_gatt_read_params *params, const void *data, |
| 64 | + uint16_t length) |
| 65 | +{ |
| 66 | + struct bt_conn_info info; |
| 67 | + bool supported = false; |
| 68 | + |
| 69 | + if (!err && data && length == 1) { |
| 70 | + const uint8_t *tmp = data; |
| 71 | + |
| 72 | + /* only 0 or 1 are valid values */ |
| 73 | + if (tmp[0] == 1) { |
| 74 | + supported = true; |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + bt_conn_get_info(conn, &info); |
| 79 | + |
| 80 | + for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) { |
| 81 | + if (bt_addr_le_cmp(info.le.dst, &cars[i].addr) == 0) { |
| 82 | + cars[i].supported = supported; |
| 83 | + break; |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | + return BT_GATT_ITER_STOP; |
| 88 | +} |
| 89 | +#endif |
| 90 | + |
44 | 91 | static void le_connected(struct bt_conn *conn, uint8_t err) |
45 | 92 | { |
46 | 93 | struct gap_device_connected_ev ev; |
@@ -505,6 +552,19 @@ static void start_directed_advertising(const uint8_t *data, uint16_t len) |
505 | 552 | adv_param.interval_min = BT_GAP_ADV_FAST_INT_MIN_2; |
506 | 553 | } |
507 | 554 |
|
| 555 | + if (options & GAP_START_DIRECTED_ADV_PEER_RPA) { |
| 556 | +#if defined(CONFIG_BT_PRIVACY) |
| 557 | + /* check if peer supports Central Address Resolution */ |
| 558 | + for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) { |
| 559 | + if (bt_addr_le_cmp(peer, &cars[i].addr) == 0) { |
| 560 | + if (cars[i].supported) { |
| 561 | + adv_param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA; |
| 562 | + } |
| 563 | + } |
| 564 | + } |
| 565 | +#endif |
| 566 | + } |
| 567 | + |
508 | 568 | if (bt_le_adv_start(&adv_param, NULL, 0, NULL, 0) < 0) { |
509 | 569 | LOG_ERR("Failed to start advertising"); |
510 | 570 | goto fail; |
@@ -840,6 +900,16 @@ void auth_pairing_failed(struct bt_conn *conn, enum bt_security_err reason) |
840 | 900 | (uint8_t *)&ev, sizeof(ev)); |
841 | 901 | } |
842 | 902 |
|
| 903 | +static void auth_pairing_complete(struct bt_conn *conn, bool bonded) |
| 904 | +{ |
| 905 | +#if defined(CONFIG_BT_PRIVACY) |
| 906 | + /* Read peer's Central Address Resolution if bonded */ |
| 907 | + if (bonded) { |
| 908 | + bt_gatt_read(conn, &read_car_params); |
| 909 | + } |
| 910 | +#endif |
| 911 | +} |
| 912 | + |
843 | 913 | static void set_io_cap(const uint8_t *data, uint16_t len) |
844 | 914 | { |
845 | 915 | const struct gap_set_io_cap_cmd *cmd = (void *) data; |
@@ -878,6 +948,7 @@ static void set_io_cap(const uint8_t *data, uint16_t len) |
878 | 948 |
|
879 | 949 | cb.pairing_accept = auth_pairing_accept; |
880 | 950 | cb.pairing_failed = auth_pairing_failed; |
| 951 | + cb.pairing_complete = auth_pairing_complete; |
881 | 952 |
|
882 | 953 | if (bt_conn_auth_cb_register(&cb)) { |
883 | 954 | status = BTP_STATUS_FAILED; |
|
0 commit comments