/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation, nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_ds_client"

#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <wireless_data_service_v01.h>
#include <utils/Log.h>
#include <log_util.h>
#include <loc_log.h>
#include <qmi_client.h>
#include <qmi_idl_lib.h>
#include <qmi_cci_target_ext.h>
#include <qmi_cci_target.h>
#include <qmi_cci_common.h>
#include <dsi_netctrl.h>
#include <ds_client.h>

#include<sys/time.h>

//Timeout to wait for wds service notification from qmi
#define DS_CLIENT_SERVICE_TIMEOUT (4000)
//Max timeout for the service to come up
#define DS_CLIENT_SERVICE_TIMEOUT_TOTAL (40000)
//Timeout for the service to respond to sync msg
#define DS_CLIENT_SYNC_MSG_TIMEOUT (5000)
/*Request messages the WDS client can send to the WDS service*/
typedef union
{
    /*Requests the service for a list of all profiles present*/
    wds_get_profile_list_req_msg_v01 *p_get_profile_list_req;
    /*Requests the service for a profile's settings*/
    wds_get_profile_settings_req_msg_v01 *p_get_profile_settings_req;
}ds_client_req_union_type;

/*Response indications that are sent by the WDS service*/
typedef union
{
    wds_get_profile_list_resp_msg_v01 *p_get_profile_list_resp;
    wds_get_profile_settings_resp_msg_v01 *p_get_profile_setting_resp;
}ds_client_resp_union_type;

struct event_strings_s
{
  char * str;
  dsi_net_evt_t evt;
};

struct event_strings_s event_string_tbl[DSI_EVT_MAX] =
{
    NAME_VAL(DSI_EVT_INVALID),
    NAME_VAL(DSI_EVT_NET_IS_CONN),
    NAME_VAL(DSI_EVT_NET_NO_NET),
    NAME_VAL(DSI_EVT_PHYSLINK_DOWN_STATE),
    NAME_VAL(DSI_EVT_PHYSLINK_UP_STATE),
    NAME_VAL(DSI_EVT_NET_RECONFIGURED),
#ifndef GPS_PDK
    NAME_VAL(DSI_EVT_WDS_CONNECTED)
#endif
};

typedef struct
{
    ds_client_event_ind_cb_type event_cb;
    void *caller_cookie;
}ds_caller_data;

typedef struct {
    //Global dsi handle
    dsi_hndl_t dsi_net_handle;
    //Handle to caller's data
    ds_caller_data caller_data;
} ds_client_session_data;

void net_ev_cb(dsi_hndl_t handle, void* user_data,
               dsi_net_evt_t evt, dsi_evt_payload_t *payload_ptr)
{
    int i;
    (void)handle;
    (void)user_data;
    (void)payload_ptr;
    ds_caller_data *callback_data = (ds_caller_data *)user_data;

    LOC_LOGD("%s:%d]: Enter. Callback data: %p\n", __func__, __LINE__, callback_data);
    if(evt > DSI_EVT_INVALID && evt < DSI_EVT_MAX)
    {
        for(i=0;i<DSI_EVT_MAX;i++)
        {
            if(event_string_tbl[i].evt == evt)
                LOC_LOGE("%s:%d]: Callback received: %s",
                         __func__, __LINE__, event_string_tbl[i].str);
        }
        switch(evt) {
        case DSI_EVT_NET_IS_CONN:
#ifndef GPS_PDK
        case DSI_EVT_WDS_CONNECTED:
#endif
        {
            LOC_LOGD("%s:%d]: Emergency call started\n", __func__, __LINE__);
            callback_data->event_cb(E_DS_CLIENT_DATA_CALL_CONNECTED,
                                    callback_data->caller_cookie);
            break;
        }
        case DSI_EVT_NET_NO_NET:
        {
            LOC_LOGD("%s:%d]: Emergency call stopped\n", __func__, __LINE__);
            callback_data->event_cb(E_DS_CLIENT_DATA_CALL_DISCONNECTED,
                                    callback_data->caller_cookie);
            break;
        }
        default:
            LOC_LOGD("%s:%d]: uninteresting event\n", __func__, __LINE__);
        }
    }
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
}

