* [PATCH v2 1/3] Bluetooth: Add support for setting SSP debug mode
From: Marcel Holtmann @ 2013-10-19 14:09 UTC (permalink / raw)
To: linux-bluetooth
Enabling and disabling SSP debug mode is useful for development. This
adds a debugfs entry that allows to configure the SSP debug mode.
On purpose this has been implemented as debugfs entry and not a public
API since it is really only useful during testing and development.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 2 ++
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 54 +++++++++++++++++++++++++++++++++++++++-
net/bluetooth/hci_event.c | 2 ++
4 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 77a971a..ac9c4a7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1043,6 +1043,8 @@ struct hci_rp_write_remote_amp_assoc {
__u8 phy_handle;
} __packed;
+#define HCI_OP_WRITE_SSP_DEBUG_MODE 0x1804
+
#define HCI_OP_LE_SET_EVENT_MASK 0x2001
struct hci_cp_le_set_event_mask {
__u8 mask[8];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c689bcf..d50cc7a 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -169,6 +169,7 @@ struct hci_dev {
__u8 page_scan_type;
__u16 le_scan_interval;
__u16 le_scan_window;
+ __u8 ssp_debug_mode;
__u16 devid_source;
__u16 devid_vendor;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 384b9db..2a9e925 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -303,6 +303,55 @@ static int auto_accept_delay_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
auto_accept_delay_set, "%llu\n");
+static int ssp_debug_mode_set(void *data, u64 val)
+{
+ struct hci_dev *hdev = data;
+ struct sk_buff *skb;
+ __u8 mode;
+ int err;
+
+ if (val != 0 && val != 1)
+ return -EINVAL;
+
+ if (!test_bit(HCI_UP, &hdev->flags))
+ return -ENETDOWN;
+
+ hci_req_lock(hdev);
+ mode = val;
+ skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
+ &mode, HCI_CMD_TIMEOUT);
+ hci_req_unlock(hdev);
+
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ err = -bt_to_errno(skb->data[0]);
+ kfree_skb(skb);
+
+ if (err < 0)
+ return err;
+
+ hci_dev_lock(hdev);
+ hdev->ssp_debug_mode = val;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+static int ssp_debug_mode_get(void *data, u64 *val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock(hdev);
+ *val = hdev->ssp_debug_mode;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
+ ssp_debug_mode_set, "%llu\n");
+
static int idle_timeout_set(void *data, u64 val)
{
struct hci_dev *hdev = data;
@@ -1199,9 +1248,12 @@ static int __hci_init(struct hci_dev *hdev)
hdev, &voice_setting_fops);
}
- if (lmp_ssp_capable(hdev))
+ if (lmp_ssp_capable(hdev)) {
debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
hdev, &auto_accept_delay_fops);
+ debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
+ hdev, &ssp_debug_mode_fops);
+ }
if (lmp_sniff_capable(hdev)) {
debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 1214d4b..5935f74 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -198,6 +198,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
hdev->scan_rsp_data_len = 0;
+
+ hdev->ssp_debug_mode = 0;
}
static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] Bluetooth: Remove interval parameter from HCI connection
From: Johan Hedberg @ 2013-10-19 13:52 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382185617-43385-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Sat, Oct 19, 2013, Marcel Holtmann wrote:
> The conn->interval parameter of HCI connections is not used at all
> and so just remove it.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> include/net/bluetooth/hci_core.h | 1 -
> net/bluetooth/hci_event.c | 1 -
> 2 files changed, 2 deletions(-)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Bluetooth: Add LE features to debugfs if available
From: Johan Hedberg @ 2013-10-19 13:52 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382174733-25708-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Sat, Oct 19, 2013, Marcel Holtmann wrote:
> For LE capable controllers at the special LE features page to the
> debugfs list with all the other features pages.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_core.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: Add support for setting SSP debug mode
From: Johan Hedberg @ 2013-10-19 13:34 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382174000-18946-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Sat, Oct 19, 2013, Marcel Holtmann wrote:
> +static int ssp_debug_mode_set(void *data, u64 val)
> +{
> + struct hci_dev *hdev = data;
> + struct sk_buff *skb;
> + __u8 mode;
> +
> + if (val != 0 && val != 1)
> + return -EINVAL;
> +
> + if (!test_bit(HCI_UP, &hdev->flags))
> + return -ENETDOWN;
> +
> + hci_req_lock(hdev);
> + mode = val;
> + skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
> + &mode, HCI_CMD_TIMEOUT);
> + hci_req_unlock(hdev);
> +
> + if (IS_ERR(skb))
> + return PTR_ERR(skb);
> +
> + if (skb->data[0]) {
> + u8 status = skb->data[0];
> + kfree_skb(skb);
> + return -bt_to_errno(status);
> + }
> +
> + hci_dev_lock(hdev);
> + hdev->ssp_debug_mode = val;
> + hci_dev_unlock(hdev);
> +
> + return 0;
> +}
Looks like skb is being leaked here if the HCI command succeeds.
Johan
^ permalink raw reply
* Re: [PATCH] Bluetooth: Expose setting if debug keys are used or not
From: Johan Hedberg @ 2013-10-19 13:31 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382141662-6799-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Fri, Oct 18, 2013, Marcel Holtmann wrote:
> The system can be figured to accept and use debug keys. Expose this
> value in debugfs for debugging purposes.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_core.c | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 1/2] Bluetooth: Select the own address type during initial setup phase
From: Johan Hedberg @ 2013-10-19 13:30 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382139490-306-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Fri, Oct 18, 2013, Marcel Holtmann wrote:
> The own address type is based on the fact if the controller has
> a public address or not. This means that this detail can be just
> configured once during setup phase.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> include/net/bluetooth/hci_core.h | 1 +
> net/bluetooth/hci_conn.c | 7 +------
> net/bluetooth/hci_core.c | 13 ++++++++++++-
> net/bluetooth/mgmt.c | 10 ++--------
> 4 files changed, 16 insertions(+), 15 deletions(-)
Both patches have been applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 0/5] Initial Android IPC
From: Szymon Janc @ 2013-10-19 13:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>
> This adds initial code for Android IPC
> - only connection establishment
> - connecting ipc from daemon to HAL after adapter is initialized
> - daemon track HAL lib lifetime and shutdown if socket is closed
> - HAL library starts daemon (via android init) and wait for it to
> connect
> - HAL library is *not* yet tracking lifetime of daemon
One more note I forgot to mention: this is not yet runtime tested on Android.
(build was verified though)
--
Szymon K. Janc
szymon.janc@gmail.com
^ permalink raw reply
* Re: [PATCH] Bluetooth: Expose current list of long term keys via debugfs
From: Johan Hedberg @ 2013-10-19 13:27 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382137017-56186-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Fri, Oct 18, 2013, Marcel Holtmann wrote:
> For debugging purposes expose the current list of long term keys
> via debugfs. This file is read-only and limited to root access.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_core.c | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Bluetooth: Expose white list size information in debugfs
From: Johan Hedberg @ 2013-10-19 13:27 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382135026-48008-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Fri, Oct 18, 2013, Marcel Holtmann wrote:
> Knowing the white list size information is important for
> debugging. So export it via debugfs.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_core.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Bluetooth: Remove bus attribute in favor of hierarchy
From: Johan Hedberg @ 2013-10-19 13:27 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382125167-44247-1-git-send-email-marcel@holtmann.org>
On Fri, Oct 18, 2013, Marcel Holtmann wrote:
> The bus information are exposed in the actual hierarchy and should
> not be exposed as attribute.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_sysfs.c | 31 -------------------------------
> 1 file changed, 31 deletions(-)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 1/7] Bluetooth: Move HCI device features into hci_core.c
From: Johan Hedberg @ 2013-10-19 13:25 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382123092-35256-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Fri, Oct 18, 2013, Marcel Holtmann wrote:
> Move the handling of HCI device features debugfs into hci_core.c and
> also extend it with handling of multiple feature pages.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_core.c | 34 +++++++++++++++++++++++++++++++++-
> net/bluetooth/hci_sysfs.c | 14 --------------
> 2 files changed, 33 insertions(+), 15 deletions(-)
All seven patches have been applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* [PATCH] Bluetooth: Expose debugfs settings for LE connection interval
From: Marcel Holtmann @ 2013-10-19 12:44 UTC (permalink / raw)
To: linux-bluetooth
For testing purposes expose the default LE connection interval values
via debugfs.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 2 ++
net/bluetooth/hci_conn.c | 5 ++--
net/bluetooth/hci_core.c | 62 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d50cc7a..8c0ab3d 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -169,6 +169,8 @@ struct hci_dev {
__u8 page_scan_type;
__u16 le_scan_interval;
__u16 le_scan_window;
+ __u16 le_conn_min_interval;
+ __u16 le_conn_max_interval;
__u8 ssp_debug_mode;
__u16 devid_source;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 974d7bc..ba5366c 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -558,11 +558,12 @@ static int hci_create_le_conn(struct hci_conn *conn)
bacpy(&cp.peer_addr, &conn->dst);
cp.peer_addr_type = conn->dst_type;
cp.own_address_type = conn->src_type;
- cp.conn_interval_min = __constant_cpu_to_le16(0x0028);
- cp.conn_interval_max = __constant_cpu_to_le16(0x0038);
+ cp.conn_interval_min = cpu_to_le16(hdev->le_conn_min_interval);
+ cp.conn_interval_max = cpu_to_le16(hdev->le_conn_max_interval);
cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
cp.min_ce_len = __constant_cpu_to_le16(0x0000);
cp.max_ce_len = __constant_cpu_to_le16(0x0000);
+
hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
err = hci_req_run(&req, create_le_conn_complete);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e30352a..26e9dfd 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -580,6 +580,62 @@ static const struct file_operations long_term_keys_fops = {
.release = single_release,
};
+static int conn_min_interval_set(void *data, u64 val)
+{
+ struct hci_dev *hdev = data;
+
+ if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
+ return -EINVAL;
+
+ hci_dev_lock(hdev);
+ hdev->le_conn_min_interval= val;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+static int conn_min_interval_get(void *data, u64 *val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock(hdev);
+ *val = hdev->le_conn_min_interval;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
+ conn_min_interval_set, "%llu\n");
+
+static int conn_max_interval_set(void *data, u64 val)
+{
+ struct hci_dev *hdev = data;
+
+ if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
+ return -EINVAL;
+
+ hci_dev_lock(hdev);
+ hdev->le_conn_max_interval= val;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+static int conn_max_interval_get(void *data, u64 *val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock(hdev);
+ *val = hdev->le_conn_max_interval;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
+ conn_max_interval_set, "%llu\n");
+
/* ---- HCI requests ---- */
static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
@@ -1344,6 +1400,10 @@ static int __hci_init(struct hci_dev *hdev)
hdev, &own_address_type_fops);
debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
hdev, &long_term_keys_fops);
+ debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
+ hdev, &conn_min_interval_fops);
+ debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
+ hdev, &conn_max_interval_fops);
}
return 0;
@@ -2809,6 +2869,8 @@ struct hci_dev *hci_alloc_dev(void)
hdev->le_scan_interval = 0x0060;
hdev->le_scan_window = 0x0030;
+ hdev->le_conn_min_interval = 0x0028;
+ hdev->le_conn_max_interval = 0x0038;
mutex_init(&hdev->lock);
mutex_init(&hdev->req_lock);
--
1.8.3.1
^ permalink raw reply related
* [PATCH] Bluetooth: Remove interval parameter from HCI connection
From: Marcel Holtmann @ 2013-10-19 12:26 UTC (permalink / raw)
To: linux-bluetooth
The conn->interval parameter of HCI connections is not used at all
and so just remove it.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 1 -
net/bluetooth/hci_event.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f621c5b..d50cc7a 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -316,7 +316,6 @@ struct hci_conn {
__u8 attempt;
__u8 dev_class[3];
__u8 features[HCI_MAX_PAGES][8];
- __u16 interval;
__u16 pkt_type;
__u16 link_policy;
__u32 link_mode;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 83478da..5935f74 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2551,7 +2551,6 @@ static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
if (conn) {
conn->mode = ev->mode;
- conn->interval = __le16_to_cpu(ev->interval);
if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
&conn->flags)) {
--
1.8.3.1
^ permalink raw reply related
* [PATCH] Bluetooth: Add support for setting DUT mode
From: Marcel Holtmann @ 2013-10-19 10:05 UTC (permalink / raw)
To: linux-bluetooth
The Device Under Test (DUT) mode is useful for doing certification
testing and so expose this as debugfs option.
This mode is actually special since you can only enter it. Restoring
normal operation means that a HCI Reset is required. The current mode
value gets tracked as a new device flag and when disabling it, the
correct command to reset the controller is sent.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 3 ++
net/bluetooth/hci_core.c | 72 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index ac9c4a7..1784c48 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -115,6 +115,7 @@ enum {
HCI_PAIRABLE,
HCI_SERVICE_CACHE,
HCI_DEBUG_KEYS,
+ HCI_DUT_MODE,
HCI_UNREGISTER,
HCI_USER_CHANNEL,
@@ -1043,6 +1044,8 @@ struct hci_rp_write_remote_amp_assoc {
__u8 phy_handle;
} __packed;
+#define HCI_OP_ENABLE_DUT_MODE 0x1803
+
#define HCI_OP_WRITE_SSP_DEBUG_MODE 0x1804
#define HCI_OP_LE_SET_EVENT_MASK 0x2001
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bfd0e0e..e30352a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -58,6 +58,70 @@ static void hci_notify(struct hci_dev *hdev, int event)
/* ---- HCI debugfs entries ---- */
+static ssize_t dut_mode_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_DUT_MODE, &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 dut_mode_write(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct hci_dev *hdev = file->private_data;
+ struct sk_buff *skb;
+ char buf[32];
+ size_t buf_size = min(count, (sizeof(buf)-1));
+ bool enable;
+
+ if (!test_bit(HCI_UP, &hdev->flags))
+ return -ENETDOWN;
+
+ 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_DUT_MODE, &hdev->dev_flags))
+ return -EALREADY;
+
+ hci_req_lock(hdev);
+ if (enable)
+ skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
+ HCI_CMD_TIMEOUT);
+ else
+ skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
+ HCI_CMD_TIMEOUT);
+ hci_req_unlock(hdev);
+
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ if (skb->data[0]) {
+ u8 status = skb->data[0];
+ kfree_skb(skb);
+ return -bt_to_errno(status);
+ }
+
+ change_bit(HCI_DUT_MODE, &hdev->dev_flags);
+
+ return count;
+}
+
+static const struct file_operations dut_mode_fops = {
+ .open = simple_open,
+ .read = dut_mode_read,
+ .write = dut_mode_write,
+ .llseek = default_llseek,
+};
+
static int features_show(struct seq_file *f, void *ptr)
{
struct hci_dev *hdev = f->private;
@@ -1199,6 +1263,14 @@ static int __hci_init(struct hci_dev *hdev)
if (err < 0)
return err;
+ /* The Device Under Test (DUT) mode is special and available for
+ * all controller types. So just create it early on.
+ */
+ if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
+ debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
+ &dut_mode_fops);
+ }
+
/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
* BR/EDR/LE type controllers. AMP controllers only need the
* first stage init.
--
1.8.3.1
^ permalink raw reply related
* [PATCH] Bluetooth: Add LE features to debugfs if available
From: Marcel Holtmann @ 2013-10-19 9:25 UTC (permalink / raw)
To: linux-bluetooth
For LE capable controllers at the special LE features page to the
debugfs list with all the other features pages.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_core.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8aae80b..bfd0e0e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -65,13 +65,20 @@ static int features_show(struct seq_file *f, void *ptr)
hci_dev_lock(hdev);
for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
- seq_printf(f, "Page %u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
+ seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
"0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
hdev->features[p][0], hdev->features[p][1],
hdev->features[p][2], hdev->features[p][3],
hdev->features[p][4], hdev->features[p][5],
hdev->features[p][6], hdev->features[p][7]);
}
+ if (lmp_le_capable(hdev))
+ seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
+ "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
+ hdev->le_features[0], hdev->le_features[1],
+ hdev->le_features[2], hdev->le_features[3],
+ hdev->le_features[4], hdev->le_features[5],
+ hdev->le_features[6], hdev->le_features[7]);
hci_dev_unlock(hdev);
return 0;
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2] Bluetooth: Add support for setting SSP debug mode
From: Marcel Holtmann @ 2013-10-19 9:13 UTC (permalink / raw)
To: linux-bluetooth
Enabling and disabling SSP debug mode is useful for development. This
adds a debugfs entry that allows to configure the SSP debug mode.
On purpose this has been implemented as debugfs entry and not a public
API since it is really only useful during testing and development.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 2 ++
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 53 +++++++++++++++++++++++++++++++++++++++-
net/bluetooth/hci_event.c | 2 ++
4 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 77a971a..ac9c4a7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1043,6 +1043,8 @@ struct hci_rp_write_remote_amp_assoc {
__u8 phy_handle;
} __packed;
+#define HCI_OP_WRITE_SSP_DEBUG_MODE 0x1804
+
#define HCI_OP_LE_SET_EVENT_MASK 0x2001
struct hci_cp_le_set_event_mask {
__u8 mask[8];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0daac39..f621c5b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -169,6 +169,7 @@ struct hci_dev {
__u8 page_scan_type;
__u16 le_scan_interval;
__u16 le_scan_window;
+ __u8 ssp_debug_mode;
__u16 devid_source;
__u16 devid_vendor;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 94d5342..8aae80b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -296,6 +296,54 @@ static int auto_accept_delay_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
auto_accept_delay_set, "%llu\n");
+static int ssp_debug_mode_set(void *data, u64 val)
+{
+ struct hci_dev *hdev = data;
+ struct sk_buff *skb;
+ __u8 mode;
+
+ if (val != 0 && val != 1)
+ return -EINVAL;
+
+ if (!test_bit(HCI_UP, &hdev->flags))
+ return -ENETDOWN;
+
+ hci_req_lock(hdev);
+ mode = val;
+ skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
+ &mode, HCI_CMD_TIMEOUT);
+ hci_req_unlock(hdev);
+
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ if (skb->data[0]) {
+ u8 status = skb->data[0];
+ kfree_skb(skb);
+ return -bt_to_errno(status);
+ }
+
+ hci_dev_lock(hdev);
+ hdev->ssp_debug_mode = val;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+static int ssp_debug_mode_get(void *data, u64 *val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock(hdev);
+ *val = hdev->ssp_debug_mode;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
+ ssp_debug_mode_set, "%llu\n");
+
static int idle_timeout_set(void *data, u64 val)
{
struct hci_dev *hdev = data;
@@ -1192,9 +1240,12 @@ static int __hci_init(struct hci_dev *hdev)
hdev, &voice_setting_fops);
}
- if (lmp_ssp_capable(hdev))
+ if (lmp_ssp_capable(hdev)) {
debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
hdev, &auto_accept_delay_fops);
+ debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
+ hdev, &ssp_debug_mode_fops);
+ }
if (lmp_sniff_capable(hdev)) {
debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8480452..83478da 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -198,6 +198,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
hdev->scan_rsp_data_len = 0;
+
+ hdev->ssp_debug_mode = 0;
}
static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
--
1.8.3.1
^ permalink raw reply related
* [PATCH] Bluetooth: Add support for setting SSP debug mode
From: Marcel Holtmann @ 2013-10-19 9:06 UTC (permalink / raw)
To: linux-bluetooth
Enabling and disabling SSP debug mode is useful for development. This
adds a debugfs entry that allows to configure the SSP debug mode.
On purpose this has been implemented as debugfs entry and not a public
API since it is really only useful during testing and development.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci.h | 2 ++
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 53 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 77a971a..ac9c4a7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1043,6 +1043,8 @@ struct hci_rp_write_remote_amp_assoc {
__u8 phy_handle;
} __packed;
+#define HCI_OP_WRITE_SSP_DEBUG_MODE 0x1804
+
#define HCI_OP_LE_SET_EVENT_MASK 0x2001
struct hci_cp_le_set_event_mask {
__u8 mask[8];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0daac39..f621c5b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -169,6 +169,7 @@ struct hci_dev {
__u8 page_scan_type;
__u16 le_scan_interval;
__u16 le_scan_window;
+ __u8 ssp_debug_mode;
__u16 devid_source;
__u16 devid_vendor;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 94d5342..8aae80b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -296,6 +296,54 @@ static int auto_accept_delay_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
auto_accept_delay_set, "%llu\n");
+static int ssp_debug_mode_set(void *data, u64 val)
+{
+ struct hci_dev *hdev = data;
+ struct sk_buff *skb;
+ __u8 mode;
+
+ if (val != 0 && val != 1)
+ return -EINVAL;
+
+ if (!test_bit(HCI_UP, &hdev->flags))
+ return -ENETDOWN;
+
+ hci_req_lock(hdev);
+ mode = val;
+ skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
+ &mode, HCI_CMD_TIMEOUT);
+ hci_req_unlock(hdev);
+
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ if (skb->data[0]) {
+ u8 status = skb->data[0];
+ kfree_skb(skb);
+ return -bt_to_errno(status);
+ }
+
+ hci_dev_lock(hdev);
+ hdev->ssp_debug_mode = val;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+static int ssp_debug_mode_get(void *data, u64 *val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock(hdev);
+ *val = hdev->ssp_debug_mode;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
+ ssp_debug_mode_set, "%llu\n");
+
static int idle_timeout_set(void *data, u64 val)
{
struct hci_dev *hdev = data;
@@ -1192,9 +1240,12 @@ static int __hci_init(struct hci_dev *hdev)
hdev, &voice_setting_fops);
}
- if (lmp_ssp_capable(hdev))
+ if (lmp_ssp_capable(hdev)) {
debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
hdev, &auto_accept_delay_fops);
+ debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
+ hdev, &ssp_debug_mode_fops);
+ }
if (lmp_sniff_capable(hdev)) {
debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
--
1.8.3.1
^ permalink raw reply related
* [PATCH] Bluetooth: Expose setting if debug keys are used or not
From: Marcel Holtmann @ 2013-10-19 0:14 UTC (permalink / raw)
To: linux-bluetooth
The system can be figured to accept and use debug keys. Expose this
value in debugfs for debugging purposes.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_core.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d47c8ec..94d5342 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -215,6 +215,24 @@ static const struct file_operations link_keys_fops = {
.release = single_release,
};
+static ssize_t use_debug_keys_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_DEBUG_KEYS, &hdev->dev_flags) ? 'Y': 'N';
+ buf[1] = '\n';
+ buf[2] = '\0';
+ return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static const struct file_operations use_debug_keys_fops = {
+ .open = simple_open,
+ .read = use_debug_keys_read,
+ .llseek = default_llseek,
+};
+
static int dev_class_show(struct seq_file *f, void *ptr)
{
struct hci_dev *hdev = f->private;
@@ -1166,6 +1184,8 @@ static int __hci_init(struct hci_dev *hdev)
hdev, &inquiry_cache_fops);
debugfs_create_file("link_keys", 0400, hdev->debugfs,
hdev, &link_keys_fops);
+ debugfs_create_file("use_debug_keys", 0444, hdev->debugfs,
+ hdev, &use_debug_keys_fops);
debugfs_create_file("dev_class", 0444, hdev->debugfs,
hdev, &dev_class_fops);
debugfs_create_file("voice_setting", 0444, hdev->debugfs,
--
1.8.3.1
^ permalink raw reply related
* [PATCH 2/2] Bluetooth: Expose debugfs entry read/write own address type
From: Marcel Holtmann @ 2013-10-18 23:38 UTC (permalink / raw)
To: linux-bluetooth
For some testing it is important to know the current own addres type,
but also be able to change it. The change is lost over powery cycles
and only intended for debugging.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_core.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c130a23..d47c8ec 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -385,6 +385,34 @@ static const struct file_operations static_address_fops = {
.release = single_release,
};
+static int own_address_type_set(void *data, u64 val)
+{
+ struct hci_dev *hdev = data;
+
+ if (val != 0 && val != 1)
+ return -EINVAL;
+
+ hci_dev_lock(hdev);
+ hdev->own_addr_type = val;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+static int own_address_type_get(void *data, u64 *val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock(hdev);
+ *val = hdev->own_addr_type;
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get,
+ own_address_type_set, "%llu\n");
+
static int long_term_keys_show(struct seq_file *f, void *ptr)
{
struct hci_dev *hdev = f->private;
@@ -1162,6 +1190,8 @@ static int __hci_init(struct hci_dev *hdev)
&hdev->le_white_list_size);
debugfs_create_file("static_address", 0444, hdev->debugfs,
hdev, &static_address_fops);
+ debugfs_create_file("own_address_type", 0644, hdev->debugfs,
+ hdev, &own_address_type_fops);
debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
hdev, &long_term_keys_fops);
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH 1/2] Bluetooth: Select the own address type during initial setup phase
From: Marcel Holtmann @ 2013-10-18 23:38 UTC (permalink / raw)
To: linux-bluetooth
The own address type is based on the fact if the controller has
a public address or not. This means that this detail can be just
configured once during setup phase.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_conn.c | 7 +------
net/bluetooth/hci_core.c | 13 ++++++++++++-
net/bluetooth/mgmt.c | 10 ++--------
4 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9b5db01..0daac39 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -142,6 +142,7 @@ struct hci_dev {
__u8 dev_type;
bdaddr_t bdaddr;
bdaddr_t static_addr;
+ __u8 own_addr_type;
__u8 dev_name[HCI_MAX_NAME_LENGTH];
__u8 short_name[HCI_MAX_SHORT_NAME_LENGTH];
__u8 eir[HCI_MAX_EIR_LENGTH];
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 4e72650..974d7bc 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -615,12 +615,7 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
else
conn->dst_type = ADDR_LE_DEV_RANDOM;
- if (bacmp(&conn->src, BDADDR_ANY)) {
- conn->src_type = ADDR_LE_DEV_PUBLIC;
- } else {
- bacpy(&conn->src, &hdev->static_addr);
- conn->src_type = ADDR_LE_DEV_RANDOM;
- }
+ conn->src_type = hdev->own_addr_type;
conn->state = BT_CONNECT;
conn->out = true;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6b1844f..c130a23 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1053,8 +1053,19 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
if (hdev->commands[5] & 0x10)
hci_setup_link_policy(req);
- if (lmp_le_capable(hdev))
+ if (lmp_le_capable(hdev)) {
+ /* If the controller has a public BD_ADDR, then by
+ * default use that one. If this is a LE only
+ * controller without one, default to the random
+ * address.
+ */
+ if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+ hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
+ else
+ hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
+
hci_set_le_support(req);
+ }
/* Read features beyond page 1 if available */
for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a727b47..fb7fc9f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1325,10 +1325,7 @@ static void enable_advertising(struct hci_request *req)
cp.min_interval = __constant_cpu_to_le16(0x0800);
cp.max_interval = __constant_cpu_to_le16(0x0800);
cp.type = get_adv_type(hdev);
- if (bacmp(&hdev->bdaddr, BDADDR_ANY))
- cp.own_address_type = ADDR_LE_DEV_PUBLIC;
- else
- cp.own_address_type = ADDR_LE_DEV_RANDOM;
+ cp.own_address_type = hdev->own_addr_type;
cp.channel_map = 0x07;
hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);
@@ -3237,10 +3234,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
param_cp.type = LE_SCAN_ACTIVE;
param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT);
param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
- if (bacmp(&hdev->bdaddr, BDADDR_ANY))
- param_cp.own_address_type = ADDR_LE_DEV_PUBLIC;
- else
- param_cp.own_address_type = ADDR_LE_DEV_RANDOM;
+ param_cp.own_address_type = hdev->own_addr_type;
hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
¶m_cp);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 5/5] android: Remove not needed property_get function form cutils stubs
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>
From: Szymon Janc <szymon.janc@tieto.com>
This is no longer used as daemon indicates its presence by connecting
socket.
---
android/cutils/properties.h | 27 ---------------------------
1 file changed, 27 deletions(-)
diff --git a/android/cutils/properties.h b/android/cutils/properties.h
index 44a712c..f318b01 100644
--- a/android/cutils/properties.h
+++ b/android/cutils/properties.h
@@ -24,33 +24,6 @@
extern "C" {
#endif
-#define PROPERTY_KEY_MAX 32
-#define PROPERTY_VALUE_MAX 92
-
-/* property_get: returns the length of the value which will never be
-** greater than PROPERTY_VALUE_MAX - 1 and will always be zero terminated.
-** (the length does not include the terminating zero).
-**
-** If the property read fails or returns an empty value, the default
-** value is used (if nonnull).
-*/
-static inline int property_get(const char *key, char *value,
- const char *default_value)
-{
- const char *env;
-
- env = getenv(key);
- if (!env)
- env = default_value;
-
- if (!value || !env)
- return 0;
-
- strncpy(value, env, PROPERTY_VALUE_MAX);
-
- return strlen(value);
-}
-
/* property_set: returns 0 on success, < 0 on failure
*/
static inline int property_set(const char *key, const char *value)
--
1.8.4.rc3
^ permalink raw reply related
* [PATCH 4/5] android: Make HAL library wait for daemon to connect on init
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>
From: Szymon Janc <szymon.janc@tieto.com>
After starting up, daemon is responsible for connecting to HAL library.
If this doesn't happen before timeout occured init will fail.
---
android/hal-bluetooth.c | 127 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 104 insertions(+), 23 deletions(-)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 2c6c2eb..c91bc98 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -19,6 +19,10 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <poll.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
@@ -31,41 +35,119 @@
#include <cutils/log.h>
#include "hal.h"
+#include "hal-msg.h"
#define SERVICE_NAME "bluetoothd"
+#define CONNECT_TIMEOUT (5 * 1000)
bt_callbacks_t *bt_hal_cbacks = NULL;
+static int cmd_sk = -1;
+static int notif_sk = -1;
+
static bool interface_ready(void)
{
return bt_hal_cbacks != NULL;
}
-static bool start_bt_daemon(void)
+static int accept_connection(int sk)
{
- int tries = 40; /* wait 4 seconds for completion */
+ int err;
+ struct pollfd pfd;
+ int new_sk;
+
+ memset(&pfd, 0 , sizeof(pfd));
+ pfd.fd = sk;
+ pfd.events = POLLIN;
+
+ err = poll(&pfd, 1, CONNECT_TIMEOUT);
+ if (err < 0) {
+ err = errno;
+ ALOGE("Failed to poll: %d (%s)", err, strerror(err));
+ return -1;
+ }
- ALOGD(__func__);
+ if (err == 0) {
+ ALOGE("bluetoothd connect timeout");
+ return -1;
+ }
+
+ new_sk = accept(sk, NULL, NULL);
+ if (new_sk < 0) {
+ err = errno;
+ ALOGE("Failed to accept socket: %d (%s)", err, strerror(err));
+ return -1;
+ }
+
+ return new_sk;
+}
+
+static bool start_daemon(void)
+{
+ struct sockaddr_un addr;
+ int sk;
+ int err;
+
+ sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
+ if (sk < 0) {
+ err = errno;
+ ALOGE("Failed to create socket: %d (%s)", err,
+ strerror(err));
+ return false;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+
+ /* Use abstract sockets so first byte needs to be \0 */
+ strcpy(addr.sun_path + 1, BLUEZ_HAL_SK_PATH);
+
+ if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ err = errno;
+ ALOGE("Failed to bind socket: %d (%s)", err, strerror(err));
+ close(sk);
+ return false;
+ }
+
+ if (listen(sk, 2) < 0) {
+ err = errno;
+ ALOGE("Failed to listen on socket: %d (%s)", err,
+ strerror(err));
+ close(sk);
+ return false;
+ }
/* Start Android Bluetooth daemon service */
property_set("ctl.start", SERVICE_NAME);
- while (tries-- > 0) {
- char val[PROPERTY_VALUE_MAX];
-
- if (property_get("init.svc." SERVICE_NAME, val, NULL)) {
- if (!strcmp(val, "running")) {
- ALOGI("Android BlueZ daemon started");
- return true;
- }
- } else {
- return false;
- }
+ cmd_sk = accept_connection(sk);
+ if (cmd_sk < 0) {
+ close(sk);
+ return false;
+ }
- usleep(100000);
+ notif_sk = accept_connection(sk);
+ if (notif_sk < 0) {
+ close(sk);
+ close(cmd_sk);
+ cmd_sk = -1;
+ return false;
}
- return false;
+ ALOGI("bluetoothd connected");
+
+ close(sk);
+
+ return true;
+}
+
+static void stop_daemon(void)
+{
+ close(cmd_sk);
+ cmd_sk = -1;
+
+ close(notif_sk);
+ notif_sk = 1;
}
static int init(bt_callbacks_t *callbacks)
@@ -75,15 +157,12 @@ static int init(bt_callbacks_t *callbacks)
if (interface_ready())
return BT_STATUS_SUCCESS;
- if (start_bt_daemon()) {
- /* TODO: open channel */
+ if (!start_daemon())
+ return BT_STATUS_FAIL;
- bt_hal_cbacks = callbacks;
+ bt_hal_cbacks = callbacks;
- return BT_STATUS_SUCCESS;
- }
-
- return BT_STATUS_UNSUPPORTED;
+ return BT_STATUS_SUCCESS;
}
static int enable(void)
@@ -110,6 +189,8 @@ static void cleanup(void)
if (!interface_ready())
return;
+ stop_daemon();
+
bt_hal_cbacks = NULL;
}
--
1.8.4.rc3
^ permalink raw reply related
* [PATCH 3/5] android: Connect daemon to HAL library
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>
From: Szymon Janc <szymon.janc@tieto.com>
Connect to HAL when adapter initialization is finished. If any problem
with connection occurs or connected socket is closed by remote daemon
shutdowns.
---
android/main.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 133 insertions(+)
diff --git a/android/main.c b/android/main.c
index c3fb80e..5b71265 100644
--- a/android/main.c
+++ b/android/main.c
@@ -32,7 +32,10 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+#include <errno.h>
#include <sys/signalfd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include <glib.h>
@@ -44,6 +47,7 @@
#include "src/shared/mgmt.h"
#include "adapter.h"
+#include "hal-msg.h"
#define SHUTDOWN_GRACE_SECONDS 10
@@ -55,8 +59,135 @@ static uint8_t mgmt_revision = 0;
static uint16_t adapter_index = MGMT_INDEX_NONE;
+static GIOChannel *hal_cmd_io = NULL;
+static GIOChannel *hal_notif_io = NULL;
+
static volatile sig_atomic_t __terminated = 0;
+static gboolean watch_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ info("HAL socket closed, terminating");
+ g_main_loop_quit(event_loop);
+
+ return FALSE;
+}
+
+static GIOChannel *create_io(void)
+{
+ int sk;
+ int err;
+ GIOChannel *io;
+
+ sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
+ if (sk < 0) {
+ err = errno;
+ error("Failed to create socket: %d (%s)", err, strerror(err));
+ return NULL;
+ }
+
+ io = g_io_channel_unix_new(sk);
+
+ g_io_channel_set_close_on_unref(io, TRUE);
+ g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
+
+ return io;
+}
+
+static int connect_io(GIOChannel *io, GIOFunc connect_cb)
+{
+ int err;
+ struct sockaddr_un addr;
+ GIOCondition cond;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+
+ /* Use abstract sockets so first byte needs to be \0 */
+ strcpy(addr.sun_path + 1, BLUEZ_HAL_SK_PATH);
+
+ err = connect(g_io_channel_unix_get_fd(io),
+ (struct sockaddr *) &addr, sizeof(addr));
+ if (err < 0) {
+ err = -errno;
+ error("Failed to connect HAL socket: %d (%s)", -err,
+ strerror(-err));
+ return err;
+ }
+
+ cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+ g_io_add_watch(io, cond, connect_cb, NULL);
+
+ return 0;
+}
+
+static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ DBG("");
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+ g_main_loop_quit(event_loop);
+ return FALSE;
+ }
+
+ cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+ g_io_add_watch(io, cond, watch_cb, NULL);
+
+ info("Successfully connected to HAL");
+
+ /* TODO start handling commands */
+
+ return FALSE;
+}
+
+static void connect_notification_socket(void)
+{
+ DBG("");
+
+ hal_notif_io = create_io();
+
+ if (hal_notif_io && connect_io(hal_notif_io, notif_connect_cb) == 0)
+ return;
+
+ error("Cannot connect to HAL, terminating");
+ g_main_loop_quit(event_loop);
+}
+
+static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ DBG("");
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+ g_main_loop_quit(event_loop);
+ return FALSE;
+ }
+
+ cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+ g_io_add_watch(io, cond, watch_cb, NULL);
+
+ connect_notification_socket();
+
+ return FALSE;
+}
+
+static void connect_cmd_socket(void)
+{
+ DBG("");
+
+ hal_cmd_io = create_io();
+
+ if (hal_cmd_io && connect_io(hal_cmd_io, cmd_connect_cb) == 0)
+ return;
+
+ error("Cannot connect to HAL, terminating");
+ g_main_loop_quit(event_loop);
+}
+
static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
gpointer user_data)
{
@@ -141,6 +272,8 @@ static void adapter_ready(struct bt_adapter *adapter, int err)
}
info("Adapter initialized");
+
+ connect_cmd_socket();
}
static void mgmt_index_added_event(uint16_t index, uint16_t length,
--
1.8.4.rc3
^ permalink raw reply related
* [PATCH 2/5] android: Define path for HAL communication socket
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>
From: Szymon Janc <szymon.janc@tieto.com>
This socket will be used by android daemon and libhal to communitate.
---
android/hal-msg.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 4c5ca69..2da5e16 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -21,6 +21,8 @@
*
*/
+#define BLUEZ_HAL_SK_PATH "bluez_hal_socket"
+
struct hal_msg_hdr {
uint8_t service_id;
uint8_t opcode;
--
1.8.4.rc3
^ permalink raw reply related
* [PATCH 1/5] android: Fix cutils/log.h stubs
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>
From: Szymon Janc <szymon.janc@tieto.com>
Provide dummy functions that will use macro parameters. This fix
build errors about set-but-not-used used local variables on linux.
---
android/cutils/log.h | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/android/cutils/log.h b/android/cutils/log.h
index d87da72..7374add 100644
--- a/android/cutils/log.h
+++ b/android/cutils/log.h
@@ -17,11 +17,13 @@
#ifndef _CUTILS_LOG_H
#define _CUTILS_LOG_H
-#define ALOGV(...)
-#define ALOGD(...)
-#define ALOGI(...)
-#define ALOGW(...)
-#define ALOGE(...)
+static inline void dummy_printf(const char *fmt, ...) { }
+
+#define ALOGV(...) dummy_printf("", __VA_ARGS__)
+#define ALOGD(...) dummy_printf("", __VA_ARGS__)
+#define ALOGI(...) dummy_printf("", __VA_ARGS__)
+#define ALOGW(...) dummy_printf("", __VA_ARGS__)
+#define ALOGE(...) dummy_printf("", __VA_ARGS__)
#define LOG_ALWAYS_FATAL(...) do { ALOGE(__VA_ARGS__); exit(1); } while (0)
#endif // _CUTILS_LOG_H
--
1.8.4.rc3
^ 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