summaryrefslogtreecommitdiff
path: root/android/health.c
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2014-06-30 15:53:44 +0300
committerSzymon Janc <szymon.janc@tieto.com>2014-06-30 15:13:57 +0200
commit147049dac962a4a8698fa70a9eb45203100817a3 (patch)
tree5cd84c1462e248b92870f8077f93c642a3dfc6e0 /android/health.c
parentd0b936a26c09065a9568e4593965a3ea6ce476d9 (diff)
downloadbluez-147049dac962a4a8698fa70a9eb45203100817a3.tar.gz
android/health: Set L2CAP mode for MCAP channels
Check configuration and set L2CAP mode. Enables several PTS test cases.
Diffstat (limited to 'android/health.c')
-rw-r--r--android/health.c75
1 files changed, 60 insertions, 15 deletions
diff --git a/android/health.c b/android/health.c
index 8e4ad5680..0b86d0fcc 100644
--- a/android/health.c
+++ b/android/health.c
@@ -1297,24 +1297,18 @@ static struct health_channel *create_channel(struct health_app *app,
return channel;
}
-static struct health_channel *connect_channel(struct mcap_mcl *mcl,
- uint8_t mdepid)
+static struct health_channel *connect_channel(struct health_app *app,
+ struct mcap_mcl *mcl,
+ uint8_t mdepid)
{
- struct health_app *app;
struct health_device *device;
struct health_channel *channel = NULL;
bdaddr_t addr;
- DBG("mcl %p mdepid %u", mcl, mdepid);
+ DBG("app %p mdepid %u", app, mdepid);
mcap_mcl_get_addr(mcl, &addr);
- if (mdepid == MDEP_ECHO)
- /* For echo service take last app */
- app = queue_peek_tail(apps);
- else
- app = search_app_by_mdepid(mdepid);
-
if (!app) {
DBG("No app found for mdepid %u", mdepid);
return NULL;
@@ -1326,25 +1320,41 @@ static struct health_channel *connect_channel(struct mcap_mcl *mcl,
channel = create_channel(app, mdepid, device);
- /* Channel is assigned here after creation */
- mcl->cb->user_data = channel;
-
return channel;
}
+static uint8_t conf_to_l2cap(uint8_t conf)
+{
+ return conf == CHANNEL_TYPE_STREAM ? L2CAP_MODE_STREAMING :
+ L2CAP_MODE_ERTM;
+}
+
static uint8_t mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
uint16_t mdlid, uint8_t *conf, void *data)
{
GError *gerr = NULL;
struct health_channel *channel;
+ struct health_app *app;
+ struct mdep_cfg *mdep;
DBG("Data channel request: mdepid %u mdlid %u", mdepid, mdlid);
- /* TODO: find / create device */
- channel = connect_channel(mcl, mdepid);
+ if (mdepid == MDEP_ECHO)
+ /* For echo service take last app */
+ app = queue_peek_tail(apps);
+ else
+ app = search_app_by_mdepid(mdepid);
+
+ if (!app)
+ return MCAP_MDL_BUSY;
+
+ channel = connect_channel(app, mcl, mdepid);
if (!channel)
return MCAP_MDL_BUSY;
+ /* Channel is assigned here after creation */
+ mcl->cb->user_data = channel;
+
if (mdepid == MDEP_ECHO) {
switch (*conf) {
case CHANNEL_TYPE_ANY:
@@ -1375,6 +1385,41 @@ static uint8_t mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
return MCAP_SUCCESS;
}
+ mdep = queue_find(app->mdeps, match_mdep_by_id, INT_TO_PTR(mdepid));
+ if (!mdep)
+ return MCAP_MDL_BUSY;
+
+ switch (*conf) {
+ case CHANNEL_TYPE_ANY:
+ if (mdep->role == HAL_HEALTH_MDEP_ROLE_SINK)
+ return MCAP_CONFIGURATION_REJECTED;
+ else
+ *conf = CHANNEL_TYPE_RELIABLE;
+ break;
+ case CHANNEL_TYPE_STREAM:
+ if (mdep->role == HAL_HEALTH_MDEP_ROLE_SOURCE)
+ return MCAP_CONFIGURATION_REJECTED;
+ break;
+ case CHANNEL_TYPE_RELIABLE:
+ if (mdep->role == HAL_HEALTH_MDEP_ROLE_SOURCE)
+ return MCAP_CONFIGURATION_REJECTED;
+ break;
+ default:
+ /*
+ * Special case defined in HDP spec 3.4. When an invalid
+ * configuration is received we shall close the MCL when
+ * we are still processing the callback.
+ */
+ /* TODO: close device */
+ return MCAP_CONFIGURATION_REJECTED; /* not processed */
+ }
+
+ if (!mcap_set_data_chan_mode(mcap, conf_to_l2cap(*conf), &gerr)) {
+ error("health: error setting L2CAP mode: %s", gerr->message);
+ g_error_free(gerr);
+ return MCAP_MDL_BUSY;
+ }
+
return MCAP_SUCCESS;
}