2014-09-02 13:54:59

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH 1/5] android/bluetooth: Extract function sending bond state

---
android/bluetooth.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index bd1e747..7c3c198 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -877,6 +877,27 @@ static uint8_t device_bond_state(struct device *dev)
return HAL_BOND_STATE_NONE;
}

+static void update_bond_state(struct device *dev, uint8_t status,
+ uint8_t old_bond, uint8_t new_bond)
+{
+ if (old_bond == new_bond)
+ return;
+
+ /*
+ * For incoming just works bonding we will switch here from
+ * non bonded to bonded directly. This is something Android
+ * will not handle in their bond state machine. To make Android
+ * handle it corretly we need to send BONDING state before BOND
+ */
+ if (old_bond == HAL_BOND_STATE_NONE &&
+ new_bond == HAL_BOND_STATE_BONDED)
+ send_bond_state_change(dev, status,
+ HAL_BOND_STATE_BONDING);
+
+ send_bond_state_change(dev, status, new_bond);
+
+}
+
static void update_device_state(struct device *dev, uint8_t addr_type,
uint8_t status, bool pairing, bool paired,
bool bonded)
@@ -892,20 +913,7 @@ static void update_device_state(struct device *dev, uint8_t addr_type,

new_bond = device_bond_state(dev);

- if (old_bond != new_bond) {
- /*
- * For incoming just works bonding we will switch here from
- * non bonded to bonded directly. This is something Android
- * will not handle in their bond state machine. To make Android
- * handle it corretly we need to send BONDING state before BOND
- */
- if (old_bond == HAL_BOND_STATE_NONE &&
- new_bond == HAL_BOND_STATE_BONDED)
- send_bond_state_change(dev, status,
- HAL_BOND_STATE_BONDING);
-
- send_bond_state_change(dev, status, new_bond);
- }
+ update_bond_state(dev, status, old_bond, new_bond);
}

static void send_device_property(struct device *dev, uint8_t type,
--
1.8.4



2014-09-02 16:04:08

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH 1/5] android/bluetooth: Extract function sending bond state

Hi Ɓukasz,

On Tuesday 02 of September 2014 15:54:59 Lukasz Rymanowski wrote:
> ---
> android/bluetooth.c | 36 ++++++++++++++++++++++--------------
> 1 file changed, 22 insertions(+), 14 deletions(-)
>
> diff --git a/android/bluetooth.c b/android/bluetooth.c
> index bd1e747..7c3c198 100644
> --- a/android/bluetooth.c
> +++ b/android/bluetooth.c
> @@ -877,6 +877,27 @@ static uint8_t device_bond_state(struct device *dev)
> return HAL_BOND_STATE_NONE;
> }
>
> +static void update_bond_state(struct device *dev, uint8_t status,
> + uint8_t old_bond, uint8_t new_bond)
> +{
> + if (old_bond == new_bond)
> + return;
> +
> + /*
> + * For incoming just works bonding we will switch here from
> + * non bonded to bonded directly. This is something Android
> + * will not handle in their bond state machine. To make Android
> + * handle it corretly we need to send BONDING state before BOND
> + */
> + if (old_bond == HAL_BOND_STATE_NONE &&
> + new_bond == HAL_BOND_STATE_BONDED)
> + send_bond_state_change(dev, status,
> + HAL_BOND_STATE_BONDING);
> +
> + send_bond_state_change(dev, status, new_bond);
> +
> +}
> +
> static void update_device_state(struct device *dev, uint8_t addr_type,
> uint8_t status, bool pairing, bool paired,
> bool bonded)
> @@ -892,20 +913,7 @@ static void update_device_state(struct device *dev, uint8_t addr_type,
>
> new_bond = device_bond_state(dev);
>
> - if (old_bond != new_bond) {
> - /*
> - * For incoming just works bonding we will switch here from
> - * non bonded to bonded directly. This is something Android
> - * will not handle in their bond state machine. To make Android
> - * handle it corretly we need to send BONDING state before BOND
> - */
> - if (old_bond == HAL_BOND_STATE_NONE &&
> - new_bond == HAL_BOND_STATE_BONDED)
> - send_bond_state_change(dev, status,
> - HAL_BOND_STATE_BONDING);
> -
> - send_bond_state_change(dev, status, new_bond);
> - }
> + update_bond_state(dev, status, old_bond, new_bond);
> }
>
> static void send_device_property(struct device *dev, uint8_t type,
>

All 5 patches applied. Thanks.

--
Best regards,
Szymon Janc

2014-09-02 13:55:03

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH 5/5] android/tester: Add test verifying correct bond state notification

Added test which verify that remote device which is paired and not
bonded has correct state in Android framework after ACL disconnection.
---
android/tester-bluetooth.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)

diff --git a/android/tester-bluetooth.c b/android/tester-bluetooth.c
index 7ea0684..a97e28e 100644
--- a/android/tester-bluetooth.c
+++ b/android/tester-bluetooth.c
@@ -448,6 +448,8 @@ static struct bt_action_data no_input_no_output_io_cap = {
.io_cap = 0x03,
};

+static uint16_t test_conn_handle = 0;
+
static void conn_cb(uint16_t handle, void *user_data)
{
struct test_data *data = tester_get_data();
@@ -455,6 +457,8 @@ static void conn_cb(uint16_t handle, void *user_data)

tester_print("New connection with handle 0x%04x", handle);

+ test_conn_handle = handle;
+
bthost_request_auth(bthost, handle);
}