/*This function is called to obtain a handle to the QMI WDS service*/
static ds_client_status_enum_type
ds_client_qmi_ctrl_point_init(qmi_client_type *p_wds_qmi_client)
{
    qmi_client_type wds_qmi_client, notifier = NULL;
    ds_client_status_enum_type status = E_DS_CLIENT_SUCCESS;
    qmi_service_info *p_service_info = NULL;
    uint32_t num_services = 0, num_entries = 0;
    qmi_client_error_type ret = QMI_NO_ERR;
    unsigned char no_signal = 0;
    qmi_client_os_params os_params;
    int timeout = 0;

    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);

    //Get service object for QMI_WDS service
    qmi_idl_service_object_type ds_client_service_object =
        wds_get_service_object_v01();
    if(ds_client_service_object == NULL) {
        LOC_LOGE("%s:%d]: wds_get_service_object_v01 failed\n" ,
                    __func__, __LINE__);
        status  = E_DS_CLIENT_FAILURE_INTERNAL;
        goto err;
    }

    //get service addressing information
    ret = qmi_client_get_service_list(ds_client_service_object, NULL, NULL,
                                      &num_services);
    LOC_LOGD("%s:%d]: qmi_client_get_service_list() first try ret %d, "
                   "num_services %d]\n", __func__, __LINE__, ret, num_services);
    if(ret != QMI_NO_ERR) {
        //Register for service notification
        ret = qmi_client_notifier_init(ds_client_service_object, &os_params, &notifier);
        if (ret != QMI_NO_ERR) {
            LOC_LOGE("%s:%d]: qmi_client_notifier_init failed %d\n",
                              __func__, __LINE__, ret);
            status = E_DS_CLIENT_FAILURE_INTERNAL;
            goto err;
        }

        do {
            QMI_CCI_OS_SIGNAL_CLEAR(&os_params);
            ret = qmi_client_get_service_list(ds_client_service_object, NULL,
                                              NULL, &num_services);
            if(ret != QMI_NO_ERR) {
                QMI_CCI_OS_SIGNAL_WAIT(&os_params, DS_CLIENT_SERVICE_TIMEOUT);
                no_signal = QMI_CCI_OS_SIGNAL_TIMED_OUT(&os_params);
                if(!no_signal)
                    ret = qmi_client_get_service_list(ds_client_service_object, NULL,
                                                      NULL, &num_services);
            }
            timeout += DS_CLIENT_SERVICE_TIMEOUT;
            LOC_LOGV("%s:%d]: qmi_client_get_service_list() returned ret: %d,"
                     "no_signal: %d, total timeout: %d\n", __func__, __LINE__,
                     ret, no_signal, timeout);
        } while( (timeout < DS_CLIENT_SERVICE_TIMEOUT_TOTAL) &&
                 no_signal &&
                 (ret != QMI_NO_ERR) );
    }

    //Handle failure cases
    if(num_services == 0 || ret != QMI_NO_ERR) {
        if(!no_signal) {
            LOC_LOGE("%s:%d]: qmi_client_get_service_list failed even though"
                     "service is up!  Error: %d \n", __func__, __LINE__, ret);
            status = E_DS_CLIENT_FAILURE_INTERNAL;
        }
        else {
            LOC_LOGE("%s:%d]: qmi_client_get_service_list failed after retries"
                     "Error: %d \n", __func__, __LINE__, ret);
            status = E_DS_CLIENT_FAILURE_TIMEOUT;
        }
        goto err;
    }

    LOC_LOGD("%s:%d]: qmi_client_get_service_list succeeded\n", __func__, __LINE__);

    //Success
    p_service_info = (qmi_service_info *)malloc(num_services * sizeof(qmi_service_info));
    if(p_service_info == NULL) {
        LOC_LOGE("%s:%d]: could not allocate memory for serviceInfo !!\n",
               __func__, __LINE__);
        status = E_DS_CLIENT_FAILURE_INTERNAL;
        goto err;
    }
    num_entries = num_services;

    //Populate service info
    ret = qmi_client_get_service_list(ds_client_service_object, p_service_info,
                                     &num_entries, &num_services);
    if(ret != QMI_NO_ERR) {
        LOC_LOGE("%s:%d]: qmi_client_get_service_list failed. ret: %d \n",
                 __func__, __LINE__, ret);
        status = E_DS_CLIENT_FAILURE_INTERNAL;
        goto err;
    }

    //Initialize wds_qmi_client
    LOC_LOGD("%s:%d]: Initializing WDS client with qmi_client_init\n", __func__,
             __LINE__);
    ret = qmi_client_init(&p_service_info[0], ds_client_service_object,
                          NULL, NULL, NULL, &wds_qmi_client);
    if(ret != QMI_NO_ERR) {
        LOC_LOGE("%s:%d]: qmi_client_init Error. ret: %d\n", __func__, __LINE__, ret);
        status = E_DS_CLIENT_FAILURE_INTERNAL;
        goto err;
    }
    LOC_LOGD("%s:%d]: WDS client initialized with qmi_client_init\n", __func__,
         __LINE__);

    //Store WDS QMI client handle in the parameter passed in
    *p_wds_qmi_client = wds_qmi_client;

    status = E_DS_CLIENT_SUCCESS;
    LOC_LOGD("%s:%d]: init success\n", __func__, __LINE__);

    if(notifier)
        qmi_client_release(notifier);

