__u8 features[HCI_MAX_PAGES][8];
__u16 pkt_type;
__u16 link_policy;
- __u32 link_mode;
__u8 key_type;
__u8 auth_type;
__u8 sec_level;
HCI_CONN_POWER_SAVE,
HCI_CONN_REMOTE_OOB,
HCI_CONN_FLUSH_KEY,
+ HCI_CONN_MASTER,
+ HCI_CONN_ENCRYPT,
+ HCI_CONN_AUTH,
+ HCI_CONN_SECURE,
+ HCI_CONN_FIPS,
};
static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return;
- encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
+ encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
l2cap_security_cfm(conn, status, encrypt);
if (conn->security_cfm_cb)
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return;
- encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
+ encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
read_lock(&hci_cb_list_lock);
list_for_each_entry(cb, &hci_cb_list, list) {
conn->state = BT_CONNECT;
conn->out = true;
- conn->link_mode = HCI_LM_MASTER;
+ set_bit(HCI_CONN_MASTER, &conn->flags);
conn->attempt++;
}
conn->out = true;
- conn->link_mode |= HCI_LM_MASTER;
+ set_bit(HCI_CONN_MASTER, &conn->flags);
params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
if (params) {
return 0;
}
- if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT))
+ if (hci_conn_ssp_enabled(conn) &&
+ !test_bit(HCI_CONN_ENCRYPT, &conn->flags))
return 0;
return 1;
if (sec_level > conn->sec_level)
conn->pending_sec_level = sec_level;
- else if (conn->link_mode & HCI_LM_AUTH)
+ else if (test_bit(HCI_CONN_AUTH, &conn->flags))
return 1;
/* Make sure we preserve an existing MITM requirement*/
/* If we're already encrypted set the REAUTH_PEND flag,
* otherwise set the ENCRYPT_PEND.
*/
- if (conn->link_mode & HCI_LM_ENCRYPT)
+ if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
else
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
return 1;
/* For other security levels we need the link key. */
- if (!(conn->link_mode & HCI_LM_AUTH))
+ if (!test_bit(HCI_CONN_AUTH, &conn->flags))
goto auth;
/* An authenticated FIPS approved combination key has sufficient
return 0;
encrypt:
- if (conn->link_mode & HCI_LM_ENCRYPT)
+ if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
return 1;
hci_conn_encrypt(conn);
{
BT_DBG("hcon %p", conn);
- if (!role && conn->link_mode & HCI_LM_MASTER)
+ if (!role && test_bit(HCI_CONN_MASTER, &conn->flags))
return 1;
if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->flags)) {
hci_dev_unlock(hdev);
}
+static u32 get_link_mode(struct hci_conn *conn)
+{
+ u32 link_mode = 0;
+
+ if (test_bit(HCI_CONN_MASTER, &conn->flags))
+ link_mode |= HCI_LM_MASTER;
+
+ if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+ link_mode |= HCI_LM_ENCRYPT;
+
+ if (test_bit(HCI_CONN_AUTH, &conn->flags))
+ link_mode |= HCI_LM_AUTH;
+
+ if (test_bit(HCI_CONN_SECURE, &conn->flags))
+ link_mode |= HCI_LM_SECURE;
+
+ if (test_bit(HCI_CONN_FIPS, &conn->flags))
+ link_mode |= HCI_LM_FIPS;
+
+ return link_mode;
+}
+
int hci_get_conn_list(void __user *arg)
{
struct hci_conn *c;
(ci + n)->type = c->type;
(ci + n)->out = c->out;
(ci + n)->state = c->state;
- (ci + n)->link_mode = c->link_mode;
+ (ci + n)->link_mode = get_link_mode(c);
if (++n >= req.conn_num)
break;
}
ci.type = conn->type;
ci.out = conn->out;
ci.state = conn->state;
- ci.link_mode = conn->link_mode;
+ ci.link_mode = get_link_mode(conn);
}
hci_dev_unlock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
if (conn) {
if (rp->role)
- conn->link_mode &= ~HCI_LM_MASTER;
+ clear_bit(HCI_CONN_MASTER, &conn->flags);
else
- conn->link_mode |= HCI_LM_MASTER;
+ set_bit(HCI_CONN_MASTER, &conn->flags);
}
hci_dev_unlock(hdev);
conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
if (conn) {
conn->out = true;
- conn->link_mode |= HCI_LM_MASTER;
+ set_bit(HCI_CONN_MASTER, &conn->flags);
} else
BT_ERR("No memory for new connection");
}
hci_conn_add_sysfs(conn);
if (test_bit(HCI_AUTH, &hdev->flags))
- conn->link_mode |= HCI_LM_AUTH;
+ set_bit(HCI_CONN_AUTH, &conn->flags);
if (test_bit(HCI_ENCRYPT, &hdev->flags))
- conn->link_mode |= HCI_LM_ENCRYPT;
+ set_bit(HCI_CONN_ENCRYPT, &conn->flags);
/* Get remote features */
if (conn->type == ACL_LINK) {
test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
BT_INFO("re-auth of legacy device is not possible.");
} else {
- conn->link_mode |= HCI_LM_AUTH;
+ set_bit(HCI_CONN_AUTH, &conn->flags);
conn->sec_level = conn->pending_sec_level;
}
} else {
if (!ev->status) {
if (ev->encrypt) {
/* Encryption implies authentication */
- conn->link_mode |= HCI_LM_AUTH;
- conn->link_mode |= HCI_LM_ENCRYPT;
+ set_bit(HCI_CONN_AUTH, &conn->flags);
+ set_bit(HCI_CONN_ENCRYPT, &conn->flags);
conn->sec_level = conn->pending_sec_level;
/* P-256 authentication key implies FIPS */
if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
- conn->link_mode |= HCI_LM_FIPS;
+ set_bit(HCI_CONN_FIPS, &conn->flags);
if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
conn->type == LE_LINK)
set_bit(HCI_CONN_AES_CCM, &conn->flags);
} else {
- conn->link_mode &= ~HCI_LM_ENCRYPT;
+ clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
clear_bit(HCI_CONN_AES_CCM, &conn->flags);
}
}
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
if (conn) {
if (!ev->status)
- conn->link_mode |= HCI_LM_SECURE;
+ set_bit(HCI_CONN_SECURE, &conn->flags);
clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
if (conn) {
if (!ev->status) {
if (ev->role)
- conn->link_mode &= ~HCI_LM_MASTER;
+ clear_bit(HCI_CONN_MASTER, &conn->flags);
else
- conn->link_mode |= HCI_LM_MASTER;
+ set_bit(HCI_CONN_MASTER, &conn->flags);
}
clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
if (ev->role == LE_CONN_ROLE_MASTER) {
conn->out = true;
- conn->link_mode |= HCI_LM_MASTER;
+ set_bit(HCI_CONN_MASTER, &conn->flags);
}
/* If we didn't have a hci_conn object previously
* been configured for this connection. If not, then trigger
* the connection update procedure.
*/
- if (!(hcon->link_mode & HCI_LM_MASTER) &&
+ if (!test_bit(HCI_CONN_MASTER, &hcon->flags) &&
(hcon->le_conn_interval < hcon->le_conn_min_interval ||
hcon->le_conn_interval > hcon->le_conn_max_interval)) {
struct l2cap_conn_param_update_req req;
u16 min, max, latency, to_multiplier;
int err;
- if (!(hcon->link_mode & HCI_LM_MASTER))
+ if (!test_bit(HCI_CONN_MASTER, &hcon->flags))
return -EINVAL;
if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
* Confirms and the slave Enters the passkey.
*/
if (method == OVERLAP) {
- if (hcon->link_mode & HCI_LM_MASTER)
+ if (test_bit(HCI_CONN_MASTER, &hcon->flags))
method = CFM_PASSKEY;
else
method = REQ_PASSKEY;
if (skb->len < sizeof(*req))
return SMP_INVALID_PARAMS;
- if (conn->hcon->link_mode & HCI_LM_MASTER)
+ if (test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
return SMP_CMD_NOTSUPP;
if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
if (skb->len < sizeof(*rsp))
return SMP_INVALID_PARAMS;
- if (!(conn->hcon->link_mode & HCI_LM_MASTER))
+ if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
return SMP_CMD_NOTSUPP;
skb_pull(skb, sizeof(*rsp));
if (skb->len < sizeof(*rp))
return SMP_INVALID_PARAMS;
- if (!(conn->hcon->link_mode & HCI_LM_MASTER))
+ if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
return SMP_CMD_NOTSUPP;
sec_level = authreq_to_seclevel(rp->auth_req);
if (sec_level > hcon->pending_sec_level)
hcon->pending_sec_level = sec_level;
- if (hcon->link_mode & HCI_LM_MASTER)
+ if (test_bit(HCI_CONN_MASTER, &hcon->flags))
if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
return 0;
hcon->pending_sec_level > BT_SECURITY_MEDIUM)
authreq |= SMP_AUTH_MITM;
- if (hcon->link_mode & HCI_LM_MASTER) {
+ if (test_bit(HCI_CONN_MASTER, &hcon->flags)) {
struct smp_cmd_pairing cp;
build_pairing_cmd(conn, &cp, NULL, authreq);