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; }
/*=========================================================================== 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; }
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) ); }
/*=========================================================================== 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; } }
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; } }
// 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()); } } }
/*=========================================================================== 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; }
/*=========================================================================== 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; }
/*=========================================================================== 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(¬if, 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(¬if, 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(¬if, 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(¬if); } } }
inline void locallog() { LOC_LOGV("LocSsrMsg"); }
/*=========================================================================== 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, ¬ifier); 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); }