/*=========================================================================== FUNCTION loc_api_sync_ioctl DESCRIPTION Synchronous IOCTL call (reentrant version) DEPENDENCIES N/A RETURN VALUE Loc API error code (0 = success) SIDE EFFECTS N/A ===========================================================================*/ int loc_api_sync_ioctl ( rpc_loc_client_handle_type handle, rpc_loc_ioctl_e_type ioctl_type, rpc_loc_ioctl_data_u_type* ioctl_data_ptr, uint32 timeout_msec, rpc_loc_ioctl_callback_s_type *cb_data_ptr ) { int rc = RPC_LOC_API_ENGINE_BUSY; int select_id; rpc_loc_ioctl_callback_s_type callback_data; // Select the callback we are waiting for select_id = loc_api_select_callback(handle, 0, ioctl_type); if (select_id >= 0) { pthread_mutex_lock(&loc_sync_data.lock); rc = loc_ioctl(handle, ioctl_type, ioctl_data_ptr); while (rc == RPC_LOC_API_ENGINE_BUSY) { /* TODO: Use timeout? */ ALOGD("loc_api_sync_ioctl: select_id = %d, engine busy, waiting...\n", select_id); pthread_cond_wait(&loc_sync_data.loc_cb_arrived_cond, &loc_sync_data.lock); rc = loc_ioctl(handle, ioctl_type, ioctl_data_ptr); } pthread_mutex_unlock(&loc_sync_data.lock); ALOGV("loc_api_sync_ioctl: select_id = %d, loc_ioctl returned %d\n", select_id, rc); if (rc != RPC_LOC_API_SUCCESS) { ALOGE("loc_api_sync_ioctl: select_id = %d, loc_ioctl returned %d\n", select_id, rc); loc_free_slot(select_id); } else { // Wait for the callback of loc_ioctl if ((rc = loc_api_wait_callback(select_id, timeout_msec / 1000, NULL, &callback_data)) != 0) { // Callback waiting failed ALOGE("loc_api_sync_ioctl: loc_api_wait_callback failed, returned %d (select id %d)\n", rc, select_id); } else { if (cb_data_ptr) memcpy(cb_data_ptr, &callback_data, sizeof *cb_data_ptr); if (callback_data.status != RPC_LOC_API_SUCCESS) { rc = callback_data.status; ALOGE("loc_api_sync_ioctl: IOCTL result failed, result: %d (select id %d)\n", rc, select_id); } } /* wait callback */ } /* loc_ioctl */ } /* select id */ return rc; }
/*=========================================================================== FUNCTION loc_eng_ioctl DESCRIPTION This function calls loc_ioctl and waits for the callback result before returning back to the user. DEPENDENCIES N/A RETURN VALUE TRUE if successful FALSE if failed SIDE EFFECTS N/A ===========================================================================*/ boolean loc_eng_ioctl( rpc_loc_client_handle_type handle, rpc_loc_ioctl_e_type ioctl_type, rpc_loc_ioctl_data_u_type* ioctl_data_ptr, uint32 timeout_msec, rpc_loc_ioctl_callback_s_type *cb_data_ptr ) { boolean ret_val; int rpc_ret_val; loc_eng_ioctl_data_s_type *ioctl_cb_data_ptr; LOGV ("loc_eng_ioctl: client = %d, ioctl_type = %d, cb_data =0x%x\n", (int32) handle, ioctl_type, (uint32) cb_data_ptr); ioctl_cb_data_ptr = &(loc_eng_data.ioctl_data); // Select the callback we are waiting for ret_val = loc_eng_ioctl_setup_cb (handle, ioctl_type); if (ret_val == TRUE) { rpc_ret_val = loc_ioctl (handle, ioctl_type, ioctl_data_ptr); LOGV ("loc_eng_ioctl: loc_ioctl returned %d \n", rpc_ret_val); if (rpc_ret_val == RPC_LOC_API_SUCCESS) { // Wait for the callback of loc_ioctl ret_val = loc_eng_ioctl_wait_cb (timeout_msec, cb_data_ptr); } else { ret_val = FALSE; } } // Reset the state when we are done pthread_mutex_lock(&ioctl_cb_data_ptr->cb_data_mutex); ioctl_cb_data_ptr->cb_is_selected = FALSE; ioctl_cb_data_ptr->cb_is_waiting = FALSE; ioctl_cb_data_ptr->cb_has_arrived = FALSE; pthread_mutex_unlock(&ioctl_cb_data_ptr->cb_data_mutex); return ret_val; }
/*=========================================================================== FUNCTION qct_loc_eng_inject_xtra_data DESCRIPTION Injects XTRA file into the engine. DEPENDENCIES N/A RETURN VALUE 0: success error code > 0 SIDE EFFECTS N/A ===========================================================================*/ static int qct_loc_eng_inject_xtra_data_one(char* data, int length) { int rpc_ret_val = RPC_LOC_API_GENERAL_FAILURE; boolean ret_val = 0; int total_parts; uint8 part; uint16 part_len; uint16 len_injected; rpc_loc_ioctl_data_u_type ioctl_data; rpc_loc_ioctl_e_type ioctl_type = RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA; rpc_loc_predicted_orbits_data_s_type *predicted_orbits_data_ptr; LOC_LOGD("qct_loc_eng_inject_xtra_data, xtra size = %d, data ptr = 0x%x\n", length, (int) data); predicted_orbits_data_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.predicted_orbits_data; predicted_orbits_data_ptr->format_type = RPC_LOC_PREDICTED_ORBITS_XTRA; predicted_orbits_data_ptr->total_size = length; total_parts = (length - 1) / XTRA_BLOCK_SIZE + 1; predicted_orbits_data_ptr->total_parts = total_parts; len_injected = 0; // O bytes injected ioctl_data.disc = ioctl_type; // XTRA injection starts with part 1 for (part = 1; part <= total_parts; part++) { predicted_orbits_data_ptr->part = part; predicted_orbits_data_ptr->part_len = XTRA_BLOCK_SIZE; if (XTRA_BLOCK_SIZE > (length - len_injected)) { predicted_orbits_data_ptr->part_len = length - len_injected; } predicted_orbits_data_ptr->data_ptr.data_ptr_len = predicted_orbits_data_ptr->part_len; predicted_orbits_data_ptr->data_ptr.data_ptr_val = data + len_injected; LOC_LOGD("qct_loc_eng_inject_xtra_data, part %d/%d, len = %d, total = %d\n", predicted_orbits_data_ptr->part, total_parts, predicted_orbits_data_ptr->part_len, len_injected); if (part < total_parts) { // No callback in this case rpc_ret_val = loc_ioctl (loc_eng_data.client_handle, ioctl_type, &ioctl_data); if (rpc_ret_val != RPC_LOC_API_SUCCESS) { ret_val = EIO; // return error LOC_LOGE("loc_ioctl for xtra error: %s\n", loc_get_ioctl_status_name(rpc_ret_val)); break; } } else // part == total_parts { // Last part injection, will need to wait for callback if (!loc_eng_ioctl(loc_eng_data.client_handle, ioctl_type, &ioctl_data, LOC_XTRA_INJECT_DEFAULT_TIMEOUT, NULL)) { ret_val = EIO; LOC_LOGE("loc_eng_ioctl for xtra error\n"); } break; // done with injection } len_injected += predicted_orbits_data_ptr->part_len; LOC_LOGD("loc_ioctl XTRA injected length: %d\n", len_injected); } return ret_val; }
/*=========================================================================== FUNCTION qct_loc_eng_inject_xtra_data DESCRIPTION Injects XTRA file into the engine. DEPENDENCIES N/A RETURN VALUE 0: success >0: failure SIDE EFFECTS N/A ===========================================================================*/ static int qct_loc_eng_inject_xtra_data(char* data, int length) { int rpc_ret_val = RPC_LOC_API_GENERAL_FAILURE; boolean ret_val = 0; int total_parts; uint8 part; uint16 part_len; uint16 len_injected; rpc_loc_ioctl_data_u_type ioctl_data; rpc_loc_predicted_orbits_data_s_type *predicted_orbits_data_ptr; LOGV ("qct_loc_eng_inject_xtra_data, xtra size = %d, data ptr = 0x%x\n", length, (int) data); ioctl_data.disc = RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA; predicted_orbits_data_ptr = &(ioctl_data.rpc_loc_ioctl_data_u_type_u.predicted_orbits_data); predicted_orbits_data_ptr->format_type = RPC_LOC_PREDICTED_ORBITS_XTRA; predicted_orbits_data_ptr->total_size = length; total_parts = (length / XTRA_BLOCK_SIZE); if ((total_parts % XTRA_BLOCK_SIZE) != 0) { total_parts += 1; } predicted_orbits_data_ptr->total_parts = total_parts; len_injected = 0; // O bytes injected // XTRA injection starts with part 1 for (part = 1; part <= total_parts; part++) { predicted_orbits_data_ptr->part = part; predicted_orbits_data_ptr->part_len = XTRA_BLOCK_SIZE; if (XTRA_BLOCK_SIZE > (length - len_injected)) { predicted_orbits_data_ptr->part_len = length - len_injected; } predicted_orbits_data_ptr->data_ptr.data_ptr_len = predicted_orbits_data_ptr->part_len; predicted_orbits_data_ptr->data_ptr.data_ptr_val = data + len_injected; LOGV ("qct_loc_eng_inject_xtra_data, inject part = %d, len = %d, len = %d\n", predicted_orbits_data_ptr->part, predicted_orbits_data_ptr->part_len, predicted_orbits_data_ptr->data_ptr.data_ptr_len); LOGV ("qct_loc_eng_inject_xtra_data, total part = %d, len = %d \n", predicted_orbits_data_ptr->part, predicted_orbits_data_ptr->part_len); if (part < total_parts) { // No callback in this case rpc_ret_val = loc_ioctl (loc_eng_data.client_handle, RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA, &ioctl_data); if (rpc_ret_val != RPC_LOC_API_SUCCESS) { LOGE ("loc_ioctl for xtra returned %d \n", rpc_ret_val); ret_val = EINVAL; // return error break; } } else // part == total_parts { // Last part injection, will need to wait for callback ret_val = loc_eng_ioctl (loc_eng_data.client_handle, RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA, &ioctl_data, LOC_XTRA_INJECT_DEFAULT_TIMEOUT, NULL /* No output information is expected*/); break; // done with injection } len_injected += predicted_orbits_data_ptr->part_len; LOGV ("loc_ioctl for xtra len injected %d \n", len_injected); } return ret_val; }