err:
    if(p_service_info)
        free(p_service_info);

    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    return status;
}

/*This function reads the error code from within the response struct*/
static ds_client_status_enum_type ds_client_convert_qmi_response(
    uint32_t req_id,
    ds_client_resp_union_type *resp_union)
{
    ds_client_status_enum_type ret = E_DS_CLIENT_FAILURE_GENERAL;
    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
    switch(req_id)
    {
    case QMI_WDS_GET_PROFILE_LIST_REQ_V01 :
    {
        if(resp_union->p_get_profile_list_resp->resp.error !=
           QMI_ERR_NONE_V01) {
            LOC_LOGE("%s:%d]: Response error: %d", __func__, __LINE__,
                     resp_union->p_get_profile_list_resp->resp.error);
        }
        else
            ret = E_DS_CLIENT_SUCCESS;
    }
    break;

    case QMI_WDS_GET_PROFILE_SETTINGS_REQ_V01 :
    {
        if(resp_union->p_get_profile_setting_resp->resp.error !=
           QMI_ERR_NONE_V01) {
            LOC_LOGE("%s:%d]: Response error: %d", __func__, __LINE__,
                     resp_union->p_get_profile_setting_resp->resp.error);
        }
        else
            ret = E_DS_CLIENT_SUCCESS;
    }
    break;

    default:
        LOC_LOGE("%s:%d]: Unknown request ID\n", __func__, __LINE__);
    }
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    return ret;
}


static ds_client_status_enum_type ds_client_send_qmi_sync_req(
    qmi_client_type *ds_client_handle,
    uint32_t req_id,
    ds_client_resp_union_type *resp_union,
    ds_client_req_union_type *req_union)
{
    uint32_t req_len = 0;
    uint32_t resp_len = 0;
    ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS;
    qmi_client_error_type qmi_ret = QMI_NO_ERR;
    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
    switch(req_id)
    {
    case QMI_WDS_GET_PROFILE_LIST_REQ_V01 :
    {
        req_len = sizeof(wds_get_profile_list_req_msg_v01);
        resp_len = sizeof(wds_get_profile_list_resp_msg_v01);
        LOC_LOGD("%s:%d]: req_id = GET_PROFILE_LIST_REQ\n",
                       __func__, __LINE__);
    }
    break;

    case QMI_WDS_GET_PROFILE_SETTINGS_REQ_V01 :
    {
        req_len = sizeof(wds_get_profile_settings_req_msg_v01);
        resp_len = sizeof(wds_get_profile_settings_resp_msg_v01);
        LOC_LOGD("%s:%d]: req_id = GET_PROFILE_SETTINGS_REQ\n",
                       __func__, __LINE__);
    }
    break;

    default:
        LOC_LOGE("%s:%d]: Error unknown req_id=%d\n", __func__, __LINE__,
                       req_id);
        ret = E_DS_CLIENT_FAILURE_INVALID_PARAMETER;
        goto err;
    }

    LOC_LOGD("%s:%d]: req_id=%d, len = %d; resp_len= %d\n", __func__, __LINE__,
             req_id, req_len, resp_len);
    //Send msg through QCCI
    qmi_ret = qmi_client_send_msg_sync(
        *ds_client_handle,
        req_id,
        (void *)req_union->p_get_profile_list_req,
        req_len,
        (void *)resp_union->p_get_profile_list_resp,
        resp_len,
        DS_CLIENT_SYNC_MSG_TIMEOUT);
    LOC_LOGD("%s:%d]: qmi_client_send_msg_sync returned: %d", __func__, __LINE__, qmi_ret);

    if(qmi_ret != QMI_NO_ERR) {
        ret = E_DS_CLIENT_FAILURE_INTERNAL;
        goto err;
    }

    ret = ds_client_convert_qmi_response(req_id, resp_union);

err:
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    return ret;
}