@@ -1178,6 +1182,30 @@ static struct test_case test_cases[] = {
ACTION_SUCCESS(bluetooth_disable_action, NULL),
CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
),
+ TEST_CASE_BREDR("Bluetooth Accept Bond - No Bond - Success",
+ ACTION_SUCCESS(bluetooth_enable_action, NULL),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
+ ACTION_SUCCESS(bt_set_property_action,
+ &prop_test_scanmode_conn_discov),
+ CALLBACK_ADAPTER_PROPS(&prop_test_scanmode_conn_discov, 1),
+ ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
+ ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
+ ACTION_SUCCESS(emu_set_io_cap, &no_input_no_output_io_cap),
+ ACTION_SUCCESS(emu_set_connect_cb_action, conn_cb),
+ ACTION_SUCCESS(emu_remote_connect_hci_action, NULL),
+ CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING,
+ &prop_emu_remote_bdadr, 1),
+ CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED,
+ &prop_emu_remote_bdadr, 1),
+ ACTION_SUCCESS(emu_remote_disconnect_hci_action,
+ &test_conn_handle),
+ ACTION_SUCCESS(bluetooth_disable_action, NULL),
+ CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING,
+ &prop_emu_remote_bdadr, 1),
+ CALLBACK_BOND_STATE(BT_BOND_STATE_NONE,
+ &prop_emu_remote_bdadr, 1),
+ CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
+ ),
};

struct queue *get_bluetooth_tests(void)
--
1.8.4


2014-09-02 13:55:02

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH 4/5] android/bluetooth: Fix bond state for non-bonded devices

When device is paired but no-bonded, Android GUI keep incorrect bonds
state after ACL disconnect. This patch fixes that

This patch also moved device_is_paired() up in the file
---
android/bluetooth.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 390a3a2..147d9f8 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2035,6 +2035,19 @@ static void mgmt_device_connected_event(uint16_t index, uint16_t length,
HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev);
}

+static bool device_is_paired(struct device *dev, uint8_t addr_type)
+{
+ if (addr_type == BDADDR_BREDR)
+ return dev->bredr_paired;
+
+ return dev->le_paired;
+}
+
+static bool device_is_bonded(struct device *dev)
+{
+ return dev->bredr_bonded || dev->le_bonded;
+}
+
static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
const void *param,
void *user_data)
@@ -2042,6 +2055,7 @@ static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
const struct mgmt_ev_device_disconnected *ev = param;
struct hal_ev_acl_state_changed hal_ev;
struct device *dev;
+ uint8_t type = ev->addr.type;

if (length < sizeof(*ev)) {
error("Too short device disconnected event (%u bytes)", length);
@@ -2058,6 +2072,11 @@ static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,

ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH,
HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev);
+
+ if (device_is_paired(dev, type) && !device_is_bonded(dev))
+ update_device_state(dev, type, HAL_STATUS_SUCCESS, false,
+ false, false);
+
}

static uint8_t status_mgmt2hal(uint8_t mgmt)
@@ -4283,14 +4302,6 @@ uint8_t bt_device_last_seen_bearer(const bdaddr_t *bdaddr)
return select_device_bearer(dev);
}

-static bool device_is_paired(struct device *dev, uint8_t addr_type)
-{
- if (addr_type == BDADDR_BREDR)
- return dev->bredr_paired;
-
- return dev->le_paired;
-}
-
static void handle_create_bond_cmd(const void *buf, uint16_t len)
{
const struct hal_cmd_create_bond *cmd = buf;
--
1.8.4


2014-09-02 13:55:01

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH 3/5] android/bluetooth: Improve sending bond state notification

This patch makes sure that any bond state changes of remote device is
corretly distributed to Android framework.
---
android/bluetooth.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 94ddf75..390a3a2 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -884,13 +884,14 @@ static void update_bond_state(struct device *dev, uint8_t status,
return;

/*
- * For incoming just works bonding we will switch here from
- * non bonded to bonded directly. This is something Android
- * will not handle in their bond state machine. To make Android
- * handle it corretly we need to send BONDING state before BOND
+ * When internal bond state changes from bond to non-bond or other way,
+ * BfA needs to send bonding state to Android in the middle. Otherwise
+ * Android will not handle it correctly
*/
- if (old_bond == HAL_BOND_STATE_NONE &&
- new_bond == HAL_BOND_STATE_BONDED)
+ if ((old_bond == HAL_BOND_STATE_NONE &&
+ new_bond == HAL_BOND_STATE_BONDED) ||
+ (old_bond == HAL_BOND_STATE_BONDED &&
+ new_bond == HAL_BOND_STATE_NONE))
send_bond_state_change(dev, HAL_STATUS_SUCCESS,
HAL_BOND_STATE_BONDING);

--
1.8.4


2014-09-02 13:55:00

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH 2/5] android/bluetooth: Fix status in "fake" bonding notification

When sending "fake" bonding" we should use SUCCESS status
---
android/bluetooth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 7c3c198..94ddf75 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -891,7 +891,7 @@ static void update_bond_state(struct device *dev, uint8_t status,
*/
if (old_bond == HAL_BOND_STATE_NONE &&
new_bond == HAL_BOND_STATE_BONDED)
- send_bond_state_change(dev, status,
+ send_bond_state_change(dev, HAL_STATUS_SUCCESS,
HAL_BOND_STATE_BONDING);

send_bond_state_change(dev, status, new_bond);
--
1.8.4