diff --git a/android/health.c b/android/health.c
index 8e4ad56..0b86d0f 100644
--- a/android/health.c
+++ b/android/health.c
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;
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:
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;
}