/*This function obtains the list of supported profiles*/
static ds_client_status_enum_type ds_client_get_profile_list(
    qmi_client_type *ds_client_handle,
    ds_client_resp_union_type *profile_list_resp_msg,
    wds_profile_type_enum_v01 profile_type)
{
    ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS;
    ds_client_req_union_type req_union;
    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);

    req_union.p_get_profile_list_req = NULL;
    req_union.p_get_profile_list_req = (wds_get_profile_list_req_msg_v01 *)
        calloc(1, sizeof(wds_get_profile_list_req_msg_v01));
    if(req_union.p_get_profile_list_req == NULL) {
        LOC_LOGE("%s:%d]: Could not allocate memory for"
                 "wds_get_profile_list_req_msg_v01\n", __func__, __LINE__);
        goto err;
    }
    //Populate required members of the request structure
    req_union.p_get_profile_list_req->profile_type_valid = 1;
    req_union.p_get_profile_list_req->profile_type = profile_type;
    ret = ds_client_send_qmi_sync_req(ds_client_handle,
                                       QMI_WDS_GET_PROFILE_LIST_REQ_V01,
                                       profile_list_resp_msg, &req_union);
    if(ret != E_DS_CLIENT_SUCCESS) {
        LOC_LOGE("%s:%d]: ds_client_send_qmi_req failed. ret: %d\n",
                 __func__, __LINE__, ret);
        goto err;
    }
err:
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    if(req_union.p_get_profile_list_req)
        free(req_union.p_get_profile_list_req);
    return ret;
}

/*This function obtains settings for the profile specified by
 the profile_identifier*/
static ds_client_status_enum_type ds_client_get_profile_settings(
    qmi_client_type *ds_client_handle,
    ds_client_resp_union_type *profile_settings_resp_msg,
    wds_profile_identifier_type_v01 *profile_identifier)
{
    ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS;
    ds_client_req_union_type req_union;

    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
    //Since it's a union containing a pointer to a structure,
    //following entities have the same address
    //- req_union
    //- req_union.p_get_profile_settings_req
    //- req_union.p_get_profile_settings_req->profile
    //so we can very well assign req_union = profile_identifier
    req_union.p_get_profile_settings_req =
        (wds_get_profile_settings_req_msg_v01 *)profile_identifier;
    ret = ds_client_send_qmi_sync_req(ds_client_handle,
                                       QMI_WDS_GET_PROFILE_SETTINGS_REQ_V01,
                                       profile_settings_resp_msg, &req_union);
    if(ret != E_DS_CLIENT_SUCCESS) {
        LOC_LOGE("%s:%d]: ds_client_send_qmi_req failed. ret: %d\n",
                 __func__, __LINE__, ret);
        goto err;
    }
err:
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    return ret;
}

