uint32_t LocationAPIClientBase::locAPIGnssUpdateConfig(GnssConfig config)
{
    uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
    if (memcmp(&mConfig, &config, sizeof(GnssConfig)) == 0) {
        LOC_LOGV("%s:%d] GnssConfig is identical to previous call", __FUNCTION__, __LINE__);
        retVal = LOCATION_ERROR_SUCCESS;
        return retVal;
    }

    pthread_mutex_lock(&mMutex);
    if (mLocationControlAPI) {

        memcpy(&mConfig, &config, sizeof(GnssConfig));

        uint32_t session = 0;
        RequestQueue* requests = mRequestQueues[REQUEST_CONFIG];
        uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
        LOC_LOGV("%s:%d] gnssUpdateConfig return array: %p", __FUNCTION__, __LINE__, idArray);
        if (!requests && idArray != nullptr) {
            requests = new RequestQueue(idArray[0]);
            mRequestQueues[REQUEST_CONFIG] = requests;
        }
        if (requests) {
            requests->push(new GnssUpdateConfigRequest(*this));
            retVal = LOCATION_ERROR_SUCCESS;
        }
    }
    pthread_mutex_unlock(&mMutex);
    return retVal;
}
Esempio n. 2
0
/*===========================================================================

FUNCTION    loc_sync_send_req

DESCRIPTION
   Synchronous req call (thread safe)

DEPENDENCIES
   N/A

RETURN VALUE
   Loc API 2.0 status

SIDE EFFECTS
   N/A

===========================================================================*/
locClientStatusEnumType loc_sync_send_req
(
      locClientHandleType       client_handle,
      uint32_t                  req_id,        /* req id */
      locClientReqUnionType     req_payload,
      uint32_t                  timeout_msec,
      uint32_t                  ind_id,  //ind ID to block for, usually the same as req_id */
      void                      *ind_payload_ptr /* can be NULL*/
)
{
   locClientStatusEnumType status = eLOC_CLIENT_SUCCESS ;
   int select_id;
   int rc = 0;

   // Select the callback we are waiting for
   select_id = loc_sync_select_ind(client_handle, ind_id, req_id,
                                   ind_payload_ptr);

   if (select_id >= 0)
   {
      status =  locClientSendReq (client_handle, req_id, req_payload);
      LOC_LOGV("%s:%d]: select_id = %d,locClientSendReq returned %d\n",
                    __func__, __LINE__, select_id, status);

      if (status != eLOC_CLIENT_SUCCESS )
      {
         loc_free_slot(select_id);
      }
      else
      {
         // Wait for the indication callback
         if (( rc = loc_sync_wait_for_ind( select_id,
                                           timeout_msec / 1000,
                                           ind_id) ) < 0)
         {
            if ( rc == -ETIMEDOUT)
               status = eLOC_CLIENT_FAILURE_TIMEOUT;
            else
               status = eLOC_CLIENT_FAILURE_INTERNAL;

            // Callback waiting failed
            LOC_LOGE("%s:%d]: loc_api_wait_for_ind failed, err %d, "
                     "select id %d, status %s", __func__, __LINE__, rc ,
                     select_id, loc_get_v02_client_status_name(status));
         }
         else
         {
            status =  eLOC_CLIENT_SUCCESS;
            LOC_LOGV("%s:%d]: success (select id %d)\n",
                          __func__, __LINE__, select_id);
         }
      }
   } /* select id */

   return status;
}
Esempio n. 3
0
void LocApiBase::reportPosition(UlpLocation &location,
                                GpsLocationExtended &locationExtended,
                                void* locationExt,
                                enum loc_sess_status status,
                                LocPosTechMask loc_technology_mask)
{
    // print the location info before delivering
    LOC_LOGV("flags: %d\n  source: %d\n  latitude: %f\n  longitude: %f\n  "
             "altitude: %f\n  speed: %f\n  bearing: %f\n  accuracy: %f\n  "
             "timestamp: %lld\n  rawDataSize: %d\n  rawData: %p\n  "
             "Session status: %d\n Technology mask: %u",
             location.gpsLocation.flags, location.position_source,
             location.gpsLocation.latitude, location.gpsLocation.longitude,
             location.gpsLocation.altitude, location.gpsLocation.speed,
             location.gpsLocation.bearing, location.gpsLocation.accuracy,
             location.gpsLocation.timestamp, location.rawDataSize,
             location.rawData, status, loc_technology_mask);
    // loop through adapters, and deliver to all adapters.
    TO_ALL_LOCADAPTERS(
        mLocAdapters[i]->reportPosition(location,
                                        locationExtended,
                                        locationExt,
                                        status,
                                        loc_technology_mask)
    );
}
Esempio n. 4
0
/*===========================================================================

FUNCTION   loc_sync_req_init

DESCRIPTION
   Initialize this module

DEPENDENCIES
   N/A

RETURN VALUE
   none

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_sync_req_init()
{
   LOC_LOGV(" %s:%d]:\n", __func__, __LINE__);
   pthread_mutex_lock(&loc_sync_call_mutex);
   if(true == loc_sync_call_initialized)
   {
      LOC_LOGD("%s:%d]:already initialized\n", __func__, __LINE__);
      pthread_mutex_unlock(&loc_sync_call_mutex);
      return;
   }

   loc_sync_array.in_use = false;

   memset(loc_sync_array.slot_in_use, 0, sizeof(loc_sync_array.slot_in_use));

   int i;
   for (i = 0; i < LOC_SYNC_REQ_BUFFER_SIZE; i++)
   {
      loc_sync_req_data_s_type *slot = &loc_sync_array.slots[i];

      pthread_mutex_init(&slot->sync_req_lock, NULL);
      pthread_cond_init(&slot->ind_arrived_cond, NULL);

      slot->client_handle = LOC_CLIENT_INVALID_HANDLE_VALUE;
      slot->ind_is_selected = false;       /* is ind selected? */
      slot->ind_is_waiting  = false;       /* is waiting?     */
      slot->ind_has_arrived = false;       /* callback has arrived */
      slot->recv_ind_id = 0;       /* ind to wait for   */
      slot->recv_ind_payload_ptr = NULL;
      slot->req_id =  0;   /* req id   */
   }

   loc_sync_call_initialized = true;
   pthread_mutex_unlock(&loc_sync_call_mutex);
}
/* Returns 1 if successful */
bool_t rpc_loc_event_cb_f_type_svc(
      rpc_loc_event_cb_f_type_args *argp,
      rpc_loc_event_cb_f_type_rets *ret,
      struct svc_req *req)
{
    // The lower word of cd_id is the index
    int index = argp->cb_id & 0xFFFF;

    /* Callback not registered, or unexpected ID (shouldn't happen) */
    if (index >= LOC_API_CB_MAX_CLIENTS || loc_glue_callback_table[index].cb_func == NULL)
    {
        LOC_LOGE("Warning: No callback handler %d.\n", index);
        ret->loc_event_cb_f_type_result = 0;
        return 1; /* simply return */
    }

