diff --git a/lib/mgmt.h b/lib/mgmt.h index a2648bcfe..3432f9467 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -447,6 +447,13 @@ struct mgmt_ev_device_unpaired { struct mgmt_addr_info addr; } __packed; +#define MGMT_EV_PASSKEY_NOTIFY 0x0017 +struct mgmt_ev_passkey_notify { + struct mgmt_addr_info addr; + uint32_t passkey; + uint8_t entered; +} __packed; + static const char *mgmt_op[] = { "<0x0000>", "Read Version", diff --git a/src/event.c b/src/event.c index 26bbf64a9..3b8596161 100644 --- a/src/event.c +++ b/src/event.c @@ -198,7 +198,8 @@ int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba) return device_request_passkey(device, passkey_cb); } -int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) +int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey, + uint8_t entered) { struct btd_adapter *adapter; struct btd_device *device; @@ -206,7 +207,7 @@ int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE)) return -ENODEV; - return device_notify_passkey(device, passkey, 0); + return device_notify_passkey(device, passkey, entered); } void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, diff --git a/src/event.h b/src/event.h index dfc158d28..7031cc9d0 100644 --- a/src/event.h +++ b/src/event.h @@ -37,7 +37,8 @@ void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer); int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey); int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba); -int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey); +int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey, + uint8_t entered); void btd_event_device_blocked(bdaddr_t *local, bdaddr_t *peer); void btd_event_device_unblocked(bdaddr_t *local, bdaddr_t *peer); void btd_event_device_unpaired(bdaddr_t *local, bdaddr_t *peer); diff --git a/src/mgmt.c b/src/mgmt.c index 45a5c9085..0ec2912ca 100644 --- a/src/mgmt.c +++ b/src/mgmt.c @@ -756,6 +756,40 @@ static void mgmt_passkey_request(int sk, uint16_t index, void *buf, size_t len) } } +static void mgmt_passkey_notify(int sk, uint16_t index, void *buf, size_t len) +{ + struct mgmt_ev_passkey_notify *ev = buf; + struct controller_info *info; + uint32_t passkey; + char addr[18]; + int err; + + if (len < sizeof(*ev)) { + error("Too small passkey_notify event"); + return; + } + + ba2str(&ev->addr.bdaddr, addr); + + DBG("hci%u %s", index, addr); + + if (index > max_index) { + error("Unexpected index %u in passkey_notify event", index); + return; + } + + info = &controllers[index]; + + passkey = bt_get_le32(&ev->passkey); + + DBG("passkey %06u entered %u", passkey, ev->entered); + + err = btd_event_user_notify(&info->bdaddr, &ev->addr.bdaddr, + passkey, ev->entered); + if (err < 0) + error("btd_event_user_notify: %s", strerror(-err)); +} + struct confirm_data { int index; bdaddr_t bdaddr; @@ -1897,6 +1931,9 @@ static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data case MGMT_EV_USER_PASSKEY_REQUEST: mgmt_passkey_request(sk, index, buf + MGMT_HDR_SIZE, len); break; + case MGMT_EV_PASSKEY_NOTIFY: + mgmt_passkey_notify(sk, index, buf + MGMT_HDR_SIZE, len); + break; case MGMT_EV_NEW_LONG_TERM_KEY: mgmt_new_ltk(sk, index, buf + MGMT_HDR_SIZE, len); break;