/*
  Starts data call using the handle and the profile index
*/
ds_client_status_enum_type
ds_client_start_call(dsClientHandleType client_handle, int profile_index, int pdp_type)
{
    ds_client_status_enum_type ret = E_DS_CLIENT_FAILURE_GENERAL;
    dsi_call_param_value_t param_info;
    dsi_hndl_t dsi_handle;
    ds_client_session_data *ds_global_data = (ds_client_session_data *)client_handle;
    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
    if(ds_global_data == NULL) {
        LOC_LOGE("%s:%d]: Null callback parameter\n", __func__, __LINE__);
        goto err;
    }
    dsi_handle = ds_global_data->dsi_net_handle;
    //Set profile index as call parameter
    param_info.buf_val = NULL;
    param_info.num_val = profile_index;
    dsi_set_data_call_param(dsi_handle,
                            DSI_CALL_INFO_UMTS_PROFILE_IDX,
                            &param_info);

    //Set IP Version as call parameter
    param_info.buf_val = NULL;
    param_info.num_val = pdp_type;
    dsi_set_data_call_param(dsi_handle,
                            DSI_CALL_INFO_IP_VERSION,
                            &param_info);
    LOC_LOGD("%s:%d]: Starting emergency call with profile index %d; pdp_type:%d\n",
             __func__, __LINE__, profile_index, pdp_type);
    if(dsi_start_data_call(dsi_handle) == DSI_SUCCESS) {
        LOC_LOGD("%s:%d]: Sent request to start data call\n",
                 __func__, __LINE__);
        ret = E_DS_CLIENT_SUCCESS;
    }
    else {
        LOC_LOGE("%s:%d]: Could not send req to start data call \n", __func__, __LINE__);
        ret = E_DS_CLIENT_FAILURE_GENERAL;
        goto err;
    }

err:
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    return ret;

}

/*Function to open an emergency call. Does the following things:
 - Obtains a handle to the WDS service
 - Obtains a list of profiles configured in the modem
 - Queries each profile and obtains settings to check if emergency calls
   are supported
 - Returns the profile index that supports emergency calls
 - Returns handle to dsi_netctrl*/