    LOC_LOGV("proc: %x  prog: %x  vers: %x\n",
         (int) req->rq_proc,
         (int) req->rq_prog,
         (int) req->rq_vers);

    LOC_LOGV("Callback received: %x (cb_id=%p handle=%d ret_ptr=%d)\n",
         (int) argp->loc_event,
               argp->cb_id,
         (int) argp->loc_handle,
         (int) ret);

    /* Forward callback to real callback procedure */
    rpc_loc_client_handle_type        loc_handle = argp->loc_handle;
    rpc_loc_event_mask_type           loc_event  = argp->loc_event;
    const rpc_loc_event_payload_u_type*  loc_event_payload =
        (const rpc_loc_event_payload_u_type*) argp->loc_event_payload;

    /* Gives control to synchronous call handler */
    loc_api_callback_process_sync_call(loc_handle, loc_event, loc_event_payload);

    int32 rc = (loc_glue_callback_table[index].cb_func)(loc_glue_callback_table[index].user,
                                                        loc_handle, loc_event, loc_event_payload);

    LOC_LOGV("cb_func=%p", loc_glue_callback_table[index].cb_func);

    ret->loc_event_cb_f_type_result = rc;

    return 1; /* ok */
}
/*!
 * \brief Checks if QCA1530 is avalable.
 *
 * Function verifies if qca1530 SoC is configured on the device. The test is
 * based on property value. For 1530 scenario, the value shall be one of the
 * following: "yes", "no", "detect". All other values are treated equally to
 * "no". When the value is "detect" the system waits for SoC detection to
 * finish before returning result.
 *
 * \retval true - QCA1530 is available.
 * \retval false - QCA1530 is not available.
 */
static bool is_qca1530(void)
{
    static const char qca1530_property_name[] = "persist.qca1530";
    bool res = false;
    int ret, i;
    char buf[PROPERTY_VALUE_MAX];

    memset(buf, 0, sizeof(buf));

    for (i = 0; i < QCA1530_DETECT_TIMEOUT; ++i)
    {
        ret = property_get(qca1530_property_name, buf, NULL);
        if (ret < 0)
        {
            LOC_LOGV( "qca1530: property %s is not accessible, ret=%d",
                  qca1530_property_name,
                  ret);

            break;
        }

        LOC_LOGV( "qca1530: property %s is set to %s",
                  qca1530_property_name,
                  buf);

        if (!memcmp(buf, QCA1530_DETECT_PRESENT,
                    sizeof(QCA1530_DETECT_PRESENT)))
        {
            res = true;
            break;
        }
        if (!memcmp(buf, QCA1530_DETECT_PROGRESS,
                    sizeof(QCA1530_DETECT_PROGRESS)))
        {
            LOC_LOGV("qca1530: SoC detection is in progress.");
            sleep(1);
            continue;
        }
        break;
    }

    LOC_LOGD("qca1530: detected=%s", res ? "true" : "false");
    return res;
}
/*===========================================================================

FUNCTION loc_api_glue_init

DESCRIPTION
   Initiates the RPC client

RETURN VALUE
   1 for success
   0 for failure

===========================================================================*/
int loc_api_glue_init(void)
{
   if (loc_api_clnt == NULL)
   {
      /* Initialize data */
      int i;
      int pid = getpid();
      for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++)
      {
          loc_glue_callback_table[i].cb_id = i | (pid << 16);
          loc_glue_callback_table[i].cb_func = NULL;
          loc_glue_callback_table[i].handle = -1;
          loc_glue_callback_table[i].rpc_cb = NULL;
          loc_glue_callback_table[i].user = NULL;
      }

      /* Print msg */
      LOC_LOGV("Trying to create RPC client...\n");
      loc_api_clnt = clnt_create(NULL, LOC_APIPROG, LOC_APIVERS, NULL);
      LOC_LOGV("Created loc_api_clnt ---- %x\n", (unsigned int)loc_api_clnt);

      if (loc_api_clnt == NULL)
      {
         LOC_LOGE("Error: cannot create RPC client.\n");
         return 0;
      }

      /* Init RPC callbacks */
      loc_api_sync_call_init();

      int rc = loc_apicb_app_init();
      if (rc >= 0)
      {
         LOC_LOGD("Loc API RPC client initialized.\n");
         clnt_register_reset_notification_cb(loc_api_clnt, loc_api_glue_rpc_cb);
      }
      else {
         LOC_LOGE("Loc API callback initialization failed.\n");
         return 0;
      }
   }

   return 1;
}
void LocPosMode::logv() const
{
    LOC_LOGV ("Position mode: %s\n  Position recurrence: %s\n  "
              "min interval: %d\n  preferred accuracy: %d\n  "
              "preferred time: %d\n  credentials: %s  provider: %s",
              loc_get_position_mode_name(mode),
              loc_get_position_recurrence_name(recurrence),
              min_interval,
              preferred_accuracy,
              preferred_time,
              credentials,
              provider);
}
void LocationAPIClientBase::onCtrlResponseCb(LocationError error, uint32_t id)
{
    if (error != LOCATION_ERROR_SUCCESS) {
        LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, error, id);
    } else {
        LOC_LOGV("%s:%d] error: %d id: %d", __FUNCTION__, __LINE__, error, id);
    }
    LocationAPIRequest* request = getRequestBySession(id);
    if (request) {
        request->onResponse(error);
        delete request;
    }
}
Esempio n. 10
0
void LocApiBase::reportSv(GnssSvStatus &svStatus,
                  GpsLocationExtended &locationExtended,
                  void* svExt)
{
    // print the SV info before delivering
    LOC_LOGV("num sv: %d", svStatus.num_svs);
    for (int i = 0; i < svStatus.num_svs && i < GNSS_MAX_SVS; i++) {
        LOC_LOGV("   %03d:   %02d    %d    %f    %f    %f   0x%02X",
                 i,
                 svStatus.gnss_sv_list[i].svid,
                 svStatus.gnss_sv_list[i].constellation,
                 svStatus.gnss_sv_list[i].c_n0_dbhz,
                 svStatus.gnss_sv_list[i].elevation,
                 svStatus.gnss_sv_list[i].azimuth,
                 svStatus.gnss_sv_list[i].flags);
    }
    // loop through adapters, and deliver to all adapters.
    TO_ALL_LOCADAPTERS(
        mLocAdapters[i]->reportSv(svStatus,
                                     locationExtended,
                                     svExt)
    );
}
/* Logs valid fields in the GNSS SV constellation report */
static void log_satellite_report(const rpc_loc_gnss_info_s_type *gnss)
{
   if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_POS_DOP)
   {
      LOC_LOGV("position dop: %.3f\n", (float) gnss->position_dop);
   }
   if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_HOR_DOP)
   {
      LOC_LOGV("horizontal dop: %.3f\n", (float) gnss->horizontal_dop);
   }
   if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_VERT_DOP)
   {
      LOC_LOGV("vertical dop: %.3f\n", (float) gnss->vertical_dop);
   }
   if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_ALTITUDE_ASSUMED)
   {
      LOC_LOGV("altitude assumed: %d\n", (int) gnss->altitude_assumed);
   }
   if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_SV_COUNT)
   {
      LOC_LOGD("sv count: %d\n", (int) gnss->sv_count);
   }
   if (gnss->valid_mask & RPC_LOC_GNSS_INFO_VALID_SV_LIST)
   {
      LOC_LOGV("sv list: ");

      if (gnss->sv_count)
      {
         LOC_LOGV("\n\tsys\tprn\thlth\tproc\teph\talm\telev\tazi\tsnr\n");
      }
      else {
         LOC_LOGV("empty\n");
      }

      int i;
      for (i = 0; i < gnss->sv_count; i++)
      {
         const rpc_loc_sv_info_s_type *sv = &gnss->sv_list.sv_list_val[i];
         rpc_loc_sv_info_valid_mask_type mask = sv->valid_mask;
         LOC_LOGV("  %d: \t%d\t%d\t%d\t%d\t%d\t%d\t%.3f\t%.3f\t%.3f\n", i,
               CHECK_MASK(int,   sv->system,         mask, RPC_LOC_SV_INFO_VALID_SYSTEM),
               CHECK_MASK(int,   sv->prn,            mask, RPC_LOC_SV_INFO_VALID_PRN),
               CHECK_MASK(int,   sv->health_status,  mask, RPC_LOC_SV_INFO_VALID_HEALTH_STATUS),
               CHECK_MASK(int,   sv->process_status, mask, RPC_LOC_SV_INFO_VALID_PROCESS_STATUS),
               CHECK_MASK(int,   sv->has_eph,        mask, RPC_LOC_SV_INFO_VALID_HAS_EPH),
               CHECK_MASK(int,   sv->has_alm,        mask, RPC_LOC_SV_INFO_VALID_HAS_ALM),
               CHECK_MASK(float, sv->elevation,      mask, RPC_LOC_SV_INFO_VALID_ELEVATION),
               CHECK_MASK(float, sv->azimuth,        mask, RPC_LOC_SV_INFO_VALID_AZIMUTH),
               CHECK_MASK(float, sv->snr,            mask, RPC_LOC_SV_INFO_VALID_SNR)
         );
      }
   }
