예제 #1
0
/*===========================================================================

FUNCTION loc_eng_ni_callback

DESCRIPTION
   Loc API callback handler

RETURN VALUE
   error code (0 for success)

===========================================================================*/
int loc_eng_ni_callback (
      rpc_loc_event_mask_type               loc_event,              /* event mask           */
      const rpc_loc_event_payload_u_type*   loc_event_payload       /* payload              */
)
{
   int rc = 0;
   const rpc_loc_ni_event_s_type *ni_req = &loc_event_payload->rpc_loc_event_payload_u_type_u.ni_request;
   if (loc_event == RPC_LOC_EVENT_NI_NOTIFY_VERIFY_REQUEST)
   {
      switch (ni_req->event)
      {
      case RPC_LOC_NI_EVENT_VX_NOTIFY_VERIFY_REQ:
         LOC_LOGI("VX Notification");
         loc_ni_request_handler("VX Notify", ni_req);
         break;

      case RPC_LOC_NI_EVENT_UMTS_CP_NOTIFY_VERIFY_REQ:
         LOC_LOGI("UMTS CP Notification\n");
         loc_ni_request_handler("UMTS CP Notify", ni_req);
         break;

      case RPC_LOC_NI_EVENT_SUPL_NOTIFY_VERIFY_REQ:
         LOC_LOGI("SUPL Notification\n");
         loc_ni_request_handler("SUPL Notify", ni_req);
         break;

      default:
         LOC_LOGE("Unknown NI event: %x\n", (int) ni_req->event);
         break;
      }
   }
   return rc;
}
uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t sessionMode,
        LocationOptions& options)
{
    uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
    pthread_mutex_lock(&mMutex);
    if (mLocationAPI) {

        if (mSessionMap.find(id) != mSessionMap.end()) {
            LOC_LOGE("%s:%d] session %d has already started.", __FUNCTION__, __LINE__, id);
            retVal = LOCATION_ERROR_ALREADY_STARTED;
        } else {
            uint32_t trackingSession = 0;
            uint32_t batchingSession = 0;

            if (sessionMode == SESSION_MODE_ON_FIX) {
                RequestQueue* requests = mRequestQueues[REQUEST_TRACKING];
                if (requests) {
                    delete requests;
                    mRequestQueues[REQUEST_TRACKING] = nullptr;
                }
                trackingSession = mLocationAPI->startTracking(options);
                LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession);
                requests = new RequestQueue(trackingSession);
                requests->push(new StartTrackingRequest(*this));
                mRequestQueues[REQUEST_TRACKING] = requests;
            } else if (sessionMode == SESSION_MODE_ON_FULL) {
                RequestQueue* requests = mRequestQueues[REQUEST_BATCHING];
                if (requests) {
                    delete requests;
                    mRequestQueues[REQUEST_BATCHING] = nullptr;
                }
                batchingSession = mLocationAPI->startBatching(options);
                LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, batchingSession);
                requests = new RequestQueue(batchingSession);
                requests->push(new StartBatchingRequest(*this));
                mRequestQueues[REQUEST_BATCHING] = requests;
            }

            SessionEntity entity;
            entity.id = id;
            entity.trackingSession = trackingSession;
            entity.batchingSession = batchingSession;
            entity.sessionMode = sessionMode;
            mSessionMap[id] = entity;

            retVal = LOCATION_ERROR_SUCCESS;
        }

    }
    pthread_mutex_unlock(&mMutex);

    return retVal;
}
uint32_t LocationAPIClientBase::locAPIAddGeofences(
        size_t count, uint32_t* ids, GeofenceOption* options, GeofenceInfo* data)
{
    uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
    pthread_mutex_lock(&mMutex);
    if (mLocationAPI) {
        RequestQueue* requests = mRequestQueues[REQUEST_GEOFENCE];
        if (!requests) {
            // Create a new RequestQueue for Geofenceing if we've not had one.
            // The RequestQueue will be released when LocationAPIClientBase is released.
            requests = new RequestQueue(GEOFENCE_SESSION_ID);
            mRequestQueues[REQUEST_GEOFENCE] = requests;
        }
        uint32_t* sessions = mLocationAPI->addGeofences(count, options, data);
        if (sessions) {
            LOC_LOGI("%s:%d] start new sessions: %p", __FUNCTION__, __LINE__, sessions);
            requests->push(new AddGeofencesRequest(*this));

            for (size_t i = 0; i < count; i++) {
                mGeofenceBiDict.set(ids[i], sessions[i], options[i].breachTypeMask);
            }
            retVal = LOCATION_ERROR_SUCCESS;
        }
    }
    pthread_mutex_unlock(&mMutex);

    return retVal;
}
LocApiAdapter* LocApiAdapter::getLocApiAdapter(LocEng &locEng)
{
    void* handle;
    LocApiAdapter* adapter = NULL;

    handle = dlopen ("libloc_api_v02.so", RTLD_NOW);

    if (!handle) {
        LOC_LOGE("%s: dlopen(libloc_api_v02.so) failed, trying to load libloc_api-rpc-qc.so", __FUNCTION__);
        LOC_LOGE("%s: %s", __FUNCTION__, dlerror());
        handle = dlopen ("libloc_api-rpc-qc.so", RTLD_NOW);
    }
    else
        LOC_LOGI("%s: dlopen(libloc_api_v02.so) succeeded.", __FUNCTION__);

    if (!handle) {
        LOC_LOGE("%s: dlopen(libloc_api-rpc-qc.so) failed, constructing LocApiAdapter", __FUNCTION__);
        adapter = new LocApiAdapter(locEng);
    } else {
        getLocApiAdapter_t* getHandle = (getLocApiAdapter_t*)dlsym(handle, "_Z16getLocApiAdapterR6LocEng");
        if (!getHandle) {
            LOC_LOGE("%s: dlsym(getLocApiAdapter) failed", __FUNCTION__);
            LOC_LOGE("%s: %s", __FUNCTION__, dlerror());
            return NULL;
        }
        adapter = (*getHandle)(locEng);
    }

    return adapter;
}
uint32_t LocationAPIClientBase::locAPIStartTracking(LocationOptions& options)
{
    uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
    pthread_mutex_lock(&mMutex);
    if (mLocationAPI) {
        if (mTracking) {
            LOC_LOGW("%s:%d] Existing tracking session present", __FUNCTION__, __LINE__);
        } else {
            RequestQueue* requests = mRequestQueues[REQUEST_TRACKING];
            if (requests) {
                delete requests;
                mRequestQueues[REQUEST_TRACKING] = nullptr;
            }
            uint32_t session = mLocationAPI->startTracking(options);
            LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
            // onResponseCb might be called from other thread immediately after
            // startTracking returns, so we are not going to unlock mutex
            // until StartTrackingRequest is pushed into mRequestQueues[REQUEST_TRACKING]
            requests = new RequestQueue(session);
            requests->push(new StartTrackingRequest(*this));
            mRequestQueues[REQUEST_TRACKING] = requests;
            mTracking = true;
        }
        retVal = LOCATION_ERROR_SUCCESS;
    }
    pthread_mutex_unlock(&mMutex);

    return retVal;
}
uint32_t LocationAPIClientBase::locAPIEnable(LocationTechnologyType techType)
{
    uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
    pthread_mutex_lock(&mMutex);
    if (mEnabled) {
        // just return success if already enabled
        retVal = LOCATION_ERROR_SUCCESS;
    } else if (mLocationControlAPI) {
        RequestQueue* requests = mRequestQueues[REQUEST_CONTROL];
        if (requests) {
            delete requests;
            mRequestQueues[REQUEST_CONTROL] = nullptr;
        }
        uint32_t session = mLocationControlAPI->enable(techType);
        LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
        requests = new RequestQueue(session);
        mRequestQueues[REQUEST_CONTROL] = requests;
        if (requests) {
            requests->push(new EnableRequest(*this));
            retVal = LOCATION_ERROR_SUCCESS;
            mEnabled = true;
        }
    }
    pthread_mutex_unlock(&mMutex);

    return retVal;
}
/*===========================================================================
FUNCTION    ulp_msg_forward_quipc_position_report

DESCRIPTION
   This function is called when libulp module need to forward a position report
   from ULP named pipe to message queue. This is done so that all ULP
   state transition is done in one thread.

DEPENDENCIES
   None

RETURN VALUE
   0: success
   -1: failure

SIDE EFFECTS
   N/A

===========================================================================*/
int ulp_msg_forward_quipc_position_report (int                    error_code,
                                           const UlpLocation*     quipc_location_ptr,
                                           int                    debug_info_length,
                                           char*                  debug_info_ptr)
{
   int ret_val = -1;
   UlpLocation quipc_location;
   char* debug_info = NULL;

   ENTRY_LOG_CALLFLOW();
   do
   {
      if (quipc_location_ptr == NULL)
      {
         break;
      }

      quipc_location = *quipc_location_ptr;

      LOC_LOGI ("%s, Debug Info = %s, Length = %d\n", __func__, debug_info_ptr, debug_info_length);

      // Make a copy of the debug info received. Needs to be freed by ulp_brain.
      if (debug_info_length != 0) {
        debug_info = new char[debug_info_length];
        if (debug_info != NULL)
        {
          strlcpy((char*)debug_info, debug_info_ptr, debug_info_length);
          quipc_location.rawData = (void*) debug_info;
          quipc_location.rawDataSize = debug_info_length;
        }
      }

      ulp_msg_report_quipc_position *ulpPositionMsg(
            new ulp_msg_report_quipc_position(&ulp_data,
                                              quipc_location,
                                              error_code));
      if (ulpPositionMsg == NULL)
      {
         LOC_LOGE ("%s, failed to create message: ulp_msg_report_quipc_position \n", __func__);

         // Free the allocated memory
         delete [] debug_info;
         debug_info = NULL;
         quipc_location.rawData = NULL;
         quipc_location.rawDataSize = 0;
         break;
      }

     msg_q_snd(ulp_data.loc_proxy->mQ,
               ulpPositionMsg,
               ulp_msg_free);

     ret_val = 0;

   } while (0);

   EXIT_LOG(%d, ret_val);
   return ret_val;
}
/*===========================================================================
FUNCTION    ulp_msg_process_stop_req

DESCRIPTION
   This function is called when libulp module receives a message to request
   universal location provider to stop producing position reports.

   The module will stop all providers that are currently producing fixes
   initiated by libulp modules.

DEPENDENCIES
   None

RETURN VALUE
   0: success
   -1: failure

SIDE EFFECTS
   N/A

===========================================================================*/
int ulp_msg_process_stop_req (void)
{
   int ret_val = 0;
   //With the new design ulp_stop is essentailly a no-op since the
   //criteria update processing will shut off all providers when
   //last criteria is removed from the queue
   ENTRY_LOG_CALLFLOW();
   LOC_LOGI ("%s, at ulp state = %d\n", __func__, ulp_data.ulp_started);

   EXIT_LOG(%d, ret_val);
   return ret_val;
}
예제 #9
0
/*===========================================================================
FUNCTION    loc_eng_ni_respond

DESCRIPTION
   This function sends an NI respond to the modem processor

DEPENDENCIES
   NONE

RETURN VALUE
   None

SIDE EFFECTS
   N/A

===========================================================================*/
void loc_eng_ni_respond(int notif_id, GpsUserResponseType user_response)
{
   if (notif_id == loc_eng_ni_data.current_notif_id &&
         loc_eng_ni_data.notif_in_progress)
   {
      LOC_LOGI("loc_eng_ni_respond: send user response %d for notif %d", user_response, notif_id);
      loc_ni_process_user_response(user_response);
   }
   else {
      LOC_LOGE("loc_eng_ni_respond: notif_id %d mismatch or notification not in progress, response: %d",
            notif_id, user_response);
   }
}
예제 #10
0
/*===========================================================================
FUNCTION    ulp_msg_process_start_req

DESCRIPTION
   This function is called when libulp module receives a message to request
   universal location provider to start producing position reports.

   The module will choose providers based on available criteria and context
   settings.

DEPENDENCIES
   None

RETURN VALUE
   0: success
   -1: failure

SIDE EFFECTS
   N/A

===========================================================================*/
int ulp_msg_process_start_req (void)
{
   int ret_val = -1;
   ENTRY_LOG_CALLFLOW();

   LOC_LOGI ("%s, at ulp state = %d\n", __func__, ulp_data.ulp_started);

   do
   {
      ulp_data.ulp_started = true;

      // We request phone context setting upon receiving first start request
      if (ulp_data.phoneSettingRequested == false)
      {
         UlpPhoneContextRequest phoneContextReq;

         phoneContextReq.context_type = (ULP_PHONE_CONTEXT_GPS_SETTING |
                                         ULP_PHONE_CONTEXT_NETWORK_POSITION_SETTING |
                                         ULP_PHONE_CONTEXT_WIFI_SETTING |
                                         ULP_PHONE_CONTEXT_BATTERY_CHARGING_STATE |
                                         ULP_PHONE_CONTEXT_AGPS_SETTING |
                                         ULP_PHONE_CONTEXT_ENH_LOCATION_SERVICES_SETTING |
                                         ULP_PHONE_CONTEXT_PIP_USER_SETTING);

         phoneContextReq.request_type = ULP_PHONE_CONTEXT_REQUEST_TYPE_ON_CHANGE;
         phoneContextReq.interval_ms = 0;

         if(ulp_data.ulp_phone_context_req_cb != NULL)
         {
             ulp_data.ulp_phone_context_req_cb(&phoneContextReq);
         }
         else
             LOC_LOGE("Ulp Phone Context call back not initialized");

         LOC_LOGD("%s, ulp_msg_request_phone_context- message send with context_type: 0x%x and req_type: 0x%x \n",
                  __func__,phoneContextReq.context_type, phoneContextReq.request_type);
         ulp_data.phoneSettingRequested = true;

         ret_val = 0;
         break;
      }

      if (ulp_data.run_provider_selection_logic == true)
      {
         ret_val = ulp_brain_select_providers ();
      }
   } while (0);

   EXIT_LOG(%d, ret_val);
   return ret_val;
}
void LocationAPIClientBase::locAPIGnssNiResponse(uint32_t id, GnssNiResponse response)
{
    pthread_mutex_lock(&mMutex);
    if (mLocationAPI) {
        RequestQueue* requests = mRequestQueues[REQUEST_NIRESPONSE];
        if (requests) {
            delete requests;
            mRequestQueues[REQUEST_NIRESPONSE] = nullptr;
        }
        uint32_t session = id;
        mLocationAPI->gnssNiResponse(id, response);
        LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
        requests = new RequestQueue(session);
        requests->push(new GnssNiResponseRequest(*this));
        mRequestQueues[REQUEST_NIRESPONSE] = requests;
    }
    pthread_mutex_unlock(&mMutex);
}
예제 #12
0
/*===========================================================================
FUNCTION    ulp_msg_process_criteria_update

DESCRIPTION
   This function is called when libulp module receives a criteria update message.
   The message is either to add a unique criteria or remove an exisitng criteria.

DEPENDENCIES
   None

RETURN VALUE
   0: success
   -1: failure

SIDE EFFECTS
   N/A

===========================================================================*/
int ulp_msg_process_criteria_update (const UlpLocationCriteria* locationCriteriaPtr)
{
   int ret_val = -1;
   ENTRY_LOG_CALLFLOW();
   if (locationCriteriaPtr != NULL)
   {
     LOC_LOGI("%s: valid 0x%x action:%d, minTime:%d, minDistance:%f, singleShot:%d, horizontalAccuracy:%d, powerRequirement:%d \n",
            __func__,
            locationCriteriaPtr->valid_mask,
            locationCriteriaPtr->action,
            locationCriteriaPtr->min_interval,
            locationCriteriaPtr->min_distance,
            locationCriteriaPtr->recurrence_type,
            locationCriteriaPtr->preferred_horizontal_accuracy,
            locationCriteriaPtr->preferred_power_consumption );

      if (locationCriteriaPtr->valid_mask & ULP_CRITERIA_HAS_ACTION)
      {
         if (locationCriteriaPtr->action == ULP_ADD_CRITERIA)
         {
            ret_val = ulp_data_add_criteria (locationCriteriaPtr);
         }
         else if (locationCriteriaPtr->action == ULP_REMOVE_CRITERIA)
         {
            ret_val = ulp_data_remove_criteria (locationCriteriaPtr);
         }
      }

      // Criteria has been successfully added or removed, invoke the brain logic
      if (ret_val == 0)
      {
         (void) ulp_brain_process_criteria_update ();
         if (ulp_data.run_provider_selection_logic == true)
         {
            ret_val = ulp_brain_select_providers ();
         }
      }
   }

   EXIT_LOG(%d, ret_val);
   return ret_val;
}
예제 #13
0
/*===========================================================================
FUNCTION    ulp_msg_process_system_update

DESCRIPTION
   This function is called when libulp module receives a system event update message.
   The message is to inform libulp of system event udaptes like Apps processor wakeup.

DEPENDENCIES
   None

RETURN VALUE
   0: success
   -1: failure

SIDE EFFECTS
   N/A

===========================================================================*/
static int ulp_msg_process_system_update (const UlpSystemEvent systemEvent)
{
   int ret_val = -1;
   ENTRY_LOG_CALLFLOW();
   LocAdapterBase*       adapter = ulp_data.loc_proxy->getAdapter();

   if (NULL == adapter) {
      LOC_LOGW("Loc HAL handshake did not happen yet...");
      return 0;
   }

   LOC_LOGI("%s: systemEvent:%d \n",__func__,systemEvent);
   ret_val = ulp_brain_process_system_update (systemEvent);
   // System event has been successfully received invoke the brain logic
   if (ret_val == 0)
   {
      ulp_msg_process_start_req();
   }

   EXIT_LOG(%d, ret_val);
   return ret_val;
}
uint32_t LocationAPIClientBase::locAPIGnssDeleteAidingData(GnssAidingData& data)
{
    uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
    pthread_mutex_lock(&mMutex);
    if (mLocationControlAPI) {
        RequestQueue* requests = mRequestQueues[REQUEST_DELETEAIDINGDATA];
        if (requests) {
            delete requests;
            mRequestQueues[REQUEST_DELETEAIDINGDATA] = nullptr;
        }
        uint32_t session = mLocationControlAPI->gnssDeleteAidingData(data);
        LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, session);
        requests = new RequestQueue(session);
        requests->push(new GnssDeleteAidingDataRequest(*this));
        mRequestQueues[REQUEST_DELETEAIDINGDATA] = requests;

        retVal = LOCATION_ERROR_SUCCESS;
    }
    pthread_mutex_unlock(&mMutex);

    return retVal;
}
uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode,
        LocationOptions& options)
{
    uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
    pthread_mutex_lock(&mMutex);
    if (mLocationAPI) {

        if (mSessionMap.find(id) != mSessionMap.end()) {
            SessionEntity& entity = mSessionMap[id];

            uint32_t trackingSession = entity.trackingSession;
            uint32_t batchingSession = entity.batchingSession;
            uint32_t sMode = entity.sessionMode;

            if (sessionMode == SESSION_MODE_ON_FIX) {
                if (sMode == SESSION_MODE_ON_FIX) {
                    RequestQueue* requests = mRequestQueues[REQUEST_TRACKING];
                    if (requests) {
                        requests->push(new UpdateTrackingOptionsRequest(*this));
                        mLocationAPI->updateTrackingOptions(trackingSession, options);
                    }
                } else if (sMode == SESSION_MODE_ON_FULL) {
                    // stop batching
                    {
                        RequestQueue* requests = mRequestQueues[REQUEST_BATCHING];
                        if (requests) {
                            requests->push(new StopBatchingRequest(*this));
                            mLocationAPI->stopBatching(batchingSession);
                            batchingSession = 0;
                        }
                    }
                    // start tracking
                    {
                        RequestQueue* requests = mRequestQueues[REQUEST_TRACKING];
                        if (requests) {
                            delete requests;
                            mRequestQueues[REQUEST_TRACKING] = nullptr;
                        }
                        trackingSession = mLocationAPI->startTracking(options);
                        LOC_LOGI("%s:%d] start new session: %d",
                                __FUNCTION__, __LINE__, trackingSession);
                        requests = new RequestQueue(trackingSession);
                        requests->push(new StartTrackingRequest(*this));
                        mRequestQueues[REQUEST_TRACKING] = requests;
                    }
                }
            } else if (sessionMode == SESSION_MODE_ON_FULL) {
                if (sMode == SESSION_MODE_ON_FIX) {
                    // stop tracking
                    {
                        RequestQueue* requests = mRequestQueues[REQUEST_TRACKING];
                        if (requests) {
                            requests->push(new StopTrackingRequest(*this));
                            mLocationAPI->stopTracking(trackingSession);
                            trackingSession = 0;
                        }
                    }
                    // start batching
                    {
                        RequestQueue* requests = mRequestQueues[REQUEST_BATCHING];
                        if (requests) {
                            delete requests;
                            mRequestQueues[REQUEST_BATCHING] = nullptr;
                        }
                        batchingSession = mLocationAPI->startBatching(options);
                        LOC_LOGI("%s:%d] start new session: %d",
                                __FUNCTION__, __LINE__, batchingSession);
                        requests = new RequestQueue(batchingSession);
                        requests->push(new StartBatchingRequest(*this));
                        mRequestQueues[REQUEST_BATCHING] = requests;
                    }
                } else if (sMode == SESSION_MODE_ON_FULL) {
                    RequestQueue* requests = mRequestQueues[REQUEST_BATCHING];
                    requests = mRequestQueues[REQUEST_BATCHING];
                    if (requests) {
                        requests->push(new UpdateBatchingOptionsRequest(*this));
                        mLocationAPI->updateBatchingOptions(batchingSession, options);
                    }
                }
            }

            entity.trackingSession = trackingSession;
            entity.batchingSession = batchingSession;
            entity.sessionMode = sessionMode;

            retVal = LOCATION_ERROR_SUCCESS;
        } else {
            retVal = LOCATION_ERROR_ID_UNKNOWN;
            LOC_LOGE("%s:%d] session %d is not exist.", __FUNCTION__, __LINE__, id);
        }

    }
    pthread_mutex_unlock(&mMutex);
    return retVal;
}
/**
@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;
    }
/**
@brief Thread listening for sensor data indications/responses
from slim daemon

Function listens for sensor data indications/responses from slim daemon
and forwards it to client using client callback function

@param  arg: NULL
*/
void* SocketClientWrapper::SocketClientWrapperThread(void* arg)
{
    SocketClientMsgHeader slim_msg_hdr;
    void* slim_msg_ptr;
    int rval = -1;

    LOC_LOGI("%s[%d]: SLIMCW_SOCK_HDLR thread starting\n", __func__, __LINE__);

    while (1)
    {
        memset(&slim_msg_hdr, 0, sizeof(slim_msg_hdr));
        LOC_LOGD("%s[%d]: Ready to read from socket...\n", __func__, __LINE__);

        if ((rval  = read(SocketClientWrapper::mSocketFd, &slim_msg_hdr, sizeof(slim_msg_hdr))) < 0)
        {
            LOC_LOGE("%s[%d]: error reading stream message for header, errno %d\n",
                            __func__, __LINE__, errno);
            break;
        }
        else if (rval == 0)
        {
            LOC_LOGE("%s[%d]: Ending connection\n", __func__, __LINE__);
            break;
        }
        else
        {
            /* Message received: check msg size */
            uint32_t q_msg_size = slim_msg_hdr.msgSize;
            uint32_t q_msg_payload_size = q_msg_size - sizeof(SocketClientMsgHeader);
            uint32_t u_num_bytes_read = rval;
            uint32_t u_num_bytes_remaining = 0;

            void* slim_msg_ptr = (void*) malloc(q_msg_size);
            if(slim_msg_ptr == NULL)
            {
                LOC_LOGE("%s: slim_msg_ptr malloc %d failed", __FUNCTION__,  q_msg_payload_size);
                break;
            }

            LOC_LOGD("%s[%d]: Recv'd message header, id=%d, size=%d,  transaction=%d, payload-size=%d, rval=%d\n",
                          __func__, __LINE__, slim_msg_hdr.msgId, slim_msg_hdr.msgSize,
                           slim_msg_hdr.slimHeader.txnId, q_msg_payload_size, rval);

            u_num_bytes_remaining = q_msg_payload_size;
            while (u_num_bytes_remaining > 0)
            {
                if ((rval  = read(SocketClientWrapper::mSocketFd, (slim_msg_ptr+u_num_bytes_read), u_num_bytes_remaining)) <= 0)
                {
                    LOC_LOGE("%s[%d]: error reading stream message for payload\n", __func__, __LINE__);
                    // TODO: Response to client?
                }
                else
                {
                    u_num_bytes_read += rval;
                    u_num_bytes_remaining -= rval;
                    LOC_LOGD("%s[%d]: Ready to process payload.. rval=%d, total-read=%d, rem=%d\n",
                                  __func__, __LINE__, rval, u_num_bytes_read, u_num_bytes_remaining);
                }
            }
            if (u_num_bytes_read == q_msg_size)
            {
                SocketClientWrapper::ProcessReceivedMessage(slim_msg_hdr, q_msg_payload_size /*slim_msg_hdr*/, slim_msg_ptr);
            }
            free(slim_msg_ptr);
        }
    }

    LOC_LOGI("%s[%d]: Done listening for sensor data indications hence"
             "killing thread and closing socket\n",
             __func__, __LINE__);
    close(SocketClientWrapper::mSocketFd);
    SocketClientWrapper::mSocketFd = -1;
    //TODO: Notify client

    LOC_LOGI("%s[%d]: SLIMCW_SOCK_HDLR thread exiting\n", __func__, __LINE__);
    return NULL;
}
void location_callback (GpsLocation * location, VzwGpsLocationExt* locExt)
{
    LOC_LOGI ("test_gps_location_cb: lat: %f, lon %f, acc %f, time %llu",
                 location->latitude, location->longitude, location->accuracy,
                 (long long) location->timestamp);
}
void status_callback(GpsStatus * status)
{
    LOC_LOGI ("test_gps_status_cb: %d", status->status);
}
void sv_status_callback(GpsSvStatus * sv_info, GpsDop* dop)
{
    LOC_LOGI ("test_gps_sv_status_cb:");
}
void nmea_callback (GpsUtcTime timestamp, const char *nmea, int length)
{
    LOC_LOGI ("test_gps_nmea_cb:");
}
예제 #22
0
/*===========================================================================
FUNCTION    ulp_msg_process_phone_setting_update

DESCRIPTION
   This function is called when libulp module receives the message regarding
   current phone setting.

   libulp will need choose the appropriate provider based on new phone
   settings.

DEPENDENCIES
   None

RETURN VALUE
   0: success
   -1: failure

SIDE EFFECTS
   N/A

===========================================================================*/
int ulp_msg_process_phone_setting_update (const UlpPhoneContextSettings* phoneSettingPtr)
{
   int      ret_val = -1;

   ENTRY_LOG_CALLFLOW();

   do
   {
      if (phoneSettingPtr == NULL)
      {
         break;
      }

      LOC_LOGI("%s, context type: 0x%x\n  gps enabled: %d\n network position available %d\n "
               "wifi setting enabled %d\n battery charging %d, agps enabled %d, enh_location_services_enabled %d"
               "is_pip_user_setting_enabled %d\n",
               __func__,
               phoneSettingPtr->context_type,
               phoneSettingPtr->is_gps_enabled,
               phoneSettingPtr->is_network_position_available,
               phoneSettingPtr->is_wifi_setting_enabled,
               phoneSettingPtr->is_battery_charging,
               phoneSettingPtr->is_agps_enabled,
               phoneSettingPtr->is_enh_location_services_enabled,
               phoneSettingPtr->is_pip_user_setting_enabled);

      // Controls GNSS
      if (phoneSettingPtr->context_type & ULP_PHONE_CONTEXT_GPS_SETTING)
      {
         ulp_data.phoneSetting.context_type |= ULP_PHONE_CONTEXT_GPS_SETTING;
         ulp_data.phoneSetting.is_gps_enabled = phoneSettingPtr->is_gps_enabled;
      }

      // Controls Network positioning
      if (phoneSettingPtr->context_type & ULP_PHONE_CONTEXT_NETWORK_POSITION_SETTING )
      {
         ulp_data.phoneSetting.context_type |= ULP_PHONE_CONTEXT_NETWORK_POSITION_SETTING ;
         ulp_data.phoneSetting.is_network_position_available = phoneSettingPtr->is_network_position_available;
      }

      // Controls QUIPC -WiFi Setting
      if (phoneSettingPtr->context_type & ULP_PHONE_CONTEXT_WIFI_SETTING)
      {
         ulp_data.phoneSetting.context_type |= ULP_PHONE_CONTEXT_WIFI_SETTING;
         ulp_data.phoneSetting.is_wifi_setting_enabled = phoneSettingPtr->is_wifi_setting_enabled;
      }

      // Controls QUIPC -Enhanced Location Services Setting configured by user through XT App
      if (phoneSettingPtr->context_type & ULP_PHONE_CONTEXT_ENH_LOCATION_SERVICES_SETTING)
      {
         ulp_data.phoneSetting.context_type |= ULP_PHONE_CONTEXT_ENH_LOCATION_SERVICES_SETTING;
         ulp_data.phoneSetting.is_enh_location_services_enabled = phoneSettingPtr->is_enh_location_services_enabled;
      }

      // AGPS setting
      // Setting change will only impact next single shot fix request
      // If there is on-going single shot session, it will not be impacted
      if (phoneSettingPtr->context_type & ULP_PHONE_CONTEXT_AGPS_SETTING)
      {
         ulp_data.phoneSetting.context_type |= ULP_PHONE_CONTEXT_AGPS_SETTING;
         ulp_data.phoneSetting.is_agps_enabled = phoneSettingPtr->is_agps_enabled;
      }

      // Battery charging state
      if (phoneSettingPtr->context_type & ULP_PHONE_CONTEXT_BATTERY_CHARGING_STATE)
      {
         ulp_data.phoneSetting.context_type |= ULP_PHONE_CONTEXT_BATTERY_CHARGING_STATE;
         ulp_data.phoneSetting.is_battery_charging = phoneSettingPtr->is_battery_charging;
      }

      // Controls QUIPC -PIP user setting through OS settings menu on UI
      if (phoneSettingPtr->context_type & ULP_PHONE_CONTEXT_PIP_USER_SETTING)
      {
         ulp_data.phoneSetting.context_type |= ULP_PHONE_CONTEXT_PIP_USER_SETTING;
         ulp_data.phoneSetting.is_pip_user_setting_enabled = phoneSettingPtr->is_pip_user_setting_enabled;
      }

      ret_val = ulp_brain_process_phone_setting_update ();

      if (ulp_data.run_provider_selection_logic == true)
      {
         ret_val = ulp_brain_select_providers ();
      }
   } while (0);
   ret_val = 0;

   EXIT_LOG(%d, ret_val);

   return ret_val;
}
예제 #23
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);
      }
   }
}