Patshset introduces extra api in haltest tool (close_channel).
PTS test case for MDL disconnect and reconnect expects only
channel disconnection/close not deletion. It can not be called
with current HAL api. This call just shutdown specified fd, which
triggers channel disconnection. Another attempt for connection
means simply start with reconnect request.
Ravi kumar Veeramally (5):
android/client/health: Introduce close_channel API.
android/health: Implement mdl_closed_cb callback
android/health: Fix deleting channels queue
android/health: Implement mdl reconnect
android/health: Implement destroy_channel call
android/client/if-hl.c | 29 +++++++++++++++
android/health.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 122 insertions(+), 5 deletions(-)
--
1.9.1
On Fri, Jun 27, 2014 at 12:30:46AM +0300, Ravi kumar Veeramally wrote:
> Delete MDL channel with MDL_DELETE_REQ.
> ---
> android/health.c | 25 +++++++++++++++++++++++--
> 1 file changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/android/health.c b/android/health.c
> index db3ae9c..e464f78 100644
> --- a/android/health.c
> +++ b/android/health.c
> @@ -1637,19 +1637,40 @@ fail:
> HAL_OP_HEALTH_CONNECT_CHANNEL, HAL_STATUS_FAILED);
> }
>
> +static void channel_delete_cb(GError *gerr, gpointer data)
> +{
> + struct health_channel *channel = data;
> +
> + DBG("");
> +
> + if (!gerr) {
> + error("health: channel delete failed %s", gerr->message);
I think this one may not work. I have sent a patch for this issue.
Best regards
Andrei Emeltchenko
Hi Ravi,
On Friday 27 of June 2014 00:30:41 Ravi kumar Veeramally wrote:
> Patshset introduces extra api in haltest tool (close_channel).
> PTS test case for MDL disconnect and reconnect expects only
> channel disconnection/close not deletion. It can not be called
> with current HAL api. This call just shutdown specified fd, which
> triggers channel disconnection. Another attempt for connection
> means simply start with reconnect request.
>
> Ravi kumar Veeramally (5):
> android/client/health: Introduce close_channel API.
> android/health: Implement mdl_closed_cb callback
> android/health: Fix deleting channels queue
> android/health: Implement mdl reconnect
> android/health: Implement destroy_channel call
>
> android/client/if-hl.c | 29 +++++++++++++++
> android/health.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++---
> 2 files changed, 122 insertions(+), 5 deletions(-)
>
All patches applied. Thanks.
--
Best regards,
Szymon Janc
Delete MDL channel with MDL_DELETE_REQ.
---
android/health.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/android/health.c b/android/health.c
index db3ae9c..e464f78 100644
--- a/android/health.c
+++ b/android/health.c
@@ -1637,19 +1637,40 @@ fail:
HAL_OP_HEALTH_CONNECT_CHANNEL, HAL_STATUS_FAILED);
}
+static void channel_delete_cb(GError *gerr, gpointer data)
+{
+ struct health_channel *channel = data;
+
+ DBG("");
+
+ if (!gerr) {
+ error("health: channel delete failed %s", gerr->message);
+ return;
+ }
+
+ destroy_channel(channel);
+}
+
static void bt_health_destroy_channel(const void *buf, uint16_t len)
{
const struct hal_cmd_health_destroy_channel *cmd = buf;
struct health_channel *channel;
+ GError *gerr = NULL;
- DBG("Not Implemented");
+ DBG("");
channel = search_channel_by_id(cmd->channel_id);
if (!channel)
goto fail;
+ if (!mcap_delete_mdl(channel->mdl, channel_delete_cb, channel,
+ NULL, &gerr)) {
+ error("health: channel delete failed %s", gerr->message);
+ goto fail;
+ }
+
ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH,
- HAL_OP_HEALTH_DESTROY_CHANNEL, HAL_STATUS_UNSUPPORTED);
+ HAL_OP_HEALTH_DESTROY_CHANNEL, HAL_STATUS_SUCCESS);
return;
--
1.9.1
Callback will be called when data channel is disconnected/closed.
It does not mean that it is deleted. So only change connected status.
---
android/health.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/android/health.c b/android/health.c
index 30a6166..3afdf9b 100644
--- a/android/health.c
+++ b/android/health.c
@@ -1057,7 +1057,14 @@ static void mcap_mdl_connected_cb(struct mcap_mdl *mdl, void *data)
static void mcap_mdl_closed_cb(struct mcap_mdl *mdl, void *data)
{
- DBG("Not Implemeneted");
+ struct health_channel *channel = data;
+
+ info("MDL closed");
+
+ if (!channel)
+ return;
+
+ channel->mdl_conn = false;
}
static void notify_channel(void *data, void *user_data)
--
1.9.1
Channels queue is created only on device creation. So do not destroy
queue on all mdls deleted in mdl_deleted_cb, just remove all entries.
---
android/health.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/health.c b/android/health.c
index 3afdf9b..717e9a6 100644
--- a/android/health.c
+++ b/android/health.c
@@ -1088,8 +1088,8 @@ static void mcap_mdl_deleted_cb(struct mcap_mdl *mdl, void *data)
/* mdl == NULL means, delete all mdls */
if (!mdl) {
queue_foreach(dev->channels, notify_channel, NULL);
- queue_destroy(dev->channels, free_health_channel);
- dev->channels = NULL;
+ queue_remove_all(dev->channels, NULL, NULL,
+ free_health_channel);
return;
}
--
1.9.1
MDL reconnection can be called only when it is already created, connected
and closed not deleted.
---
android/health.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/android/health.c b/android/health.c
index 717e9a6..db3ae9c 100644
--- a/android/health.c
+++ b/android/health.c
@@ -1147,6 +1147,59 @@ fail:
destroy_channel(channel);
}
+static void reconnect_mdl_cb(struct mcap_mdl *mdl, GError *gerr, gpointer data)
+{
+ struct health_channel *channel = data;
+ uint8_t mode;
+ GError *err = NULL;
+
+ DBG("");
+
+ if (gerr) {
+ error("health: error reconnecting to MDL %s", gerr->message);
+ goto fail;
+ }
+
+ channel->mdl_id = mcap_mdl_get_mdlid(mdl);
+
+ if (channel->type == CHANNEL_TYPE_RELIABLE)
+ mode = L2CAP_MODE_ERTM;
+ else
+ mode = L2CAP_MODE_STREAMING;
+
+ if (!mcap_connect_mdl(channel->mdl, mode, channel->dev->dcpsm,
+ connect_mdl_cb, channel,
+ NULL, &err)) {
+ error("health: error connecting to mdl");
+ g_error_free(err);
+ goto fail;
+ }
+
+ return;
+
+fail:
+ /* TODO: mcap_mdl_abort */
+ destroy_channel(channel);
+}
+
+static int reconnect_mdl(struct health_channel *channel)
+{
+ GError *gerr = NULL;
+
+ DBG("");
+
+ if (!channel)
+ return -1;
+
+ if (!mcap_reconnect_mdl(channel->mdl, reconnect_mdl_cb, channel,
+ NULL, &gerr)){
+ error("health: reconnect failed %s", gerr->message);
+ destroy_channel(channel);
+ }
+
+ return 0;
+}
+
static void create_mdl_cb(struct mcap_mdl *mdl, uint8_t type, GError *gerr,
gpointer data)
{
@@ -1563,6 +1616,13 @@ static void bt_health_connect_channel(const void *buf, uint16_t len)
/* create mdl if it does not exists */
if (!channel->mdl && get_mdep(channel) < 0)
goto fail;
+
+ /* reconnect mdl if it exists */
+ if (channel->mdl && !channel->mdl_conn) {
+ if (reconnect_mdl(channel) < 0)
+ goto fail;
+ }
+
}
rsp.channel_id = channel->id;
--
1.9.1
In order to run PTS MDL disconnect and reconnect, HAL api does
not support it. This close simply shutdown the fd, remote device
will be notified like data channel is closed not deleted. So ready
for reconnection.
---
android/client/if-hl.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/android/client/if-hl.c b/android/client/if-hl.c
index 34e8b27..949c574 100644
--- a/android/client/if-hl.c
+++ b/android/client/if-hl.c
@@ -275,6 +275,34 @@ static void destroy_channel_p(int argc, const char **argv)
EXEC(if_hl->destroy_channel, channel_id);
}
+/* close_channel */
+
+static void close_channel_p(int argc, const char **argv)
+{
+ uint32_t app_id;
+ uint8_t mdep_cfg_index;
+
+ RETURN_IF_NULL(if_hl);
+
+ if (argc <= 2) {
+ haltest_error("No app id is specified");
+ return;
+ }
+
+ if (argc <= 3) {
+ haltest_error("No mdep_cfg_index is specified");
+ return;
+ }
+
+ app_id = (uint32_t) atoi(argv[2]);
+ mdep_cfg_index = (uint8_t) atoi(argv[3]);
+
+ if (app_info[app_id][mdep_cfg_index][2] >= 0) {
+ shutdown(app_info[app_id][mdep_cfg_index][2], SHUT_RDWR);
+ app_info[app_id][mdep_cfg_index][2] = -1;
+ }
+}
+
/* cleanup */
static void cleanup_p(int argc, const char **argv)
@@ -295,6 +323,7 @@ static struct method methods[] = {
STD_METHODH(unregister_application, "<app_id>"),
STD_METHODH(connect_channel, "<app_id> <bd_addr> <mdep_cfg_index>"),
STD_METHODH(destroy_channel, "<channel_id>"),
+ STD_METHODH(close_channel, "<app_id> <mdep_cfg_index>"),
STD_METHOD(cleanup),
END_METHOD
};
--
1.9.1