Bluetooth: BR/EDR: Handle User Confirmation Request event
Enables processing, as pairing acceptor, user interactive passkey confirmation request if local and remote IO Capabilities supports 'display yes/no'. Based on such validation, both parties can confirm interactively passkey value or JustWorks (auto-accept) model is used. > HCI Event: Command Complete (0x0e) plen 10 IO Capability Request Reply (0x01|0x002b) ncmd 1 Status: Success (0x00) Address: 00:1A:7D:DA:71:13 (cyber-blue(HK)Ltd) > HCI Event: User Confirmation Request (0x33) plen 10 Address: 00:1A:7D:DA:71:13 (cyber-blue(HK)Ltd) Passkey: 565990 < HCI Command: User Confirmation Request Reply (0x01|0x002c) plen 6 Address: 00:1A:7D:DA:71:13 (cyber-blue(HK)Ltd) > HCI Event: Command Complete (0x0e) plen 10 User Confirmation Request Reply (0x01|0x002c) ncmd 1 Status: Success (0x00) Address: 00:1A:7D:DA:71:13 (cyber-blue(HK)Ltd) > HCI Event: Simple Pairing Complete (0x36) plen 7 Status: Success (0x00) Address: 00:1A:7D:DA:71:13 (cyber-blue(HK)Ltd) Change-Id: Ice7a57a1c6150c10ea22402554954ed84aa94d0e Signed-off-by: Arkadiusz Lichwa <arkadiusz.lichwa@tieto.com>
This commit is contained in:
parent
02f541dfc5
commit
7b2799da1c
4 changed files with 100 additions and 0 deletions
|
@ -282,6 +282,16 @@ struct bt_hci_cp_io_capability_reply {
|
||||||
uint8_t authentication;
|
uint8_t authentication;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
#define BT_HCI_OP_USER_CONFIRM_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002c)
|
||||||
|
#define BT_HCI_OP_USER_CONFIRM_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002d)
|
||||||
|
struct bt_hci_cp_user_confirm_reply {
|
||||||
|
bt_addr_t bdaddr;
|
||||||
|
} __packed;
|
||||||
|
struct bt_hci_rp_user_confirm_reply {
|
||||||
|
uint8_t status;
|
||||||
|
bt_addr_t bdaddr;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
#define BT_HCI_OP_IO_CAPABILITY_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x0034)
|
#define BT_HCI_OP_IO_CAPABILITY_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x0034)
|
||||||
struct bt_hci_cp_io_capability_neg_reply {
|
struct bt_hci_cp_io_capability_neg_reply {
|
||||||
bt_addr_t bdaddr;
|
bt_addr_t bdaddr;
|
||||||
|
@ -690,6 +700,12 @@ struct bt_hci_evt_io_capa_resp {
|
||||||
uint8_t authentication;
|
uint8_t authentication;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
#define BT_HCI_EVT_USER_CONFIRM_REQ 0x33
|
||||||
|
struct bt_hci_evt_user_confirm_req {
|
||||||
|
bt_addr_t bdaddr;
|
||||||
|
uint32_t passkey;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
#define BT_HCI_EVT_SSP_COMPLETE 0x36
|
#define BT_HCI_EVT_SSP_COMPLETE 0x36
|
||||||
struct bt_hci_evt_ssp_complete {
|
struct bt_hci_evt_ssp_complete {
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
|
|
@ -816,6 +816,60 @@ uint8_t bt_conn_ssp_get_auth(const struct bt_conn *conn)
|
||||||
/* No MITM protection possible so ignore remote MITM requirement. */
|
/* No MITM protection possible so ignore remote MITM requirement. */
|
||||||
return (conn->br.remote_auth & ~BT_MITM);
|
return (conn->br.remote_auth & ~BT_MITM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ssp_confirm_reply(struct bt_conn *conn)
|
||||||
|
{
|
||||||
|
struct bt_hci_cp_user_confirm_reply *cp;
|
||||||
|
struct net_buf *buf;
|
||||||
|
|
||||||
|
BT_DBG("");
|
||||||
|
|
||||||
|
buf = bt_hci_cmd_create(BT_HCI_OP_USER_CONFIRM_REPLY, sizeof(*cp));
|
||||||
|
if (!buf) {
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = net_buf_add(buf, sizeof(*cp));
|
||||||
|
bt_addr_copy(&cp->bdaddr, &conn->br.dst);
|
||||||
|
|
||||||
|
return bt_hci_cmd_send_sync(BT_HCI_OP_USER_CONFIRM_REPLY, buf, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssp_confirm_neg_reply(struct bt_conn *conn)
|
||||||
|
{
|
||||||
|
struct bt_hci_cp_user_confirm_reply *cp;
|
||||||
|
struct net_buf *buf;
|
||||||
|
|
||||||
|
BT_DBG("");
|
||||||
|
|
||||||
|
buf = bt_hci_cmd_create(BT_HCI_OP_USER_CONFIRM_NEG_REPLY, sizeof(*cp));
|
||||||
|
if (!buf) {
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = net_buf_add(buf, sizeof(*cp));
|
||||||
|
bt_addr_copy(&cp->bdaddr, &conn->br.dst);
|
||||||
|
|
||||||
|
return bt_hci_cmd_send_sync(BT_HCI_OP_USER_CONFIRM_NEG_REPLY, buf,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bt_conn_ssp_auth(struct bt_conn *conn, uint32_t passkey)
|
||||||
|
{
|
||||||
|
conn->br.ssp_method = ssp_pair_method(conn);
|
||||||
|
|
||||||
|
/* TODO: As pairing acceptor call user pairing consent API callback. */
|
||||||
|
|
||||||
|
/* Start interactive authentication if valid, default to justworks. */
|
||||||
|
switch (conn->br.ssp_method) {
|
||||||
|
case PASSKEY_CONFIRM:
|
||||||
|
bt_auth->passkey_confirm(conn, passkey);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ssp_confirm_reply(conn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void timeout_fiber(int arg1, int arg2)
|
static void timeout_fiber(int arg1, int arg2)
|
||||||
|
@ -1344,6 +1398,11 @@ int bt_conn_auth_passkey_confirm(struct bt_conn *conn)
|
||||||
return bt_smp_auth_passkey_confirm(conn);
|
return bt_smp_auth_passkey_confirm(conn);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLUETOOTH_SMP */
|
#endif /* CONFIG_BLUETOOTH_SMP */
|
||||||
|
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||||
|
if (conn->type == BT_CONN_TYPE_BR) {
|
||||||
|
return ssp_confirm_reply(conn);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -1365,6 +1424,10 @@ int bt_conn_auth_cancel(struct bt_conn *conn)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conn->br.ssp_method == PASSKEY_CONFIRM) {
|
||||||
|
return ssp_confirm_neg_reply(conn);
|
||||||
|
}
|
||||||
|
|
||||||
return pin_code_neg_reply(&conn->br.dst);
|
return pin_code_neg_reply(&conn->br.dst);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||||
|
|
|
@ -55,6 +55,7 @@ struct bt_conn_br {
|
||||||
bt_addr_t dst;
|
bt_addr_t dst;
|
||||||
uint8_t remote_io_capa;
|
uint8_t remote_io_capa;
|
||||||
uint8_t remote_auth;
|
uint8_t remote_auth;
|
||||||
|
uint8_t ssp_method;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -126,6 +127,7 @@ struct bt_conn *bt_conn_lookup_addr_br(const bt_addr_t *peer);
|
||||||
void bt_conn_pin_code_req(struct bt_conn *conn);
|
void bt_conn_pin_code_req(struct bt_conn *conn);
|
||||||
uint8_t bt_conn_get_io_capa(void);
|
uint8_t bt_conn_get_io_capa(void);
|
||||||
uint8_t bt_conn_ssp_get_auth(const struct bt_conn *conn);
|
uint8_t bt_conn_ssp_get_auth(const struct bt_conn *conn);
|
||||||
|
void bt_conn_ssp_auth(struct bt_conn *conn, uint32_t passkey);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Look up an existing connection */
|
/* Look up an existing connection */
|
||||||
|
|
|
@ -1230,6 +1230,21 @@ static void ssp_complete(struct net_buf *buf)
|
||||||
|
|
||||||
bt_conn_unref(conn);
|
bt_conn_unref(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void user_confirm_req(struct net_buf *buf)
|
||||||
|
{
|
||||||
|
struct bt_hci_evt_user_confirm_req *evt = (void *)buf->data;
|
||||||
|
struct bt_conn *conn;
|
||||||
|
|
||||||
|
conn = bt_conn_lookup_addr_br(&evt->bdaddr);
|
||||||
|
if (!conn) {
|
||||||
|
BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_conn_ssp_auth(conn, sys_le32_to_cpu(evt->passkey));
|
||||||
|
bt_conn_unref(conn);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR)
|
#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR)
|
||||||
|
@ -1911,6 +1926,9 @@ static void hci_event(struct net_buf *buf)
|
||||||
case BT_HCI_EVT_SSP_COMPLETE:
|
case BT_HCI_EVT_SSP_COMPLETE:
|
||||||
ssp_complete(buf);
|
ssp_complete(buf);
|
||||||
break;
|
break;
|
||||||
|
case BT_HCI_EVT_USER_CONFIRM_REQ:
|
||||||
|
user_confirm_req(buf);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||||
case BT_HCI_EVT_DISCONN_COMPLETE:
|
case BT_HCI_EVT_DISCONN_COMPLETE:
|
||||||
|
@ -2374,6 +2392,7 @@ static int set_event_mask(void)
|
||||||
ev->events[2] |= 0x80; /* Link Key Notif */
|
ev->events[2] |= 0x80; /* Link Key Notif */
|
||||||
ev->events[6] |= 0x01; /* IO Capability Request */
|
ev->events[6] |= 0x01; /* IO Capability Request */
|
||||||
ev->events[6] |= 0x02; /* IO Capability Response */
|
ev->events[6] |= 0x02; /* IO Capability Response */
|
||||||
|
ev->events[6] |= 0x04; /* User Confirmation Request */
|
||||||
ev->events[6] |= 0x20; /* Simple Pairing Complete */
|
ev->events[6] |= 0x20; /* Simple Pairing Complete */
|
||||||
#endif
|
#endif
|
||||||
ev->events[1] |= 0x20; /* Command Complete */
|
ev->events[1] |= 0x20; /* Command Complete */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue