static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out) { memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus)); out.numSvs = in.count; if (out.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) { LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.", __FUNCTION__, out.numSvs, GnssMax::SVS_COUNT); out.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT); } for (size_t i = 0; i < out.numSvs; i++) { IGnssCallback::GnssSvInfo& info = out.gnssSvList[i]; info.svid = in.gnssSvs[i].svId; convertGnssConstellationType(in.gnssSvs[i].type, info.constellation); info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz; info.elevationDegrees = in.gnssSvs[i].elevation; info.azimuthDegrees = in.gnssSvs[i].azimuth; info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE); if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT) info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA; if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT) info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA; if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT) info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX; } }
int LocApiAdapter::decodeAddress(char *addr_string, int string_size, const char *data, int data_size) { const char addr_prefix = 0x91; int i, idxOutput = 0; if (!data || !addr_string) { return 0; } if (data[0] != addr_prefix) { LOC_LOGW("decodeAddress: address prefix is not 0x%x but 0x%x", addr_prefix, data[0]); addr_string[0] = '\0'; return 0; // prefix not correct } for (i = 1; i < data_size; i++) { unsigned char ch = data[i], low = ch & 0x0F, hi = ch >> 4; if (low <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = low + '0'; } if (hi <= 9 && idxOutput < string_size - 1) { addr_string[idxOutput++] = hi + '0'; } } addr_string[idxOutput] = '\0'; // Terminates the string return idxOutput; }
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; }
AgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data) { LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event); if (mStateMachine->hasSubscribers()) { LOC_LOGE("Error: %s subscriber list not empty!!!", whoami()); // I don't know how to recover from it. I am adding this rather // for debugging purpose. } AgpsState* nextState = this; switch (event) { case RSRC_SUBSCRIBE: { // no notification until we get RSRC_GRANTED // but we need to add subscriber to the list mStateMachine->addSubscriber((Subscriber*)data); // request from connecivity service for NIF //The if condition is added so that if the data call setup fails //for DS State Machine, we want to retry in released state. //for AGps State Machine, sendRsrcRequest() will always return success if(!mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN)) { // move the state to PENDING nextState = mPendingState; } } break; case RSRC_UNSUBSCRIBE: { // the list should really be empty, nothing to remove. // but we might as well just tell the client it is // unsubscribed. False tolerance, right? Subscriber* subscriber = (Subscriber*) data; Notification notification(subscriber, event, false); subscriber->notifyRsrcStatus(notification); } // break; case RSRC_GRANTED: case RSRC_RELEASED: case RSRC_DENIED: default: LOC_LOGW("%s: unrecognized event %d", whoami(), event); // no state change. break; } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; }
void AgpsStateMachine::onRsrcEvent(AgpsRsrcStatus event) { switch (event) { case RSRC_GRANTED: case RSRC_RELEASED: case RSRC_DENIED: mStatePtr = mStatePtr->onRsrcEvent(event, NULL); break; default: LOC_LOGW("AgpsStateMachine: unrecognized event %d", event); break; } }
void loc_clear(rpc_loc_client_handle_type handle) { /* Clean the client's callback function in callback table */ int i; for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++) { if (loc_glue_callback_table[i].handle == handle) { /* Found the client */ loc_glue_callback_table[i].cb_func = NULL; loc_glue_callback_table[i].rpc_cb = NULL; loc_glue_callback_table[i].handle = -1; loc_glue_callback_table[i].user = NULL; break; } } if (i == LOC_API_CB_MAX_CLIENTS) { LOC_LOGW("Handle not found (handle=%d)...\n", (int) handle); } }
/*=========================================================================== 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; }
/*=========================================================================== FUNCTION loc_read_gps_conf DESCRIPTION Reads the gps.conf file and sets global parameter data DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_read_gps_conf(void) { FILE *gps_conf_fp = NULL; char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */ char *lasts; char *param_name, *param_str_value; int param_value; int i; loc_default_parameters(); if((gps_conf_fp = fopen(GPS_CONF_FILE, "r")) != NULL) { LOC_LOGD("loc_read_gps_conf: using %s", GPS_CONF_FILE); } else { LOC_LOGW("loc_read_gps_conf: no %s file, using defaults", GPS_CONF_FILE); return; /* no parameter file */ } while(fgets(input_buf, LOC_MAX_PARAM_LINE, gps_conf_fp) != NULL) { /* Separate variable and value */ param_name = strtok_r(input_buf, "=", &lasts); if (param_name == NULL) continue; /* skip lines that do not contain "=" */ param_str_value = strtok_r(NULL, "=", &lasts); if (param_str_value == NULL) continue; /* skip lines that do not contain two operands */ /* Trim leading and trailing spaces */ trim_space(param_name); trim_space(param_str_value); // printf("*(%s) = (%s)\n", param_name, param_str_value); /* Parse numerical value */ if (param_str_value[0] == '0' && tolower(param_str_value[1]) == 'x') { /* hex */ param_value = (int) strtol(¶m_str_value[2], (char**) NULL, 16); } else { /* dec */ param_value = atoi(param_str_value); /* dec */ } for(i = 0; i < loc_param_num; i++) { if (strcmp(loc_parameter_table[i].param_name, param_name) == 0 && loc_parameter_table[i].param_ptr) { switch (loc_parameter_table[i].param_type) { case 's': if (strcmp(param_str_value, "NULL") == 0) { *((char*)loc_parameter_table[i].param_ptr) = '\0'; } else { strlcpy((char*) loc_parameter_table[i].param_ptr, param_str_value, LOC_MAX_PARAM_STRING + 1); } /* Log INI values */ LOC_LOGD("loc_read_gps_conf: PARAM %s = %s\n", param_name, (char*)loc_parameter_table[i].param_ptr); break; case 'n': *((int *)loc_parameter_table[i].param_ptr) = param_value; /* Log INI values */ LOC_LOGD("loc_read_gps_conf: PARAM %s = %d\n", param_name, param_value); break; default: LOC_LOGE("loc_read_gps_conf: PARAM %s parameter type must be n or n", param_name); } } } } fclose(gps_conf_fp); }
/*=========================================================================== FUNCTION loc_read_conf DESCRIPTION Reads the specified configuration file and sets defined values based on the passed in configuration table. This table maps strings to values to set along with the type of each of these values. PARAMETERS: conf_file_name: configuration file to read config_table: table definition of strings to places to store information table_length: length of the configuration table DEPENDENCIES N/A RETURN VALUE None SIDE EFFECTS N/A ===========================================================================*/ void loc_read_conf(const char* conf_file_name, loc_param_s_type* config_table, uint32_t table_length) { FILE *gps_conf_fp = NULL; char input_buf[LOC_MAX_PARAM_LINE]; /* declare a char array */ char *lasts; loc_param_v_type config_value; uint32_t i; if((gps_conf_fp = fopen(conf_file_name, "r")) != NULL) { LOC_LOGD("%s: using %s", __FUNCTION__, conf_file_name); } else { LOC_LOGW("%s: no %s file found", __FUNCTION__, conf_file_name); loc_logger_init(DEBUG_LEVEL, TIMESTAMP); return; /* no parameter file */ } /* Clear all validity bits */ for(i = 0; NULL != config_table && i < table_length; i++) { if(NULL != config_table[i].param_set) { *(config_table[i].param_set) = 0; } } while(fgets(input_buf, LOC_MAX_PARAM_LINE, gps_conf_fp) != NULL) { memset(&config_value, 0, sizeof(config_value)); /* Separate variable and value */ config_value.param_name = strtok_r(input_buf, "=", &lasts); if (config_value.param_name == NULL) continue; /* skip lines that do not contain "=" */ config_value.param_str_value = strtok_r(NULL, "=", &lasts); if (config_value.param_str_value == NULL) continue; /* skip lines that do not contain two operands */ /* Trim leading and trailing spaces */ trim_space(config_value.param_name); trim_space(config_value.param_str_value); /* Parse numerical value */ if (config_value.param_str_value[0] == '0' && tolower(config_value.param_str_value[1]) == 'x') { /* hex */ config_value.param_int_value = (int) strtol(&config_value.param_str_value[2], (char**) NULL, 16); } else { config_value.param_double_value = (double) atof(config_value.param_str_value); /* float */ config_value.param_int_value = atoi(config_value.param_str_value); /* dec */ } for(i = 0; NULL != config_table && i < table_length; i++) { loc_set_config_entry(&config_table[i], &config_value); } for(i = 0; i < loc_param_num; i++) { loc_set_config_entry(&loc_parameter_table[i], &config_value); } } fclose(gps_conf_fp); /* Initialize logging mechanism with parsed data */ loc_logger_init(DEBUG_LEVEL, TIMESTAMP); }
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; }
AgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data) { AgpsState* nextState = this; switch (event) { case RSRC_SUBSCRIBE: { // we already have the NIF resource, simply notify subscriber Subscriber* subscriber = (Subscriber*) data; // we have rsrc in hand, so grant it right away Notification notification(subscriber, RSRC_GRANTED, false); subscriber->notifyRsrcStatus(notification); // add subscriber to the list mStateMachine->addSubscriber(subscriber); // no state change. } break; case RSRC_UNSUBSCRIBE: { Subscriber* subscriber = (Subscriber*) data; if (subscriber->waitForCloseComplete()) { subscriber->setInactive(); } else { // auto notify this subscriber of the unsubscribe Notification notification(subscriber, event, true); mStateMachine->notifySubscribers(notification); } // now check if there is any subscribers left if (!mStateMachine->hasSubscribers()) { // no more subscribers, move to RELEASED state nextState = mReleasedState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } else if (!mStateMachine->hasActiveSubscribers()) { // only inactive subscribers, move to RELEASING state nextState = mReleasingState; // tell connecivity service we can release NIF mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN); } } break; case RSRC_GRANTED: LOC_LOGW("%s: %d, RSRC_GRANTED already received", whoami(), event); // no state change. break; case RSRC_RELEASED: { LOC_LOGW("%s: %d, a force rsrc release", whoami(), event); nextState = mReleasedState; Notification notification(Notification::BROADCAST_ALL, event, true); // by setting true, we remove subscribers from the linked list mStateMachine->notifySubscribers(notification); } break; case RSRC_DENIED: // no state change. // we are expecting RELEASED. Handling DENIED // may like break our state machine in race conditions. break; default: LOC_LOGE("%s: unrecognized event %d", whoami(), event); // no state change. } LOC_LOGD("onRsrcEvent, old state %s, new state %s, event %d", whoami(), nextState->whoami(), event); return nextState; }
/*=========================================================================== 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); } } }
/*=========================================================================== FUNCTION loc_sync_wait_for_ind DESCRIPTION Waits for a selected indication. The wait expires in timeout_seconds seconds. If the function is called before an existing wait has finished, it will immediately return error. DEPENDENCIES N/A RETURN VALUE 0 on SUCCESS, -ve value on failure SIDE EFFECTS N/A ===========================================================================*/ static int loc_sync_wait_for_ind( int select_id, /* ID from loc_sync_select_ind() */ int timeout_seconds, /* Timeout in this number of seconds */ uint32_t ind_id ) { if (select_id < 0 || select_id >= LOC_SYNC_REQ_BUFFER_SIZE || !loc_sync_array.slot_in_use[select_id]) { LOC_LOGE("%s:%d]: invalid select_id: %d \n", __func__, __LINE__, select_id); return (-EINVAL); } loc_sync_req_data_s_type *slot = &loc_sync_array.slots[select_id]; int ret_val = 0; /* the return value of this function: 0 = no error */ int rc; /* return code from pthread calls */ struct timeval present_time; struct timespec expire_time; pthread_mutex_lock(&slot->sync_req_lock); do { if (slot->ind_has_arrived) { ret_val = 0; /* success */ break; } if (slot->ind_is_waiting) { LOC_LOGW("%s:%d]: already waiting in this slot %d\n", __func__, __LINE__, select_id); ret_val = -EBUSY; // busy break; } /* Calculate absolute expire time */ gettimeofday(&present_time, NULL); expire_time.tv_sec = present_time.tv_sec; expire_time.tv_nsec = present_time.tv_usec * 1000; expire_time.tv_sec += timeout_seconds; /* Take new wait request */ slot->ind_is_waiting = true; /* Waiting */ rc = pthread_cond_timedwait(&slot->ind_arrived_cond, &slot->sync_req_lock, &expire_time); slot->ind_is_waiting = false; if(rc == ETIMEDOUT) { LOC_LOGE("%s:%d]: slot %d, timed out for ind_id %s\n", __func__, __LINE__, select_id, loc_get_v02_event_name(ind_id)); ret_val = -ETIMEDOUT; //time out } } while (0); pthread_mutex_unlock(&slot->sync_req_lock); loc_free_slot(select_id); return ret_val; }