Merge "snd-card-parser: avoid virtual card info returned improperly"
diff --git a/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp b/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp
index 520a2af..9b2d1d0 100644
--- a/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp
+++ b/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp
@@ -451,6 +451,10 @@
         uint32_t num = (uint32_t) *num_aif_info;
         int ret = -EINVAL;
         android::sp<IAGM> agm_client = get_agm_server();
+
+        if (!agm_client) {
+            goto error_exit_fn;
+        }
         auto status = agm_client->ipc_agm_get_aif_info_list(num,[&](int32_t _ret,
                                             hidl_vec<AifInfo> aif_list_ret_hidl,
                                             uint32_t num_aif_info_hidl )
@@ -475,6 +479,7 @@
         }
         return ret;
     }
+error_exit_fn:
     return -EINVAL;
 }
 
diff --git a/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp b/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
index b8dd8c7..78b83f0 100644
--- a/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
+++ b/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
@@ -541,6 +541,10 @@
     ALOGV("%s called with aif_id = %d, size = %d\n", __func__, aif_id, size);
     uint8_t * metadata_l = NULL;
     int32_t ret = 0;
+
+    if (metadata.size() < size) {
+        return -EINVAL;
+    }
     metadata_l = (uint8_t *) calloc(1,size);
     if (metadata_l == NULL) {
         ALOGE("%s: Cannot allocate memory for metadata_l\n", __func__);
@@ -558,6 +562,11 @@
     ALOGV("%s : session_id = %d, size = %d\n", __func__, session_id, size);
     uint8_t * metadata_l = NULL;
     int32_t ret = 0;
+
+    if (metadata.size() < size) {
+        return -EINVAL;
+    }
+
     metadata_l = (uint8_t *) calloc(1,size);
     if (metadata_l == NULL) {
         ALOGE("%s: Cannot allocate memory for metadata_l\n", __func__);
@@ -581,6 +590,11 @@
                                                       session_id, aif_id, size);
     uint8_t * metadata_l = NULL;
     int32_t ret = 0;
+
+    if (metadata.size() < size) {
+        return -EINVAL;
+    }
+
     metadata_l = (uint8_t *) calloc(1,size);
     if (metadata_l == NULL) {
         ALOGE("%s: Cannot allocate memory for metadata_l\n", __func__);
@@ -652,6 +666,11 @@
     int32_t ret = 0;
     hidl_vec<uint8_t> payload_hidl;
 
+     if (buff.size() < size) {
+        _hidl_cb(-EINVAL, size);
+        return Void();
+    }
+
     payload_local = (uint8_t *) calloc (1, size);
     if (payload_local == NULL) {
         ALOGE("%s: Cannot allocate memory for payload_local\n", __func__);
@@ -707,6 +726,11 @@
     int32_t ret = 0;
 
     ALOGV("%s : aif_id =%d, size = %d\n", __func__, aif_id, size);
+
+    if (payload.size() < size) {
+        return -EINVAL;
+    }
+
     payload_local = (void*) calloc (1,size);
     if (payload_local == NULL) {
         ALOGE("%s: calloc failed for payload_local\n", __func__);
@@ -727,6 +751,11 @@
     size_t size_local = (size_t) size;
     void * payload_local = NULL;
     int32_t ret = 0;
+
+    if (payload.size() < size) {
+        return -EINVAL;
+    }
+
     payload_local = (void*) calloc (1,size);
     if (payload_local == NULL) {
         ALOGE("%s: Cannot allocate memory for payload_local\n", __func__);
@@ -778,6 +807,11 @@
     size_t size_local = (size_t) size;
     void * payload_local = NULL;
     int32_t ret = 0;
+
+    if (payload.size() < size) {
+        return -EINVAL;
+    }
+
     payload_local = (void*) calloc (1,size);
     if (payload_local == NULL) {
         ALOGE("%s: Cannot allocate memory for payload_local\n", __func__);
@@ -826,6 +860,10 @@
     size_t size_local = (size_t) size;
     void * payload_local = NULL;
     int32_t ret = 0;
+
+    if (payload.size() < size) {
+        return -EINVAL;
+    }
     payload_local = (void*) calloc(1,size);
     if (payload_local == NULL) {
         ALOGE("%s: Cannot allocate memory for payload_local\n", __func__);
@@ -1070,6 +1108,12 @@
                                         ipc_agm_session_write_cb _hidl_cb) {
     ALOGV("%s called with handle = %llx \n", __func__, (unsigned long long) hndl);
     void* buffer = NULL;
+
+    if (buff.size() < count) {
+        _hidl_cb(-EINVAL, count);
+        return Void();
+    }
+
     buffer = (void*) calloc(1,count);
     if (buffer == NULL) {
         ALOGE("%s: Cannot allocate memory for buffer\n", __func__);
@@ -1419,6 +1463,10 @@
     buf.addr = nullptr;
     buf.metadata = nullptr;
 
+    if (buff_hidl.data()->metadata.size() < buff_hidl.data()->metadata_size) {
+        _hidl_cb(-EINVAL, buff_hidl.data()->metadata_size);
+        return Void();
+    }
     bufSize = buff_hidl.data()->size;
     buf.addr = (uint8_t *)calloc(1, bufSize);
     if (!buf.addr) {
diff --git a/ipc/SwBinders/agm_server/src/ipc_proxy_server.cpp b/ipc/SwBinders/agm_server/src/ipc_proxy_server.cpp
index 2840a1c..82cd647 100644
--- a/ipc/SwBinders/agm_server/src/ipc_proxy_server.cpp
+++ b/ipc/SwBinders/agm_server/src/ipc_proxy_server.cpp
@@ -1190,11 +1190,27 @@
         clbk_data_obj->client_data = (void *)data.readInt64();
         sp<IBinder> binder = data.readStrongBinder();
         clbk_data_obj->cb_binder = interface_cast<ICallback>(binder);
-        list_add_tail(&clbk_data_list, &clbk_data_obj->list);
-        pthread_mutex_unlock(&clbk_data_list_lock);
+        if (clbk_data_obj->cb_func != NULL) {
+            list_add_tail(&clbk_data_list, &clbk_data_obj->list);
+            rc = ipc_agm_session_register_cb(clbk_data_obj->session_id,
+                            &ipc_cb, evnt, clbk_data_obj->client_data);
+        } else {
+            clbk_data *clbk_data_obj_tmp = NULL;
+            struct listnode *node = NULL, *next = NULL;
+            list_for_each_safe(node, next, &clbk_data_list) {
+                clbk_data_obj_tmp = node_to_item(node, clbk_data, list);
+                if ((clbk_data_obj_tmp->session_id == clbk_data_obj->session_id) &&
+                    (clbk_data_obj_tmp->client_data == clbk_data_obj->client_data)) {
+                    list_remove(&clbk_data_obj_tmp->list);
+                    free(clbk_data_obj_tmp);
+                }
+            }
+            rc = ipc_agm_session_register_cb(clbk_data_obj->session_id,
+                            NULL, evnt, clbk_data_obj->client_data);
+            free(clbk_data_obj);
+        }
 
-        rc = ipc_agm_session_register_cb(clbk_data_obj->session_id,
-                        &ipc_cb, evnt, clbk_data_obj->client_data);
+        pthread_mutex_unlock(&clbk_data_list_lock);
         reply->writeInt32(rc);
         break ; }
 
diff --git a/plugins/tinyalsa/src/agm_pcm_plugin.c b/plugins/tinyalsa/src/agm_pcm_plugin.c
index 92c53ce..92561fc 100644
--- a/plugins/tinyalsa/src/agm_pcm_plugin.c
+++ b/plugins/tinyalsa/src/agm_pcm_plugin.c
@@ -59,7 +59,8 @@
 #define AGM_PULL_PUSH_IDX_RETRY_COUNT 2
 #define AGM_PULL_PUSH_FRAME_CNT_RETRY_COUNT 5
 
-#define SNDCARD_PATH "/sys/kernel/snd_card/card_state"
+/* multiplier of timeout for wating for mmap buffers */
+#define MMAP_TOUT_MULTI 4
 
 struct agm_shared_pos_buffer {
     volatile uint32_t frame_counter;
@@ -100,7 +101,7 @@
     /* idx: 0: out port, 1: in port */
     struct agm_mmap_buffer_port mmap_buffer_port[2];
     bool mmap_status;
-    int fd;
+    uint32_t mmap_buf_tout;
 };
 
 struct pcm_plugin_hw_constraints agm_pcm_constrs = {
@@ -310,28 +311,6 @@
     return -EAGAIN;
 }
 
-static int agm_pcm_plugin_get_card_status(struct agm_pcm_priv *priv)
-{
-    char buf[10];
-    int card_status = -1;
-
-    if (priv->fd < 0) {
-         if ((priv->fd = open(SNDCARD_PATH, O_RDWR)) < 0) {
-             AGM_LOGE(LOG_TAG, "Open failed snd sysfs node");
-             errno = ENETRESET;
-             return -ENETRESET;
-        }
-        AGM_LOGD(LOG_TAG, "Snd sysfs node open successful");
-    }
-
-    memset(buf, 0, sizeof(buf));
-    read(priv->fd, buf, 1);
-    lseek(priv->fd, 0L, SEEK_SET);
-    sscanf(buf, "%d", &card_status);
-
-    return card_status;
-}
-
 static int agm_pcm_plugin_update_hw_ptr(struct agm_pcm_priv *priv)
 {
     int retries = 10;
@@ -340,18 +319,12 @@
     uint32_t read_index, wall_clk_msw, wall_clk_lsw;
     int64_t delta_wall_clk_us = 0;
     uint32_t delta_wall_clk_frames = 0;
+    uint64_t sub_res = 0;
     int ret = 0;
     uint32_t period_size = priv->period_size; /** in frames */
     uint32_t crossed_boundary = 0;
-    int card_status = -1;
     uint32_t old_frame_counter = priv->pos_buf->frame_counter;
 
-    card_status = agm_pcm_plugin_get_card_status(priv);
-    if (card_status != 1) {    // 1 assume to be snd card status online
-        AGM_LOGE("%s: Snd card is Offline\n", __func__);
-        errno = ENETRESET;
-        return -ENETRESET;
-    }
     do {
         ret = agm_pcm_plugin_get_shared_pos(priv->pos_buf,
                 &read_index, &wall_clk_msw, &wall_clk_lsw);
@@ -371,7 +344,8 @@
                                          priv->pos_buf->wall_clk_lsw);
             // Compute delta only if diff is greater than zero
             if (dsp_wall_clk > cached_wall_clk) {
-                delta_wall_clk_us = (int64_t)(dsp_wall_clk - cached_wall_clk);
+                __builtin_usubl_overflow(dsp_wall_clk,cached_wall_clk,&sub_res);
+                delta_wall_clk_us = (int64_t)sub_res;
             }
         }
         // Identify the number of times of shared buffer length that the
@@ -725,10 +699,6 @@
             close(priv->buf_info->data_buf_fd);
         free(priv->buf_info);
     }
-    if (priv->fd >= 0) {
-        close(priv->fd);
-        priv->fd = -1;
-    }
     free(plugin->priv);
     free(plugin);
 
@@ -765,6 +735,7 @@
     uint32_t period_size = priv->period_size;
     snd_pcm_sframes_t avail;
     int ret = 0;
+    uint32_t period_to_msec = period_size / (priv->media_config->rate / 1000);
 
     avail = agm_pcm_get_avail(plugin);
 
@@ -775,8 +746,6 @@
         ret = agm_pcm_plugin_update_hw_ptr(priv);
         if (ret == 0)
             avail = agm_pcm_get_avail(plugin);
-        else if (ret == -ENETRESET)
-            return ret;
     }
 
     if (avail >= period_size) {
@@ -787,8 +756,16 @@
             pfd->revents = POLLOUT;
             ret = POLLOUT;
         }
+        priv->mmap_buf_tout = 0;
     } else {
         ret = 0; /* TIMEOUT */
+        priv->mmap_buf_tout += timeout;
+        if (priv->mmap_buf_tout > (period_to_msec * MMAP_TOUT_MULTI)) {
+            AGM_LOGE("timeout in waiting for mmap buffer");
+            priv->mmap_buf_tout = 0;
+            errno = ETIMEDOUT;
+            return -ETIMEDOUT;
+        }
     }
 
     return ret;
@@ -965,13 +942,6 @@
         goto err_buf_free;
     }
 
-    priv->fd = -1;
-    if ((priv->fd = open(SNDCARD_PATH, O_RDWR)) < 0) {
-        AGM_LOGE(LOG_TAG, "Open failed snd sysfs node");
-        ret = -EINVAL;
-        goto err_session_free;
-    }
-
     card_node = snd_card_def_get_card(card);
     if (!card_node) {
         ret = -EINVAL;
@@ -1019,10 +989,6 @@
 err_card_put:
     snd_card_def_put_card(card_node);
 err_session_free:
-    if (priv->fd >= 0) {
-        close(priv->fd);
-        priv->fd = -1;
-    }
     free(session_config);
 err_buf_free:
     free(buffer_config);
diff --git a/service/inc/private/agm/device.h b/service/inc/private/agm/device.h
index 7fda4a3..9bd6a08 100644
--- a/service/inc/private/agm/device.h
+++ b/service/inc/private/agm/device.h
@@ -89,6 +89,7 @@
 #define  PCM_RT_PROXY               0x7
 #define  AUDIOSS_DMA                0x8
 #define  PCM_DUMMY                  0x9
+#define  BTFM_PROXY                 0xa
 
 #define  AUDIO_OUTPUT               0x1 /**< playback usecases*/
 #define  AUDIO_INPUT                0x2 /**< capture/voice activation usecases*/
diff --git a/service/src/agm.c b/service/src/agm.c
index bc8bb0c..f56e7a4 100644
--- a/service/src/agm.c
+++ b/service/src/agm.c
@@ -648,6 +648,9 @@
     struct session_obj *obj = NULL;
     int ret = 0;
 
+    AGM_LOGI("%sconnecting aifid:%d with session id=%d\n",
+                                      (state ? "": "dis"), aif_id, session_id);
+
     ret = session_obj_get(session_id, &obj);
     if (ret) {
         AGM_LOGE("Error:%d retrieving session obj with session id=%d\n",
diff --git a/service/src/device.c b/service/src/device.c
index 808b927..5d509bc 100644
--- a/service/src/device.c
+++ b/service/src/device.c
@@ -738,9 +738,11 @@
 {
    int ret = 0;
 
+   AGM_LOGI("Setting device metadata for %s\n", dev_obj->name);
    pthread_mutex_lock(&dev_obj->lock);
    metadata_free(&dev_obj->metadata);
    ret = metadata_copy(&(dev_obj->metadata), size, metadata);
+   metadata_print(&(dev_obj->metadata));
    pthread_mutex_unlock(&dev_obj->lock);
 
    return ret;
diff --git a/service/src/device_hw_ep.c b/service/src/device_hw_ep.c
index 155f0a0..bee6bce 100644
--- a/service/src/device_hw_ep.c
+++ b/service/src/device_hw_ep.c
@@ -178,6 +178,8 @@
         hw_ep_info->intf = AUDIOSS_DMA;
     else if (!strcmp(intf, "PCM_DUMMY"))
         hw_ep_info->intf = PCM_DUMMY;
+    else if (!strcmp(intf, "BTFM_PROXY"))
+        hw_ep_info->intf = BTFM_PROXY;
     else {
         AGM_LOGE("No matching intf found\n");
         return -EINVAL;
@@ -232,7 +234,7 @@
 
 }
 
-static int populate_pcm_rt_proxy_ep_info(hw_ep_info_t *hw_ep_info, char *value)
+static int populate_btfm_rt_proxy_ep_info(hw_ep_info_t *hw_ep_info, char *value)
 {
     char arg[DEV_ARG_SIZE] = {0};
     struct hw_ep_pcm_rt_proxy_config *pcm_rt_proxy_config;
@@ -410,7 +412,8 @@
     case USB_AUDIO:
         return populate_slim_dp_usb_ep_info(&dev_obj->hw_ep_info, value);
     case PCM_RT_PROXY:
-        return populate_pcm_rt_proxy_ep_info(&dev_obj->hw_ep_info, value);
+    case BTFM_PROXY:
+        return populate_btfm_rt_proxy_ep_info(&dev_obj->hw_ep_info, value);
     case AUDIOSS_DMA:
         return populate_audioss_dma_ep_info(&dev_obj->hw_ep_info, value);
     case PCM_DUMMY:
diff --git a/service/src/graph.c b/service/src/graph.c
index 0e79b8c..481baa2 100644
--- a/service/src/graph.c
+++ b/service/src/graph.c
@@ -538,6 +538,7 @@
     size_t arraysize = 0;
     module_info_t *stream_module_list = NULL;
     module_info_t *hw_ep_module = NULL;
+    module_info_t *add_module = NULL;
 
     list_declare(node_sess);
     list_init(&node_sess);
@@ -616,10 +617,16 @@
                         goto free_graph_obj;
                     }
                     mod = mod_list->data;
-                    mod->miid = gsl_tag_entry->module_entry[0].module_iid;
-                    mod->mid = gsl_tag_entry->module_entry[0].module_id;
-                    AGM_LOGD("miid %x mid %x tag %x", mod->miid, mod->mid, mod->tag);
-                    ADD_MODULE(*mod, NULL);
+                    add_module = ADD_MODULE(*mod, NULL);
+                    if (!add_module) {
+                        AGM_LOGE("no memory to allocate add_module");
+                        ret = -ENOMEM;
+                        goto free_graph_obj;
+                    }
+                    add_module->miid = gsl_tag_entry->module_entry[0].module_iid;
+                    add_module->mid = gsl_tag_entry->module_entry[0].module_id;
+                    add_module->gkv = NULL;
+                    AGM_LOGD("miid %x mid %x tag %x", add_module->miid, add_module->mid, add_module->tag);
                     goto tag_list;
                 }
             }
@@ -641,8 +648,14 @@
                         goto free_graph_obj;
                     }
                     mod = mod_list->data;
-                    mod->miid = gsl_tag_entry->module_entry[0].module_iid;
-                    mod->mid = gsl_tag_entry->module_entry[0].module_id;
+                    add_module = ADD_MODULE(*mod, dev_obj);
+                    if (!add_module) {
+                        AGM_LOGE("no memory to allocate add_module");
+                        ret = -ENOMEM;
+                        goto free_graph_obj;
+                    }
+                    add_module->miid = gsl_tag_entry->module_entry[0].module_iid;
+                    add_module->mid = gsl_tag_entry->module_entry[0].module_id;
                     /*store GKV which describes/contains this module*/
                     gkv = calloc(1, sizeof(struct agm_key_vector_gsl));
                     if (!gkv) {
@@ -660,9 +673,8 @@
                     }
                     memcpy(gkv->kv, meta_data_kv->gkv.kv,
                           gkv->num_kvs * sizeof(struct agm_key_value));
-                    mod->gkv = gkv;
-                    AGM_LOGD("miid %x mid %x tag %x", mod->miid, mod->mid, mod->tag);
-                    ADD_MODULE(*mod, dev_obj);
+                    add_module->gkv = gkv;
+                    AGM_LOGD("miid %x mid %x tag %x", add_module->miid, add_module->mid, add_module->tag);
                     goto tag_list;
                 }
             }
@@ -919,6 +931,7 @@
     }
 
     if (meta_data) {
+        metadata_print(meta_data);
         memcpy (&(gsl_cmd_prop.gkv), &(meta_data->gkv),
                                        sizeof(struct gsl_key_vector));
         gsl_cmd_prop.property_id = meta_data->sg_props.prop_id;
@@ -1186,7 +1199,7 @@
     size_t size = 0;
     struct gsl_tag_module_info *tag_info;
     struct gsl_tag_module_info_entry *tag_entry;
-    uint32_t offset = 0;
+    uint32_t offset = 0, temp_sum = 0;
     uint32_t total_parsed_size = 0;
     uint8_t tag_pool[TAGGED_MOD_SIZE_BYTES] = { 0 };
 
@@ -1268,9 +1281,10 @@
         payloadACDBTunnelInfo->num_gkvs * sizeof(struct agm_key_value);
 
     AGM_LOGD("blob size = %d", payloadACDBTunnelInfo->blob_size);
-    actual_size = payloadACDBTunnelInfo->blob_size -
-        (payloadACDBTunnelInfo->num_gkvs + payloadACDBTunnelInfo->num_kvs) *
-                sizeof(struct agm_key_value);
+    __builtin_add_overflow(payloadACDBTunnelInfo->num_gkvs * sizeof(struct agm_key_value),
+            payloadACDBTunnelInfo->num_kvs * sizeof(struct agm_key_value),
+            &temp_sum);
+    __builtin_sub_overflow(payloadACDBTunnelInfo->blob_size, temp_sum, &actual_size);
     AGM_LOGD("actual size = 0x%x", actual_size);
     AGM_LOGI("num kvs = %d", kv.num_kvs);
     ptr = kv.kv;
@@ -1457,6 +1471,7 @@
         bool mod_present = false;
         size_t arraysize;
         module_info_t *hw_ep_module = NULL;
+        module_info_t *add_module = NULL;
 
         get_hw_ep_module_list_array(&hw_ep_module, &arraysize);
         if (dev_obj->hw_ep_info.dir == AUDIO_OUTPUT)
@@ -1474,8 +1489,6 @@
                           mod->tag);
             goto done;
         }
-        mod->miid = module_info->module_entry[0].module_iid;
-        mod->mid = module_info->module_entry[0].module_id;
         /**
          *Check if this is the same device object as was passed for graph open
          *or a new one.We do this by comparing the module_iid of the module
@@ -1484,7 +1497,7 @@
          */
         list_for_each(node, &graph_obj->tagged_mod_list) {
             temp_mod = node_to_item(node, module_info_t, list);
-            if (temp_mod->miid == mod->miid) {
+            if (temp_mod->miid == module_info->module_entry[0].module_iid) {
                 mod_present = true;
                 /**
                  * Module might have configured previously as we don't reset in
@@ -1501,6 +1514,14 @@
              */
             /*Make a local copy of gkv and use when we query gsl
             for tagged data*/
+            add_module = ADD_MODULE(*mod, dev_obj);
+            if (!add_module) {
+                AGM_LOGE("no memory to allocate add_module");
+                ret = -ENOMEM;
+                goto done;
+            }
+            add_module->miid = module_info->module_entry[0].module_iid;
+            add_module->mid = module_info->module_entry[0].module_id;
             gkv = calloc(1, sizeof(struct agm_key_vector_gsl));
             if (!gkv) {
                 AGM_LOGE("No memory to allocate for gkv\n");
@@ -1517,11 +1538,10 @@
             }
             memcpy(gkv->kv, meta_data_kv->gkv.kv,
                     gkv->num_kvs * sizeof(struct agm_key_value));
-            mod->gkv = gkv;
+            add_module->gkv = gkv;
             gkv = NULL;
             AGM_LOGD("Adding the new module tag %x mid %x miid %x\n",
-                                    mod->tag, mod->mid, mod->miid);
-            ADD_MODULE(*mod, dev_obj);
+                    add_module->tag, add_module->mid, add_module->miid);
         }
     }
     /* Configure the newly added modules only if graph is in start state,
diff --git a/service/src/graph_module.c b/service/src/graph_module.c
index f77aa0f..1a0cb70 100644
--- a/service/src/graph_module.c
+++ b/service/src/graph_module.c
@@ -744,10 +744,11 @@
     int ret = 0;
     struct device_obj *dev_obj = mod->dev_obj;
 
-    if(dev_obj->hw_ep_info.intf == PCM_RT_PROXY || dev_obj->hw_ep_info.intf == PCM_DUMMY) {
+    if ((dev_obj->hw_ep_info.intf == PCM_RT_PROXY) ||
+        (dev_obj->hw_ep_info.intf == PCM_DUMMY) ||
+        (dev_obj->hw_ep_info.intf == BTFM_PROXY)) {
         AGM_LOGD("no ep media config for %d\n",  dev_obj->hw_ep_info.intf);
-    }
-    else {
+    } else {
         ret = configure_hw_ep_media_config(mod, graph_obj);
         if (ret) {
             AGM_LOGE("hw_ep_media_config failed %d", ret);
@@ -772,19 +773,15 @@
          break;
     case DISPLAY_PORT:
     case USB_AUDIO:
-        AGM_LOGD("no ep configuration for %d\n",  dev_obj->hw_ep_info.intf);
-        break;
     case PCM_RT_PROXY:
-        AGM_LOGD("no ep configuration for %d\n",  dev_obj->hw_ep_info.intf);
-        break;
     case AUDIOSS_DMA:
-        AGM_LOGD("no ep configuration for %d\n",  dev_obj->hw_ep_info.intf);
-        break;
     case PCM_DUMMY:
+    case BTFM_PROXY:
         AGM_LOGD("no ep configuration for %d\n",  dev_obj->hw_ep_info.intf);
         break;
     default:
          AGM_LOGE("hw intf %d not enabled yet", dev_obj->hw_ep_info.intf);
+         ret = -EINVAL;
          break;
     }
     return ret;
diff --git a/service/src/session_obj.c b/service/src/session_obj.c
index be3591a..7809de4 100644
--- a/service/src/session_obj.c
+++ b/service/src/session_obj.c
@@ -1081,7 +1081,7 @@
 
         pthread_mutex_lock(&hwep_lock);
 
-        //For Slimbus EP - First configure the slave ports via device_prepare/start
+        //For Slimbus/CP EP - First configure the slave ports via device_prepare/start
         //and then start the master side via graph_start.
         list_for_each(node, &sess_obj->aif_pool) {
             aif_obj = node_to_item(node, struct aif, node);
@@ -1090,8 +1090,9 @@
                 goto device_stop;
             }
 
-            if (aif_obj->dev_obj->hw_ep_info.intf == SLIMBUS) {
-                AGM_LOGD("configuring device early - for SLIMBUS EPs\n");
+            if ((aif_obj->dev_obj->hw_ep_info.intf == SLIMBUS) ||
+                (aif_obj->dev_obj->hw_ep_info.intf == BTFM_PROXY)) {
+                AGM_LOGD("configuring device early - for SLIMBUS/Connectivity Proxy EPs\n");
                 if (aif_obj->state == AIF_OPENED || aif_obj->state == AIF_STOPPED) {
                     ret = device_prepare(aif_obj->dev_obj);
                     if (ret) {
@@ -1128,9 +1129,11 @@
                 goto unwind;
             }
 
-            //Continue/SKIP for SLIMBUS EP as they are started early.
-            if (aif_obj->dev_obj->hw_ep_info.intf == SLIMBUS)
+            //Continue/SKIP for SLIMBUS/Connectivity Proxy EP as they are started early.
+            if ((aif_obj->dev_obj->hw_ep_info.intf == SLIMBUS) ||
+                (aif_obj->dev_obj->hw_ep_info.intf == BTFM_PROXY)) {
                 continue;
+            }
 
             if (aif_obj->state == AIF_OPENED || aif_obj->state == AIF_STOPPED) {
                 ret = device_prepare(aif_obj->dev_obj);
@@ -1254,6 +1257,7 @@
     struct aif *aif_obj = NULL;
     enum agm_session_mode sess_mode = sess_obj->stream_config.sess_mode;
     struct listnode *node = NULL;
+    struct listnode *next = NULL;
 
     AGM_LOGD("enter");
     if (sess_obj->state == SESSION_CLOSED) {
@@ -1279,7 +1283,7 @@
     sess_obj->loopback_state = false;
 
     if (sess_mode != AGM_SESSION_NON_TUNNEL  && sess_mode != AGM_SESSION_NO_CONFIG) {
-        list_for_each(node, &sess_obj->aif_pool) {
+        list_for_each_safe(node, next, &sess_obj->aif_pool) {
             aif_obj = node_to_item(node, struct aif, node);
             if (!aif_obj) {
                 AGM_LOGE("Error:%d could not find aif node\n", ret);
@@ -1746,6 +1750,7 @@
     int ret = 0;
     struct aif *aif_obj = NULL;
 
+    AGM_LOGI("Setting metadata for sess aif id %d\n", aif_id);
     pthread_mutex_lock(&sess_obj->lock);
     ret = aif_obj_get(sess_obj, aif_id, &aif_obj);
     if (ret) {
@@ -1761,9 +1766,11 @@
                   sess_id:%d, aif_id:%d \n",
                   sess_obj->sess_id, aif_obj->aif_id);
     }
+    metadata_print(&(aif_obj->sess_aif_meta));
 
 done:
     pthread_mutex_unlock(&sess_obj->lock);
+    AGM_LOGI("Exit");
     return ret;
 }