* [PATCH v2 06/13] Bluetooth: Enable Authenticated Payload Timeout Expired event
From: Marcel Holtmann @ 2014-01-10 6:40 UTC (permalink / raw)
To: linux-bluetooth
With Secure Connections capable controllers, the authenticated payload
timeout can trigger. Enable the event so the controller informs the
host when this happens.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_core.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5e8663c194c1..52e398f37129 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1288,6 +1288,10 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
events[2] |= 0x08; /* Truncated Page Complete */
}
+ /* Enable Authenticated Payload Timeout Expired event if supported */
+ if (lmp_ping_capable(hdev))
+ events[2] |= 0x80;
+
hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
}
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 05/13] Bluetooth: Add support for handling P-256 derived link keys
From: Marcel Holtmann @ 2014-01-10 6:40 UTC (permalink / raw)
To: linux-bluetooth
Before being able to enable Secure Connections support, the core needs
to know on how to handle P-256 derived link keys. The difference between
authenticated and unauthenticated P-256 derived link keys is the same as
its P-192 counter parts.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_conn.c | 6 ++++--
net/bluetooth/hci_event.c | 3 ++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 251f22e32fbf..cf96b3438a91 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -802,12 +802,14 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
/* An authenticated combination key has sufficient security for any
security level. */
- if (conn->key_type == HCI_LK_AUTH_COMBINATION_P192)
+ if (conn->key_type == HCI_LK_AUTH_COMBINATION_P192 ||
+ conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
goto encrypt;
/* An unauthenticated combination key has sufficient security for
security level 1 and 2. */
- if (conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 &&
+ if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 ||
+ conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) &&
(sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW))
goto encrypt;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index defa1252b534..b3c5396e0c1b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2633,7 +2633,8 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (conn) {
- if (key->type == HCI_LK_UNAUTH_COMBINATION_P192 &&
+ if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
+ key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
BT_DBG("%s ignoring unauthenticated key", hdev->name);
goto not_found;
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 04/13] Bluetooth: Add definitions for new link key types
From: Marcel Holtmann @ 2014-01-10 6:40 UTC (permalink / raw)
To: linux-bluetooth
With the introduction of Secure Connections, the list of link key types
got extended by P-256 versions of authenticated and unauthenticated
link keys.
To avoid any confusion the previous authenticated and unauthenticated
link key types got ammended with a P912 postfix. And the two new keys
have a P256 postfix now. Existing code using the previous definitions
has been adjusted.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 6 ++++--
net/bluetooth/hci_conn.c | 4 ++--
net/bluetooth/hci_event.c | 2 +-
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e4e94bfc5232..8d888bc432c6 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -331,9 +331,11 @@ enum {
#define HCI_LK_LOCAL_UNIT 0x01
#define HCI_LK_REMOTE_UNIT 0x02
#define HCI_LK_DEBUG_COMBINATION 0x03
-#define HCI_LK_UNAUTH_COMBINATION 0x04
-#define HCI_LK_AUTH_COMBINATION 0x05
+#define HCI_LK_UNAUTH_COMBINATION_P192 0x04
+#define HCI_LK_AUTH_COMBINATION_P192 0x05
#define HCI_LK_CHANGED_COMBINATION 0x06
+#define HCI_LK_UNAUTH_COMBINATION_P256 0x07
+#define HCI_LK_AUTH_COMBINATION_P256 0x08
/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
#define HCI_SMP_STK 0x80
#define HCI_SMP_STK_SLAVE 0x81
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ba5366c320da..251f22e32fbf 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -802,12 +802,12 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
/* An authenticated combination key has sufficient security for any
security level. */
- if (conn->key_type == HCI_LK_AUTH_COMBINATION)
+ if (conn->key_type == HCI_LK_AUTH_COMBINATION_P192)
goto encrypt;
/* An unauthenticated combination key has sufficient security for
security level 1 and 2. */
- if (conn->key_type == HCI_LK_UNAUTH_COMBINATION &&
+ if (conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 &&
(sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW))
goto encrypt;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index cfcce448957b..defa1252b534 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2633,7 +2633,7 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (conn) {
- if (key->type == HCI_LK_UNAUTH_COMBINATION &&
+ if (key->type == HCI_LK_UNAUTH_COMBINATION_P192 &&
conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
BT_DBG("%s ignoring unauthenticated key", hdev->name);
goto not_found;
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 03/13] Bluetooth: Add HCI command definition for extended OOB data
From: Marcel Holtmann @ 2014-01-10 6:40 UTC (permalink / raw)
To: linux-bluetooth
The Secure Connections feature introduces the support for P-256 strength
pairings (compared to P-192 with Secure Simple Pairing). This however
means that for out-of-band pairing the hash and randomizer needs to be
differentiated. Two new commands are introduced to handle the possible
combinations of P-192 and P-256. This add the HCI command definition
for both.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 2a35d273de2c..e4e94bfc5232 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -664,6 +664,15 @@ struct hci_rp_set_csb {
#define HCI_OP_START_SYNC_TRAIN 0x0443
+#define HCI_OP_REMOTE_OOB_EXT_DATA_REPLY 0x0445
+struct hci_cp_remote_oob_ext_data_reply {
+ bdaddr_t bdaddr;
+ __u8 hash192[16];
+ __u8 randomizer192[16];
+ __u8 hash256[16];
+ __u8 randomizer256[16];
+} __packed;
+
#define HCI_OP_SNIFF_MODE 0x0803
struct hci_cp_sniff_mode {
__le16 handle;
@@ -948,6 +957,15 @@ struct hci_cp_write_sc_support {
__u8 support;
} __packed;
+#define HCI_OP_READ_LOCAL_OOB_EXT_DATA 0x0c7d
+struct hci_rp_read_local_oob_ext_data {
+ __u8 status;
+ __u8 hash192[16];
+ __u8 randomizer192[16];
+ __u8 hash256[16];
+ __u8 randomizer256[16];
+} __packed;
+
#define HCI_OP_READ_LOCAL_VERSION 0x1001
struct hci_rp_read_local_version {
__u8 status;
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 02/13] Bluetooth: Add HCI command definition for Secure Connections enabling
From: Marcel Holtmann @ 2014-01-10 6:40 UTC (permalink / raw)
To: linux-bluetooth
The Secure Connections feature is optional and host stacks have to
manually enable it. This add the HCI command definiton for reading
and writing this setting.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index cd40219d32aa..2a35d273de2c 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -937,6 +937,17 @@ struct hci_rp_write_sync_train_params {
__le16 sync_train_int;
} __packed;
+#define HCI_OP_READ_SC_SUPPORT 0x0c79
+struct hci_rp_read_sc_support {
+ __u8 status;
+ __u8 support;
+} __packed;
+
+#define HCI_OP_WRITE_SC_SUPPORT 0x0c7a
+struct hci_cp_write_sc_support {
+ __u8 support;
+} __packed;
+
#define HCI_OP_READ_LOCAL_VERSION 0x1001
struct hci_rp_read_local_version {
__u8 status;
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 01/13] Bluetooth: Add LMP feature definitions for Secure Connections support
From: Marcel Holtmann @ 2014-01-10 6:40 UTC (permalink / raw)
To: linux-bluetooth
The support for Secure Connections introduces two new controller
features and one new host feature.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 4 ++++
include/net/bluetooth/hci_core.h | 3 +++
2 files changed, 7 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 66c1cd87bfe7..cd40219d32aa 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -282,10 +282,14 @@ enum {
#define LMP_SYNC_TRAIN 0x04
#define LMP_SYNC_SCAN 0x08
+#define LMP_SC 0x01
+#define LMP_PING 0x02
+
/* Host features */
#define LMP_HOST_SSP 0x01
#define LMP_HOST_LE 0x02
#define LMP_HOST_LE_BREDR 0x04
+#define LMP_HOST_SC 0x08
/* Connection modes */
#define HCI_CM_ACTIVE 0x0000
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f2f0cf5865c4..bb984d0626b7 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -803,9 +803,12 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_csb_slave_capable(dev) ((dev)->features[2][0] & LMP_CSB_SLAVE)
#define lmp_sync_train_capable(dev) ((dev)->features[2][0] & LMP_SYNC_TRAIN)
#define lmp_sync_scan_capable(dev) ((dev)->features[2][0] & LMP_SYNC_SCAN)
+#define lmp_sc_capable(dev) ((dev)->features[2][1] & LMP_SC)
+#define lmp_ping_capable(dev) ((dev)->features[2][1] & LMP_PING)
/* ----- Host capabilities ----- */
#define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP)
+#define lmp_host_sc_capable(dev) ((dev)->features[1][0] & LMP_HOST_SC)
#define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE))
#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
--
1.8.4.2
^ permalink raw reply related
* [PATCH] Bluetooth: Provide remote OOB data for Secure Connections
From: Marcel Holtmann @ 2014-01-10 5:58 UTC (permalink / raw)
To: linux-bluetooth
When Secure Connections has been enabled it is possible to provide P-192
and/or P-256 data during the pairing process. The internal out-of-band
credentials storage has been extended to also hold P-256 data.
Initially the P-256 data will be empty and with Secure Connections enabled
no P-256 data will be provided. This is according to the specification
since it might be possible that the remote side did not provide either
of the out-of-band credentials.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 4 ++--
include/net/bluetooth/hci_core.h | 6 ++++--
net/bluetooth/hci_core.c | 6 +++---
net/bluetooth/hci_event.c | 32 ++++++++++++++++++++++++--------
4 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 4850da41f788..2bc19881e250 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -668,8 +668,8 @@ struct hci_rp_set_csb {
#define HCI_OP_START_SYNC_TRAIN 0x0443
-#define HCI_OP_REMOTE_OOB_DATA_EXT_REPLY 0x0445
-struct hci_cp_remote_oob_data_ext_reply {
+#define HCI_OP_REMOTE_OOB_EXT_DATA_REPLY 0x0445
+struct hci_cp_remote_oob_ext_data_reply {
bdaddr_t bdaddr;
__u8 hash192[16];
__u8 randomizer192[16];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index bd15eaa4c06e..5948930f92e6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -114,8 +114,10 @@ struct link_key {
struct oob_data {
struct list_head list;
bdaddr_t bdaddr;
- u8 hash[16];
- u8 randomizer[16];
+ u8 hash192[16];
+ u8 randomizer192[16];
+ u8 hash256[16];
+ u8 randomizer256[16];
};
#define HCI_MAX_SHORT_NAME_LENGTH 10
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 946631ffe802..f13c0550f368 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2802,7 +2802,7 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
data = hci_find_remote_oob_data(hdev, bdaddr);
if (!data) {
- data = kmalloc(sizeof(*data), GFP_ATOMIC);
+ data = kzalloc(sizeof(*data), GFP_ATOMIC);
if (!data)
return -ENOMEM;
@@ -2810,8 +2810,8 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
list_add(&data->list, &hdev->remote_oob_data);
}
- memcpy(data->hash, hash, sizeof(data->hash));
- memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
+ memcpy(data->hash192, hash, sizeof(data->hash192));
+ memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
BT_DBG("%s for %pMR", hdev->name, bdaddr);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6923241d2b3e..47b953e24864 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3391,20 +3391,36 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
if (data) {
- struct hci_cp_remote_oob_data_reply cp;
+ if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
+ struct hci_cp_remote_oob_ext_data_reply cp;
- bacpy(&cp.bdaddr, &ev->bdaddr);
- memcpy(cp.hash, data->hash, sizeof(cp.hash));
- memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
+ bacpy(&cp.bdaddr, &ev->bdaddr);
+ memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
+ memcpy(cp.randomizer192, data->randomizer192,
+ sizeof(cp.randomizer192));
+ memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
+ memcpy(cp.randomizer256, data->randomizer256,
+ sizeof(cp.randomizer256));
+
+ hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
+ sizeof(cp), &cp);
+ } else {
+ struct hci_cp_remote_oob_data_reply cp;
- hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
- &cp);
+ bacpy(&cp.bdaddr, &ev->bdaddr);
+ memcpy(cp.hash, data->hash192, sizeof(cp.hash));
+ memcpy(cp.randomizer, data->randomizer192,
+ sizeof(cp.randomizer));
+
+ hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
+ sizeof(cp), &cp);
+ }
} else {
struct hci_cp_remote_oob_data_neg_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
- hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
- &cp);
+ hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
+ sizeof(cp), &cp);
}
unlock:
--
1.8.4.2
^ permalink raw reply related
* [PATCH] Bluetooth: Add debugfs quirk for forcing Secure Connections support
From: Marcel Holtmann @ 2014-01-10 5:24 UTC (permalink / raw)
To: linux-bluetooth
The Bluetooth 4.1 specification with Secure Connections support has
just been released and controllers with this feature are still in
an early stage.
A handful of controllers have already support for it, but they do
not always identify this feature correctly. This debugfs entry
allows to tell the kernel that the controller can be treated as
it would fully support Secure Connections.
Using debugfs to force Secure Connections support of course does
not make this feature magically appear in all controllers. This
is a debug functionality for early adopters. Once the majority
of controllers matures this quirk will be removed.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 1 +
net/bluetooth/hci_core.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-
net/bluetooth/mgmt.c | 6 ++++--
3 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index d38202500206..4850da41f788 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -117,6 +117,7 @@ enum {
HCI_SERVICE_CACHE,
HCI_DEBUG_KEYS,
HCI_DUT_MODE,
+ HCI_FORCE_SC,
HCI_UNREGISTER,
HCI_USER_CHANNEL,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b3b619a448b5..946631ffe802 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -415,6 +415,52 @@ static int ssp_debug_mode_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
ssp_debug_mode_set, "%llu\n");
+static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct hci_dev *hdev = file->private_data;
+ char buf[3];
+
+ buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N';
+ buf[1] = '\n';
+ buf[2] = '\0';
+ return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t force_sc_support_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct hci_dev *hdev = file->private_data;
+ char buf[32];
+ size_t buf_size = min(count, (sizeof(buf)-1));
+ bool enable;
+
+ if (test_bit(HCI_UP, &hdev->flags))
+ return -EBUSY;
+
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+
+ buf[buf_size] = '\0';
+ if (strtobool(buf, &enable))
+ return -EINVAL;
+
+ if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags))
+ return -EALREADY;
+
+ change_bit(HCI_FORCE_SC, &hdev->dev_flags);
+
+ return count;
+}
+
+static const struct file_operations force_sc_support_fops = {
+ .open = simple_open,
+ .read = force_sc_support_read,
+ .write = force_sc_support_write,
+ .llseek = default_llseek,
+};
+
static int idle_timeout_set(void *data, u64 val)
{
struct hci_dev *hdev = data;
@@ -1365,7 +1411,8 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt)
hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
/* Enable Secure Connections if supported and configured */
- if (lmp_sc_capable(hdev) &&
+ if ((lmp_sc_capable(hdev) ||
+ test_bit(HCI_FORCE_SC, &hdev->dev_flags)) &&
test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
u8 support = 0x01;
hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
@@ -1442,6 +1489,8 @@ static int __hci_init(struct hci_dev *hdev)
hdev, &auto_accept_delay_fops);
debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
hdev, &ssp_debug_mode_fops);
+ debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
+ hdev, &force_sc_support_fops);
}
if (lmp_sniff_capable(hdev)) {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a7d4ae679ab7..bbe30c983492 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -378,7 +378,8 @@ static u32 get_supported_settings(struct hci_dev *hdev)
settings |= MGMT_SETTING_HS;
}
- if (lmp_sc_capable(hdev))
+ if (lmp_sc_capable(hdev) ||
+ test_bit(HCI_FORCE_SC, &hdev->dev_flags))
settings |= MGMT_SETTING_SECURE_CONN;
}
@@ -4026,7 +4027,8 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
status);
- if (!lmp_sc_capable(hdev))
+ if (!lmp_sc_capable(hdev) &&
+ !test_bit(HCI_FORCE_SC, &hdev->dev_flags))
return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
MGMT_STATUS_NOT_SUPPORTED);
--
1.8.4.2
^ permalink raw reply related
* [PATCH] Bluetooth: Add support for local OOB data with Secure Connections
From: Marcel Holtmann @ 2014-01-10 4:09 UTC (permalink / raw)
To: linux-bluetooth
For Secure Connections support and the usage of out-of-band pairing,
it is needed to read the P-256 hash and randomizer or P-192 hash and
randomizer. This change will read P-192 data when Secure Connections
is disabled and P-192 and P-256 data when it is enabled.
The difference is between using HCI Read Local OOB Data and using the
new HCI Read Local OOB Extended Data command. The first one has been
introduced with Bluetooth 2.1 and returns only the P-192 data.
< HCI Command: Read Local OOB Data (0x03|0x0057) plen 0
> HCI Event: Command Complete (0x0e) plen 36
Read Local OOB Data (0x03|0x0057) ncmd 1
Status: Success (0x00)
Hash C from P-192: 975a59baa1c4eee391477cb410b23e6d
Randomizer R with P-192: 9ee63b7dec411d3b467c5ae446df7f7d
The second command has been introduced with Bluetooth 4.1 and will
return P-192 and P-256 data.
< HCI Command: Read Local OOB Extended Data (0x03|0x007d) plen 0
> HCI Event: Command Complete (0x0e) plen 68
Read Local OOB Extended Data (0x03|0x007d) ncmd 1
Status: Success (0x00)
Hash C from P-192: 6489731804b156fa6355efb8124a1389
Randomizer R with P-192: 4781d5352fb215b2958222b3937b6026
Hash C from P-256: 69ef8a928b9d07fc149e630e74ecb991
Randomizer R with P-256: 4781d5352fb215b2958222b3937b6026
The change for the management interface is transparent and no change
is required for existing userspace. The Secure Connections feature
needs to be manually enabled. When it is disabled, then userspace
only gets the P-192 returned and with Secure Connections enabled,
userspace gets P-192 and P-256 in an extended structure.
It is also acceptable to just ignore the P-256 data since it is not
required to support them. The pairing with out-of-band credentials
will still succeed. However then of course no Secure Connection will
b established.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 5 +++--
include/net/bluetooth/mgmt.h | 6 ++++++
net/bluetooth/hci_event.c | 28 ++++++++++++++++++++++-----
net/bluetooth/mgmt.c | 41 ++++++++++++++++++++++++++++++++--------
4 files changed, 65 insertions(+), 15 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 1eb55ec40ac0..bd15eaa4c06e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1129,8 +1129,9 @@ void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
u8 status);
void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
-void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
- u8 *randomizer, u8 status);
+void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
+ u8 *randomizer192, u8 *hash256,
+ u8 *randomizer256, u8 status);
void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
u8 ssp, u8 *eir, u16 eir_len);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 8a2c78175997..036ddc7dc7ed 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -295,6 +295,12 @@ struct mgmt_rp_read_local_oob_data {
__u8 hash[16];
__u8 randomizer[16];
} __packed;
+struct mgmt_rp_read_local_oob_ext_data {
+ __u8 hash192[16];
+ __u8 randomizer192[16];
+ __u8 hash256[16];
+ __u8 randomizer256[16];
+} __packed;
#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0021
struct mgmt_cp_add_remote_oob_data {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 820a01965ce3..6923241d2b3e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -932,16 +932,30 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
hci_dev_unlock(hdev);
}
-static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
- struct sk_buff *skb)
+static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
+ struct sk_buff *skb)
{
struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
hci_dev_lock(hdev);
- mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
- rp->randomizer, rp->status);
+ mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
+ NULL, NULL, rp->status);
+ hci_dev_unlock(hdev);
+}
+
+static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+ hci_dev_lock(hdev);
+ mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
+ rp->hash256, rp->randomizer256,
+ rp->status);
hci_dev_unlock(hdev);
}
@@ -2248,7 +2262,11 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
break;
case HCI_OP_READ_LOCAL_OOB_DATA:
- hci_cc_read_local_oob_data_reply(hdev, skb);
+ hci_cc_read_local_oob_data(hdev, skb);
+ break;
+
+ case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
+ hci_cc_read_local_oob_ext_data(hdev, skb);
break;
case HCI_OP_LE_READ_BUFFER_SIZE:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 9b162038acb7..a7d4ae679ab7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3078,7 +3078,12 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
goto unlock;
}
- err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
+ if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
+ err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_EXT_DATA,
+ 0, NULL);
+ else
+ err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
+
if (err < 0)
mgmt_pending_remove(cmd);
@@ -5077,8 +5082,9 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
cmd ? cmd->sk : NULL);
}
-void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
- u8 *randomizer, u8 status)
+void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
+ u8 *randomizer192, u8 *hash256,
+ u8 *randomizer256, u8 status)
{
struct pending_cmd *cmd;
@@ -5092,13 +5098,32 @@ void mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
mgmt_status(status));
} else {
- struct mgmt_rp_read_local_oob_data rp;
+ if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
+ hash256 && randomizer256) {
+ struct mgmt_rp_read_local_oob_ext_data rp;
+
+ memcpy(rp.hash192, hash192, sizeof(rp.hash192));
+ memcpy(rp.randomizer192, randomizer192,
+ sizeof(rp.randomizer192));
- memcpy(rp.hash, hash, sizeof(rp.hash));
- memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer));
+ memcpy(rp.hash256, hash256, sizeof(rp.hash256));
+ memcpy(rp.randomizer256, randomizer256,
+ sizeof(rp.randomizer256));
- cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
- 0, &rp, sizeof(rp));
+ cmd_complete(cmd->sk, hdev->id,
+ MGMT_OP_READ_LOCAL_OOB_DATA, 0,
+ &rp, sizeof(rp));
+ } else {
+ struct mgmt_rp_read_local_oob_data rp;
+
+ memcpy(rp.hash, hash192, sizeof(rp.hash));
+ memcpy(rp.randomizer, randomizer192,
+ sizeof(rp.randomizer));
+
+ cmd_complete(cmd->sk, hdev->id,
+ MGMT_OP_READ_LOCAL_OOB_DATA, 0,
+ &rp, sizeof(rp));
+ }
}
mgmt_pending_remove(cmd);
--
1.8.4.2
^ permalink raw reply related
* linux-firmware: pull-request Marvell mwifiex-firmware 2014-01-09
From: Bing Zhao @ 2014-01-10 3:48 UTC (permalink / raw)
To: Ben Hutchings; +Cc: linux-wireless, linux-bluetooth, Frank Huang, Bing Zhao
The following changes since commit 52d77db9f133afe4d2b26aeccfd603745f45fda1:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/egrumbach/linux-firmware (2013-12-30 15:22:40 +0100)
are available in the git repository at:
git://git.marvell.com/mwifiex-firmware.git master
for you to fetch changes up to 2d4aa2037a7015c4d78cde40006f80b8012537a6:
linux-firmware: add Marvell USB8897-B0 firmware combo image (2014-01-09 19:17:35 -0800)
----------------------------------------------------------------
Bing Zhao (3):
linux-firmware: update Marvell USB8797-B0 firmware image
linux-firmware: update Marvell SD8897-B0 firmware combo image
linux-firmware: add Marvell USB8897-B0 firmware combo image
WHENCE | 7 +++++--
mrvl/sd8897_uapsta.bin | Bin 639012 -> 668028 bytes
mrvl/usb8797_uapsta.bin | Bin 508372 -> 541048 bytes
mrvl/usb8897_uapsta.bin | Bin 0 -> 705364 bytes
4 files changed, 5 insertions(+), 2 deletions(-)
create mode 100644 mrvl/usb8897_uapsta.bin
diff --git a/WHENCE b/WHENCE
index 4f87d8a..23faafa 100644
--- a/WHENCE
+++ b/WHENCE
@@ -730,10 +730,13 @@ File: mrvl/sd8797_uapsta.bin
Version: 14.66.11.p151
File: mrvl/sd8897_uapsta.bin
-Version: 15.69.2.p11
+Version: 15.68.201.p113
File: mrvl/usb8797_uapsta.bin
-Version: 14.69.11.p179
+Version: 14.68.29.p26
+
+File: mrvl/usb8897_uapsta.bin
+Version: 15.68.201.p113
File: mrvl/pcie8897_uapsta.bin
Version: 15.69.2.p11
diff --git a/mrvl/sd8897_uapsta.bin b/mrvl/sd8897_uapsta.bin
index 70732a6..e68a049 100644
Binary files a/mrvl/sd8897_uapsta.bin and b/mrvl/sd8897_uapsta.bin differ
diff --git a/mrvl/usb8797_uapsta.bin b/mrvl/usb8797_uapsta.bin
index bd7c07c..1963798 100644
Binary files a/mrvl/usb8797_uapsta.bin and b/mrvl/usb8797_uapsta.bin differ
diff --git a/mrvl/usb8897_uapsta.bin b/mrvl/usb8897_uapsta.bin
new file mode 100644
index 0000000..59aef78
Binary files /dev/null and b/mrvl/usb8897_uapsta.bin differ
^ permalink raw reply related
* [PATCH v2 7/7] android/audio: Add audio_ipc_cleanup function
From: Lukasz Rymanowski @ 2014-01-10 1:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: luiz.dentz, johan.hedberg, Lukasz Rymanowski
In-Reply-To: <1389317068-12540-1-git-send-email-lukasz.rymanowski@tieto.com>
---
android/hal-audio.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 3b94e62..49cc375 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -46,6 +46,14 @@ struct a2dp_audio_dev {
struct audio_stream_out *out;
};
+static void audio_ipc_cleanup(void)
+{
+ if (audio_sk >= 0) {
+ shutdown(audio_sk, SHUT_RDWR);
+ audio_sk = -1;
+ }
+}
+
static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
void *param, size_t *rsp_len, void *rsp, int *fd)
{
@@ -188,8 +196,7 @@ static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
failed:
/* Some serious issue happen on IPC - recover */
- shutdown(audio_sk, SHUT_RDWR);
- audio_sk = -1;
+ audio_ipc_cleanup();
return AUDIO_STATUS_FAILED;
}
@@ -575,7 +582,7 @@ static int audio_close(hw_device_t *device)
DBG("");
pthread_mutex_lock(&close_mutex);
- shutdown(audio_sk, SHUT_RDWR);
+ audio_ipc_cleanup();
close_thread = true;
pthread_mutex_unlock(&close_mutex);
@@ -609,7 +616,7 @@ static void *ipc_handler(void *data)
if (ipc_open_cmd() == AUDIO_STATUS_FAILED) {
error("audio: Failed to open endpoint, recover");
- shutdown(audio_sk, SHUT_RDWR);
+ audio_ipc_cleanup();
continue;
}
--
1.8.4
^ permalink raw reply related
* [PATCH v2 6/7] android/audio: Add audio_ipc_cmd
From: Lukasz Rymanowski @ 2014-01-10 1:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: luiz.dentz, johan.hedberg, Lukasz Rymanowski
In-Reply-To: <1389317068-12540-1-git-send-email-lukasz.rymanowski@tieto.com>
Adds function to handle send/receive on audio_sk
Also moves ipc related functions on top of the file to avoid moving it
later on when implementing AudioFlinger functions.
---
android/Makefile.am | 1 +
android/hal-audio.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 172 insertions(+), 7 deletions(-)
diff --git a/android/Makefile.am b/android/Makefile.am
index 0a32a95..94e5329 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -117,6 +117,7 @@ android_android_tester_LDFLAGS = -pthread
noinst_LTLIBRARIES += android/libaudio-internal.la
android_libaudio_internal_la_SOURCES = android/audio-msg.h \
+ android/hal-msg.h \
android/hal-audio.c \
android/hardware/audio.h \
android/hardware/audio_effect.h \
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 4c5a9d9..3b94e62 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -31,6 +31,7 @@
#include "audio-msg.h"
#include "hal-log.h"
+#include "hal-msg.h"
static int listen_sk = -1;
static int audio_sk = -1;
@@ -38,12 +39,182 @@ static bool close_thread = false;
static pthread_t ipc_th = 0;
static pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER;
struct a2dp_audio_dev {
struct audio_hw_device dev;
struct audio_stream_out *out;
};
+static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
+ void *param, size_t *rsp_len, void *rsp, int *fd)
+{
+ ssize_t ret;
+ struct msghdr msg;
+ struct iovec iv[2];
+ struct hal_hdr cmd;
+ char cmsgbuf[CMSG_SPACE(sizeof(int))];
+ struct hal_status s;
+ size_t s_len = sizeof(s);
+
+ if (audio_sk < 0) {
+ error("audio: Invalid cmd socket passed to audio_ipc_cmd");
+ goto failed;
+ }
+
+ if (!rsp || !rsp_len) {
+ memset(&s, 0, s_len);
+ rsp_len = &s_len;
+ rsp = &s;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&cmd, 0, sizeof(cmd));
+
+ cmd.service_id = service_id;
+ cmd.opcode = opcode;
+ cmd.len = len;
+
+ iv[0].iov_base = &cmd;
+ iv[0].iov_len = sizeof(cmd);
+
+ iv[1].iov_base = param;
+ iv[1].iov_len = len;
+
+ msg.msg_iov = iv;
+ msg.msg_iovlen = 2;
+
+ pthread_mutex_lock(&sk_mutex);
+
+ ret = sendmsg(audio_sk, &msg, 0);
+ if (ret < 0) {
+ error("audio: Sending command failed:%s", strerror(errno));
+ pthread_mutex_unlock(&sk_mutex);
+ goto failed;
+ }
+
+ /* socket was shutdown */
+ if (ret == 0) {
+ error("audio: Command socket closed");
+ goto failed;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&cmd, 0, sizeof(cmd));
+
+ iv[0].iov_base = &cmd;
+ iv[0].iov_len = sizeof(cmd);
+
+ iv[1].iov_base = rsp;
+ iv[1].iov_len = *rsp_len;
+
+ msg.msg_iov = iv;
+ msg.msg_iovlen = 2;
+
+ if (fd) {
+ memset(cmsgbuf, 0, sizeof(cmsgbuf));
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ }
+
+ ret = recvmsg(audio_sk, &msg, 0);
+ if (ret < 0) {
+ error("audio: Receiving command response failed:%s",
+ strerror(errno));
+ pthread_mutex_unlock(&sk_mutex);
+ goto failed;
+ }
+
+ pthread_mutex_unlock(&sk_mutex);
+
+ if (ret < (ssize_t) sizeof(cmd)) {
+ error("audio: Too small response received(%zd bytes)", ret);
+ goto failed;
+ }
+
+ if (cmd.service_id != service_id) {
+ error("audio: Invalid service id (%u vs %u)", cmd.service_id,
+ service_id);
+ goto failed;
+ }
+
+ if (ret != (ssize_t) (sizeof(cmd) + cmd.len)) {
+ error("audio: Malformed response received(%zd bytes)", ret);
+ goto failed;
+ }
+
+ if (cmd.opcode != opcode && cmd.opcode != AUDIO_OP_STATUS) {
+ error("audio: Invalid opcode received (%u vs %u)",
+ cmd.opcode, opcode);
+ goto failed;
+ }
+
+ if (cmd.opcode == AUDIO_OP_STATUS) {
+ struct hal_status *s = rsp;
+
+ if (sizeof(*s) != cmd.len) {
+ error("audio: Invalid status length");
+ goto failed;
+ }
+
+ if (s->code == AUDIO_STATUS_SUCCESS) {
+ error("audio: Invalid success status response");
+ goto failed;
+ }
+
+ return s->code;
+ }
+
+ /* Receive auxiliary data in msg */
+ if (fd) {
+ struct cmsghdr *cmsg;
+
+ *fd = -1;
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET
+ && cmsg->cmsg_type == SCM_RIGHTS) {
+ memcpy(fd, CMSG_DATA(cmsg), sizeof(int));
+ break;
+ }
+ }
+ }
+
+ if (rsp_len)
+ *rsp_len = cmd.len;
+
+ return AUDIO_STATUS_SUCCESS;
+
+failed:
+ /* Some serious issue happen on IPC - recover */
+ shutdown(audio_sk, SHUT_RDWR);
+ audio_sk = -1;
+ return AUDIO_STATUS_FAILED;
+}
+
+static int ipc_open_cmd(void)
+{
+ struct audio_rsp_open rsp;
+ uint8_t buf[sizeof(struct audio_cmd_open) +
+ sizeof(struct audio_preset)];
+ size_t rsp_len = sizeof(rsp);
+ int result;
+
+ DBG("");
+
+ memset(&buf, 0, sizeof(buf));
+
+ /* TODO: Fill in buf here with smth */
+
+ result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN, sizeof(buf), buf,
+ &rsp_len, &rsp, NULL);
+
+ /*TODO: Read response and store endoint id */
+
+ return result;
+}
+
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
@@ -417,13 +588,6 @@ static int audio_close(hw_device_t *device)
return 0;
}
-static int ipc_open_cmd(void)
-{
- DBG("Not Implemented");
-
- return AUDIO_STATUS_FAILED;
-}
-
static void *ipc_handler(void *data)
{
bool done = false;
--
1.8.4
^ permalink raw reply related
* [PATCH v2 5/7] android/audio: Add skeleton for ipc_open_cmd function
From: Lukasz Rymanowski @ 2014-01-10 1:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: luiz.dentz, johan.hedberg, Lukasz Rymanowski
In-Reply-To: <1389317068-12540-1-git-send-email-lukasz.rymanowski@tieto.com>
---
android/hal-audio.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 0b345ed..4c5a9d9 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -417,6 +417,13 @@ static int audio_close(hw_device_t *device)
return 0;
}
+static int ipc_open_cmd(void)
+{
+ DBG("Not Implemented");
+
+ return AUDIO_STATUS_FAILED;
+}
+
static void *ipc_handler(void *data)
{
bool done = false;
@@ -436,7 +443,11 @@ static void *ipc_handler(void *data)
DBG("Audio IPC: Connected");
- /* TODO: Register ENDPOINT here */
+ if (ipc_open_cmd() == AUDIO_STATUS_FAILED) {
+ error("audio: Failed to open endpoint, recover");
+ shutdown(audio_sk, SHUT_RDWR);
+ continue;
+ }
memset(&pfd, 0, sizeof(pfd));
pfd.fd = audio_sk;
--
1.8.4
^ permalink raw reply related
* [PATCH v2 4/7] android/audio: Trivial function move
From: Lukasz Rymanowski @ 2014-01-10 1:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: luiz.dentz, johan.hedberg, Lukasz Rymanowski
In-Reply-To: <1389317068-12540-1-git-send-email-lukasz.rymanowski@tieto.com>
Just moves create_listening_audio_ipc() closer to audio_open()
---
android/hal-audio.c | 87 +++++++++++++++++++++++++++--------------------------
1 file changed, 44 insertions(+), 43 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index b0e0b1d..0b345ed 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -417,6 +417,50 @@ static int audio_close(hw_device_t *device)
return 0;
}
+static void *ipc_handler(void *data)
+{
+ bool done = false;
+ struct pollfd pfd;
+
+ DBG("");
+
+ while (!done) {
+ DBG("Waiting for audio_ipc connection ...");
+ audio_sk = accept(listen_sk, NULL, NULL);
+ if (audio_sk < 0) {
+ int err = errno;
+ error("audio: Failed to accept socket: %d (%s)", err,
+ strerror(err));
+ continue;
+ }
+
+ DBG("Audio IPC: Connected");
+
+ /* TODO: Register ENDPOINT here */
+
+ memset(&pfd, 0, sizeof(pfd));
+ pfd.fd = audio_sk;
+ pfd.events = POLLHUP | POLLERR | POLLNVAL;
+
+ /* Check if socket is still alive. Empty while loop.*/
+ while (poll(&pfd, 1, -1) < 0 && errno == EINTR);
+
+ if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
+ info("Audio HAL: Socket closed");
+ audio_sk = -1;
+ }
+
+ /*Check if audio_dev is closed */
+ pthread_mutex_lock(&close_mutex);
+ done = close_thread;
+ close_thread = false;
+ pthread_mutex_unlock(&close_mutex);
+ }
+
+ info("Closing bluetooth_watcher thread");
+ return NULL;
+}
+
static int create_listening_audio_ipc(void)
{
struct sockaddr_un addr;
@@ -461,49 +505,6 @@ failed:
return err;
}
-static void *ipc_handler(void *data)
-{
- bool done = false;
- struct pollfd pfd;
-
- DBG("");
-
- while (!done) {
- audio_sk = accept(listen_sk, NULL, NULL);
- if (audio_sk < 0) {
- int err = errno;
- error("audio: Failed to accept socket: %d (%s)", err,
- strerror(err));
- continue;
- }
-
- DBG("Audio IPC: Connected");
-
- /* TODO: Register ENDPOINT here */
-
- memset(&pfd, 0, sizeof(pfd));
- pfd.fd = audio_sk;
- pfd.events = POLLHUP | POLLERR | POLLNVAL;
-
- /* Check if socket is still alive. Empty while loop.*/
- while (poll(&pfd, 1, -1) < 0 && errno == EINTR);
-
- if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
- info("Audio HAL: Socket closed");
- audio_sk = -1;
- }
-
- /*Check if audio_dev is closed */
- pthread_mutex_lock(&close_mutex);
- done = close_thread;
- close_thread = false;
- pthread_mutex_unlock(&close_mutex);
- }
-
- info("Closing bluetooth_watcher thread");
- return NULL;
-}
-
static int audio_open(const hw_module_t *module, const char *name,
hw_device_t **device)
{
--
1.8.4
^ permalink raw reply related
* [PATCH v2 3/7] android/audio: Refactor create_audio_ipc
From: Lukasz Rymanowski @ 2014-01-10 1:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: luiz.dentz, johan.hedberg, Lukasz Rymanowski
In-Reply-To: <1389317068-12540-1-git-send-email-lukasz.rymanowski@tieto.com>
This patch adds creating listening audio ipc socket in AudioFlinger
context on audio_open() and moves accepting connection to ipc_th.
---
android/hal-audio.c | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index c71b93c..b0e0b1d 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -32,6 +32,7 @@
#include "audio-msg.h"
#include "hal-log.h"
+static int listen_sk = -1;
static int audio_sk = -1;
static bool close_thread = false;
@@ -409,11 +410,14 @@ static int audio_close(hw_device_t *device)
pthread_join(ipc_th, NULL);
+ close(listen_sk);
+ listen_sk = -1;
+
free(a2dp_dev);
return 0;
}
-static bool create_audio_ipc(void)
+static int create_listening_audio_ipc(void)
{
struct sockaddr_un addr;
int err;
@@ -426,7 +430,7 @@ static bool create_audio_ipc(void)
err = errno;
error("audio: Failed to create socket: %d (%s)", err,
strerror(err));
- return false;
+ return err;
}
memset(&addr, 0, sizeof(addr));
@@ -449,19 +453,12 @@ static bool create_audio_ipc(void)
goto failed;
}
- audio_sk = accept(sk, NULL, NULL);
- if (audio_sk < 0) {
- err = errno;
- error("audio: Failed to accept socket: %d (%s)", err, strerror(err));
- goto failed;
- }
-
- close(sk);
- return true;
+ listen_sk = sk;
+ return 0;
failed:
close(sk);
- return false;
+ return err;
}
static void *ipc_handler(void *data)
@@ -472,9 +469,11 @@ static void *ipc_handler(void *data)
DBG("");
while (!done) {
- if(!create_audio_ipc()) {
- error("audio: Failed to create listening socket");
- sleep(1);
+ audio_sk = accept(listen_sk, NULL, NULL);
+ if (audio_sk < 0) {
+ int err = errno;
+ error("audio: Failed to accept socket: %d (%s)", err,
+ strerror(err));
continue;
}
@@ -519,6 +518,10 @@ static int audio_open(const hw_module_t *module, const char *name,
return -EINVAL;
}
+ err = create_listening_audio_ipc();
+ if (err)
+ return -err;
+
a2dp_dev = calloc(1, sizeof(struct a2dp_audio_dev));
if (!a2dp_dev)
return -ENOMEM;
--
1.8.4
^ permalink raw reply related
* [PATCH v2 2/7] android: Fix error check from pthread_create
From: Lukasz Rymanowski @ 2014-01-10 1:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: luiz.dentz, johan.hedberg, Lukasz Rymanowski
In-Reply-To: <1389317068-12540-1-git-send-email-lukasz.rymanowski@tieto.com>
pthread_create() returns 0 on success or errno code which is non negative
number
---
android/hal-audio.c | 4 ++--
android/hal-ipc.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 4b48783..c71b93c 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -548,10 +548,10 @@ static int audio_open(const hw_module_t *module, const char *name,
*device = &a2dp_dev->dev.common;
err = pthread_create(&ipc_th, NULL, ipc_handler, NULL);
- if (err < 0) {
+ if (err) {
ipc_th = 0;
error("audio: Failed to start Audio IPC thread: %d (%s)",
- -err, strerror(-err));
+ err, strerror(err));
return (-err);
}
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index b19704a..97f1bcd 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -284,10 +284,10 @@ bool hal_ipc_init(void)
close(sk);
err = pthread_create(¬if_th, NULL, notification_handler, NULL);
- if (err < 0) {
+ if (err) {
notif_th = 0;
- error("Failed to start notification thread: %d (%s)", -err,
- strerror(-err));
+ error("Failed to start notification thread: %d (%s)", err,
+ strerror(err));
close(cmd_sk);
cmd_sk = -1;
close(notif_sk);
--
1.8.4
^ permalink raw reply related
* [PATCH v2 1/7] android/audio: Prefix error log with "audio"
From: Lukasz Rymanowski @ 2014-01-10 1:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: luiz.dentz, johan.hedberg, Lukasz Rymanowski
In-Reply-To: <1389317068-12540-1-git-send-email-lukasz.rymanowski@tieto.com>
---
android/hal-audio.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 7d7e97e..4b48783 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -424,7 +424,8 @@ static bool create_audio_ipc(void)
sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
if (sk < 0) {
err = errno;
- error("Failed to create socket: %d (%s)", err, strerror(err));
+ error("audio: Failed to create socket: %d (%s)", err,
+ strerror(err));
return false;
}
@@ -436,13 +437,14 @@ static bool create_audio_ipc(void)
if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
err = errno;
- error("Failed to bind socket: %d (%s)", err, strerror(err));
+ error("audio: Failed to bind socket: %d (%s)", err,
+ strerror(err));
goto failed;
}
if (listen(sk, 1) < 0) {
err = errno;
- error("Failed to listen on the socket: %d (%s)", err,
+ error("audio: Failed to listen on the socket: %d (%s)", err,
strerror(err));
goto failed;
}
@@ -450,7 +452,7 @@ static bool create_audio_ipc(void)
audio_sk = accept(sk, NULL, NULL);
if (audio_sk < 0) {
err = errno;
- error("Failed to accept socket: %d (%s)", err, strerror(err));
+ error("audio: Failed to accept socket: %d (%s)", err, strerror(err));
goto failed;
}
@@ -471,7 +473,7 @@ static void *ipc_handler(void *data)
while (!done) {
if(!create_audio_ipc()) {
- error("Failed to create listening socket");
+ error("audio: Failed to create listening socket");
sleep(1);
continue;
}
@@ -512,7 +514,7 @@ static int audio_open(const hw_module_t *module, const char *name,
DBG("");
if (strcmp(name, AUDIO_HARDWARE_INTERFACE)) {
- error("interface %s not matching [%s]", name,
+ error("audio: interface %s not matching [%s]", name,
AUDIO_HARDWARE_INTERFACE);
return -EINVAL;
}
@@ -548,7 +550,7 @@ static int audio_open(const hw_module_t *module, const char *name,
err = pthread_create(&ipc_th, NULL, ipc_handler, NULL);
if (err < 0) {
ipc_th = 0;
- error("Failed to start Audio IPC thread: %d (%s)",
+ error("audio: Failed to start Audio IPC thread: %d (%s)",
-err, strerror(-err));
return (-err);
}
--
1.8.4
^ permalink raw reply related
* [PATCH v2 0/7] Next skeleton patches for audio plugin
From: Lukasz Rymanowski @ 2014-01-10 1:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: luiz.dentz, johan.hedberg, Lukasz Rymanowski
v1:
Those patches adds function to handle send/receive msg on audio IPC.
Also adds some small changes.
Not that since we do not yet support AUDIO_OP_OPEN, audio socket will be
reseted just after connect.
v2:
Fixes suggester by Luiz
Some additional fixes
Lukasz Rymanowski (7):
android/audio: Prefix error log with "audio"
android: Fix error check from pthread_create
android/audio: Refactor create_audio_ipc
android/audio: Trivial function move
android/audio: Add skeleton for ipc_open_cmd function
android/audio: Add audio_ipc_cmd
android/audio: Add audio_ipc_cleanup function
android/Makefile.am | 1 +
android/hal-audio.c | 304 ++++++++++++++++++++++++++++++++++++++++++----------
android/hal-ipc.c | 6 +-
3 files changed, 250 insertions(+), 61 deletions(-)
--
1.8.4
^ permalink raw reply
* Re: [PATCH v4] Bluetooth: Add hci_h4p driver
From: Sebastian Reichel @ 2014-01-10 0:32 UTC (permalink / raw)
To: Pavel Machek
Cc: Marcel Holtmann, Pali Rohár,
Ивайло Димитров,
Gustavo F. Padovan, Johan Hedberg, linux-kernel,
linux-bluetooth@vger.kernel.org development, Ville Tervo
In-Reply-To: <20140109233843.GB19974@amd.pavel.ucw.cz>
[-- Attachment #1: Type: text/plain, Size: 368 bytes --]
Hi Pavel,
On Fri, Jan 10, 2014 at 12:38:43AM +0100, Pavel Machek wrote:
> > Here are some cleanup suggestions for probe, removal & module
> > initialization functions.
>
> ...and here's the patch implementing those suggestions. Thanks!
That looks right, but you forgot to cleanup hci_h4p_remove. Also I
suggest to simply merge this as v5.
-- Sebastian
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v4] Bluetooth: Add hci_h4p driver
From: Pavel Machek @ 2014-01-09 23:38 UTC (permalink / raw)
To: Marcel Holtmann, Pali Rohár,
Ивайло Димитров,
Gustavo F. Padovan, Johan Hedberg, linux-kernel,
linux-bluetooth@vger.kernel.org development, Ville Tervo
In-Reply-To: <20140103013640.GB27678@earth.universe>
Hi!
> Here are some cleanup suggestions for probe, removal & module
> initialization functions.
...and here's the patch implementing those suggestions. Thanks!
Reported-by: Sebastian Reichel <sre@ring0.de>
Signed-off-by: Pavel Machek <pavel@ucw.cz>
diff --git a/drivers/bluetooth/nokia_core.c b/drivers/bluetooth/nokia_core.c
index 5c7acad..d69362d 100644
--- a/drivers/bluetooth/nokia_core.c
+++ b/drivers/bluetooth/nokia_core.c
@@ -39,6 +39,7 @@
#include <linux/gpio.h>
#include <linux/timer.h>
#include <linux/kthread.h>
+#include <linux/io.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -1079,7 +1080,7 @@ static int hci_h4p_probe(struct platform_device *pdev)
int err;
dev_info(&pdev->dev, "Registering HCI H4P device\n");
- info = kzalloc(sizeof(struct hci_h4p_info), GFP_KERNEL);
+ info = devm_kzalloc(&pdev->dev, sizeof(struct hci_h4p_info), GFP_KERNEL);
if (!info)
return -ENOMEM;
@@ -1092,7 +1093,6 @@ static int hci_h4p_probe(struct platform_device *pdev)
if (pdev->dev.platform_data == NULL) {
dev_err(&pdev->dev, "Could not get Bluetooth config data\n");
- kfree(info);
return -ENODATA;
}
@@ -1113,67 +1113,59 @@ static int hci_h4p_probe(struct platform_device *pdev)
complete_all(&info->test_completion);
if (!info->reset_gpio_shared) {
- err = gpio_request(info->reset_gpio, "bt_reset");
+ err = devm_gpio_request_one(&pdev->dev, info->reset_gpio,
+ GPIOF_OUT_INIT_LOW, "bt_reset");
if (err < 0) {
dev_err(&pdev->dev, "Cannot get GPIO line %d\n",
info->reset_gpio);
- goto cleanup_setup;
+ return err;
}
}
- err = gpio_request(info->bt_wakeup_gpio, "bt_wakeup");
+ err = devm_gpio_request_one(&pdev->dev, info->bt_wakeup_gpio,
+ GPIOF_OUT_INIT_LOW, "bt_wakeup");
+
if (err < 0) {
dev_err(info->dev, "Cannot get GPIO line 0x%d",
info->bt_wakeup_gpio);
- if (!info->reset_gpio_shared)
- gpio_free(info->reset_gpio);
- goto cleanup_setup;
+ return err;
}
- err = gpio_request(info->host_wakeup_gpio, "host_wakeup");
+ err = devm_gpio_request_one(&pdev->dev, info->host_wakeup_gpio,
+ GPIOF_DIR_IN, "host_wakeup");
if (err < 0) {
dev_err(info->dev, "Cannot get GPIO line %d",
info->host_wakeup_gpio);
- if (!info->reset_gpio_shared)
- gpio_free(info->reset_gpio);
- gpio_free(info->bt_wakeup_gpio);
- goto cleanup_setup;
+ return err;
}
- gpio_direction_output(info->reset_gpio, 0);
- gpio_direction_output(info->bt_wakeup_gpio, 0);
- gpio_direction_input(info->host_wakeup_gpio);
-
info->irq = bt_plat_data->uart_irq;
- info->uart_base = ioremap(bt_plat_data->uart_base, SZ_2K);
- info->uart_iclk = clk_get(NULL, bt_plat_data->uart_iclk);
- info->uart_fclk = clk_get(NULL, bt_plat_data->uart_fclk);
+ info->uart_base = devm_ioremap(&pdev->dev, bt_plat_data->uart_base, SZ_2K);
+ info->uart_iclk = devm_clk_get(&pdev->dev, bt_plat_data->uart_iclk);
+ info->uart_fclk = devm_clk_get(&pdev->dev, bt_plat_data->uart_fclk);
err = request_irq(info->irq, hci_h4p_interrupt, IRQF_DISABLED, "hci_h4p",
info);
if (err < 0) {
dev_err(info->dev, "hci_h4p: unable to get IRQ %d\n", info->irq);
- goto cleanup;
+ return err;
}
- err = request_irq(gpio_to_irq(info->host_wakeup_gpio),
+ err = devm_request_irq(&pdev->dev, gpio_to_irq(info->host_wakeup_gpio),
hci_h4p_wakeup_interrupt, IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING | IRQF_DISABLED,
"hci_h4p_wkup", info);
if (err < 0) {
dev_err(info->dev, "hci_h4p: unable to get wakeup IRQ %d\n",
gpio_to_irq(info->host_wakeup_gpio));
- free_irq(info->irq, info);
- goto cleanup;
+ return err;
}
err = irq_set_irq_wake(gpio_to_irq(info->host_wakeup_gpio), 1);
if (err < 0) {
dev_err(info->dev, "hci_h4p: unable to set wakeup for IRQ %d\n",
gpio_to_irq(info->host_wakeup_gpio));
- free_irq(info->irq, info);
- free_irq(gpio_to_irq(info->host_wakeup_gpio), info);
- goto cleanup;
+ return err;
}
init_timer_deferrable(&info->lazy_release);
@@ -1182,7 +1174,7 @@ static int hci_h4p_probe(struct platform_device *pdev)
hci_h4p_set_clk(info, &info->tx_clocks_en, 1);
err = hci_h4p_reset_uart(info);
if (err < 0)
- goto cleanup_irq;
+ return err;
gpio_set_value(info->reset_gpio, 0);
hci_h4p_set_clk(info, &info->tx_clocks_en, 0);
@@ -1190,23 +1182,10 @@ static int hci_h4p_probe(struct platform_device *pdev)
if (hci_h4p_register_hdev(info) < 0) {
dev_err(info->dev, "failed to register hci_h4p hci device\n");
- goto cleanup_irq;
+ return -EINVAL;
}
return 0;
-
-cleanup_irq:
- free_irq(info->irq, (void *)info);
- free_irq(gpio_to_irq(info->host_wakeup_gpio), info);
-cleanup:
- gpio_set_value(info->reset_gpio, 0);
- if (!info->reset_gpio_shared)
- gpio_free(info->reset_gpio);
- gpio_free(info->bt_wakeup_gpio);
- gpio_free(info->host_wakeup_gpio);
-cleanup_setup:
- kfree(info);
- return err;
}
static int hci_h4p_remove(struct platform_device *pdev)
@@ -1238,25 +1217,7 @@ static struct platform_driver hci_h4p_driver = {
},
};
-static int __init hci_h4p_init(void)
-{
- int err = 0;
-
- /* Register the driver with LDM */
- err = platform_driver_register(&hci_h4p_driver);
- if (err < 0)
- printk(KERN_WARNING "failed to register hci_h4p driver\n");
-
- return err;
-}
-
-static void __exit hci_h4p_exit(void)
-{
- platform_driver_unregister(&hci_h4p_driver);
-}
-
-module_init(hci_h4p_init);
-module_exit(hci_h4p_exit);
+module_platform_driver(hci_h4p_driver);
MODULE_ALIAS("platform:hci_h4p");
MODULE_DESCRIPTION("Bluetooth h4 driver with nokia extensions");
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply related
* [PATCH 10/10] Bluetooth: Limit acceptable link key types to only supported ones
From: Marcel Holtmann @ 2014-01-09 20:56 UTC (permalink / raw)
To: linux-bluetooth
The link keys that are loaded by userspace during controller setup
should be limited to actual valid and supported types. With the
support for Secure Connections, it is limited to types 0x00 - 0x08
at the moment. Reject any other link key types.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/mgmt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 68a3c998d19c..9b162038acb7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2241,7 +2241,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
for (i = 0; i < key_count; i++) {
struct mgmt_link_key_info *key = &cp->keys[i];
- if (key->addr.type != BDADDR_BREDR)
+ if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
MGMT_STATUS_INVALID_PARAMS);
}
--
1.8.4.2
^ permalink raw reply related
* [PATCH 09/10] Bluetooth: Enable Secure Connection during power on if configured
From: Marcel Holtmann @ 2014-01-09 20:56 UTC (permalink / raw)
To: linux-bluetooth
If support for Secure Connection has been configured, then make sure
to send the appropiate HCI command to enable it when powering on the
controller.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 52e398f37129..b3b619a448b5 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1363,6 +1363,14 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt)
/* Check for Synchronization Train support */
if (lmp_sync_train_capable(hdev))
hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
+
+ /* Enable Secure Connections if supported and configured */
+ if (lmp_sc_capable(hdev) &&
+ test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
+ u8 support = 0x01;
+ hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
+ sizeof(support), &support);
+ }
}
static int __hci_init(struct hci_dev *hdev)
--
1.8.4.2
^ permalink raw reply related
* [PATCH 08/10] Bluetooth: Add management command for enabling Secure Connections
From: Marcel Holtmann @ 2014-01-09 20:56 UTC (permalink / raw)
To: linux-bluetooth
The support for Secure Connections need to be explicitly enabled by
userspace. This is required since only userspace that can handle the
new link key types should enable support for Secure Connections.
This command handling is similar to how Secure Simple Pairing enabling
is done. It also tracks the case when Secure Connections support is
enabled via raw HCI commands. This makes sure that the host features
page is updated as well.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 1 +
include/net/bluetooth/mgmt.h | 2 +
net/bluetooth/hci_event.c | 32 ++++++++++++
net/bluetooth/mgmt.c | 106 +++++++++++++++++++++++++++++++++++++++
4 files changed, 141 insertions(+)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index bb984d0626b7..1eb55ec40ac0 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1125,6 +1125,7 @@ void mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 status);
void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
+void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
u8 status);
void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 4ec17dec62e0..8a2c78175997 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -370,6 +370,8 @@ struct mgmt_cp_set_scan_params {
} __packed;
#define MGMT_SET_SCAN_PARAMS_SIZE 4
+#define MGMT_OP_SET_SECURE_CONN 0x002D
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b3c5396e0c1b..820a01965ce3 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -461,6 +461,34 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
}
}
+static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
+ struct hci_cp_write_sc_support *sent;
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+ sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
+ if (!sent)
+ return;
+
+ if (!status) {
+ if (sent->support)
+ hdev->features[1][0] |= LMP_HOST_SC;
+ else
+ hdev->features[1][0] &= ~LMP_HOST_SC;
+ }
+
+ if (test_bit(HCI_MGMT, &hdev->dev_flags))
+ mgmt_sc_enable_complete(hdev, sent->support, status);
+ else if (!status) {
+ if (sent->support)
+ set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+ else
+ clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+ }
+}
+
static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_local_version *rp = (void *) skb->data;
@@ -2147,6 +2175,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cc_write_ssp_mode(hdev, skb);
break;
+ case HCI_OP_WRITE_SC_SUPPORT:
+ hci_cc_write_sc_support(hdev, skb);
+ break;
+
case HCI_OP_READ_LOCAL_VERSION:
hci_cc_read_local_version(hdev, skb);
break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b00fa0253cba..68a3c998d19c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4006,6 +4006,79 @@ unlock:
return err;
}
+static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
+ void *data, u16 len)
+{
+ struct mgmt_mode *cp = data;
+ struct pending_cmd *cmd;
+ u8 status;
+ int err;
+
+ BT_DBG("request for %s", hdev->name);
+
+ status = mgmt_bredr_support(hdev);
+ if (status)
+ return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
+ status);
+
+ if (!lmp_sc_capable(hdev))
+ return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
+ MGMT_STATUS_NOT_SUPPORTED);
+
+ if (cp->val != 0x00 && cp->val != 0x01)
+ return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
+ MGMT_STATUS_INVALID_PARAMS);
+
+ hci_dev_lock(hdev);
+
+ if (!hdev_is_powered(hdev)) {
+ bool changed;
+
+ if (cp->val)
+ changed = !test_and_set_bit(HCI_SC_ENABLED,
+ &hdev->dev_flags);
+ else
+ changed = test_and_clear_bit(HCI_SC_ENABLED,
+ &hdev->dev_flags);
+
+ err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
+ if (err < 0)
+ goto failed;
+
+ if (changed)
+ err = new_settings(hdev, sk);
+
+ goto failed;
+ }
+
+ if (mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) {
+ err = cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
+ MGMT_STATUS_BUSY);
+ goto failed;
+ }
+
+ if (!!cp->val == test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
+ err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
+ goto failed;
+ }
+
+ cmd = mgmt_pending_add(sk, MGMT_OP_SET_SECURE_CONN, hdev, data, len);
+ if (!cmd) {
+ err = -ENOMEM;
+ goto failed;
+ }
+
+ err = hci_send_cmd(hdev, HCI_OP_WRITE_SC_SUPPORT, 1, &cp->val);
+ if (err < 0) {
+ mgmt_pending_remove(cmd);
+ goto failed;
+ }
+
+failed:
+ hci_dev_unlock(hdev);
+ return err;
+}
+
static bool ltk_is_valid(struct mgmt_ltk_info *key)
{
if (key->authenticated != 0x00 && key->authenticated != 0x01)
@@ -4134,6 +4207,7 @@ static const struct mgmt_handler {
{ set_bredr, false, MGMT_SETTING_SIZE },
{ set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE },
{ set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE },
+ { set_secure_conn, false, MGMT_SETTING_SIZE },
};
@@ -4917,6 +4991,38 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
hci_req_run(&req, NULL);
}
+void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
+{
+ struct cmd_lookup match = { NULL, hdev };
+ bool changed = false;
+
+ if (status) {
+ u8 mgmt_err = mgmt_status(status);
+
+ if (enable && test_and_clear_bit(HCI_SC_ENABLED,
+ &hdev->dev_flags))
+ new_settings(hdev, NULL);
+
+ mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev,
+ cmd_status_rsp, &mgmt_err);
+ return;
+ }
+
+ if (enable)
+ changed = !test_and_set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+ else
+ changed = test_and_clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
+
+ mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev,
+ settings_rsp, &match);
+
+ if (changed)
+ new_settings(hdev, match.sk);
+
+ if (match.sk)
+ sock_put(match.sk);
+}
+
static void sk_lookup(struct pending_cmd *cmd, void *data)
{
struct cmd_lookup *match = data;
--
1.8.4.2
^ permalink raw reply related
* [PATCH 07/10] Bluetooth: Add flags and setting for Secure Connections support
From: Marcel Holtmann @ 2014-01-09 20:56 UTC (permalink / raw)
To: linux-bluetooth
The MGMT_SETTING_SECURE_CONN setting is used to track the support and
status for Secure Connections from the management interface. For HCI
based tracking HCI_SC_ENABLED flag is used.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/mgmt.h | 1 +
net/bluetooth/mgmt.c | 7 +++++++
3 files changed, 9 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 238a5f3a0661..d38202500206 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -122,6 +122,7 @@ enum {
HCI_LE_SCAN,
HCI_SSP_ENABLED,
+ HCI_SC_ENABLED,
HCI_HS_ENABLED,
HCI_LE_ENABLED,
HCI_ADVERTISING,
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 518c5c84e39a..4ec17dec62e0 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -94,6 +94,7 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_HS 0x00000100
#define MGMT_SETTING_LE 0x00000200
#define MGMT_SETTING_ADVERTISING 0x00000400
+#define MGMT_SETTING_SECURE_CONN 0x00000800
#define MGMT_OP_READ_INFO 0x0004
#define MGMT_READ_INFO_SIZE 0
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a03ca3ca91bf..b00fa0253cba 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -79,6 +79,7 @@ static const u16 mgmt_commands[] = {
MGMT_OP_SET_BREDR,
MGMT_OP_SET_STATIC_ADDRESS,
MGMT_OP_SET_SCAN_PARAMS,
+ MGMT_OP_SET_SECURE_CONN,
};
static const u16 mgmt_events[] = {
@@ -376,6 +377,9 @@ static u32 get_supported_settings(struct hci_dev *hdev)
settings |= MGMT_SETTING_SSP;
settings |= MGMT_SETTING_HS;
}
+
+ if (lmp_sc_capable(hdev))
+ settings |= MGMT_SETTING_SECURE_CONN;
}
if (lmp_le_capable(hdev)) {
@@ -423,6 +427,9 @@ static u32 get_current_settings(struct hci_dev *hdev)
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
settings |= MGMT_SETTING_ADVERTISING;
+ if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
+ settings |= MGMT_SETTING_SECURE_CONN;
+
return settings;
}
--
1.8.4.2
^ permalink raw reply related
* [PATCH 06/10] Bluetooth: Enable Authenticated Payload Timeout Expired event
From: Marcel Holtmann @ 2014-01-09 20:56 UTC (permalink / raw)
To: linux-bluetooth
With Secure Connections capable controllers, the authenticated payload
timeout can trigger. Enable the event so the controller informs the
host when this happens.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_core.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5e8663c194c1..52e398f37129 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1288,6 +1288,10 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
events[2] |= 0x08; /* Truncated Page Complete */
}
+ /* Enable Authenticated Payload Timeout Expired event if supported */
+ if (lmp_ping_capable(hdev))
+ events[2] |= 0x80;
+
hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
}
--
1.8.4.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox