From e48a1489ac34aa8888edcb87ec95a125a53350c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 17 Dec 2014 07:02:51 +0100 Subject: [PATCH] lib: Add definitions and functions for handling LE resolving list --- lib/hci.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/hci.h | 31 +++++++++++ lib/hci_lib.h | 6 +++ 3 files changed, 177 insertions(+) diff --git a/lib/hci.c b/lib/hci.c index e3cc513cd..c25be9e5f 100644 --- a/lib/hci.c +++ b/lib/hci.c @@ -1428,6 +1428,146 @@ int hci_le_clear_white_list(int dd, int to) return 0; } +int hci_le_add_resolving_list(int dd, const bdaddr_t *bdaddr, uint8_t type, + uint8_t *peer_irk, uint8_t *local_irk, int to) +{ + struct hci_request rq; + le_add_device_to_resolv_list_cp cp; + uint8_t status; + + memset(&cp, 0, sizeof(cp)); + cp.bdaddr_type = type; + bacpy(&cp.bdaddr, bdaddr); + if (peer_irk) + memcpy(cp.peer_irk, peer_irk, 16); + if (local_irk) + memcpy(cp.local_irk, local_irk, 16); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_RESOLV_LIST; + rq.cparam = &cp; + rq.clen = LE_ADD_DEVICE_TO_RESOLV_LIST_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (status) { + errno = EIO; + return -1; + } + + return 0; +} + +int hci_le_rm_resolving_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to) +{ + struct hci_request rq; + le_remove_device_from_resolv_list_cp cp; + uint8_t status; + + memset(&cp, 0, sizeof(cp)); + cp.bdaddr_type = type; + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_RESOLV_LIST; + rq.cparam = &cp; + rq.clen = LE_REMOVE_DEVICE_FROM_RESOLV_LIST_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (status) { + errno = EIO; + return -1; + } + + return 0; +} + +int hci_le_clear_resolving_list(int dd, int to) +{ + struct hci_request rq; + uint8_t status; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_RESOLV_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (status) { + errno = EIO; + return -1; + } + + return 0; +} + +int hci_le_read_resolving_list_size(int dd, uint8_t *size, int to) +{ + struct hci_request rq; + le_read_resolv_list_size_rp rp; + + memset(&rp, 0, sizeof(rp)); + memset(&rq, 0, sizeof(rq)); + + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_RESOLV_LIST_SIZE; + rq.rparam = &rp; + rq.rlen = LE_READ_RESOLV_LIST_SIZE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + if (size) + *size = rp.size; + + return 0; +} + +int hci_le_set_address_resolution_enable(int dd, uint8_t enable, int to) +{ + struct hci_request rq; + le_set_address_resolution_enable_cp cp; + uint8_t status; + + memset(&cp, 0, sizeof(cp)); + cp.enable = enable; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADDRESS_RESOLUTION_ENABLE; + rq.cparam = &cp; + rq.clen = LE_SET_ADDRESS_RESOLUTION_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_local_name(int dd, int len, char *name, int to) { read_local_name_rp rp; diff --git a/lib/hci.h b/lib/hci.h index 0c9482969..4ce77f727 100644 --- a/lib/hci.h +++ b/lib/hci.h @@ -1706,6 +1706,37 @@ typedef struct { } __attribute__ ((packed)) le_test_end_rp; #define LE_TEST_END_RP_SIZE 3 +#define OCF_LE_ADD_DEVICE_TO_RESOLV_LIST 0x0027 +typedef struct { + uint8_t bdaddr_type; + bdaddr_t bdaddr; + uint8_t peer_irk[16]; + uint8_t local_irk[16]; +} __attribute__ ((packed)) le_add_device_to_resolv_list_cp; +#define LE_ADD_DEVICE_TO_RESOLV_LIST_CP_SIZE 39 + +#define OCF_LE_REMOVE_DEVICE_FROM_RESOLV_LIST 0x0028 +typedef struct { + uint8_t bdaddr_type; + bdaddr_t bdaddr; +} __attribute__ ((packed)) le_remove_device_from_resolv_list_cp; +#define LE_REMOVE_DEVICE_FROM_RESOLV_LIST_CP_SIZE 7 + +#define OCF_LE_CLEAR_RESOLV_LIST 0x0029 + +#define OCF_LE_READ_RESOLV_LIST_SIZE 0x002A +typedef struct { + uint8_t status; + uint8_t size; +} __attribute__ ((packed)) le_read_resolv_list_size_rp; +#define LE_READ_RESOLV_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_SET_ADDRESS_RESOLUTION_ENABLE 0x002D +typedef struct { + uint8_t enable; +} __attribute__ ((packed)) le_set_address_resolution_enable_cp; +#define LE_SET_ADDRESS_RESOLUTION_ENABLE_CP_SIZE 1 + /* Vendor specific commands */ #define OGF_VENDOR_CMD 0x3f diff --git a/lib/hci_lib.h b/lib/hci_lib.h index eba3cd1d7..55aeb1760 100644 --- a/lib/hci_lib.h +++ b/lib/hci_lib.h @@ -134,6 +134,12 @@ int hci_le_add_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to); int hci_le_rm_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to); int hci_le_read_white_list_size(int dd, uint8_t *size, int to); int hci_le_clear_white_list(int dd, int to); +int hci_le_add_resolving_list(int dd, const bdaddr_t *bdaddr, uint8_t type, + uint8_t *peer_irk, uint8_t *local_irk, int to); +int hci_le_rm_resolving_list(int dd, const bdaddr_t *bdaddr, uint8_t type, int to); +int hci_le_clear_resolving_list(int dd, int to); +int hci_le_read_resolving_list_size(int dd, uint8_t *size, int to); +int hci_le_set_address_resolution_enable(int dev_id, uint8_t enable, int to); int hci_le_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to); int hci_for_each_dev(int flag, int(*func)(int dd, int dev_id, long arg), long arg);