/*===========================================================================

FUNCTION QMI_IP_WDS_RELEASE()

DESCRIPTION

  This function releases the WDS client handles

DEPENDENCIES
  None.

RETURN VALUE
  QTI_SUCCESS on success
  QTI_FAILURE on failure


SIDE EFFECTS
  None
===========================================================================*/
void qmi_ip_wds_release(qmi_ip_conf_t * conf){
  int ret;

  if ((conf->qmi_ip_v4_wds_handle == 0) && (conf->qmi_ip_v6_wds_handle == 0)){
    LOG_MSG_INFO1("Handles not populated",0,0,0);
    return;
  }

  ret = qmi_client_release(conf->qmi_ip_v4_wds_handle);
  if (ret != QMI_NO_ERR)
  {
     LOG_MSG_ERROR("Error %d while releasing wds v4 client handle", ret,0,0);
  }
  else
    LOG_MSG_INFO1("Successfully released the wds v4 handle",0,0,0);

  ret = qmi_client_release(conf->qmi_ip_v6_wds_handle);
  if (ret != QMI_NO_ERR)
  {
    LOG_MSG_ERROR("Error %d while releasing wds v6 client handle", ret,0,0);
  }
  else
    LOG_MSG_INFO1("Successfully released the wds v6 handle",0,0,0);

  conf->qmi_ip_v4_wds_handle = (qmi_client_type) NULL;
  conf->qmi_ip_v6_wds_handle = (qmi_client_type) NULL;
}
static boolean qmi_ip_wait_for_srv_then_get_info
(
  qmi_idl_service_object_type svc_obj,
  qmi_service_info *qmi_svc_info,
  qmi_client_qmux_instance_type rmnet_instance
)
{
  qmi_client_os_params os_params;
  qmi_client_type notifier_handle;
  qmi_client_error_type err;
  boolean success = FALSE;
  uint32_t num_services = 0, num_entries = 0;
  qmi_service_info            info[10];

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -*/

  LOG_MSG_INFO1("Entering qti_qmi_wait_for_srv_then_get_info",0,0,0);
  err = qmi_cci_qmux_xport_register(rmnet_instance);

  /*-----------------------------------------------------------------------
  Initialize client notifier
  ------------------------------------------------------------------------*/
  err = qmi_client_notifier_init(svc_obj, &os_params, &notifier_handle);
  if (err != QMI_NO_ERR)
  {
    LOG_MSG_ERROR("Error %d while trying to initialize client notifier",
                  err,0,0);
  }
  else
  {
    err = qmi_client_get_service_instance(svc_obj,
                                          rmnet_instance,
                                          qmi_svc_info);

    if (err != QMI_NO_ERR)
    {
      LOG_MSG_ERROR("Error %d while trying to get service info", err,0,0);
    }
    else
    {
      LOG_MSG_INFO1("Got service instance success",0,0,0);
      success = TRUE;
    }

    /*----------------------------------------------------------------------
     We need to release the client notifier here. Client notifier is only
     used to notify the client when the QMI service comes up.However client
     notifier acts as an actual QMI service client even though it is not used
     as an actual client of the service. We need to release it here to avoid
     unnecessary overhead of maintaining another client.
    ------------------------------------------------------------------------*/
    err = qmi_client_release(notifier_handle);
    if (err != QMI_NO_ERR)
    {
      LOG_MSG_ERROR("Error %d while releasing client notifier handle", err,0,0);
    }
  }

  return success;
}
/** @ingroup netmgr_dpm

    @brief
    Called in response to DPM events as part of command executor module

    @params None.
    @return None.
*/
void netmgr_qmi_dpm_process_cmdq_event
(
  netmgr_dpm_event_t   evt
)
{
  qmi_idl_service_object_type dpm_svc_obj = dpm_get_service_object_v01();

  if (NULL == dpm_svc_obj)
  {
    netmgr_log_err("netmgr_qmi_dpm_process_cmdq_event(): Could not get DPM object!");
    return;
  }

  switch (evt)
  {
  case NETMGR_QMI_DPM_OOS_EV:
    /* We have received SSR notification, clean up existing DPM
     * handle. Initialize a notifier client and register for notifier
     * callback so that we know when DPM service becomes available again
     * on modem which means SSR recovery happened */

    netmgr_log_med("netmgr_qmi_dpm_process_cmdq_event(): Releasing dpm client");
    (void) qmi_client_release(netmgr_qmi_dpm_state.dpm_clid);
    (void) qmi_client_notifier_init(dpm_svc_obj, &dpm_os_params, &dpm_notifier);
    (void) qmi_client_register_notify_cb(dpm_notifier, netmgr_qmi_dpm_notify_cb, NULL);

    /* Reset internal flags */
    netmgr_qmi_dpm_state.dpm_inited = FALSE;
    netmgr_qmi_dpm_state.open_req_sent = FALSE;
    break;

  case NETMGR_QMI_DPM_IS_EV:
    /* We have received SSR recovery message */
    netmgr_log_med("netmgr_qmi_dpm_process_cmdq_event():"
                   " Initializing DPM client and opening port...");
    (void) qmi_client_release(dpm_notifier);
    (void) netmgr_qmi_dpm_init();
    (void) netmgr_qmi_dpm_port_open();
    break;

  default:
    netmgr_log_err("netmgr_qmi_dpm_process_cmdq_event(): Unsupported operation");
    break;
  }
}
void qup_manager_qmi_client_thread(void *unused)
{
  qmi_client_type clnt;
  qmi_txn_handle txn;
  qmi_client_type notifier;
  unsigned int num_services, num_entries=10, i=0, num_services_old=0;
  int rc;
  qmi_cci_os_signal_type os_params;
  qmi_service_info info[10];

  qup_manager_registration(unused);

  os_params.ext_signal = NULL;
  os_params.sig = QMI_CLNT_WAIT_SIG;
  os_params.timer_sig = QMI_CLNT_TIMER_SIG;

  qmi_idl_service_object_type qupm_service_object = qupm_get_service_object_v01();
  if (!qupm_service_object)
  {
    ERR_PRINTF("%s: Unable to get QUP Manager Service Object\n", __func__, 0);
  }

  rc = qmi_client_notifier_init(qupm_service_object, &os_params, &notifier);
  DEBUG_PRINTF("%s: qmi_client_notifier_init, rc=%d \n", __func__, rc);

  /* Check if the service is up, if not wait on a signal */
  while(1)
  {
    QMI_CCI_OS_SIGNAL_WAIT(&os_params, 0);
    QMI_CCI_OS_SIGNAL_CLEAR(&os_params);
    /* The server has come up, store the information in info variable */
    num_entries=10;
    rc = qmi_client_get_service_list( qupm_service_object, info, &num_entries, &num_services);

    if(rc != QMI_NO_ERR || num_services == num_services_old)
      continue;

    num_services_old = num_services;

    for(i = 0; i < num_services; i++)
    {
      rc = qmi_client_init(&info[i], qupm_service_object, qup_manager_ping_ind_cb, NULL, &os_params, &clnt);

      DEBUG_PRINTF("Registered test client with QUP MANAGER service: %d, rc=%d \n", i, rc);
      rc = qup_manager_ping_msg_test(&clnt, &txn);
	  if (rc)
        qmi_client_release(clnt);
    }
  }
}
/*=============================================================================
  FUNCTION QTI_QCMAP_EXIT()

  DESCRIPTION

  This function releases QCMAP client

  DEPENDENCIES
  None.

  RETURN VALUE
  QTI_PPP_SUCCESS on success
  QTI_PPP_FAILURE on failure

  SIDE EFFECTS
  None
==============================================================================*/
 int qti_ppp_qcmap_exit()
{
  qmi_client_error_type     qmi_error;

/*----------------------------------------------------------------------------*/

  qmi_error = qmi_client_release(qti_ppp_qcmap_conf->qti_ppp_qcmap_msgr_handle);
  qti_ppp_qcmap_conf->qti_ppp_qcmap_msgr_handle = NULL;

  if (qmi_error != QMI_NO_ERR)
  {
    LOG_MSG_ERROR("Can not release client qcmap client handle %d",
                  qmi_error,0,0);
    return QTI_PPP_FAILURE;
  }

  return QTI_PPP_SUCCESS;
}
/*=============================================================================
  FUNCTION qmi_ip_QCMAP_EXIT()

  DESCRIPTION

  This function releases QCMAP client

  DEPENDENCIES
  None.

  RETURN VALUE
  QMI_IP_SUCCESS on success
  QMI_IP_ERROR on failure

  SIDE EFFECTS
  None
==============================================================================*/
int qmi_ip_qcmap_exit(void)
{
  qmi_client_error_type     qmi_error;

/*----------------------------------------------------------------------------*/

  qmi_error = qmi_client_release(qmi_ip_conf.qmi_ip_qcmap_msgr_handle);
  qmi_ip_conf.qmi_ip_qcmap_msgr_handle = NULL;

  if (qmi_error != QMI_NO_ERR)
  {
    LOG_MSG_ERROR("Can not release client qcmap client handle %d",
                  qmi_error,0,0);
    return QMI_IP_ERROR;
  }

  return QMI_IP_SUCCESS;
}
/*=============================================================================
  FUNCTION qmi_ip_QCMAP_INIT()

  DESCRIPTION

  This function initializes qmi_ip interface to QCMAP

  DEPENDENCIES
  None.

  RETURN VALUE
  QMI_IP_SUCCESS on success
  QMI_IP_ERROR on failure

  SIDE EFFECTS
  None
==============================================================================*/
int qmi_ip_qcmap_init(qmi_ip_conf_t * conf)
{
  qmi_idl_service_object_type                            qmi_ip_qcmap_msgr_service_object;
  uint32_t                                               num_services = 0, num_entries = 0;
  qmi_service_info                                       info[10];
  qmi_client_error_type                                  qmi_error, qmi_err_code = QMI_NO_ERR;
  qcmap_msgr_mobile_ap_status_ind_register_req_msg_v01   qcmap_mobile_ap_status_ind_reg;
  qcmap_msgr_mobile_ap_status_ind_register_resp_msg_v01  qcmap_mobile_ap_status_ind_rsp;
  qcmap_msgr_wwan_status_ind_register_req_msg_v01        wwan_status_ind_reg;
  qcmap_msgr_wwan_status_ind_register_resp_msg_v01       wwan_status_ind_rsp;
  qmi_client_type                                        qmi_ip_qcmap_msgr_notifier;
  qmi_cci_os_signal_type                                 qmi_ip_qcmap_msgr_os_params;
  int                                                    retry_count = 0;
/*---------------------------------------------------------------------------*/

  if(conf == NULL)
  {
    LOG_MSG_ERROR("qmi_ip_qcmap_init() failed: conf null", 0, 0, 0);
    return QMI_IP_ERROR;
  }

  LOG_MSG_INFO1("qmi_ip_qcmap_init()", 0, 0, 0);

/*-----------------------------------------------------------------------------
  Obtain a QCMAP messenger service client for qmi_ip
  - get the service object
  - notify the client
  - get service list
  - obtain the client
------------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
  Get the service object
------------------------------------------------------------------------------*/
  qmi_ip_qcmap_msgr_service_object = qcmap_msgr_get_service_object_v01();
  if (qmi_ip_qcmap_msgr_service_object == NULL)
  {
    LOG_MSG_ERROR("qmi_ip QCMAP messenger service object not available",
                   0, 0, 0);
    return QMI_IP_ERROR;
  }

/*-----------------------------------------------------------------------------
  Notify the client
------------------------------------------------------------------------------*/

  qmi_error = qmi_client_notifier_init(qmi_ip_qcmap_msgr_service_object,
                                       &qmi_ip_qcmap_msgr_os_params,
                                       &qmi_ip_qcmap_msgr_notifier);
  if (qmi_error < 0)
  {
    LOG_MSG_ERROR("qmi_ip:qmi_client_notifier_init(qcmap_msgr) returned %d",
                   qmi_error, 0, 0);
    return QMI_IP_ERROR;
  }

/*----------------------------------------------------------------------------
  Check if the service is up, if not wait on a signal
-----------------------------------------------------------------------------*/
  while(retry_count < 10)//max retry
  {
    qmi_error = qmi_client_get_service_list(qmi_ip_qcmap_msgr_service_object,
                                            NULL,
                                            NULL,
                                            &num_services);
    LOG_MSG_INFO1(" qmi_ip: qmi_client_get_service_list: %d", qmi_error, 0, 0);

    if(qmi_error == QMI_NO_ERR)
      break;

/*----------------------------------------------------------------------------
     wait for server to come up
-----------------------------------------------------------------------------*/
    QMI_CCI_OS_SIGNAL_WAIT(&qmi_ip_qcmap_msgr_os_params, 500);//max timeout
    QMI_CCI_OS_SIGNAL_CLEAR(&qmi_ip_qcmap_msgr_os_params);
    LOG_MSG_INFO1("Returned from os signal wait", 0, 0, 0);
    retry_count++;
  }

  if(retry_count == 10 )//max retry
  {
    qmi_client_release(qmi_ip_qcmap_msgr_notifier);
    qmi_ip_qcmap_msgr_notifier = NULL;
    LOG_MSG_ERROR("Reached maximum retry attempts %d", retry_count, 0, 0);
    return QMI_IP_ERROR;
  }

  num_entries = num_services;

  LOG_MSG_INFO1(" qmi_ip: qmi_client_get_service_list: num_e %d num_s %d",
                num_entries, num_services, 0);

/*----------------------------------------------------------------------------
   The server has come up, store the information in info variable
------------------------------------------------------------------------------*/
  qmi_error = qmi_client_get_service_list(qmi_ip_qcmap_msgr_service_object,
                                          info,
                                          &num_entries,
                                          &num_services);

  LOG_MSG_INFO1("qmi_client_get_service_list: num_e %d num_s %d error %d",
                num_entries, num_services, qmi_error);

  if (qmi_error != QMI_NO_ERR)
  {
    qmi_client_release(qmi_ip_qcmap_msgr_notifier);
    qmi_ip_qcmap_msgr_notifier = NULL;
    LOG_MSG_ERROR("Can not get qcmap_msgr service list %d",
                  qmi_error, 0, 0);
    return QMI_IP_ERROR;
  }

/*----------------------------------------------------------------------------
  Obtain a QCMAP messenger client for qmi_ip
------------------------------------------------------------------------------*/
  qmi_error = qmi_client_init(&info[0],
                              qmi_ip_qcmap_msgr_service_object,
                              qmi_ip_qcmap_msgr_ind_cb,
                              NULL,
                              NULL,
                              &(conf->qmi_ip_qcmap_msgr_handle));

  LOG_MSG_INFO1("qmi_client_init: %d", qmi_error, 0, 0);


  if (qmi_error != QMI_NO_ERR)
  {
    qmi_client_release(qmi_ip_qcmap_msgr_notifier);
    qmi_ip_qcmap_msgr_notifier = NULL;
    LOG_MSG_ERROR("Can not init qcmap_msgr client %d", qmi_error, 0, 0);
    return QMI_IP_ERROR;
  }

/*----------------------------------------------------------------------------
  Release QCMAP notifier as it acts as a client also
------------------------------------------------------------------------------*/
  qmi_error = qmi_client_release(qmi_ip_qcmap_msgr_notifier);
  qmi_ip_qcmap_msgr_notifier = NULL;

  if (qmi_error != QMI_NO_ERR)
  {
    LOG_MSG_ERROR("Can not release client qcmap notifier %d",
                  qmi_error,0,0);
  }

/*-----------------------------------------------------------------------------
  Register for WWAN indications from QCMAP
-----------------------------------------------------------------------------*/
  memset(&wwan_status_ind_reg,0,
         sizeof(qcmap_msgr_wwan_status_ind_register_req_msg_v01));

  memset(&wwan_status_ind_rsp,0,
         sizeof(qcmap_msgr_wwan_status_ind_register_resp_msg_v01));

  wwan_status_ind_reg.register_indication = 1;
  qmi_error = qmi_client_send_msg_sync(conf->qmi_ip_qcmap_msgr_handle,
                                       QMI_QCMAP_MSGR_WWAN_STATUS_IND_REG_REQ_V01,
                                       (void*)&wwan_status_ind_reg,
                                       sizeof(qcmap_msgr_wwan_status_ind_register_req_msg_v01),
                                       (void*)&wwan_status_ind_rsp,
                                       sizeof(qcmap_msgr_wwan_status_ind_register_resp_msg_v01),
                                       QMI_TIMEOUT);

  LOG_MSG_INFO1("qmi_client_send_msg_sync(enable): error %d result %d",
      qmi_error, wwan_status_ind_rsp.resp.result,0);

  if ((qmi_error != QMI_NO_ERR) ||
      (wwan_status_ind_rsp.resp.result != QMI_NO_ERR))
  {
    LOG_MSG_ERROR("Can not register for wwan status %d : %d",
        qmi_error, wwan_status_ind_rsp.resp.error,0);
    return QMI_IP_ERROR;
  }

  LOG_MSG_INFO1("Done registering for wwan status",0,0,0);



/*-----------------------------------------------------------------------------
  Register for MOBILE AP state indications from QCMAP
-----------------------------------------------------------------------------*/
  memset(&qcmap_mobile_ap_status_ind_reg, 0,
         sizeof(qcmap_msgr_mobile_ap_status_ind_register_req_msg_v01));
  memset(&qcmap_mobile_ap_status_ind_rsp, 0,
         sizeof(qcmap_msgr_mobile_ap_status_ind_register_resp_msg_v01));

  qcmap_mobile_ap_status_ind_reg.register_indication = 1;
  qmi_error = qmi_client_send_msg_sync(conf->qmi_ip_qcmap_msgr_handle,
                                       QMI_QCMAP_MSGR_MOBILE_AP_STATUS_IND_REG_REQ_V01,
                                       (void*)&qcmap_mobile_ap_status_ind_reg,
                                       sizeof(qcmap_msgr_mobile_ap_status_ind_register_req_msg_v01),
                                       (void*)&qcmap_mobile_ap_status_ind_rsp,
                                       sizeof(qcmap_msgr_mobile_ap_status_ind_register_resp_msg_v01),
                                       9000);

  LOG_MSG_INFO1("qmi_client_send_msg_sync(enable): error %d result %d",
      qmi_error, qcmap_mobile_ap_status_ind_rsp.resp.result, 0);

  if ((qmi_error != QMI_NO_ERR) ||
      (qcmap_mobile_ap_status_ind_rsp.resp.result != QMI_NO_ERR))
  {
    LOG_MSG_ERROR("Can not register for mobile ap status %d : %d",
                  qmi_error,
                  qcmap_mobile_ap_status_ind_rsp.resp.error, 0);
    return QMI_IP_ERROR;
  }

  LOG_MSG_INFO1("Done registering for mobile ap status",0,0,0);

  return QMI_IP_SUCCESS;
}
/**
 * @brief Prepares for call.
 *
 * Obtains a handle to the dsi_netctrl layer and looks up the profile
 * to make the call. As of now. It only searches for profiles that
 * support emergency calls.
 *
 * 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
 *
 * @param[out] client_handle Client handle to initialize.
 * @param[in]  callback      Pointer to callback function table.
 * @param[in]  cookie        Client's cookie for using with callback calls.
 * @param[out] profile_index Pointer to profile index number.
 * @param[out] pdp_type      Pointer to PDP type.
 *
 * @return Operation result
 * @retval E_DS_CLIENT_SUCCESS    On success. Output parameters are initialized.
 * @retval E_DS_CLIENT_FAILURE... On error.
 */
static  ds_client_status_enum_type ds_client_open_call
(
  dsClientHandleType *client_handle,
  const ds_client_cb_data *callback,
  void *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 = 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;
}
/*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;
}