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);
    }
  }
}
int qmi_ip_wds_init(qmi_ip_conf_t * conf, SSL* s, qmi_client_qmux_instance_type rmnet_instance)
{
  qmi_service_info qmi_svc_info;
  int ret_val;
  qmi_client_error_type err;
  qmi_idl_service_object_type wds_service_object;
  wds_indication_register_req_msg_v01 ind_req;
  wds_indication_register_resp_msg_v01 ind_resp;
/*- - - - - - - - - --  - - - - - - -- - - - - - - - - - - - - - - - - - - - */
  if (s == NULL || conf == NULL)
    return -1;
  ssl = s;

  if ((conf->qmi_ip_v4_wds_handle != 0) && (conf->qmi_ip_v6_wds_handle != 0)){
    LOG_MSG_ERROR("Handles already populated",0,0,0);
    return QMI_IP_SUCCESS;
  }

  /*------------------------------------------------------------------
  Get the service object, wait for the service and get the information
  about the service and then get an handle for the service.
  -------------------------------------------------------------------*/
  wds_service_object = wds_get_service_object_v01();

  if(!wds_service_object)
  {
    LOG_MSG_ERROR("qmi_ip wds get service object failed",0,0,0);
    return QMI_IP_ERROR;
  }

  memset(&qmi_svc_info,0,sizeof(qmi_service_info ));

  if(!qmi_ip_wait_for_srv_then_get_info(wds_service_object,
                                      &qmi_svc_info,
                                        rmnet_instance))
  {
    LOG_MSG_ERROR("Error getting info for QMI_IP service",0,0,0);
    return QMI_IP_ERROR;
  }
  /*----------------------------------------------------------------
  Get handle for IPv4
  ------------------------------------------------------------------*/
  ret_val = qmi_client_init(&qmi_svc_info,
                            wds_service_object,
                            (void *) qmi_ip_wds_ind_cb,
                            NULL,
                            NULL,
                            &(conf->qmi_ip_v4_wds_handle));

  if(ret_val != QMI_NO_ERR)
  {
    LOG_MSG_ERROR("Error while trying to initialize client %d", ret_val,0,0);
    return QMI_IP_ERROR;
  }
  else
  {
    LOG_MSG_INFO1("Successfully allocated client init WDS service for v4, handle %d",
                  conf->qmi_ip_v4_wds_handle,0,0);
  }

  if (rmnet_instance != QMI_CLIENT_QMUX_RMNET_INSTANCE_8)
  {
    memset(&ind_req, 0, sizeof(wds_indication_register_req_msg_v01));
    memset(&ind_resp, 0, sizeof(wds_indication_register_resp_msg_v01));
    ind_req.report_embms_tmgi_list_valid = 1;
    ind_req.report_embms_tmgi_list = 1;
    ret_val = qmi_client_send_msg_sync(conf->qmi_ip_v4_wds_handle,
                                       QMI_WDS_INDICATION_REGISTER_REQ_V01,
                                       (void*)&ind_req,
                                       sizeof(wds_indication_register_req_msg_v01),
                                       (void*)&ind_resp,
                                       sizeof(wds_indication_register_resp_msg_v01),
                                       QMI_TIMEOUT);

    if((ret_val != QMI_NO_ERR) || (ind_resp.resp.result != QMI_NO_ERR))
    {
      LOG_MSG_ERROR("Error while trying send message: %d %d", ret_val,
                    ind_resp.resp.result,0);
      return QMI_IP_ERROR;
    }
  }

  /*----------------------------------------------------------------------
  Get handle for IPV6
  -----------------------------------------------------------------------*/
  ret_val = qmi_client_init(&qmi_svc_info,
                            wds_service_object,
                            (void *) qmi_ip_wds_ind_cb,
                            NULL,
                            NULL,
                            &(conf->qmi_ip_v6_wds_handle));
  if(ret_val != QMI_NO_ERR)
  {
    LOG_MSG_ERROR("Error while trying to initialize client ",0,0,0);
    return QMI_IP_ERROR;
  }
  else
  {
    LOG_MSG_INFO1("Successfully allocated client for v6, handle %d",
                  conf->qmi_ip_v6_wds_handle,0,0);
  }

  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;
}
/*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;
}