* [RFC v11 14/15] Bluetooth: Create hci_req_add_le_passive_scan helper
From: Andre Guedes @ 2014-02-24 22:31 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
This patches creates the hci_req_add_le_passive_scan helper so it can
be re-used in the next patch.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_core.c | 46 ++++++++++++++++++++++++++--------------------
1 file changed, 26 insertions(+), 20 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5d51086..e0ebbd9 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -5095,6 +5095,31 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
}
+static void hci_req_add_le_passive_scan(struct hci_request *req,
+ struct hci_dev *hdev)
+{
+ struct hci_cp_le_set_scan_param param_cp;
+ struct hci_cp_le_set_scan_enable enable_cp;
+ u8 own_addr_type;
+
+ if (hci_update_random_address(req, true, &own_addr_type))
+ return;
+
+ memset(¶m_cp, 0, sizeof(param_cp));
+ param_cp.type = LE_SCAN_PASSIVE;
+ param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
+ param_cp.window = cpu_to_le16(hdev->le_scan_window);
+ param_cp.own_address_type = own_addr_type;
+ hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
+ ¶m_cp);
+
+ memset(&enable_cp, 0, sizeof(enable_cp));
+ enable_cp.enable = LE_SCAN_ENABLE;
+ enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
+ hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
+ &enable_cp);
+}
+
static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
{
if (status)
@@ -5110,8 +5135,6 @@ static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
*/
void hci_update_background_scan(struct hci_dev *hdev)
{
- struct hci_cp_le_set_scan_param param_cp;
- struct hci_cp_le_set_scan_enable enable_cp;
struct hci_request req;
struct hci_conn *conn;
int err;
@@ -5131,8 +5154,6 @@ void hci_update_background_scan(struct hci_dev *hdev)
BT_DBG("%s stopping background scanning", hdev->name);
} else {
- u8 own_addr_type;
-
/* If there is at least one pending LE connection, we should
* keep the background scan running.
*/
@@ -5149,22 +5170,7 @@ void hci_update_background_scan(struct hci_dev *hdev)
if (conn)
return;
- if (hci_update_random_address(&req, false, &own_addr_type))
- return;
-
- memset(¶m_cp, 0, sizeof(param_cp));
- param_cp.type = LE_SCAN_PASSIVE;
- param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
- param_cp.window = cpu_to_le16(hdev->le_scan_window);
- param_cp.own_address_type = own_addr_type;
- hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
- ¶m_cp);
-
- memset(&enable_cp, 0, sizeof(enable_cp));
- enable_cp.enable = LE_SCAN_ENABLE;
- enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
- hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
- &enable_cp);
+ hci_req_add_le_passive_scan(&req, hdev);
BT_DBG("%s starting background scanning", hdev->name);
}
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 13/15] Bluetooth: Add le_auto_conn file on debugfs
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
This patch adds to debugfs the le_auto_conn file. This file will be
used to test LE auto connection infrastructure.
To add a new auto connection address we write on le_auto_conn file
following the format <address> <address type> <auto_connect>.
The <address type> values are:
* 0 for public address
* 1 for random address
The <auto_connect> values are (for more details see struct hci_
conn_params):
* 0 for disabled
* 1 for always
* 2 for link loss
So for instance, if you want the kernel autonomously establishes
connections with device AA:BB:CC:DD:EE:FF (public address) every
time the device enters in connectable mode (starts advertising),
you should run the command:
$ echo "AA:BB:CC:DD:EE:FF 0 1" > /sys/kernel/debug/bluetooth/hci0/le_auto_conn
To get the list of connection parameters configured in kernel, read
the le_auto_conn file:
$ cat /sys/kernel/debug/bluetooth/hci0/le_auto_conn
Finally, to clear the connection parameters list, write an empty
string:
$ echo "" > /sys/kernel/debug/bluetooth/hci0/le_auto_conn
This file is created only if LE is enabled.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_core.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 92 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index a8baf9a..5d51086 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -896,6 +896,96 @@ static const struct file_operations lowpan_debugfs_fops = {
.llseek = default_llseek,
};
+static int le_auto_conn_show(struct seq_file *sf, void *ptr)
+{
+ struct hci_dev *hdev = sf->private;
+ struct hci_conn_params *p;
+
+ hci_dev_lock(hdev);
+
+ list_for_each_entry(p, &hdev->le_conn_params, list) {
+ seq_printf(sf, "%pMR %u %u\n", &p->addr, p->addr_type,
+ p->auto_connect);
+ }
+
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+static int le_auto_conn_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, le_auto_conn_show, inode->i_private);
+}
+
+static ssize_t le_auto_conn_write(struct file *file, const char __user *data,
+ size_t count, loff_t *offset)
+{
+ struct seq_file *sf = file->private_data;
+ struct hci_dev *hdev = sf->private;
+ u8 auto_connect;
+ bdaddr_t addr;
+ u8 addr_type;
+ char *buf;
+ int err;
+ int n;
+
+ /* Don't allow partial write */
+ if (*offset != 0)
+ return -EINVAL;
+
+ /* If empty string, clear the connection parameters and pending LE
+ * connection list.
+ */
+ if (count == 1) {
+ hci_dev_lock(hdev);
+ hci_conn_params_clear(hdev);
+ hci_pend_le_conns_clear(hdev);
+ hci_update_background_scan(hdev);
+ hci_dev_unlock(hdev);
+ return count;
+ }
+
+ buf = kzalloc(count, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ if (copy_from_user(buf, data, count)) {
+ kfree(buf);
+ return -EFAULT;
+ }
+
+ n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu %hhu", &addr.b[5],
+ &addr.b[4], &addr.b[3], &addr.b[2], &addr.b[1], &addr.b[0],
+ &addr_type, &auto_connect);
+ if (n != 8) {
+ kfree(buf);
+ return -EINVAL;
+ }
+
+ hci_dev_lock(hdev);
+ err = hci_conn_params_add(hdev, &addr, addr_type, auto_connect,
+ hdev->le_conn_min_interval,
+ hdev->le_conn_max_interval);
+ hci_dev_unlock(hdev);
+
+ if (err) {
+ kfree(buf);
+ return err;
+ }
+
+ kfree(buf);
+ return count;
+}
+
+static const struct file_operations le_auto_conn_fops = {
+ .open = le_auto_conn_open,
+ .read = seq_read,
+ .write = le_auto_conn_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* ---- HCI requests ---- */
static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
@@ -1694,6 +1784,8 @@ static int __hci_init(struct hci_dev *hdev)
hdev, &adv_channel_map_fops);
debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
&lowpan_debugfs_fops);
+ debugfs_create_file("le_auto_conn", 0644, hdev->debugfs, hdev,
+ &le_auto_conn_fops);
}
return 0;
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 12/15] Bluetooth: Support resolvable private addresses
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
Only identity addresses are inserted into hdev->pend_le_conns. So,
in order to support resolvable private addresses in auto connection
mechanism, we should resolve the address before checking for pending
connections.
Thus, this patch adds an extra check in check_pending_le_conn() and
updates 'addr' and 'addr_type' variables before hci_pend_le_conn_
lookup().
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_event.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 7acf066..d44cb23 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3706,8 +3706,18 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
u8 addr_type)
{
struct hci_conn *conn;
+ struct smp_irk *irk;
u8 bdaddr_type;
+ /* If this is a resolvable address, we should resolve it and then
+ * update address and address type variables.
+ */
+ irk = hci_get_irk(hdev, addr, addr_type);
+ if (irk) {
+ addr = &irk->bdaddr;
+ addr_type = irk->addr_type;
+ }
+
if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
return;
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 11/15] Bluetooth: Connection parameters and resolvable address
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
We should only add connection parameters for public, random static and
random private resolvable with IRK. If we allow non-resolvable or
resolvable without IRK, the background scan may run indefinitely. So, to
avoid this undesired behavior, we should check the address type in
hci_conn_params_add().
Additionally, since the IRK is removed during unpair, we should also
remove the connection parameters from that device.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 18 +++++++++++++++---
net/bluetooth/hci_core.c | 24 ++++++++++++++++++++----
net/bluetooth/mgmt.c | 2 ++
3 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5539dea..c81847e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -799,9 +799,9 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
bdaddr_t *addr, u8 addr_type);
-void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
- u8 auto_connect, u16 conn_min_interval,
- u16 conn_max_interval);
+int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
+ u8 auto_connect, u16 conn_min_interval,
+ u16 conn_max_interval);
void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
void hci_conn_params_clear(struct hci_dev *hdev);
@@ -1117,6 +1117,18 @@ static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
return false;
}
+/* Check if address is "random private non-resolvable" type */
+static inline bool hci_bdaddr_is_non_rpa(bdaddr_t *bdaddr, u8 addr_type)
+{
+ if (addr_type != 0x01)
+ return false;
+
+ if ((bdaddr->b[5] & 0xc0) == 0x00)
+ return true;
+
+ return false;
+}
+
static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 addr_type)
{
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e78e48e..a8baf9a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3221,12 +3221,26 @@ static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
}
/* This function requires the caller holds hdev->lock */
-void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
- u8 auto_connect, u16 conn_min_interval,
- u16 conn_max_interval)
+int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
+ u8 auto_connect, u16 conn_min_interval,
+ u16 conn_max_interval)
{
struct hci_conn_params *params;
+ if (hci_bdaddr_is_non_rpa(addr, addr_type))
+ return -EINVAL;
+
+ if (hci_bdaddr_is_rpa(addr, addr_type)) {
+ struct smp_irk *irk;
+
+ irk = hci_get_irk(hdev, addr, addr_type);
+ if (!irk)
+ return -EINVAL;
+
+ addr = &irk->bdaddr;
+ addr_type = irk->addr_type;
+ }
+
params = hci_conn_params_lookup(hdev, addr, addr_type);
if (params)
goto update;
@@ -3234,7 +3248,7 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
params = kzalloc(sizeof(*params), GFP_KERNEL);
if (!params) {
BT_ERR("Out of memory");
- return;
+ return -ENOMEM;
}
bacpy(¶ms->addr, addr);
@@ -3261,6 +3275,8 @@ update:
BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x "
"conn_max_interval 0x%.4x", addr, addr_type, auto_connect,
conn_min_interval, conn_max_interval);
+
+ return 0;
}
/* This function requires the caller holds hdev->lock */
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a08c2bf..4745fb5 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2419,6 +2419,8 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
hci_remove_irk(hdev, &cp->addr.bdaddr, addr_type);
+ hci_conn_params_del(hdev, &cp->addr.bdaddr, addr_type);
+
err = hci_remove_ltk(hdev, &cp->addr.bdaddr, addr_type);
}
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 10/15] Bluetooth: Auto connection and power on
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
When hdev is closed (e.g. Mgmt power off command, RFKILL or controller
is reset), the ongoing active connections are silently dropped by the
controller (no Disconnection Complete Event is sent to host). For that
reason, the devices that require HCI_AUTO_CONN_ALWAYS are not added to
hdev->pend_le_conns list and they won't auto connect.
So to fix this issue, during hdev closing, we remove all pending LE
connections. After adapter is powered on, we add a pending LE connection
for each HCI_AUTO_CONN_ALWAYS address.
This way, the auto connection mechanism works propely after a power
off and power on sequence as well as RFKILL block/unblock.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_core.c | 1 +
net/bluetooth/mgmt.c | 13 +++++++++++++
2 files changed, 14 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 831cca8..e78e48e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2266,6 +2266,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_dev_lock(hdev);
hci_inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
+ hci_pend_le_conns_clear(hdev);
hci_dev_unlock(hdev);
hci_notify(hdev, HCI_DEV_DOWN);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 7c8a611..a08c2bf 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4662,6 +4662,17 @@ void mgmt_index_removed(struct hci_dev *hdev)
mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
}
+/* This function requires the caller holds hdev->lock */
+static void restart_le_auto_conns(struct hci_dev *hdev)
+{
+ struct hci_conn_params *p;
+
+ list_for_each_entry(p, &hdev->le_conn_params, list) {
+ if (p->auto_connect == HCI_AUTO_CONN_ALWAYS)
+ hci_pend_le_conn_add(hdev, &p->addr, p->addr_type);
+ }
+}
+
static void powered_complete(struct hci_dev *hdev, u8 status)
{
struct cmd_lookup match = { NULL, hdev };
@@ -4670,6 +4681,8 @@ static void powered_complete(struct hci_dev *hdev, u8 status)
hci_dev_lock(hdev);
+ restart_le_auto_conns(hdev);
+
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
new_settings(hdev, match.sk);
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 09/15] Bluetooth: Temporarily stop background scanning on discovery
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
If the user sends a mgmt start discovery command while the background
scanning is running, we should temporarily stop it. Once the discovery
finishes, we start the background scanning again.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_core.c | 2 ++
net/bluetooth/mgmt.c | 12 ++++++------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 0c1d2e3..831cca8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1786,6 +1786,8 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state)
switch (state) {
case DISCOVERY_STOPPED:
+ hci_update_background_scan(hdev);
+
if (hdev->discovery.state != DISCOVERY_STARTING)
mgmt_discovering(hdev, 0);
break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index c722914..7c8a611 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3432,12 +3432,12 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
goto failed;
}
- if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
- err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
- MGMT_STATUS_BUSY);
- mgmt_pending_remove(cmd);
- goto failed;
- }
+ /* If controller is scanning, it means the background scanning
+ * is running. Thus, we should temporarily stop it in order to
+ * set the discovery scanning parameters.
+ */
+ if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+ hci_req_add_le_scan_disable(&req);
memset(¶m_cp, 0, sizeof(param_cp));
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 08/15] Bluetooth: Connection parameters and auto connection
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
This patch modifies hci_conn_params_add() and hci_conn_params_del() so
they also add/delete pending LE connections according to the auto_
connect option. This way, background scan is automatically triggered/
untriggered when connection parameters are added/removed.
For instance, when a new connection parameters with HCI_AUTO_CONN_ALWAYS
option is added and we are not connected to the device, we add a pending
LE connection for that device.
Likewise, when the connection parameters are updated we add or delete
a pending LE connection according to its new auto_connect option.
Finally, when the connection parameter is deleted we also delete the
pending LE connection (if any).
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_core.c | 42 +++++++++++++++++++++++++++++++++++-------
1 file changed, 35 insertions(+), 7 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index dbd4e8a..0c1d2e3 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3200,6 +3200,23 @@ struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
return NULL;
}
+static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
+{
+ struct hci_conn *conn;
+
+ conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
+ if (!conn)
+ return false;
+
+ if (conn->dst_type != type)
+ return false;
+
+ if (conn->state != BT_CONNECTED)
+ return false;
+
+ return true;
+}
+
/* This function requires the caller holds hdev->lock */
void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
u8 auto_connect, u16 conn_min_interval,
@@ -3208,12 +3225,8 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
struct hci_conn_params *params;
params = hci_conn_params_lookup(hdev, addr, addr_type);
- if (params) {
- params->conn_min_interval = conn_min_interval;
- params->conn_max_interval = conn_max_interval;
- params->auto_connect = auto_connect;
- return;
- }
+ if (params)
+ goto update;
params = kzalloc(sizeof(*params), GFP_KERNEL);
if (!params) {
@@ -3223,11 +3236,24 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
bacpy(¶ms->addr, addr);
params->addr_type = addr_type;
+
+ list_add(¶ms->list, &hdev->le_conn_params);
+
+update:
params->conn_min_interval = conn_min_interval;
params->conn_max_interval = conn_max_interval;
params->auto_connect = auto_connect;
- list_add(¶ms->list, &hdev->le_conn_params);
+ switch (auto_connect) {
+ case HCI_AUTO_CONN_DISABLED:
+ case HCI_AUTO_CONN_LINK_LOSS:
+ hci_pend_le_conn_del(hdev, addr, addr_type);
+ break;
+ case HCI_AUTO_CONN_ALWAYS:
+ if (!is_connected(hdev, addr, addr_type))
+ hci_pend_le_conn_add(hdev, addr, addr_type);
+ break;
+ }
BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x "
"conn_max_interval 0x%.4x", addr, addr_type, auto_connect,
@@ -3243,6 +3269,8 @@ void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
if (!params)
return;
+ hci_pend_le_conn_del(hdev, addr, addr_type);
+
list_del(¶ms->list);
kfree(params);
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 07/15] Bluetooth: Introduce LE auto connect options
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
This patch introduces the LE auto connection options: HCI_AUTO_CONN_
ALWAYS and HCI_AUTO_CONN_LINK_LOSS. Their working mechanism are
described as follows:
The HCI_AUTO_CONN_ALWAYS option configures the kernel to always re-
establish the connection, no matter the reason the connection was
terminated. This feature is required by some LE profiles such as
HID over GATT, Health Thermometer and Blood Pressure. These profiles
require the host autonomously connect to the device as soon as it
enters in connectable mode (start advertising) so the device is able
to delivery notifications or indications.
The BT_AUTO_CONN_LINK_LOSS option configures the kernel to re-
establish the connection in case the connection was terminated due
to a link loss. This feature is required by the majority of LE
profiles such as Proximity, Find Me, Cycling Speed and Cadence and
Time.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 9 ++++++++-
net/bluetooth/hci_core.c | 11 +++++++----
net/bluetooth/hci_event.c | 18 ++++++++++++++++++
3 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 950a7d8..5539dea 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -402,6 +402,12 @@ struct hci_conn_params {
u16 conn_min_interval;
u16 conn_max_interval;
+
+ enum {
+ HCI_AUTO_CONN_DISABLED,
+ HCI_AUTO_CONN_ALWAYS,
+ HCI_AUTO_CONN_LINK_LOSS,
+ } auto_connect;
};
extern struct list_head hci_dev_list;
@@ -794,7 +800,8 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
bdaddr_t *addr, u8 addr_type);
void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
- u16 conn_min_interval, u16 conn_max_interval);
+ u8 auto_connect, u16 conn_min_interval,
+ u16 conn_max_interval);
void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
void hci_conn_params_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b1c247f..dbd4e8a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3202,7 +3202,8 @@ struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
/* This function requires the caller holds hdev->lock */
void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
- u16 conn_min_interval, u16 conn_max_interval)
+ u8 auto_connect, u16 conn_min_interval,
+ u16 conn_max_interval)
{
struct hci_conn_params *params;
@@ -3210,6 +3211,7 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
if (params) {
params->conn_min_interval = conn_min_interval;
params->conn_max_interval = conn_max_interval;
+ params->auto_connect = auto_connect;
return;
}
@@ -3223,12 +3225,13 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
params->addr_type = addr_type;
params->conn_min_interval = conn_min_interval;
params->conn_max_interval = conn_max_interval;
+ params->auto_connect = auto_connect;
list_add(¶ms->list, &hdev->le_conn_params);
- BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x "
- "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval,
- conn_max_interval);
+ BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x "
+ "conn_max_interval 0x%.4x", addr, addr_type, auto_connect,
+ conn_min_interval, conn_max_interval);
}
/* This function requires the caller holds hdev->lock */
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d5bf23d..7acf066 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1841,6 +1841,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_disconn_complete *ev = (void *) skb->data;
u8 reason = hci_to_mgmt_reason(ev->reason);
+ struct hci_conn_params *params;
struct hci_conn *conn;
bool mgmt_connected;
u8 type;
@@ -1868,6 +1869,23 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (conn->type == ACL_LINK && conn->flush_key)
hci_remove_link_key(hdev, &conn->dst);
+ params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
+ if (params) {
+ switch (params->auto_connect) {
+ case HCI_AUTO_CONN_LINK_LOSS:
+ if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
+ break;
+ /* Fall through */
+
+ case HCI_AUTO_CONN_ALWAYS:
+ hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
+ break;
+
+ default:
+ break;
+ }
+ }
+
type = conn->type;
hci_proto_disconn_cfm(conn, ev->reason);
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 06/15] Bluetooth: Introduce LE auto connection infrastructure
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
This patch introduces the LE auto connection infrastructure which
will be used to implement the LE auto connection options.
In summary, the auto connection mechanism works as follows: Once the
first pending LE connection is created, the background scanning is
started. When the target device is found in range, the kernel
autonomously starts the connection attempt. If connection is
established successfully, that pending LE connection is deleted and
the background is stopped.
To achieve that, this patch introduces the hci_update_background_scan()
which controls the background scanning state. This function starts or
stops the background scanning based on the hdev->pend_le_conns list. If
there is no pending LE connection, the background scanning is stopped.
Otherwise, we start the background scanning.
Then, every time a pending LE connection is added we call hci_update_
background_scan() so the background scanning is started (in case it is
not already running). Likewise, every time a pending LE connection is
deleted we call hci_update_background_scan() so the background scanning
is stopped (in case this was the last pending LE connection) or it is
started again (in case we have more pending LE connections). Finally,
we also call hci_update_background_scan() in hci_le_conn_failed() so
the background scan is restarted in case the connection establishment
fails. This way the background scanning keeps running until all pending
LE connection are established.
At this point, resolvable addresses are not support by this
infrastructure. The proper support is added in upcoming patches.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 2 +
net/bluetooth/hci_conn.c | 5 +++
net/bluetooth/hci_core.c | 89 +++++++++++++++++++++++++++++++++++++++-
net/bluetooth/hci_event.c | 44 ++++++++++++++++++++
4 files changed, 138 insertions(+), 2 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b1ceaad..950a7d8 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -804,6 +804,8 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
void hci_pend_le_conns_clear(struct hci_dev *hdev);
+void hci_update_background_scan(struct hci_dev *hdev);
+
void hci_uuids_clear(struct hci_dev *hdev);
void hci_link_keys_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index a823d30..d654a90 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -527,6 +527,11 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
+
+ /* Since we may have temporarily stopped the background scanning in
+ * favor of connection establishment, we should restart it.
+ */
+ hci_update_background_scan(hdev);
}
static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 142ecd8..b1c247f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3281,7 +3281,7 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
if (entry)
- return;
+ goto done;
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
@@ -3295,6 +3295,9 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
list_add(&entry->list, &hdev->pend_le_conns);
BT_DBG("addr %pMR (type %u)", addr, addr_type);
+
+done:
+ hci_update_background_scan(hdev);
}
/* This function requires the caller holds hdev->lock */
@@ -3304,12 +3307,15 @@ void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
if (!entry)
- return;
+ goto done;
list_del(&entry->list);
kfree(entry);
BT_DBG("addr %pMR (type %u)", addr, addr_type);
+
+done:
+ hci_update_background_scan(hdev);
}
/* This function requires the caller holds hdev->lock */
@@ -4946,3 +4952,82 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
cp.enable = LE_SCAN_DISABLE;
hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
}
+
+static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
+{
+ if (status)
+ BT_DBG("HCI request failed to update background scanning: "
+ "status 0x%2.2x", status);
+}
+
+/* This function controls the background scanning based on hdev->pend_le_conns
+ * list. If there are pending LE connection we start the background scanning,
+ * otherwise we stop it.
+ *
+ * This function requires the caller holds hdev->lock.
+ */
+void hci_update_background_scan(struct hci_dev *hdev)
+{
+ struct hci_cp_le_set_scan_param param_cp;
+ struct hci_cp_le_set_scan_enable enable_cp;
+ struct hci_request req;
+ struct hci_conn *conn;
+ int err;
+
+ hci_req_init(&req, hdev);
+
+ if (list_empty(&hdev->pend_le_conns)) {
+ /* If there is no pending LE connections, we should stop
+ * the background scanning.
+ */
+
+ /* If controller is not scanning we are done. */
+ if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+ return;
+
+ hci_req_add_le_scan_disable(&req);
+
+ BT_DBG("%s stopping background scanning", hdev->name);
+ } else {
+ u8 own_addr_type;
+
+ /* If there is at least one pending LE connection, we should
+ * keep the background scan running.
+ */
+
+ /* If controller is already scanning we are done. */
+ if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+ return;
+
+ /* If controller is connecting, we should not start scanning
+ * since some controllers are not able to scan and connect at
+ * the same time.
+ */
+ conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
+ if (conn)
+ return;
+
+ if (hci_update_random_address(&req, false, &own_addr_type))
+ return;
+
+ memset(¶m_cp, 0, sizeof(param_cp));
+ param_cp.type = LE_SCAN_PASSIVE;
+ param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
+ param_cp.window = cpu_to_le16(hdev->le_scan_window);
+ param_cp.own_address_type = own_addr_type;
+ hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
+ ¶m_cp);
+
+ memset(&enable_cp, 0, sizeof(enable_cp));
+ enable_cp.enable = LE_SCAN_ENABLE;
+ enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
+ hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
+ &enable_cp);
+
+ BT_DBG("%s starting background scanning", hdev->name);
+ }
+
+ err = hci_req_run(&req, update_background_scan_complete);
+ if (err)
+ BT_ERR("Failed to run HCI request: err %d", err);
+}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index eaa6965..d5bf23d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3677,25 +3677,69 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_proto_connect_cfm(conn, ev->status);
+ hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
+
unlock:
hci_dev_unlock(hdev);
}
+/* This function requires the caller holds hdev->lock */
+static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
+ u8 addr_type)
+{
+ struct hci_conn *conn;
+ u8 bdaddr_type;
+
+ if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
+ return;
+
+ if (addr_type == ADDR_LE_DEV_PUBLIC)
+ bdaddr_type = BDADDR_LE_PUBLIC;
+ else
+ bdaddr_type = BDADDR_LE_RANDOM;
+
+ conn = hci_connect(hdev, LE_LINK, addr, bdaddr_type, BT_SECURITY_LOW,
+ HCI_AT_NO_BONDING);
+ if (!IS_ERR(conn))
+ return;
+
+ switch (PTR_ERR(conn)) {
+ case -EBUSY:
+ /* If hci_connect() returns -EBUSY it means there is already
+ * an LE connection attempt going on. Since controllers don't
+ * support more than one connection attempt at the time, we
+ * don't consider this an error case.
+ */
+ break;
+ default:
+ BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
+ }
+}
+
static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
u8 num_reports = skb->data[0];
void *ptr = &skb->data[1];
s8 rssi;
+ hci_dev_lock(hdev);
+
while (num_reports--) {
struct hci_ev_le_advertising_info *ev = ptr;
+ if (ev->evt_type == LE_ADV_IND ||
+ ev->evt_type == LE_ADV_DIRECT_IND)
+ check_pending_le_conn(hdev, &ev->bdaddr,
+ ev->bdaddr_type);
+
rssi = ev->data[ev->length];
mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
NULL, rssi, 0, 1, ev->data, ev->length);
ptr += sizeof(*ev) + ev->length + 1;
}
+
+ hci_dev_unlock(hdev);
}
static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 05/15] Bluetooth: Introduce hdev->pend_le_conn list
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
This patch introduces the hdev->pend_le_conn list which holds the
device addresses the kernel should autonomously connect. It also
introduces some helper functions to manipulate the list.
The list and helper functions will be used by the next patch which
implements the LE auto connection infrastructure.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 7 +++++
net/bluetooth/hci_core.c | 68 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ebc9c4f..b1ceaad 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -284,6 +284,7 @@ struct hci_dev {
struct list_head identity_resolving_keys;
struct list_head remote_oob_data;
struct list_head le_conn_params;
+ struct list_head pend_le_conns;
struct hci_dev_stats stat;
@@ -797,6 +798,12 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
void hci_conn_params_clear(struct hci_dev *hdev);
+struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
+ bdaddr_t *addr, u8 addr_type);
+void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
+void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
+void hci_pend_le_conns_clear(struct hci_dev *hdev);
+
void hci_uuids_clear(struct hci_dev *hdev);
void hci_link_keys_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9a078cf..142ecd8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3259,6 +3259,72 @@ void hci_conn_params_clear(struct hci_dev *hdev)
BT_DBG("All LE connection parameters were removed");
}
+/* This function requires the caller holds hdev->lock */
+struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
+ bdaddr_t *addr, u8 addr_type)
+{
+ struct bdaddr_list *entry;
+
+ list_for_each_entry(entry, &hdev->pend_le_conns, list) {
+ if (bacmp(&entry->bdaddr, addr) == 0 &&
+ entry->bdaddr_type == addr_type)
+ return entry;
+ }
+
+ return NULL;
+}
+
+/* This function requires the caller holds hdev->lock */
+void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
+{
+ struct bdaddr_list *entry;
+
+ entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
+ if (entry)
+ return;
+
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry) {
+ BT_ERR("Out of memory");
+ return;
+ }
+
+ bacpy(&entry->bdaddr, addr);
+ entry->bdaddr_type = addr_type;
+
+ list_add(&entry->list, &hdev->pend_le_conns);
+
+ BT_DBG("addr %pMR (type %u)", addr, addr_type);
+}
+
+/* This function requires the caller holds hdev->lock */
+void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
+{
+ struct bdaddr_list *entry;
+
+ entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
+ if (!entry)
+ return;
+
+ list_del(&entry->list);
+ kfree(entry);
+
+ BT_DBG("addr %pMR (type %u)", addr, addr_type);
+}
+
+/* This function requires the caller holds hdev->lock */
+void hci_pend_le_conns_clear(struct hci_dev *hdev)
+{
+ struct bdaddr_list *entry, *tmp;
+
+ list_for_each_entry_safe(entry, tmp, &hdev->pend_le_conns, list) {
+ list_del(&entry->list);
+ kfree(entry);
+ }
+
+ BT_DBG("All LE pending connections cleared");
+}
+
static void inquiry_complete(struct hci_dev *hdev, u8 status)
{
if (status) {
@@ -3441,6 +3507,7 @@ struct hci_dev *hci_alloc_dev(void)
INIT_LIST_HEAD(&hdev->identity_resolving_keys);
INIT_LIST_HEAD(&hdev->remote_oob_data);
INIT_LIST_HEAD(&hdev->le_conn_params);
+ INIT_LIST_HEAD(&hdev->pend_le_conns);
INIT_LIST_HEAD(&hdev->conn_hash.list);
INIT_WORK(&hdev->rx_work, hci_rx_work);
@@ -3642,6 +3709,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_smp_irks_clear(hdev);
hci_remote_oob_data_clear(hdev);
hci_conn_params_clear(hdev);
+ hci_pend_le_conns_clear(hdev);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 04/15] Bluetooth: Remove unused function
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
This patch removes hci_create_le_conn() since it is not used anymore.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_conn.c | 43 -------------------------------------------
1 file changed, 43 deletions(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ae2c3e1..a823d30 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -551,49 +551,6 @@ done:
hci_dev_unlock(hdev);
}
-static int hci_create_le_conn(struct hci_conn *conn)
-{
- struct hci_dev *hdev = conn->hdev;
- struct hci_cp_le_create_conn cp;
- struct hci_request req;
- u8 own_addr_type;
- int err;
-
- hci_req_init(&req, hdev);
-
- memset(&cp, 0, sizeof(cp));
-
- /* Update random address, but set require_privacy to false so
- * that we never connect with an unresolvable address.
- */
- err = hci_update_random_address(&req, false, &own_addr_type);
- if (err < 0)
- return err;
-
- conn->src_type = own_addr_type;
-
- cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
- cp.scan_window = cpu_to_le16(hdev->le_scan_window);
- bacpy(&cp.peer_addr, &conn->dst);
- cp.peer_addr_type = conn->dst_type;
- cp.own_address_type = own_addr_type;
- cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
- cp.conn_interval_max = cpu_to_le16(conn->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);
- if (err) {
- hci_conn_del(conn);
- return err;
- }
-
- return 0;
-}
-
static void hci_req_add_le_create_conn(struct hci_request *req,
struct hci_conn *conn)
{
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 03/15] Bluetooth: Stop scanning on LE connection
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
Some LE controllers don't support scanning and creating a connection
at the same time. So we should always stop scanning in order to
establish the connection.
Since we may prematurely stop the discovery procedure in favor of
the connection establishment, we should also cancel hdev->le_scan_
disable delayed work and set the discovery state to DISCOVERY_STOPPED.
This change does a small improvement since it is not mandatory the
user stops scanning before connecting anymore. Moreover, this change
is required by upcoming LE auto connection mechanism in order to work
properly with controllers that don't support background scanning and
connection establishment at the same time.
In future, we might want to do a small optimization by checking if
controller is able to scan and connect at the same time. For now,
we want the simplest approach so we always stop scanning (even if
the controller is able to carry out both operations).
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci.h | 1 +
net/bluetooth/hci_conn.c | 89 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 1bb45a4..c3834d3 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -356,6 +356,7 @@ enum {
/* ---- HCI Error Codes ---- */
#define HCI_ERROR_AUTH_FAILURE 0x05
+#define HCI_ERROR_MEMORY_EXCEEDED 0x07
#define HCI_ERROR_CONNECTION_TIMEOUT 0x08
#define HCI_ERROR_REJ_BAD_ADDR 0x0f
#define HCI_ERROR_REMOTE_USER_TERM 0x13
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index dc8aad9..ae2c3e1 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -594,12 +594,83 @@ static int hci_create_le_conn(struct hci_conn *conn)
return 0;
}
+static void hci_req_add_le_create_conn(struct hci_request *req,
+ struct hci_conn *conn)
+{
+ struct hci_cp_le_create_conn cp;
+ struct hci_dev *hdev = conn->hdev;
+ u8 own_addr_type;
+
+ memset(&cp, 0, sizeof(cp));
+
+ /* Update random address, but set require_privacy to false so
+ * that we never connect with an unresolvable address.
+ */
+ if (hci_update_random_address(req, false, &own_addr_type))
+ return;
+
+ conn->src_type = own_addr_type;
+
+ cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
+ cp.scan_window = cpu_to_le16(hdev->le_scan_window);
+ bacpy(&cp.peer_addr, &conn->dst);
+ cp.peer_addr_type = conn->dst_type;
+ cp.own_address_type = conn->src_type;
+ cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
+ cp.conn_interval_max = cpu_to_le16(conn->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);
+}
+
+static void stop_scan_complete(struct hci_dev *hdev, u8 status)
+{
+ struct hci_request req;
+ struct hci_conn *conn;
+ int err;
+
+ conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
+ if (!conn)
+ return;
+
+ if (status) {
+ BT_DBG("HCI request failed to stop scanning: status 0x%2.2x",
+ status);
+
+ hci_dev_lock(hdev);
+ hci_le_conn_failed(conn, status);
+ hci_dev_unlock(hdev);
+ return;
+ }
+
+ /* Since we may have prematurely stopped discovery procedure, we should
+ * update discovery state.
+ */
+ cancel_delayed_work(&hdev->le_scan_disable);
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+
+ hci_req_init(&req, hdev);
+
+ hci_req_add_le_create_conn(&req, conn);
+
+ err = hci_req_run(&req, create_le_conn_complete);
+ if (err) {
+ hci_dev_lock(hdev);
+ hci_le_conn_failed(conn, HCI_ERROR_MEMORY_EXCEEDED);
+ hci_dev_unlock(hdev);
+ return;
+ }
+}
+
static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
u8 dst_type, u8 sec_level, u8 auth_type)
{
struct hci_conn_params *params;
struct hci_conn *conn;
struct smp_irk *irk;
+ struct hci_request req;
int err;
if (test_bit(HCI_ADVERTISING, &hdev->flags))
@@ -675,9 +746,23 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
conn->le_conn_max_interval = hdev->le_conn_max_interval;
}
- err = hci_create_le_conn(conn);
- if (err)
+ hci_req_init(&req, hdev);
+
+ /* If controller is scanning, we stop it since some controllers are
+ * not able to scan and connect at the same time.
+ */
+ if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
+ hci_req_add_le_scan_disable(&req);
+ err = hci_req_run(&req, stop_scan_complete);
+ } else {
+ hci_req_add_le_create_conn(&req, conn);
+ err = hci_req_run(&req, create_le_conn_complete);
+ }
+
+ if (err) {
+ hci_conn_del(conn);
return ERR_PTR(err);
+ }
done:
hci_conn_hold(conn);
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 02/15] Bluetooth: Declare le_conn_failed in hci_core.h
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
This patch adds the "hci_" prefix to le_conn_failed() helper and
declares it in hci_core.h so it can be reused in hci_event.c.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 2 ++
net/bluetooth/hci_conn.c | 4 ++--
net/bluetooth/hci_event.c | 6 +-----
3 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e394577..ebc9c4f 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -653,6 +653,8 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
+void hci_le_conn_failed(struct hci_conn *conn, u8 status);
+
/*
* hci_conn_get() and hci_conn_put() are used to control the life-time of an
* "hci_conn" object. They do not guarantee that the hci_conn object is running,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 3d6b1cf..dc8aad9 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -515,7 +515,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
EXPORT_SYMBOL(hci_get_route);
/* This function requires the caller holds hdev->lock */
-static void le_conn_failed(struct hci_conn *conn, u8 status)
+void hci_le_conn_failed(struct hci_conn *conn, u8 status)
{
struct hci_dev *hdev = conn->hdev;
@@ -545,7 +545,7 @@ static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
if (!conn)
goto done;
- le_conn_failed(conn, status);
+ hci_le_conn_failed(conn, status);
done:
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 877cee8..eaa6965 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3658,11 +3658,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
}
if (ev->status) {
- mgmt_connect_failed(hdev, &conn->dst, conn->type,
- conn->dst_type, ev->status);
- hci_proto_connect_cfm(conn, ev->status);
- conn->state = BT_CLOSED;
- hci_conn_del(conn);
+ hci_le_conn_failed(conn, ev->status);
goto unlock;
}
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 01/15] Bluetooth: Create hci_req_add_le_scan_disable helper
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393281061-14320-1-git-send-email-andre.guedes@openbossa.org>
This patch moves stop LE scanning duplicate code to one single
place and reuses it. This will avoid more duplicate code in
upcoming patches.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 14 ++++++++++----
net/bluetooth/mgmt.c | 6 +-----
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 269c820..e394577 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1128,6 +1128,7 @@ void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
const void *param, u8 event);
void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
+void hci_req_add_le_scan_disable(struct hci_request *req);
struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
const void *param, u32 timeout);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 669c76e..9a078cf 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3318,7 +3318,6 @@ static void le_scan_disable_work(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev,
le_scan_disable.work);
- struct hci_cp_le_set_scan_enable cp;
struct hci_request req;
int err;
@@ -3326,9 +3325,7 @@ static void le_scan_disable_work(struct work_struct *work)
hci_req_init(&req, hdev);
- memset(&cp, 0, sizeof(cp));
- cp.enable = LE_SCAN_DISABLE;
- hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
+ hci_req_add_le_scan_disable(&req);
err = hci_req_run(&req, le_scan_disable_work_complete);
if (err)
@@ -4872,3 +4869,12 @@ static void hci_cmd_work(struct work_struct *work)
}
}
}
+
+void hci_req_add_le_scan_disable(struct hci_request *req)
+{
+ struct hci_cp_le_set_scan_enable cp;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.enable = LE_SCAN_DISABLE;
+ hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
+}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 25b8b27..c722914 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3526,7 +3526,6 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
struct hci_cp_remote_name_req_cancel cp;
struct inquiry_entry *e;
struct hci_request req;
- struct hci_cp_le_set_scan_enable enable_cp;
int err;
BT_DBG("%s", hdev->name);
@@ -3562,10 +3561,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
} else {
cancel_delayed_work(&hdev->le_scan_disable);
- memset(&enable_cp, 0, sizeof(enable_cp));
- enable_cp.enable = LE_SCAN_DISABLE;
- hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE,
- sizeof(enable_cp), &enable_cp);
+ hci_req_add_le_scan_disable(&req);
}
break;
--
1.8.5.4
^ permalink raw reply related
* [RFC v11 00/15] LE auto connection
From: Andre Guedes @ 2014-02-24 22:30 UTC (permalink / raw)
To: linux-bluetooth
Hi all,
This patch set takes in consideration Marcel's comments from previous revirew as
well as introduces privacy feature support to LE auto connection mechanism.
Below follows a summary to help the review process:
* Patches from 1-10 are pretty much the same from previous version
(exception to Patch 8). They introduce the LE auto connection
infrastructure and auto connnection options.
* Patch 8 modifies hci_conn_params_add() and hci_conn_params_del() so they
also add/delete pending LE connections according to the auto_connect
option. This way, background scan is automatically triggered/untriggered
when connection parameters are added/removed. This feature was requested
in "[RFC v10 10/10] Bluetooth: Add le_auto_conn file on debugfs" review.
* Patches 11-12 add resolvable addresses support for LE auto connection
mechanism.
* Patches 14-15 change set_scan_params() so it restart background scan when
new scanning parameters are set. This allows us to update scanning
parameters on the fly.
This patch set don't filter duplicates on background scanning. The "time to
time re-enable scan" approach suggested in previous review might not be good
enough. Depending on how many time we wait to restart background scan, some
low latency reconnection profiles, such as HID over GATT, can become
impractical.
Moreover, just fine-tuning the scan parameters might be good enough. With
patches 14-15, we can easily change background scan parameters and do lots
experiments.
Finally, if enabling filter duplicates is really the way to go, I can write a
small patch set improving the background scan routine.
BR,
Andre
Andre Guedes (15):
Bluetooth: Create hci_req_add_le_scan_disable helper
Bluetooth: Declare le_conn_failed in hci_core.h
Bluetooth: Stop scanning on LE connection
Bluetooth: Remove unused function
Bluetooth: Introduce hdev->pend_le_conn list
Bluetooth: Introduce LE auto connection infrastructure
Bluetooth: Introduce LE auto connect options
Bluetooth: Connection parameters and auto connection
Bluetooth: Temporarily stop background scanning on discovery
Bluetooth: Auto connection and power on
Bluetooth: Connection parameters and resolvable address
Bluetooth: Support resolvable private addresses
Bluetooth: Add le_auto_conn file on debugfs
Bluetooth: Create hci_req_add_le_passive_scan helper
Bluetooth: Update background scan parameters
include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/hci_core.h | 36 +++-
net/bluetooth/hci_conn.c | 85 +++++++--
net/bluetooth/hci_core.c | 365 +++++++++++++++++++++++++++++++++++++--
net/bluetooth/hci_event.c | 78 ++++++++-
net/bluetooth/mgmt.c | 40 +++--
6 files changed, 552 insertions(+), 53 deletions(-)
--
1.8.5.4
^ permalink raw reply
* Re: [PATCH] Bluetooth: Fix bluetooth.h for inclusion in clang projects
From: Anderson Lizardo @ 2014-02-24 20:51 UTC (permalink / raw)
To: Donald Carr; +Cc: BlueZ development
In-Reply-To: <CAOVeLGQe8FF0eGf0M0N2T34KsOK=HvPDDc5j+0TqSjToAdN4vQ@mail.gmail.com>
Hi Donald,
On Mon, Feb 24, 2014 at 12:38 PM, Donald Carr <sirspudd@gmail.com> wrote:
> From b12351dacb8e7fc44668ab4011db1d1b2b83e883 Mon Sep 17 00:00:00 2001
> From: Donald Carr <sirspudd@gmail.com>
> Date: Mon, 24 Feb 2014 08:34:46 -0800
> Subject: [PATCH] Move from typeof gcc intrinsic to __typeof__
>
> Change-Id: Ic3aa6ec1446876bfabdcc5e120ec327e177ffc74
I wonder why I'm not having any warnings when compiling BlueZ with
clang. Can you confirm which clang parameters are causing problems?
What I use is (when compiling bluez):
###
CC=clang ./bootstrap-configure
make
###
Regarding your patch, a few comments:
1) you should remove the "Change-Id" field (it is not used on BlueZ).
2) Your e-mail seems badly formatted (like as if you just copied one
email inside another). I suggest using "git send-email" for sending
properly formatted patches to the list.
3) The "Bluetooth:" subject prefix is only used for kernel patches.
For userspace patches, add a prefix which describes which part of the
code is affected (usually the subdirectory name is enough), in this
case:
lib: Move from typeof gcc intrinsic to __typeof__
4) A more verbose commit message would not hurt :)
Best Regards,
--
Anderson Lizardo
http://www.indt.org/?lang=en
INdT - Manaus - Brazil
^ permalink raw reply
* Re: [PATCH] android/pics: Add PICS and PIXIT for HSP
From: Szymon Janc @ 2014-02-24 20:31 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Sebastian Chlad,
bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <781D8095-A034-40C5-904A-E56BB63870AC@holtmann.org>
Hi Marcel,
On Monday 24 February 2014 11:34:26 Marcel Holtmann wrote:
> Hi Szymon,
>
> >>> Added PICS and PIXIT target Android 4.4
> >>> ---
> >>> android/Makefile.am | 2 +
> >>> android/pics-hsp.txt | 103
> >>> ++++++++++++++++++++++++++++++++++++++++++++++++++ android/pixit-hsp.txt
> >>>
> >>> | 30 +++++++++++++++
> >>>
> >>> 3 files changed, 135 insertions(+)
> >>> create mode 100644 android/pics-hsp.txt
> >>> create mode 100644 android/pixit-hsp.txt
> >>
> >> so we are doing Headset profile (HSP) and also Handsfree profile (HFP). I
> >> am fine with also doing HSP since it seems that is what Android uses on
> >> tablets.
> >
> > Both HSP and HFP are handled by handsfree HAL sp we would probably need
> > some extra argument in IPC to allow disabling HFP if not required. And
> > some configuration (runtime/compile time?) flag for libhal.
>
> I do not want a compile time option. Is that how Bluedroid handles it. For
> examples Nexus 4 vs Nexus 7.
Yes, Bluedroid is compile-time configured, device that wants to use
non-default options provides those in bdroid_buildcfg.h header eg.
this is defined for Nexus7 (flo), but not for Nexus4 (mako)
#define BTIF_HF_SERVICES (BTA_HSP_SERVICE_MASK)
>
> The easiest would be to have some IPC option to set HSP and HFP. Meaning
> that we could have a property that the HAL sets and then just uses that to
> tell the daemon what to enabled.
>
> I am thinking we might just need a flags parameter to the Register module
> command in the core service. Or alternatively, have a Set Option command.
>
> Right now I would tend to do the Set Option command. So the HAL can
> configure certain options.
I agree, for now we can provide such option command, if it turns out that more
profiles HALs need configuration we can move to flags in register commands.
--
Szymon K. Janc
szymon.janc@gmail.com
^ permalink raw reply
* Re: pull request: bluetooth-next 2014-02-21
From: John W. Linville @ 2014-02-24 20:05 UTC (permalink / raw)
To: Gustavo Padovan, linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20140222024745.GE1417@joana>
On Fri, Feb 21, 2014 at 11:47:45PM -0300, Gustavo Padovan wrote:
> Hi John,
>
> This is our first pull request for 3.15, the main feature here is the addition of
> the privacy feature for low energy devices. Other than that we have a bunch of small
> improvements, fixes, and clean ups all over the tree.
>
> Please pull or let me know of any concerns you may have. Thanks.
>
> Gustavo
>
> ---
> The following changes since commit e57f1734d87aa0e9a00905ed08888f0c62f56227:
>
> mwifiex: add key material v2 support (2014-02-12 15:36:26 -0500)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git for-upstream
>
> for you to fetch changes up to 668b7b19820b0801c425d31cc27fd6f499050e5c:
>
> Bluetooth: Fix iterating wrong list in hci_remove_irk() (2014-02-21 11:07:46 -0300)
Pulling now...
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [PATCH 1/2] android/bluetooth: Don't set remote name to empty string
From: Szymon Janc @ 2014-02-24 19:36 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1393001393-1160-1-git-send-email-szymon.janc@tieto.com>
On Friday 21 February 2014 17:49:52 Szymon Janc wrote:
> If remote device has name but it is empty (0 bytes) just ignore it and
> continue using address as name. This will avoid sending remote device
> property notification with empty name.
> ---
> android/bluetooth.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/android/bluetooth.c b/android/bluetooth.c
> index 31092e3..e225264 100644
> --- a/android/bluetooth.c
> +++ b/android/bluetooth.c
> @@ -1096,7 +1096,7 @@ static void update_new_device(struct device *dev,
> int8_t rssi, ev->num_props++;
> }
>
> - if (eir->name) {
> + if (eir->name && strlen(eir->name)) {
> g_free(dev->name);
> dev->name = g_strdup(eir->name);
> size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_NAME,
> @@ -1136,7 +1136,7 @@ static void update_device(struct device *dev, int8_t
> rssi, ev->num_props++;
> }
>
> - if (eir->name && strcmp(dev->name, eir->name)) {
> + if (eir->name && strlen(eir->name) && strcmp(dev->name, eir->name)) {
> g_free(dev->name);
> dev->name = g_strdup(eir->name);
> size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_NAME,
Both patches are now pushed upstream.
--
Szymon K. Janc
szymon.janc@gmail.com
^ permalink raw reply
* Re: [PATCH] android/pics: Add PICS and PIXIT for HSP
From: Marcel Holtmann @ 2014-02-24 19:34 UTC (permalink / raw)
To: Szymon Janc
Cc: Sebastian Chlad,
bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1813726.pFGF1AVLyQ@athlon>
Hi Szymon,
>>> Added PICS and PIXIT target Android 4.4
>>> ---
>>> android/Makefile.am | 2 +
>>> android/pics-hsp.txt | 103
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++ android/pixit-hsp.txt
>>> | 30 +++++++++++++++
>>> 3 files changed, 135 insertions(+)
>>> create mode 100644 android/pics-hsp.txt
>>> create mode 100644 android/pixit-hsp.txt
>>
>> so we are doing Headset profile (HSP) and also Handsfree profile (HFP). I am
>> fine with also doing HSP since it seems that is what Android uses on
>> tablets.
>
> Both HSP and HFP are handled by handsfree HAL sp we would probably need some
> extra argument in IPC to allow disabling HFP if not required. And some
> configuration (runtime/compile time?) flag for libhal.
I do not want a compile time option. Is that how Bluedroid handles it. For examples Nexus 4 vs Nexus 7.
The easiest would be to have some IPC option to set HSP and HFP. Meaning that we could have a property that the HAL sets and then just uses that to tell the daemon what to enabled.
I am thinking we might just need a flags parameter to the Register module command in the core service. Or alternatively, have a Set Option command.
Right now I would tend to do the Set Option command. So the HAL can configure certain options.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] android/pics: Add PICS and PIXIT for HSP
From: Szymon Janc @ 2014-02-24 19:17 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Sebastian Chlad,
bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <6632C143-D06A-48DC-A403-FDE4B40AB1B5@holtmann.org>
Hi Marcel,
On Monday 24 February 2014 09:57:14 Marcel Holtmann wrote:
> Hi Sebastian,
>
> > Added PICS and PIXIT target Android 4.4
> > ---
> > android/Makefile.am | 2 +
> > android/pics-hsp.txt | 103
> > ++++++++++++++++++++++++++++++++++++++++++++++++++ android/pixit-hsp.txt
> > | 30 +++++++++++++++
> > 3 files changed, 135 insertions(+)
> > create mode 100644 android/pics-hsp.txt
> > create mode 100644 android/pixit-hsp.txt
>
> so we are doing Headset profile (HSP) and also Handsfree profile (HFP). I am
> fine with also doing HSP since it seems that is what Android uses on
> tablets.
Both HSP and HFP are handled by handsfree HAL sp we would probably need some
extra argument in IPC to allow disabling HFP if not required. And some
configuration (runtime/compile time?) flag for libhal.
--
Szymon K. Janc
szymon.janc@gmail.com
^ permalink raw reply
* Re: [PATCH 0/7] Bluetooth: Graceful power off procedure
From: Marcel Holtmann @ 2014-02-24 19:12 UTC (permalink / raw)
To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1393246342-27980-1-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> This set of patches updates the power off procedure (as triggered
> through mgmt) to perform a graceful power off by first cleaning up HCI
> state such as connections, scan modes and advertising before requesting
> the HCI driver to actually power off.
>
> Johan
>
> ----------------------------------------------------------------
> Johan Hedberg (7):
> Bluetooth: Add convenience function for getting total connection count
> Bluetooth: Move HCI_ADVERTISING handling into mgmt.c
> Bluetooth: Move check for MGMT_CONNECTED flag into mgmt.c
> Bluetooth: Don't clear HCI_DISCOVERABLE when powering off
> Bluetooth: Don't clear HCI_CONNECTABLE when powering off
> Bluetooth: Don't clear HCI_ADVERTISING when powering off
> Bluetooth: Clean up HCI state when doing power off
>
> include/net/bluetooth/hci_core.h | 11 ++++-
> net/bluetooth/hci_event.c | 15 +++---
> net/bluetooth/mgmt.c | 96 ++++++++++++++++++++++++++++++++++--
> 3 files changed, 107 insertions(+), 15 deletions(-)
all 7 patches have been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] Bluetooth: Fix canceling RPA expiry timer
From: Marcel Holtmann @ 2014-02-24 19:06 UTC (permalink / raw)
To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1393266907-25867-1-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> The RPA expiry timer is only initialized inside mgmt.c when we receive
> the first command from user space. This action also involves setting the
> HCI_MGMT flag for the first time so that flag acts as a good indicator
> of whether the delayed work variable can be touched or not. This patch
> fixes hci_dev_do_close to first check the flag.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/hci_core.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* [PATCH] Bluetooth: Fix canceling RPA expiry timer
From: johan.hedberg @ 2014-02-24 18:35 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
The RPA expiry timer is only initialized inside mgmt.c when we receive
the first command from user space. This action also involves setting the
HCI_MGMT flag for the first time so that flag acts as a good indicator
of whether the delayed work variable can be touched or not. This patch
fixes hci_dev_do_close to first check the flag.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/hci_core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4bb4f4e7bbbe..669c76ec659a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2257,7 +2257,9 @@ static int hci_dev_do_close(struct hci_dev *hdev)
cancel_delayed_work(&hdev->service_cache);
cancel_delayed_work_sync(&hdev->le_scan_disable);
- cancel_delayed_work_sync(&hdev->rpa_expired);
+
+ if (test_bit(HCI_MGMT, &hdev->dev_flags))
+ cancel_delayed_work_sync(&hdev->rpa_expired);
hci_dev_lock(hdev);
hci_inquiry_cache_flush(hdev);
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH] android/pics: Add PICS and PIXIT for HSP
From: Marcel Holtmann @ 2014-02-24 17:57 UTC (permalink / raw)
To: Sebastian Chlad; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1393242895-19447-1-git-send-email-sebastian.chlad@tieto.com>
Hi Sebastian,
> Added PICS and PIXIT target Android 4.4
> ---
> android/Makefile.am | 2 +
> android/pics-hsp.txt | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++
> android/pixit-hsp.txt | 30 +++++++++++++++
> 3 files changed, 135 insertions(+)
> create mode 100644 android/pics-hsp.txt
> create mode 100644 android/pixit-hsp.txt
so we are doing Headset profile (HSP) and also Handsfree profile (HFP). I am fine with also doing HSP since it seems that is what Android uses on tablets.
Regards
Marcel
^ permalink raw reply
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