ds_client_status_enum_type
ds_client_open_call(dsClientHandleType *client_handle,
                    ds_client_cb_data *callback,
                    void *caller_cookie,
                    int *profile_index,
                    int *pdp_type)
{
    ds_client_status_enum_type ret = E_DS_CLIENT_FAILURE_GENERAL;
    ds_client_resp_union_type profile_list_resp_msg;
    ds_client_resp_union_type profile_settings_resp_msg;
    wds_profile_identifier_type_v01 profile_identifier;
    uint32_t i=0;
    dsi_hndl_t dsi_handle;
    ds_client_session_data **ds_global_data = (ds_client_session_data **)client_handle;
    unsigned char call_profile_index_found = 0;
    uint32_t emergency_profile_index=0;
    qmi_client_type wds_qmi_client;

    profile_list_resp_msg.p_get_profile_list_resp = NULL;
    profile_settings_resp_msg.p_get_profile_setting_resp = NULL;

    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
    if(callback == NULL || ds_global_data == NULL) {
        LOC_LOGE("%s:%d]: Null callback parameter\n", __func__, __LINE__);
        goto err;
    }

    ret = ds_client_qmi_ctrl_point_init(&wds_qmi_client);
    if(ret != E_DS_CLIENT_SUCCESS) {
        LOC_LOGE("%s:%d]: ds_client_qmi_ctrl_point_init failed. ret: %d\n",
                 __func__, __LINE__, ret);
        goto err;
    }

    //Allocate memory for the response msg to obtain a list of profiles
    profile_list_resp_msg.p_get_profile_list_resp = (wds_get_profile_list_resp_msg_v01 *)
        calloc(1, sizeof(wds_get_profile_list_resp_msg_v01));
    if(profile_list_resp_msg.p_get_profile_list_resp == NULL) {
        LOC_LOGE("%s:%d]: Could not allocate memory for"
                 "p_get_profile_list_resp\n", __func__, __LINE__);
        ret = E_DS_CLIENT_FAILURE_NOT_ENOUGH_MEMORY;
        goto err;
    }

    LOC_LOGD("%s:%d]: Getting profile list\n", __func__, __LINE__);
    ret = ds_client_get_profile_list(&wds_qmi_client,
                                      &profile_list_resp_msg,
                                      WDS_PROFILE_TYPE_3GPP_V01);
    if(ret != E_DS_CLIENT_SUCCESS) {
        LOC_LOGE("%s:%d]: ds_client_get_profile_list failed. ret: %d\n",
                 __func__, __LINE__, ret);
        goto err;
    }
    LOC_LOGD("%s:%d]: Got profile list; length = %d\n", __func__, __LINE__,
             profile_list_resp_msg.p_get_profile_list_resp->profile_list_len);

    //Allocate memory for the response msg to obtain profile settings
    //We allocate memory for only one response msg and keep re-using it
    profile_settings_resp_msg.p_get_profile_setting_resp =
        (wds_get_profile_settings_resp_msg_v01 *)
        calloc(1, sizeof(wds_get_profile_settings_resp_msg_v01));
    if(profile_settings_resp_msg.p_get_profile_setting_resp == NULL) {
        LOC_LOGE("%s:%d]: Could not allocate memory for"
                 "p_get_profile_setting_resp\n", __func__, __LINE__);
        ret = E_DS_CLIENT_FAILURE_NOT_ENOUGH_MEMORY;
        goto err;
    }

    //Loop over the list of profiles to find a profile that supports
    //emergency calls
    for(i=0; i < profile_list_resp_msg.p_get_profile_list_resp->profile_list_len; i++) {
        /*QMI_WDS_GET_PROFILE_SETTINGS_REQ requires an input data
          structure that is of type wds_profile_identifier_type_v01
          We have to fill that structure for each profile from the
          info obtained from the profile list*/
        //copy profile type
        profile_identifier.profile_type =
            profile_list_resp_msg.p_get_profile_list_resp->profile_list[i].profile_type;
        //copy profile index
        profile_identifier.profile_index =
            profile_list_resp_msg.p_get_profile_list_resp->profile_list[i].profile_index;

        ret = ds_client_get_profile_settings(&wds_qmi_client,
                                             &profile_settings_resp_msg,
                                             &profile_identifier);
        if(ret != E_DS_CLIENT_SUCCESS) {
            LOC_LOGE("%s:%d]: ds_client_get_profile_settings failed. ret: %d\n",
                     __func__, __LINE__, ret);
            goto err;
        }
        LOC_LOGD("%s:%d]: Got profile setting for profile %d; name: %s\n",
                 __func__, __LINE__, i,
                 profile_settings_resp_msg.p_get_profile_setting_resp->profile_name);

        if(profile_settings_resp_msg.p_get_profile_setting_resp->support_emergency_calls_valid) {
            if(profile_settings_resp_msg.p_get_profile_setting_resp->support_emergency_calls) {
                LOC_LOGD("%s:%d]: Found emergency profile in profile %d"
                         , __func__, __LINE__, i);
                call_profile_index_found = 1;
                emergency_profile_index = profile_identifier.profile_index;

                if(profile_settings_resp_msg.p_get_profile_setting_resp->pdp_type_valid) {
                    *pdp_type = (int)profile_settings_resp_msg.p_get_profile_setting_resp->pdp_type;
                    LOC_LOGD("%s:%d]: pdp_type: %d\n", __func__, __LINE__, *pdp_type);
                    switch(*pdp_type) {
                    case WDS_PDP_TYPE_PDP_IPV4_V01:
                        *pdp_type = DSI_IP_VERSION_4;
                        break;
                    case WDS_PDP_TYPE_PDP_IPV6_V01:
                        *pdp_type = DSI_IP_VERSION_6;
                        break;
                    case WDS_PDP_TYPE_PDP_IPV4V6_V01:
                        *pdp_type = DSI_IP_VERSION_4_6;
                        break;
                    default:
                        LOC_LOGE("%s:%d]: pdp_type unknown. Setting default as ipv4/v6\n",
                                 __func__, __LINE__);
                        *pdp_type = DSI_IP_VERSION_4;

                    }
                }
                else {
                    LOC_LOGD("%s:%d]: pdp type not valid in profile setting. Default ipv4\n",
                             __func__, __LINE__);
                    *pdp_type = DSI_IP_VERSION_4;
                }
                //Break out of for loop since we found the emergency profile
                break;
            }
            else
                LOC_LOGE("%s:%d]: Emergency profile valid but not supported in profile: %d "
                         , __func__, __LINE__, i);
        }
        //Since this struct is loaded with settings for the next profile,
        //it is important to clear out the memory to avoid values/flags
        //from being carried over
        memset((void *)profile_settings_resp_msg.p_get_profile_setting_resp,
               0, sizeof(wds_get_profile_settings_resp_msg_v01));
    }

    //Release qmi client handle
    if(qmi_client_release(wds_qmi_client) != QMI_NO_ERR) {
        LOC_LOGE("%s:%d]: Could not release qmi client handle\n",
                 __func__, __LINE__);
        ret = E_DS_CLIENT_FAILURE_GENERAL;
    }

    if(call_profile_index_found) {
        *profile_index = emergency_profile_index;
        *ds_global_data = (ds_client_session_data *)calloc(1, sizeof(ds_client_session_data));
        if(*ds_global_data == NULL) {
            LOC_LOGE("%s:%d]: Could not allocate memory for ds_global_data. Failing\n",
                     __func__, __LINE__);
            ret = E_DS_CLIENT_FAILURE_NOT_ENOUGH_MEMORY;
            goto err;
        }

        (*ds_global_data)->caller_data.event_cb = callback->event_cb;
        (*ds_global_data)->caller_data.caller_cookie = caller_cookie;
        dsi_handle = dsi_get_data_srvc_hndl(net_ev_cb, &(*ds_global_data)->caller_data);
        if(dsi_handle == NULL) {
            LOC_LOGE("%s:%d]: Could not get data handle. Retry Later\n",
                     __func__, __LINE__);
            ret = E_DS_CLIENT_RETRY_LATER;
            goto err;
        }
        else
            (*ds_global_data)->dsi_net_handle = dsi_handle;
    }
    else {
        LOC_LOGE("%s:%d]: Could not find a profile that supports emergency calls",
                 __func__, __LINE__);
        ret = E_DS_CLIENT_FAILURE_GENERAL;
    }
err:
    if(profile_list_resp_msg.p_get_profile_list_resp)
        free(profile_list_resp_msg.p_get_profile_list_resp);
    if(profile_settings_resp_msg.p_get_profile_setting_resp)
        free(profile_settings_resp_msg.p_get_profile_setting_resp);
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    return ret;
}

