Bluetooth: Add support for responding to LTK requests

Add an event handler for LTK requests that looks up the LTK using the
new bt_keys API.

Change-Id: Ifc4e5f96e84026d7e8c68eacb64154dc0a9c72b3
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2015-05-21 15:30:08 +03:00 committed by Anas Nashif
commit 0821341d3f
2 changed files with 71 additions and 0 deletions

View file

@ -244,6 +244,17 @@ struct bt_hci_rp_le_rand {
uint8_t rand[8];
} PACK_STRUCT;
#define BT_HCI_OP_LE_LTK_REQ_REPLY BT_OP(BT_OGF_LE, 0x001a)
struct bt_hci_cp_le_ltk_req_reply {
uint16_t handle;
uint8_t ltk[16];
} PACK_STRUCT;
#define BT_HCI_OP_LE_LTK_REQ_NEG_REPLY BT_OP(BT_OGF_LE, 0x001b)
struct bt_hci_cp_le_ltk_req_neg_reply {
uint16_t handle;
} PACK_STRUCT;
/* Event definitions */
#define BT_HCI_EVT_DISCONN_COMPLETE 0x05
@ -302,4 +313,11 @@ struct bt_hci_ev_le_advertising_info {
uint8_t data[0];
} PACK_STRUCT;
#define BT_HCI_EVT_LE_LTK_REQUEST 0x05
struct bt_hci_evt_le_ltk_request {
uint16_t handle;
uint64_t rand;
uint16_t ediv;
} PACK_STRUCT;
#endif /* __BT_HCI_H */

View file

@ -452,6 +452,56 @@ static void le_adv_report(struct bt_buf *buf)
}
}
static void le_ltk_request(struct bt_buf *buf)
{
struct bt_hci_evt_le_ltk_request *evt = (void *)buf->data;
struct bt_conn *conn;
struct bt_keys *keys;
uint16_t handle;
handle = sys_le16_to_cpu(evt->handle);
BT_DBG("handle %u\n", handle);
conn = bt_conn_lookup(handle);
if (!conn) {
BT_ERR("Unable to lookup conn for handle %u\n", handle);
return;
}
keys = bt_keys_find(conn->dst, conn->dst_type);
if (keys) {
struct bt_hci_cp_le_ltk_req_reply *cp;
buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_REPLY,
sizeof(*cp));
if (!buf) {
BT_ERR("Out of command buffers\n");
return;
}
cp = bt_buf_add(buf, sizeof(*cp));
cp->handle = evt->handle;
memcpy(cp->ltk, keys->slave_ltk, 16);
bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_REPLY, buf);
} else {
struct bt_hci_cp_le_ltk_req_neg_reply *cp;
buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_NEG_REPLY,
sizeof(*cp));
if (!buf) {
BT_ERR("Out of command buffers\n");
return;
}
cp = bt_buf_add(buf, sizeof(*cp));
cp->handle = evt->handle;
bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_NEG_REPLY, buf);
}
}
static void hci_le_meta_event(struct bt_buf *buf)
{
struct bt_hci_evt_le_meta_event *evt = (void *)buf->data;
@ -465,6 +515,9 @@ static void hci_le_meta_event(struct bt_buf *buf)
case BT_HCI_EVT_LE_ADVERTISING_REPORT:
le_adv_report(buf);
break;
case BT_HCI_EVT_LE_LTK_REQUEST:
le_ltk_request(buf);
break;
default:
BT_DBG("Unhandled LE event %x\n", evt->subevent);
break;