uint8_t *util_unhex(char *in, size_t len, uint8_t *out) { uint32_t j; uint8_t *c = out; if(!out || !in) return NULL; if(!len) len = strlen(in); for(j=0; (j+1)<len; j+=2) { *c = ((hexcode(in[j]) * 16) & 0xF0) + (hexcode(in[j+1]) & 0xF); c++; } return out; }
char *util_ishex(char *str, uint32_t len) { uint32_t i; for(i=0;i<len;i++) { if(!str[i]) return NULL; if(str[i] == hexcode(str[i])) return NULL; } return str; }
/*=========================================================================== 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); } } }