ds_client_status_enum_type ds_client_stop_call(dsClientHandleType client_handle)
{
    ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS;
    ds_client_session_data *p_ds_global_data = (ds_client_session_data *)client_handle;
    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);

    if(client_handle == NULL) {
        LOC_LOGE("%s:%d]: Null argument received. Failing\n", __func__, __LINE__);
        ret = E_DS_CLIENT_FAILURE_GENERAL;
        goto err;
    }

    if(dsi_stop_data_call(p_ds_global_data->dsi_net_handle) == DSI_SUCCESS) {
        LOC_LOGD("%s:%d]: Sent request to stop data call\n", __func__, __LINE__);
    }
    else {
        LOC_LOGE("%s:%d]: Could not send request to stop data call\n",
                 __func__, __LINE__);
        ret = E_DS_CLIENT_FAILURE_GENERAL;
        goto err;
    }

err:
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    return ret;
}

/*
  Stops data call associated with the data handle
*/
void ds_client_close_call(dsClientHandleType *client_handle)
{
    ds_client_session_data **ds_global_data = (ds_client_session_data **)client_handle;
    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
    if(client_handle == NULL || *client_handle == NULL) {
        LOC_LOGE("%s:%d]: Null argument received. Failing\n", __func__, __LINE__);
        goto err;
    }
    dsi_rel_data_srvc_hndl((*ds_global_data)->dsi_net_handle);
    (*ds_global_data)->dsi_net_handle = NULL;
    free(*ds_global_data);
    *ds_global_data = NULL;
    LOC_LOGD("%s:%d]: Released Data handle\n", __func__, __LINE__);
err:
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    return;
}

int ds_client_init()
{
    int ret = 0;
    LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
    if(DSI_SUCCESS != dsi_init(DSI_MODE_GENERAL))
    {
        LOC_LOGE("%s:%d]:dsi_init failed\n", __func__, __LINE__);
        ret = -1;
    }
    LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
    return ret;
}
