2014-06-30 15:31:49

by Ravi kumar Veeramally

[permalink] [raw]
Subject: [PATCH 0/5] Implement disconenct and reconnect

Patchset supports incoming MCL and MDL disconnection and
reconnection.

Ravi kumar Veeramally (5):
android/health: Implement mcl_disconnected cb
android/health: Implement mcl_uncached callback
android/health: Fix do not set mdl callbacks on mcl_reconneced call
back
android/health: Implement MDL reconnection from remote device
android/health: Update PTS result

android/health.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++------
android/pts-hdp.txt | 24 +++++++++--
2 files changed, 131 insertions(+), 15 deletions(-)

--
1.9.1



2014-06-30 16:36:55

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH 4/5] android/health: Implement MDL reconnection from remote device

Hi Ravi,

On Monday 30 of June 2014 18:31:53 Ravi kumar Veeramally wrote:
> ---
> android/health.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 52 insertions(+), 4 deletions(-)
>
> diff --git a/android/health.c b/android/health.c
> index 0327542..b77ab4e 100644
> --- a/android/health.c
> +++ b/android/health.c
> @@ -235,6 +235,14 @@ static void free_health_app(void *data)
> free(app);
> }
>
> +static bool match_channel_by_mdl(const void *data, const void *user_data)
> +{
> + const struct health_channel *channel = data;
> + const struct mcap_mdl *mdl = user_data;
> +
> + return channel->mdl == mdl;
> +}
> +
> static bool match_channel_by_id(const void *data, const void *user_data)
> {
> const struct health_channel *channel = data;
> @@ -298,6 +306,7 @@ static bool match_app_by_id(const void *data, const void *user_data)
> */
> struct channel_search {
> uint16_t channel_id;
> + struct mcap_mdl *mdl;
> struct health_channel *channel;
> };
>
> @@ -309,8 +318,13 @@ static void device_search_channel(void *data, void *user_data)
> if (search->channel)
> return;
>
> - search->channel = queue_find(dev->channels, match_channel_by_id,
> + if (search->channel_id)
> + search->channel = queue_find(dev->channels, match_channel_by_id,
> INT_TO_PTR(search->channel_id));
> + else if (search->mdl)
> + search->channel = queue_find(dev->channels,
> + match_channel_by_mdl,
> + search->mdl);
> }
>
> static void app_search_channel(void *data, void *user_data)
> @@ -331,6 +345,21 @@ static struct health_channel *search_channel_by_id(uint16_t id)
> DBG("");
>
> search.channel_id = id;
> + search.mdl = NULL;
> + search.channel = NULL;
> + queue_foreach(apps, app_search_channel, &search);
> +
> + return search.channel;
> +}
> +
> +static struct health_channel *search_channel_by_mdl(struct mcap_mdl *mdl)
> +{
> + struct channel_search search;
> +
> + DBG("");
> +
> + search.channel_id = 0;
> + search.mdl = mdl;
> search.channel = NULL;
> queue_foreach(apps, app_search_channel, &search);
>
> @@ -1176,11 +1205,14 @@ static void mcap_mdl_connected_cb(struct mcap_mdl *mdl, void *data)
> struct health_channel *channel = data;
> int fd;
>
> + DBG("Data channel connected: mdl %p channel %p", mdl, channel);
> +
> + if (!channel)
> + channel = search_channel_by_mdl(mdl);
> +

This can return NULL if matching channel is not found.

> if (!channel->mdl)
> channel->mdl = mcap_mdl_ref(mdl);
>
> - DBG("Data channel connected: mdl %p channel %p", mdl, channel);
> -
> fd = mcap_mdl_get_fd(channel->mdl);
> if (fd < 0) {
> error("health: error retrieving fd");
> @@ -1475,7 +1507,23 @@ static uint8_t mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
>
> static uint8_t mcap_mdl_reconn_req_cb(struct mcap_mdl *mdl, void *data)
> {
> - DBG("Not Implemeneted");
> + struct health_channel *channel;
> + GError *err = NULL;
> +
> + DBG("");
> +
> + channel = search_channel_by_mdl(mdl);
> + if (!channel) {
> + error("health: channel data does not exist");
> + return MCAP_UNSPECIFIED_ERROR;
> + }
> +
> + if (!mcap_set_data_chan_mode(mcap,
> + conf_to_l2cap(channel->type), &err)) {
> + error("health: %s", err->message);
> + g_error_free(err);
> + return MCAP_MDL_BUSY;
> + }
>
> return MCAP_SUCCESS;
> }
>

--
Best regards,
Szymon Janc

2014-06-30 15:31:54

by Ravi kumar Veeramally

[permalink] [raw]
Subject: [PATCH 5/5] android/health: Update PTS result

Results for TC_SRC_HCT_BV_04_I, TC_SRC_HCT_BV_06_C and
TC_SNK_HCT_BV_04_I.
---
android/pts-hdp.txt | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/android/pts-hdp.txt b/android/pts-hdp.txt
index fc5bd93..29a2434 100644
--- a/android/pts-hdp.txt
+++ b/android/pts-hdp.txt
@@ -108,9 +108,21 @@ TC_SRC_HCT_BV_02_I PASS haltest:
BTHL_MDEP_ROLE_SOURCE 4100
BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter
TC_SRC_HCT_BV_03_I N/A
-TC_SRC_HCT_BV_04_I INC
+TC_SRC_HCT_BV_04_I PASS haltest:
+ hl register_application bluez-android Bluez
+ bluez-hdp health-device-profile 1
+ BTHL_MDEP_ROLE_SOURCE 4100
+ BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter
+
+ when prompted: bluetooth ssp_reply <args>
TC_SRC_HCT_BV_05_C N/A
-TC_SRC_HCT_BV_06_C INC
+TC_SRC_HCT_BV_06_C PASS haltest:
+ hl register_application bluez-android Bluez
+ bluez-hdp health-device-profile 1
+ BTHL_MDEP_ROLE_SOURCE 4100
+ BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter
+
+ when prompted: bluetooth ssp_reply <args>
TC_SRC_HCT_BV_07_C INC
TC_SRC_DE_BV_01_I INC
TC_SRC_DE_BV_02_I PASS haltest:
@@ -222,7 +234,13 @@ TC_SNK_HCT_BV_02_I PASS haltest:
BTHL_MDEP_ROLE_SINK 4100
BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter
TC_SNK_HCT_BV_03_I N/A
-TC_SNK_HCT_BV_04_I INC
+TC_SNK_HCT_BV_04_I PASS haltest:
+ hl register_application bluez-android Bluez
+ bluez-hdp health-device-profile 1
+ BTHL_MDEP_ROLE_SINK 4100
+ BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter
+
+ when prompted: bluetooth ssp_reply <args>
TC_SNK_HCT_BV_05_C N/A
TC_SNK_HCT_BV_06_C PASS haltest:
hl register_application bluez-android Bluez
--
1.9.1


2014-06-30 15:31:52

by Ravi kumar Veeramally

[permalink] [raw]
Subject: [PATCH 3/5] android/health: Fix do not set mdl callbacks on mcl_reconneced call back

MDL related callbacks should be already set when creating mcl. Only
update connection status.
---
android/health.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/android/health.c b/android/health.c
index 7518dad..0327542 100644
--- a/android/health.c
+++ b/android/health.c
@@ -2001,16 +2001,17 @@ static void mcl_connected(struct mcap_mcl *mcl, gpointer data)

static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)
{
- GError *gerr = NULL;
- bool ret;
+ struct health_device *dev;

DBG("");

- ret = set_mcl_cb(mcl, NULL, &gerr);
- if (!ret) {
- error("health: error setting mcl callbacks: %s", gerr->message);
- g_error_free(gerr);
+ dev = search_dev_by_mcl(mcl);
+ if (!dev) {
+ error("device data does not exists");
+ return;
}
+
+ dev->mcl_conn = true;
}

static void mcl_disconnected(struct mcap_mcl *mcl, gpointer data)
--
1.9.1


2014-06-30 15:31:51

by Ravi kumar Veeramally

[permalink] [raw]
Subject: [PATCH 2/5] android/health: Implement mcl_uncached callback

---
android/health.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/android/health.c b/android/health.c
index 1905862..7518dad 100644
--- a/android/health.c
+++ b/android/health.c
@@ -2026,7 +2026,12 @@ static void mcl_disconnected(struct mcap_mcl *mcl, gpointer data)

static void mcl_uncached(struct mcap_mcl *mcl, gpointer data)
{
- DBG("Not implemented");
+ struct health_device *dev;
+
+ DBG("");
+
+ dev = search_dev_by_mcl(mcl);
+ free_health_device(dev);
}

bool bt_health_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
--
1.9.1


2014-06-30 15:31:53

by Ravi kumar Veeramally

[permalink] [raw]
Subject: [PATCH 4/5] android/health: Implement MDL reconnection from remote device

---
android/health.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 52 insertions(+), 4 deletions(-)

diff --git a/android/health.c b/android/health.c
index 0327542..b77ab4e 100644
--- a/android/health.c
+++ b/android/health.c
@@ -235,6 +235,14 @@ static void free_health_app(void *data)
free(app);
}

+static bool match_channel_by_mdl(const void *data, const void *user_data)
+{
+ const struct health_channel *channel = data;
+ const struct mcap_mdl *mdl = user_data;
+
+ return channel->mdl == mdl;
+}
+
static bool match_channel_by_id(const void *data, const void *user_data)
{
const struct health_channel *channel = data;
@@ -298,6 +306,7 @@ static bool match_app_by_id(const void *data, const void *user_data)
*/
struct channel_search {
uint16_t channel_id;
+ struct mcap_mdl *mdl;
struct health_channel *channel;
};

@@ -309,8 +318,13 @@ static void device_search_channel(void *data, void *user_data)
if (search->channel)
return;

- search->channel = queue_find(dev->channels, match_channel_by_id,
+ if (search->channel_id)
+ search->channel = queue_find(dev->channels, match_channel_by_id,
INT_TO_PTR(search->channel_id));
+ else if (search->mdl)
+ search->channel = queue_find(dev->channels,
+ match_channel_by_mdl,
+ search->mdl);
}

static void app_search_channel(void *data, void *user_data)
@@ -331,6 +345,21 @@ static struct health_channel *search_channel_by_id(uint16_t id)
DBG("");

search.channel_id = id;
+ search.mdl = NULL;
+ search.channel = NULL;
+ queue_foreach(apps, app_search_channel, &search);
+
+ return search.channel;
+}
+
+static struct health_channel *search_channel_by_mdl(struct mcap_mdl *mdl)
+{
+ struct channel_search search;
+
+ DBG("");
+
+ search.channel_id = 0;
+ search.mdl = mdl;
search.channel = NULL;
queue_foreach(apps, app_search_channel, &search);

@@ -1176,11 +1205,14 @@ static void mcap_mdl_connected_cb(struct mcap_mdl *mdl, void *data)
struct health_channel *channel = data;
int fd;

+ DBG("Data channel connected: mdl %p channel %p", mdl, channel);
+
+ if (!channel)
+ channel = search_channel_by_mdl(mdl);
+
if (!channel->mdl)
channel->mdl = mcap_mdl_ref(mdl);

- DBG("Data channel connected: mdl %p channel %p", mdl, channel);
-
fd = mcap_mdl_get_fd(channel->mdl);
if (fd < 0) {
error("health: error retrieving fd");
@@ -1475,7 +1507,23 @@ static uint8_t mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,

static uint8_t mcap_mdl_reconn_req_cb(struct mcap_mdl *mdl, void *data)
{
- DBG("Not Implemeneted");
+ struct health_channel *channel;
+ GError *err = NULL;
+
+ DBG("");
+
+ channel = search_channel_by_mdl(mdl);
+ if (!channel) {
+ error("health: channel data does not exist");
+ return MCAP_UNSPECIFIED_ERROR;
+ }
+
+ if (!mcap_set_data_chan_mode(mcap,
+ conf_to_l2cap(channel->type), &err)) {
+ error("health: %s", err->message);
+ g_error_free(err);
+ return MCAP_MDL_BUSY;
+ }

return MCAP_SUCCESS;
}
--
1.9.1


2014-06-30 15:31:50

by Ravi kumar Veeramally

[permalink] [raw]
Subject: [PATCH 1/5] android/health: Implement mcl_disconnected cb

Provide a utility to find device by mcl and update the
mcl status.
---
android/health.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/android/health.c b/android/health.c
index 3225617..1905862 100644
--- a/android/health.c
+++ b/android/health.c
@@ -243,6 +243,14 @@ static bool match_channel_by_id(const void *data, const void *user_data)
return channel->id == channel_id;
}

+static bool match_dev_by_mcl(const void *data, const void *user_data)
+{
+ const struct health_device *dev = data;
+ const struct mcap_mcl *mcl = user_data;
+
+ return dev->mcl == mcl;
+}
+
static bool match_dev_by_addr(const void *data, const void *user_data)
{
const struct health_device *dev = data;
@@ -329,6 +337,36 @@ static struct health_channel *search_channel_by_id(uint16_t id)
return search.channel;
}

+struct mcl_search {
+ struct mcap_mcl *mcl;
+ struct health_device *dev;
+};
+
+static void app_search_dev(void *data, void *user_data)
+{
+ struct health_app *app = data;
+ struct mcl_search *search = user_data;
+
+ if (search->dev)
+ return;
+
+ search->dev = queue_find(app->devices, match_dev_by_mcl, search->mcl);
+}
+
+static struct health_device *search_dev_by_mcl(struct mcap_mcl *mcl)
+{
+ struct mcl_search search;
+
+ DBG("");
+
+ search.mcl = mcl;
+ search.dev = NULL;
+
+ queue_foreach(apps, app_search_dev, &search);
+
+ return search.dev;
+}
+
struct app_search {
uint8_t mdepid;
struct health_app *app;
@@ -1977,7 +2015,13 @@ static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)

static void mcl_disconnected(struct mcap_mcl *mcl, gpointer data)
{
- DBG("Not implemented");
+ struct health_device *dev;
+
+ DBG("");
+
+ dev = search_dev_by_mcl(mcl);
+ if (dev)
+ dev->mcl_conn = false;
}

static void mcl_uncached(struct mcap_mcl *mcl, gpointer data)
--
1.9.1