LocEng::LocEng(void* caller,
               LOC_API_ADAPTER_EVENT_MASK_T emask,
               gps_acquire_wakelock acqwl,
               gps_release_wakelock relwl,
               loc_msg_sender msgSender,
               loc_msg_sender msgUlpSender,
               loc_ext_parser posParser,
               loc_ext_parser svParser) :
        owner(caller),
        eventMask(emask), acquireWakelock(acqwl),
        releaseWakeLock(relwl), sendMsge(msgSender), sendUlpMsg(msgUlpSender),
        extPosInfo(NULL == posParser ? noProc : posParser),
        extSvInfo(NULL == svParser ? noProc : svParser)
{
    LOC_LOGV("LocEng constructor %p, %p", posParser, svParser);
}
void LocationAPIClientBase::onCtrlCollectiveResponseCb(
        size_t count, LocationError* errors, uint32_t* ids)
{
    for (size_t i = 0; i < count; i++) {
        if (errors[i] != LOCATION_ERROR_SUCCESS) {
            LOC_LOGE("%s:%d] ERROR: %d ID: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
        } else {
            LOC_LOGV("%s:%d] error: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
        }
    }
    LocationAPIRequest* request = nullptr;
    pthread_mutex_lock(&mMutex);
    if (mRequestQueues[REQUEST_CONFIG] != nullptr) {
        request = mRequestQueues[REQUEST_CONFIG]->pop();
    }
    pthread_mutex_unlock(&mMutex);
    if (request) {
        request->onCollectiveResponse(count, errors, ids);
        delete request;
    }
}
Esempio n. 14
0
// callbacks
void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
{
    LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
    mLocationCapabilitiesMask = capabilitiesMask;
    mLocationCapabilitiesCached = true;
    if (mGnssCbIface != nullptr) {
        uint32_t data = 0;
        if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
                (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
                (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
                (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
            data |= IGnssCallback::Capabilities::SCHEDULING;
        if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
            data |= IGnssCallback::Capabilities::GEOFENCING;
        if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
            data |= IGnssCallback::Capabilities::MEASUREMENTS;
        if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
            data |= IGnssCallback::Capabilities::MSB;
        if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
            data |= IGnssCallback::Capabilities::MSA;
        auto r = mGnssCbIface->gnssSetCapabilitesCb(data);
        if (!r.isOk()) {
            LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
                __func__, r.description().c_str());
        }
    }
    if (mGnssCbIface != nullptr) {
        IGnssCallback::GnssSystemInfo gnssInfo;
        gnssInfo.yearOfHw = 2015;
        if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
            gnssInfo.yearOfHw = 2017;
        }
        LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
        auto r = mGnssCbIface->gnssSetSystemInfoCb(gnssInfo);
        if (!r.isOk()) {
            LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
                __func__, r.description().c_str());
        }
    }
}
Esempio n. 15
0
/*===========================================================================

FUNCTION    loc_alloc_slot

DESCRIPTION
   Allocates a buffer slot for the synchronous API call

DEPENDENCIES
   N/A

RETURN VALUE
   Select ID (>=0)     : successful
   -1                  : buffer full

SIDE EFFECTS
   N/A

===========================================================================*/
static int loc_alloc_slot()
{
   int i, select_id = -1; /* no free buffer */

   pthread_mutex_lock(&loc_sync_call_mutex);

   for (i = 0; i < LOC_SYNC_REQ_BUFFER_SIZE; i++)
   {
      if (!loc_sync_array.slot_in_use[i])
      {
         select_id = i;
         loc_sync_array.slot_in_use[i] = 1;
         loc_sync_array.in_use = true;
         break;
      }
   }

   pthread_mutex_unlock(&loc_sync_call_mutex);
   LOC_LOGV("%s:%d]: returning slot %d\n",
                 __func__, __LINE__, select_id);
   return select_id;
}
Esempio n. 16
0
/*===========================================================================

FUNCTION    loc_sync_select_ind

DESCRIPTION
   Selects which indication to wait for.


DEPENDENCIES
   N/A

RETURN VALUE
   Select ID (>=0)     : successful
   -ENOMEM                  : out of buffer

SIDE EFFECTS
   N/A

===========================================================================*/
static int loc_sync_select_ind(
      locClientHandleType       client_handle,   /* Client handle */
      uint32_t                  ind_id,  /* ind Id wait for */
      uint32_t                  req_id,   /* req id */
      void *                    ind_payload_ptr /* ptr where payload should be copied to*/
)
{
   int select_id = loc_alloc_slot();

   LOC_LOGV("%s:%d]: client handle %p, ind_id %u, req_id %u \n",
                 __func__, __LINE__, client_handle, ind_id, req_id);

   if (select_id < 0)
   {
      LOC_LOGE("%s:%d]: buffer full for this synchronous req %s \n",
                 __func__, __LINE__, loc_get_v02_event_name(req_id));
      return -ENOMEM;
   }

   loc_sync_req_data_s_type *slot = &loc_sync_array.slots[select_id];

   pthread_mutex_lock(&slot->sync_req_lock);

   slot->client_handle = client_handle;
   slot->ind_is_selected = true;
   slot->ind_is_waiting = false;
   slot->ind_has_arrived = false;

   slot->recv_ind_id = ind_id;
   slot->req_id      = req_id;
   slot->recv_ind_payload_ptr = ind_payload_ptr; //store the payload ptr

   pthread_mutex_unlock(&slot->sync_req_lock);

   return select_id;
}
rpc_loc_client_handle_type loc_open (
    rpc_loc_event_mask_type       event_reg_mask,
    loc_event_cb_f_type           *event_callback,
    loc_reset_notif_cb_f_type     *rpc_cb,
    void*                         userData
)
{
    int try_num = RPC_TRY_NUM;
    ENTRY_LOG();
    LOC_GLUE_CHECK_INIT(rpc_loc_client_handle_type);

    rpc_loc_client_handle_type ret_val;

    rpc_loc_open_args args;
    args.event_reg_mask = event_reg_mask;

    int i, j = LOC_API_CB_MAX_CLIENTS;
    for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++)
    {
        if (loc_glue_callback_table[i].user == userData)
        {
            LOC_LOGW("Client already opened service (callback=%p)...\n",
                  event_callback);
            break;
        } else if (j == LOC_API_CB_MAX_CLIENTS &&
                   loc_glue_callback_table[i].user == NULL) {
            j = i;
        }
    }

    if (i == LOC_API_CB_MAX_CLIENTS)
    {
        i = j;
    }

    if (i == LOC_API_CB_MAX_CLIENTS)
    {
        LOC_LOGE("Too many clients opened at once...\n");
        return RPC_LOC_CLIENT_HANDLE_INVALID;
    }

    loc_glue_callback_table[i].cb_func = event_callback;
    loc_glue_callback_table[i].rpc_cb = rpc_cb;
    loc_glue_callback_table[i].user = userData;

    args.event_callback = loc_glue_callback_table[i].cb_id;
    LOC_LOGV("cb_id=%d, func=0x%x", i, (unsigned int) event_callback);

    rpc_loc_open_rets rets;
    enum clnt_stat stat = RPC_SUCCESS;

    EXIT_LOG_CALLFLOW(%s, "loc client open");

     /*try more for rpc_loc_open_xx()*/

    do
    {
        stat = RPC_FUNC_VERSION(rpc_loc_open_, RPC_LOC_OPEN_VERSION)(&args, &rets, loc_api_clnt);
        ret_val = (rpc_loc_client_handle_type) rets.loc_open_result;
        try_num--;

    }while( (RPC_SUCCESS != stat||0 > ret_val) && 0 != try_num );

    LOC_GLUE_CHECK_RESULT(stat, int32);

    /* save the handle in the table */
    loc_glue_callback_table[i].handle = (rpc_loc_client_handle_type) rets.loc_open_result;

    return ret_val;

}
LocApiAdapter::~LocApiAdapter()
{
    LOC_LOGV("LocApiAdapter deleted");
}
/*=====================================================================================
 * Function ulp_msg_main thread processing routine
 *
 * Description
 *  This is the processing routine of ulp_msg thread. It waits on messages posted
 *  to libulp module and processes on those messages.
 *
 * Parameters:
 *   context.  //unused
 *
 * Return value:
 *   NULL: on exit
 =============================================================================================*/
void ulp_msg_main(void * context)
{
   int msg_length;
   ulp_msg *msg = NULL;

   ENTRY_LOG_CALLFLOW();

   while (1)
   {
      msq_q_err_type result = msg_q_rcv(ulp_data.loc_proxy->mQ,
                                        (void **) &msg);
      if (eMSG_Q_SUCCESS != result)
      {
         LOC_LOGE("%s:%d] fail receiving msg: \n", __func__, __LINE__);
         return;
      }
      LOC_LOGD("%s received msg of type: 0x%x\n", __func__, msg->msgid);

      switch(msg->msgid)
      {
      // Message is sent by GPS HAL layer to add/remove unique request criteria
      case ULP_MSG_UPDATE_CRITERIA:
      {
         ulp_msg_update_criteria* criteriaMsg = (ulp_msg_update_criteria*) msg;
         ulp_msg_process_criteria_update (&(criteriaMsg->locationCriteria));
         break;
      }

      // Message is sent by GPS HAL layer to request ULP to provide the debug info.
      case ULP_MSG_INJECT_RAW_COMMAND:
      {
        ulp_msg_inject_raw_command* rawCmdMsg = (ulp_msg_inject_raw_command*) msg;
        ulp_msg_process_raw_command(rawCmdMsg->rawCommand, rawCmdMsg->rawCommandLength);
        break;
      }

      // Message is sent by GPS HAL layer to request ULP to start producing position fixes
      case ULP_MSG_START_FIX:
      {
         ulp_msg_process_start_req ();
         break;
      }

      // Message is sent by FLP to request ULP to stop producing position fixes
      case ULP_MSG_STOP_FLP_FIX:
      {
         ulp_msg_process_stop_req ();
         break;
      }

      // Message is sent by GPS HAL to request ULP to stop producing position fixes
      case ULP_MSG_STOP_GNSS_FIX:
      {
         ulp_msg_process_gnss_stop ();
         break;
      }


      // Message is sent by GPS HAL layer to report phone context setting
      // include initial phone context setting and subsequent changes
      case ULP_MSG_INJECT_PHONE_CONTEXT_SETTINGS:
      {
         ulp_msg_inject_phone_context_settings* phoneSettingMsg = (ulp_msg_inject_phone_context_settings*) msg;
         ulp_msg_process_phone_setting_update (&phoneSettingMsg->phoneSetting);
         break;
      }

      // Message is sent by network provider to report the position in UlpNetworkPositionReport format
      case ULP_MSG_INJECT_NETWORK_POSITION:
      {
         ulp_msg_inject_network_position* networkPositionMsg = (ulp_msg_inject_network_position*) msg;
         ulp_msg_process_network_position_report (&networkPositionMsg->networkPosition);
         break;
      }

      // Message is sent by GNSS provider in order to report the position in GpsPosition format
      case ULP_MSG_REPORT_POSITION:
      {
         ulp_msg_report_position* positionMsg = (ulp_msg_report_position*) msg;

         if ( positionMsg->location.position_source == ULP_LOCATION_IS_FROM_GNSS)
         {
            ulp_msg_process_gnss_position_report ( positionMsg->status,
                                                   positionMsg->technology_mask,
                                                   &positionMsg->location,
                                                   &positionMsg->locationExtended,
                                                   positionMsg->locationExt);
         }
         else if(positionMsg->location.position_source == ULP_LOCATION_IS_FROM_ZPP)
         {
            ulp_msg_process_zpp_position_report ( positionMsg->status,
                                                  positionMsg->technology_mask,
                                                  &positionMsg->location);
         }
         else if(positionMsg->location.position_source == ULP_LOCATION_IS_FROM_GEOFENCE)
         {
            LOC_LOGD("%s:%d]: ULP_MSG_REPORT_POSITION ULP_LOCATION_IS_FROM_GEOFENCE",
                     __func__, __LINE__);
            ulp_msg_process_geofence_position_report ( &positionMsg->location);
         }
         else if(positionMsg->location.position_source == ULP_LOCATION_IS_FROM_HW_FLP)
         {
             LOC_LOGD("%s:%d]: ULP_MSG_REPORT_POSITION ULP_LOCATION_IS_FROM_HW_FLP",
                     __func__, __LINE__);
             //TODO
         }
         break;
      }

      // Message is sent by HW FLP
      case ULP_MSG_REPORT_POSITIONS:
      {
          ulp_msg_report_positions* positionMsg = (ulp_msg_report_positions*) msg;
          LOC_LOGD("%s:%d]: ULP_MSG_REPORT_POSITION ULP_LOCATION_IS_FROM_HW_FLP",
                  __func__, __LINE__);
          //TODO
          break;
      }

      // Message is sent by GNSS provider in order to report the SV info
      case ULP_MSG_REPORT_SV:
      {
         ulp_msg_report_sv* svMsg = (ulp_msg_report_sv*) msg;
         ulp_msg_process_gnss_sv_report ( &svMsg->svStatus, &svMsg->locationExtended, svMsg->svExt);
         break;
      }

      // Message is sent by QUIPC in order to report the position in GpsPosition format
      // together with QUIPC status
      case ULP_MSG_REPORT_QUIPC_POSITION:
      {
         ulp_msg_report_quipc_position* positionMsg = (ulp_msg_report_quipc_position*) msg;
         ulp_msg_process_quipc_position_report (positionMsg->quipc_error_code, &positionMsg->location);
         break;
      }

      // Message is sent by QUIPC in order to request coarse position info
      case ULP_MSG_REQUEST_COARSE_POSITION:
      {
         ulp_msg_process_coarse_position_request ();
         break;
      }

      // Message is sent by ULP monitor thread to request ULP main thread
      // to re-evaulate the status of each subsystem
      case ULP_MSG_MONITOR:
      {
         ulp_msg_process_monitor_request ();
         break;
      }

      // Message is sent by GPS Location provider to start a session
      case ULP_MSG_SET_POSITION_MODE:
      {
         ulp_msg_position_mode *setPosModeMsg = (ulp_msg_position_mode*)msg;
         ulp_msg_process_gnss_set_pos_mode(setPosModeMsg->pMode.min_interval,
                                           setPosModeMsg->pMode.recurrence,
                                           setPosModeMsg->pMode.mode);
         break;
      }

      //Status report is sent by GPS engine to inform the following events:
      //Session begin, session end, engine on, engine off
      case ULP_MSG_REPORT_STATUS:
      {
          ulp_msg_report_status *statusMsg = (ulp_msg_report_status*)msg;
          ulp_msg_process_status_report(statusMsg->engStatus);
          break;
      }

      // Message is sent to ULP module when system events occur
      case ULP_MSG_SYSTEM_UPDATE:
      {
         ulp_msg_system_update* systemUpdateMsg = (ulp_msg_system_update* ) msg;
         ulp_msg_process_system_update (systemUpdateMsg->systemEvent);
         break;
      }

      case ULP_MSG_REPORT_BATCHING_SESSION:
      {
          //TODO
          ulp_msg_report_batching_session * batchingSessionMsg =
              (ulp_msg_report_batching_session*)msg;
          LOC_LOGV("%s:%d]",__func__, __LINE__);
          LOC_LOGV("Max Power Allocation(mw): %f\n sources to use: %d\n flags: %d\n period(ns) %lld active: %d\n",
              batchingSessionMsg->options.max_power_allocation_mW,
              batchingSessionMsg->options.sources_to_use,
              batchingSessionMsg->options.flags,
              batchingSessionMsg->options.period_ns,
              batchingSessionMsg->active);
          break;
      }

      default:
         LOC_LOGE ("%s, received unknown message of type %d, discard \n", __func__, msg->msgid);
         break;
      }

      delete msg;
   };

   EXIT_LOG(%s, VOID_RET);
   return;
}
Esempio n. 20
0
/*===========================================================================

FUNCTION loc_ni_request_handler

DESCRIPTION
   Displays the NI request and awaits user input. If a previous request is
   in session, it is ignored.

RETURN VALUE
   none

===========================================================================*/
static void loc_ni_request_handler(const char *msg, const rpc_loc_ni_event_s_type *ni_req)
{
   GpsNiNotification notif;
   char lcs_addr[32]; // Decoded LCS address for UMTS CP NI

   notif.size = sizeof(notif);
   strlcpy(notif.text, "[text]", sizeof notif.text);    // defaults
   strlcpy(notif.requestor_id, "[requestor id]", sizeof notif.requestor_id);

   /* If busy, use default or deny */
   if (loc_eng_ni_data.notif_in_progress)
   {
      /* XXX Consider sending a NO RESPONSE reply or queue the request */
      LOC_LOGW("loc_ni_request_handler, notification in progress, new NI request ignored, type: %d",
            ni_req->event);
   }
   else {
      /* Print notification */
      LOC_LOGD("NI Notification: %s, event: %d", msg, ni_req->event);

      pthread_mutex_lock(&loc_eng_ni_data.loc_ni_lock);

      /* Save request */
      memcpy(&loc_eng_ni_data.loc_ni_request, ni_req, sizeof loc_eng_ni_data.loc_ni_request);

      /* Set up NI response waiting */
      loc_eng_ni_data.notif_in_progress = TRUE;
      loc_eng_ni_data.current_notif_id = abs(rand());

      /* Fill in notification */
      notif.notification_id = loc_eng_ni_data.current_notif_id;

      const rpc_loc_ni_vx_notify_verify_req_s_type *vx_req;
      const rpc_loc_ni_supl_notify_verify_req_s_type *supl_req;
      const rpc_loc_ni_umts_cp_notify_verify_req_s_type *umts_cp_req;

      switch (ni_req->event)
      {
      case RPC_LOC_NI_EVENT_VX_NOTIFY_VERIFY_REQ:
         vx_req = &ni_req->payload.rpc_loc_ni_event_payload_u_type_u.vx_req;
         notif.ni_type     = GPS_NI_TYPE_VOICE;
         notif.timeout     = LOC_NI_NO_RESPONSE_TIME; // vx_req->user_resp_timer_val;
         memset(notif.extras, 0, sizeof notif.extras);
         memset(notif.text, 0, sizeof notif.text);
         memset(notif.requestor_id, 0, sizeof notif.requestor_id);

         // Requestor ID
         hexcode(notif.requestor_id, sizeof notif.requestor_id,
               vx_req->requester_id.requester_id,
               vx_req->requester_id.requester_id_length);

         notif.text_encoding = 0; // No text and no encoding
         notif.requestor_id_encoding = convert_encoding_type(vx_req->encoding_scheme);

         // Set default_response & notify_flags
         loc_ni_fill_notif_verify_type(&notif, vx_req->notification_priv_type);

         // Privacy override handling
         if (vx_req->notification_priv_type == RPC_LOC_NI_USER_PRIVACY_OVERRIDE)
         {
            loc_eng_mute_one_session();
         }

         break;

      case RPC_LOC_NI_EVENT_UMTS_CP_NOTIFY_VERIFY_REQ:
         umts_cp_req = &ni_req->payload.rpc_loc_ni_event_payload_u_type_u.umts_cp_req;
         notif.ni_type     = GPS_NI_TYPE_UMTS_CTRL_PLANE;
         notif.timeout     = LOC_NI_NO_RESPONSE_TIME; // umts_cp_req->user_response_timer;
         memset(notif.extras, 0, sizeof notif.extras);
         memset(notif.text, 0, sizeof notif.text);
         memset(notif.requestor_id, 0, sizeof notif.requestor_id);

         // Stores notification text
#if (AMSS_VERSION==3200)
         hexcode(notif.text, sizeof notif.text,
               umts_cp_req->notification_text.notification_text_val,
               umts_cp_req->notification_length);
#else
         hexcode(notif.text, sizeof notif.text,
               umts_cp_req->notification_text,
               umts_cp_req->notification_length);
#endif /* #if (AMSS_VERSION==3200) */

         // Stores requestor ID
#if (AMSS_VERSION==3200)
         hexcode(notif.requestor_id, sizeof notif.requestor_id,
               umts_cp_req->requestor_id.requestor_id_string.requestor_id_string_val,
               umts_cp_req->requestor_id.string_len);
#else
         hexcode(notif.requestor_id, sizeof notif.requestor_id,
               umts_cp_req->requestor_id.requestor_id_string,
               umts_cp_req->requestor_id.string_len);
#endif

         // Encodings
         notif.text_encoding = convert_encoding_type(umts_cp_req->datacoding_scheme);
         notif.requestor_id_encoding = convert_encoding_type(umts_cp_req->datacoding_scheme);

         // LCS address (using extras field)
         if (umts_cp_req->ext_client_address_data.ext_client_address_len != 0)
         {
            // Copy LCS Address into notif.extras in the format: Address = 012345
            strlcat(notif.extras, LOC_NI_NOTIF_KEY_ADDRESS, sizeof notif.extras);
            strlcat(notif.extras, " = ", sizeof notif.extras);
            int addr_len = 0;
            const char *address_source = NULL;

#if (AMSS_VERSION==3200)
            address_source = umts_cp_req->ext_client_address_data.ext_client_address.ext_client_address_val;
#else
            address_source = umts_cp_req->ext_client_address_data.ext_client_address;
#endif /* #if (AMSS_VERSION==3200) */

            addr_len = decode_address(lcs_addr, sizeof lcs_addr,
               address_source, umts_cp_req->ext_client_address_data.ext_client_address_len);

            // The address is ASCII string
            if (addr_len)
            {
               strlcat(notif.extras, lcs_addr, sizeof notif.extras);
            }
         }

         // Set default_response & notify_flags
         loc_ni_fill_notif_verify_type(&notif, umts_cp_req->notification_priv_type);

         // Privacy override handling
         if (umts_cp_req->notification_priv_type == RPC_LOC_NI_USER_PRIVACY_OVERRIDE)
         {
            loc_eng_mute_one_session();
         }

         break;

      case RPC_LOC_NI_EVENT_SUPL_NOTIFY_VERIFY_REQ:
         supl_req = &ni_req->payload.rpc_loc_ni_event_payload_u_type_u.supl_req;
         notif.ni_type     = GPS_NI_TYPE_UMTS_SUPL;
         notif.timeout     = LOC_NI_NO_RESPONSE_TIME; // supl_req->user_response_timer;
         memset(notif.extras, 0, sizeof notif.extras);
         memset(notif.text, 0, sizeof notif.text);
         memset(notif.requestor_id, 0, sizeof notif.requestor_id);

         // Client name
         if (supl_req->flags & RPC_LOC_NI_CLIENT_NAME_PRESENT)
         {

#if (AMSS_VERSION==3200)
            hexcode(notif.text, sizeof notif.text,
                    supl_req->client_name.client_name_string.client_name_string_val,   /* buffer */
                    supl_req->client_name.string_len                                   /* length */
            );
#else
            hexcode(notif.text, sizeof notif.text,
                            supl_req->client_name.client_name_string,   /* buffer */
                            supl_req->client_name.string_len            /* length */
            );
#endif /* #if (AMSS_VERSION==3200) */

            LOC_LOGV("SUPL NI: client_name: %s len=%d", notif.text, supl_req->client_name.string_len);
         }
         else {
            LOC_LOGV("SUPL NI: client_name not present.");
         }

         // Requestor ID
         if (supl_req->flags & RPC_LOC_NI_REQUESTOR_ID_PRESENT)
         {
#if (AMSS_VERSION==3200)
            hexcode(notif.requestor_id, sizeof notif.requestor_id,
                  supl_req->requestor_id.requestor_id_string.requestor_id_string_val,  /* buffer */
                  supl_req->requestor_id.string_len                                    /* length */
            );
#else
            hexcode(notif.requestor_id, sizeof notif.requestor_id,
                  supl_req->requestor_id.requestor_id_string,  /* buffer */
                  supl_req->requestor_id.string_len            /* length */
            );
#endif /* #if (AMSS_VERSION==3200) */
            LOC_LOGV("SUPL NI: requestor_id: %s len=%d", notif.requestor_id, supl_req->requestor_id.string_len);
         }
         else {
            LOC_LOGV("SUPL NI: requestor_id not present.");
         }

         // Encoding type
         if (supl_req->flags & RPC_LOC_NI_ENCODING_TYPE_PRESENT)
         {
            notif.text_encoding = convert_encoding_type(supl_req->datacoding_scheme);
            notif.requestor_id_encoding = convert_encoding_type(supl_req->datacoding_scheme);
         }
         else {
            notif.text_encoding = notif.requestor_id_encoding = GPS_ENC_UNKNOWN;
         }

         // Set default_response & notify_flags
         loc_ni_fill_notif_verify_type(&notif, ni_req->payload.rpc_loc_ni_event_payload_u_type_u.supl_req.notification_priv_type);

         // Privacy override handling
         if (ni_req->payload.rpc_loc_ni_event_payload_u_type_u.supl_req.notification_priv_type == RPC_LOC_NI_USER_PRIVACY_OVERRIDE)
         {
            loc_eng_mute_one_session();
         }

         break;

      default:
         LOC_LOGE("loc_ni_request_handler, unknown request event: %d", ni_req->event);
         return;
      }

      /* Log requestor ID and text for debugging */
      LOC_LOGI("Notification: notif_type: %d, timeout: %d, default_resp: %d", notif.ni_type, notif.timeout, notif.default_response);
      LOC_LOGI("              requestor_id: %s (encoding: %d)", notif.requestor_id, notif.requestor_id_encoding);
      LOC_LOGI("              text: %s text (encoding: %d)", notif.text, notif.text_encoding);
      if (notif.extras[0])
      {
         LOC_LOGI("              extras: %s", notif.extras);
      }

      /* For robustness, spawn a thread at this point to timeout to clear up the notification status, even though
       * the OEM layer in java does not do so.
       **/
      loc_eng_ni_data.response_time_left = 5 + (notif.timeout != 0 ? notif.timeout : LOC_NI_NO_RESPONSE_TIME);
      LOC_LOGI("Automatically sends 'no response' in %d seconds (to clear status)\n", loc_eng_ni_data.response_time_left);

      /* @todo may required when android framework issue is fixed
       * loc_eng_ni_data.callbacks_ref->create_thread_cb("loc_api_ni", loc_ni_thread_proc, NULL);
       */

      int rc = 0;
      rc = pthread_create(&loc_eng_ni_data.loc_ni_thread, NULL, loc_ni_thread_proc, NULL);
      if (rc)
      {
         LOC_LOGE("Loc NI thread is not created.\n");
      }
      rc = pthread_detach(loc_eng_ni_data.loc_ni_thread);
      if (rc)
      {
         LOC_LOGE("Loc NI thread is not detached.\n");
      }
      pthread_mutex_unlock(&loc_eng_ni_data.loc_ni_lock);

      /* Notify callback */
      if (loc_eng_data.ni_notify_cb != NULL)
      {
         loc_eng_data.ni_notify_cb(&notif);
      }
   }
}
 inline void locallog() {
     LOC_LOGV("LocSsrMsg");
 }
Esempio n. 22
0
/*===========================================================================

FUNCTION    loc_sync_process_ind

DESCRIPTION
   Wakes up blocked API calls to check if the needed callback has arrived

DEPENDENCIES
   N/A

RETURN VALUE
   none

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_sync_process_ind(
      locClientHandleType    client_handle, /* handle of the client */
      uint32_t               ind_id ,      /* ind id */
      void                   *ind_payload_ptr /* payload              */
)
{

   LOC_LOGV("%s:%d]: received indication, handle = %p ind_id = %u \n",
                 __func__,__LINE__, client_handle, ind_id);

   pthread_mutex_lock(&loc_sync_call_mutex);

   if (!loc_sync_array.in_use)
   {
      LOC_LOGD("%s:%d]: loc_sync_array not in use \n",
                    __func__, __LINE__);
      pthread_mutex_unlock(&loc_sync_call_mutex);
      return;
   }

   bool in_use = false, consumed = false;
   int i;

   for (i = 0; i < LOC_SYNC_REQ_BUFFER_SIZE && !consumed; i++)
   {
      loc_sync_req_data_s_type *slot = &loc_sync_array.slots[i];

      in_use |= loc_sync_array.slot_in_use[i];

      pthread_mutex_lock(&slot->sync_req_lock);

      if ( (loc_sync_array.slot_in_use[i]) && (slot->client_handle == client_handle)
            && (ind_id == slot->recv_ind_id) && (!slot->ind_has_arrived))
      {
         // copy the payload to the slot waiting for this ind
         size_t payload_size = 0;

         LOC_LOGV("%s:%d]: found slot %d selected for ind %u \n",
                       __func__, __LINE__, i, ind_id);

         if(true == locClientGetSizeByRespIndId(ind_id, &payload_size) &&
            NULL != slot->recv_ind_payload_ptr && NULL != ind_payload_ptr)
         {
            LOC_LOGV("%s:%d]: copying ind payload size = %u \n",
                          __func__, __LINE__, payload_size);

            memcpy(slot->recv_ind_payload_ptr, ind_payload_ptr, payload_size);

            consumed = true;

         }
         /* Received a callback while waiting, wake up thread to check it */
         if (slot->ind_is_waiting)
         {
            slot->recv_ind_id = ind_id;

            pthread_cond_signal(&slot->ind_arrived_cond);
         }
         else
         {
            /* If callback arrives before wait, remember it */
            LOC_LOGV("%s:%d]: ind %u arrived before wait was called \n",
                          __func__, __LINE__, ind_id);

            slot->ind_has_arrived = true;
         }
      }
      pthread_mutex_unlock(&slot->sync_req_lock);
   }

   if (!in_use) {
      loc_sync_array.in_use = false;
   }

   pthread_mutex_unlock(&loc_sync_call_mutex);
}
/*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;
}
static void *timer_thread(void *thread_data)
{
    int ret = -ETIMEDOUT;
    struct timespec ts;
    struct timeval tv;
    timer_data* t = (timer_data*)thread_data;

    LOC_LOGD("%s:%d]: Enter. Delay = %d\n", __func__, __LINE__, t->time_msec);

    gettimeofday(&tv, NULL);
    clock_gettime(CLOCK_REALTIME, &ts);
    if(t->time_msec >= 1000) {
        ts.tv_sec += t->time_msec/1000;
        t->time_msec = t->time_msec % 1000;
    }
    if(t->time_msec)
        ts.tv_nsec += t->time_msec * 1000000;
    if(ts.tv_nsec > 999999999) {
        LOC_LOGD("%s:%d]: Large nanosecs\n", __func__, __LINE__);
        ts.tv_sec += 1;
        ts.tv_nsec -= 1000000000;
    }
    LOC_LOGD("%s:%d]: ts.tv_sec:%d; ts.tv_nsec:%d\n"
             "\t Current time: %d sec; %d nsec",
             __func__, __LINE__, (int)ts.tv_sec, (int)ts.tv_nsec,
             (int)tv.tv_sec, (int)tv.tv_usec*1000);

    pthread_mutex_lock(&(t->timer_mutex));
    if (READY == t->state) {
        t->state = WAITING;
        ret = pthread_cond_timedwait(&t->timer_cond, &t->timer_mutex, &ts);
        t->state = DONE;
    }
    pthread_mutex_unlock(&(t->timer_mutex));

    switch (ret) {
    case ETIMEDOUT:
        LOC_LOGV("%s:%d]: loc_timer timed out",  __func__, __LINE__);
        break;
    case 0:
        LOC_LOGV("%s:%d]: loc_timer stopped",  __func__, __LINE__);
        break;
    case -ETIMEDOUT:
        LOC_LOGV("%s:%d]: loc_timer cancelled",  __func__, __LINE__);
        break;
    default:
        LOC_LOGE("%s:%d]: Call to pthread timedwait failed; ret=%d\n",
                 __func__, __LINE__, ret);
        break;
    }

    if(ETIMEDOUT == ret)
        t->callback_func(t->user_data, ret);

    // A (should be rare) race condition is that, when the loc_time_stop is called
    // and acquired mutex, we reach here.  pthread_mutex_destroy will fail with
    // error code EBUSY.  We give it 6 tries in 5 seconds.  Should be eanough time
    // for loc_timer_stop to complete.  With the 7th try, we also perform unlock
    // prior to destroy.
    {
        int i;
        for (i = 0; EBUSY == pthread_mutex_destroy(&t->timer_mutex) && i <= 5; i++) {
            if (i < 5) {
                sleep(1);
            } else {
                // nah, forget it, something is seriously wrong.  Mutex has been
                // held too long.  Unlock the mutext here.
                pthread_mutex_unlock(&t->timer_mutex);
            }
        }
    }
    pthread_cond_destroy(&t->timer_cond);

    free(t);
    LOC_LOGD("%s:%d]: Exit\n", __func__, __LINE__);
    return NULL;
}
/**
@brief Process received sensor data indications/response from
       slim daemon

Function forwards sensor client the sensor data
indication/response from slim daemon

@param  slim_msg_hdr: Message header
@param  q_msg_payload_size: Payload size
@param  slim_msg_ptr: Pointer to indication/response data
*/
int SocketClientWrapper::ProcessReceivedMessage
(
   SocketClientMsgHeader &slim_msg_hdr,
   uint32_t q_msg_payload_size,
   void* slim_msg_ptr
)
{
    int ret_val = 0;
    //TODO: Forward response to the client
    if ( (slim_msg_ptr == NULL) )
    {
        LOC_LOGE("%s[%d]: SLIMCW_SOCK_HDLR: Null payload %p\n",
                        __func__, __LINE__, slim_msg_ptr);
        return -1;
    }

    LOC_LOGI("%s[%d]: SLIMCW_SOCK_HDLR: received msg-id=%d, payload-size=%d\n",
                   __func__, __LINE__, slim_msg_hdr.msgId, q_msg_payload_size);
    switch (slim_msg_hdr.msgId)
    {
    case eSLIM_SOCKET_CLIENT_MSG_ID_OPEN_RESP:
    {
        LOC_LOGV("%s:%d] Received open response",
                 __func__,__LINE__);
        break;
    }
    case eSLIM_SOCKET_CLIENT_MSG_ID_SENSOR_DATA_RESP:
    {
        LOC_LOGV("%s:%d] Received sensor data response",
                 __func__,__LINE__);
        break;
    }
    case eSLIM_SOCKET_CLIENT_MSG_ID_CLOSE_RESP:
    {
        LOC_LOGV("%s:%d] Received close response",
                 __func__,__LINE__);
        break;
    }

    case eSLIM_SOCKET_CLIENT_MSG_ID_SENSOR_DATA_IND:
    {

        LOC_LOGV("%s:%d] Received sensor indication",
                 __func__,__LINE__);

        LOC_LOGV("%s:%d] Received sensor service is %d",
                 __func__,__LINE__, slim_msg_hdr.slimHeader.service);

        if(slim_msg_hdr.slimHeader.msgId ==eSLIM_MESSAGE_ID_SENSOR_DATA_IND)
        {
            SocketClientSensorDataInd *pz_SensorData =
                (SocketClientSensorDataInd*)slim_msg_ptr;

            IF_LOC_LOGV {
                LOC_LOGV("%s: Received sensor-%d data with len-%d", __func__,
                        pz_SensorData->msgPayload.sensorType, pz_SensorData->msgPayload.samples_len);

                for(uint32_t i=0;i<pz_SensorData->msgPayload.samples_len;i++)
                {
                    LOC_LOGV("%s: Received data with time offset-%d, data-(%f,%f,%f)", __func__,
                            pz_SensorData->msgPayload.samples[i].sampleTimeOffset,
                            pz_SensorData->msgPayload.samples[i].sample[0],
                            pz_SensorData->msgPayload.samples[i].sample[1],
                            pz_SensorData->msgPayload.samples[i].sample[2]);
                }
            }

            if(SocketClientWrapper::mCallbackFunction)
                SocketClientWrapper::mCallbackFunction(0,&slim_msg_hdr.slimHeader, (void *)&pz_SensorData->msgPayload);
        }
        else
        {
            LOC_LOGV("%s:%d] Received is not indication",
                 __func__,__LINE__);
        }


        break;
    }
static void *timer_thread(void *thread_data)
{
    int ret = -ETIMEDOUT;
    struct timespec ts;
    struct timeval tv;
    timer_data* t = (timer_data*)thread_data;

    LOC_LOGD("%s:%d]: Enter. Delay = %d\n", __func__, __LINE__, t->time_msec);

    gettimeofday(&tv, NULL);
    clock_gettime(CLOCK_REALTIME, &ts);
    if(t->time_msec >= 1000) {
        ts.tv_sec += t->time_msec/1000;
        t->time_msec = t->time_msec % 1000;
    }
    if(t->time_msec)
        ts.tv_nsec += t->time_msec * 1000000;
    if(ts.tv_nsec > 999999999) {
        LOC_LOGD("%s:%d]: Large nanosecs\n", __func__, __LINE__);
        ts.tv_sec += 1;
        ts.tv_nsec -= 1000000000;
    }
    LOC_LOGD("%s:%d]: ts.tv_sec:%d; ts.tv_nsec:%d\n"
             "\t Current time: %d sec; %d nsec",
             __func__, __LINE__, (int)ts.tv_sec, (int)ts.tv_nsec,
             (int)tv.tv_sec, (int)tv.tv_usec*1000);

    pthread_mutex_lock(&(t->timer_mutex));
    if (READY == t->state) {
        t->state = WAITING;
        ret = pthread_cond_timedwait(&t->timer_cond, &t->timer_mutex, &ts);
        t->state = DONE;
    }
    pthread_mutex_unlock(&(t->timer_mutex));

    switch (ret) {
    case ETIMEDOUT:
        LOC_LOGV("%s:%d]: loc_timer timed out",  __func__, __LINE__);
        break;
    case 0:
        LOC_LOGV("%s:%d]: loc_timer stopped",  __func__, __LINE__);
        break;
    case -ETIMEDOUT:
        LOC_LOGV("%s:%d]: loc_timer cancelled",  __func__, __LINE__);
        break;
    default:
        LOC_LOGE("%s:%d]: Call to pthread timedwait failed; ret=%d\n",
                 __func__, __LINE__, ret);
        break;
    }

    pthread_mutex_destroy(&t->timer_mutex);
    pthread_cond_destroy(&t->timer_cond);

    if(ETIMEDOUT == ret)
        t->callback_func(t->user_data, ret);

    free(t);
    LOC_LOGD("%s:%d]: Exit\n", __func__, __LINE__);
    return NULL;
}
 inline void locallog() {
     LOC_LOGV("%s:%d]: LocOpen Mask: %x\n",
              __func__, __LINE__, mMask);
 }