1/****************************************************************************** 2 @file loc_api_rpc_glue.c 3 @brief Android Loc API glue code using rpcgen. 4 5 DESCRIPTION 6 Loc API glue code for Android 7 8 ----------------------------------------------------------------------------- 9Copyright (c) 2009, QUALCOMM USA, INC. 10 11All rights reserved. 12 13Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 14 15· Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 16 17· Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 18 19· Neither the name of the QUALCOMM USA, INC. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 20 21THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 ----------------------------------------------------------------------------- 23 ******************************************************************************/ 24/*===================================================================== 25 EDIT HISTORY FOR MODULE 26 27 This section contains comments describing changes made to the module. 28 Notice that changes are listed in reverse chronological order. 29 30when who what, where, why 31-------- --- ------------------------------------------------------- 3203/05/2009 dx Initial version 33 34======================================================================*/ 35/*===================================================================== 36 37 INCLUDE FILES FOR MODULE 38 39======================================================================*/ 40//#define LOG_NDDEBUG 0 41 42#include <stdio.h> 43#include <pthread.h> 44#include <errno.h> 45#include <string.h> 46#include <sys/select.h> 47#include <sys/time.h> 48#include <sys/types.h> 49#include <sys/stat.h> 50#include <fcntl.h> 51#include <sys/mman.h> 52#include <unistd.h> 53#include <stdlib.h> 54#include <assert.h> 55 56#include <rpc/rpc.h> 57#include <rpc/clnt.h> 58 59/* Include RPC headers */ 60#include "loc_api_rpc_glue.h" 61 62/* Callback init */ 63#include "loc_apicb_appinit.h" 64 65/* Logging */ 66#define LOG_TAG "lib_api_rpc_glue" 67#include <utils/Log.h> 68 69/* Comment this out to enable logging */ 70#undef ALOGD 71#define ALOGD(...) {} 72 73/*===================================================================== 74 External declarations 75======================================================================*/ 76 77CLIENT* loc_api_clnt = NULL; 78 79/* Callback ID and pointer */ 80#define LOC_API_CB_ID 1 81loc_event_cb_f_type *loc_api_saved_cb = NULL; /* the only callback of Loc API client */ 82 83#define RPC_FUNC_VERSION_BASE(a,b) a ## b 84#define RPC_FUNC_VERSION(a,b) RPC_FUNC_VERSION_BASE(a,b) 85 86#define LOC_GLUE_CHECK_INIT(ret_type) \ 87 if (loc_api_clnt == NULL) { return (ret_type) RPC_LOC_API_RPC_FAILURE; } 88 89#define LOC_GLUE_CHECK_RESULT(stat, ret_type) \ 90 if (stat != RPC_SUCCESS) { return (ret_type) RPC_LOC_API_RPC_FAILURE; } 91 92/* Callback functions */ 93/* Returns 1 if successful */ 94bool_t rpc_loc_event_cb_f_type_0x00040001_svc( 95 rpc_loc_event_cb_f_type_args *argp, 96 rpc_loc_event_cb_f_type_rets *ret, 97 struct svc_req *req) 98{ 99 /* Callback not registered, or unexpected ID (shouldn't happen) */ 100 if (loc_api_saved_cb == NULL || argp->cb_id != LOC_API_CB_ID) 101 { 102 ALOGD("Warning: No callback handler.\n"); 103 ret->loc_event_cb_f_type_result = 0; 104 return 1; /* simply return */ 105 } 106 107 ALOGD("proc: %x prog: %x vers: %x\n", 108 (int) req->rq_proc, 109 (int) req->rq_prog, 110 (int) req->rq_vers); 111 112 ALOGD("Callback received: %x (handle=%d ret_ptr=%d)\n", 113 (int) argp->loc_event, 114 (int) argp->loc_handle, 115 (int) ret); 116 117 /* Forward callback to real callback procedure */ 118 rpc_loc_client_handle_type loc_handle = argp->loc_handle; 119 rpc_loc_event_mask_type loc_event = argp->loc_event; 120 const rpc_loc_event_payload_u_type* loc_event_payload = 121 (const rpc_loc_event_payload_u_type*) argp->loc_event_payload; 122 123 int32 rc = loc_api_saved_cb(loc_handle, loc_event, loc_event_payload); 124 ret->loc_event_cb_f_type_result = rc; 125 126 return 1; /* ok */ 127} 128 129int loc_apicbprog_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result) 130{ 131 xdr_free (xdr_result, result); 132 133 /* 134 * Insert additional freeing code here, if needed 135 */ 136 // ALOGD("***** loc_apicbprog_freeresult\n"); 137 138 return 1; 139} 140 141int loc_apicbprog_0x00040001_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result) 142{ 143 return loc_apicbprog_freeresult (transp, xdr_result, result); 144} 145 146/*=========================================================================== 147 148FUNCTION loc_api_glue_init 149 150DESCRIPTION 151 Initiates the RPC client 152 153RETURN VALUE 154 1 for success 155 0 for failure 156 157===========================================================================*/ 158int loc_api_glue_init(void) 159{ 160 if (loc_api_clnt == NULL) 161 { 162 /* Print msg */ 163 ALOGD("Trying to create RPC client...\n"); 164 loc_api_clnt = clnt_create(NULL, LOC_APIPROG, LOC_APIVERS, NULL); 165 ALOGD("Created loc_api_clnt ---- %x\n", (unsigned int)loc_api_clnt); 166 167 if (loc_api_clnt == NULL) 168 { 169 fprintf(stderr, "Error: cannot create RPC client.\n"); 170 return 0; 171 } 172 173 /* Init RPC callbacks */ 174 int rc = loc_apicb_app_init(); 175 if (rc >= 0) 176 { 177 ALOGD("Loc API callback initialized.\n"); 178 } else { 179 fprintf(stderr, "Loc API callback initialization failed.\n"); 180 return 0; 181 } 182 } 183 184 return 1; 185} 186 187rpc_loc_client_handle_type loc_open ( 188 rpc_loc_event_mask_type event_reg_mask, 189 loc_event_cb_f_type *event_callback 190 ) 191{ 192 LOC_GLUE_CHECK_INIT(rpc_loc_client_handle_type); 193 194 rpc_loc_open_args args; 195 args.event_reg_mask = event_reg_mask; 196 args.event_callback = LOC_API_CB_ID; 197 loc_api_saved_cb = event_callback; 198 199 rpc_loc_open_rets rets; 200 enum clnt_stat stat = RPC_SUCCESS; 201 202 stat = RPC_FUNC_VERSION(rpc_loc_open_, /* LOC_APIVERS */ 0x00040001)(&args, &rets, loc_api_clnt); 203 LOC_GLUE_CHECK_RESULT(stat, int32); 204 205 return (rpc_loc_client_handle_type) rets.loc_open_result; 206} 207 208int32 loc_close(rpc_loc_client_handle_type handle) 209{ 210 LOC_GLUE_CHECK_INIT(int32); 211 212 rpc_loc_close_args args; 213 args.handle = handle; 214 215 rpc_loc_close_rets rets; 216 enum clnt_stat stat = RPC_SUCCESS; 217 218 stat = RPC_FUNC_VERSION(rpc_loc_close_, /* LOC_APIVERS */ 0x00040001)(&args, &rets, loc_api_clnt); 219 LOC_GLUE_CHECK_RESULT(stat, int32); 220 221 return (int32) rets.loc_close_result; 222} 223 224int32 loc_start_fix(rpc_loc_client_handle_type handle) 225{ 226 LOC_GLUE_CHECK_INIT(int32); 227 228 rpc_loc_start_fix_args args; 229 args.handle = handle; 230 231 rpc_loc_start_fix_rets rets; 232 enum clnt_stat stat = RPC_SUCCESS; 233 234 stat = RPC_FUNC_VERSION(rpc_loc_start_fix_, /* LOC_APIVERS */ 0x00040001)(&args, &rets, loc_api_clnt); 235 LOC_GLUE_CHECK_RESULT(stat, int32); 236 237 return (int32) rets.loc_start_fix_result; 238} 239 240int32 loc_stop_fix(rpc_loc_client_handle_type handle) 241{ 242 LOC_GLUE_CHECK_INIT(int32); 243 244 rpc_loc_stop_fix_args args; 245 args.handle = handle; 246 247 rpc_loc_stop_fix_rets rets; 248 enum clnt_stat stat = RPC_SUCCESS; 249 250 stat = RPC_FUNC_VERSION(rpc_loc_stop_fix_, /* LOC_APIVERS */ 0x00040001)(&args, &rets, loc_api_clnt); 251 LOC_GLUE_CHECK_RESULT(stat, int32); 252 253 return (int32) rets.loc_stop_fix_result; 254} 255 256int32 loc_ioctl( 257 rpc_loc_client_handle_type handle, 258 rpc_loc_ioctl_e_type ioctl_type, 259 rpc_loc_ioctl_data_u_type* ioctl_data 260 ) 261{ 262 LOC_GLUE_CHECK_INIT(int32); 263 264 rpc_loc_ioctl_args args; 265 args.handle = handle; 266 args.ioctl_data = ioctl_data; 267 args.ioctl_type = ioctl_type; 268 if (ioctl_data != NULL) 269 { 270 /* Assign ioctl union discriminator */ 271 ioctl_data->disc = ioctl_type; 272 273 /* In case the user hasn't filled in other disc fields, 274 automatically fill them in here */ 275 switch (ioctl_type) 276 { 277 case RPC_LOC_IOCTL_GET_API_VERSION: 278 case RPC_LOC_IOCTL_SET_FIX_CRITERIA: 279 case RPC_LOC_IOCTL_GET_FIX_CRITERIA: 280 case RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE: 281 case RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA: 282 case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_VALIDITY: 283 case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE: 284 case RPC_LOC_IOCTL_SET_PREDICTED_ORBITS_DATA_AUTO_DOWNLOAD: 285 case RPC_LOC_IOCTL_INJECT_UTC_TIME: 286 case RPC_LOC_IOCTL_INJECT_RTC_VALUE: 287 case RPC_LOC_IOCTL_INJECT_POSITION: 288 case RPC_LOC_IOCTL_QUERY_ENGINE_STATE: 289 case RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS: 290 case RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS: 291 case RPC_LOC_IOCTL_SET_ENGINE_LOCK: 292 case RPC_LOC_IOCTL_GET_ENGINE_LOCK: 293 case RPC_LOC_IOCTL_SET_SBAS_CONFIG: 294 case RPC_LOC_IOCTL_GET_SBAS_CONFIG: 295 case RPC_LOC_IOCTL_SET_NMEA_TYPES: 296 case RPC_LOC_IOCTL_GET_NMEA_TYPES: 297 break; 298 case RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR: 299 case RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR: 300 case RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR: 301 args.ioctl_data->rpc_loc_ioctl_data_u_type_u.server_addr.addr_info.disc = 302 args.ioctl_data->rpc_loc_ioctl_data_u_type_u.server_addr.addr_type; 303 break; 304 case RPC_LOC_IOCTL_GET_CDMA_PDE_SERVER_ADDR: 305 case RPC_LOC_IOCTL_GET_CDMA_MPC_SERVER_ADDR: 306 case RPC_LOC_IOCTL_GET_UMTS_SLP_SERVER_ADDR: 307 break; 308 case RPC_LOC_IOCTL_SET_ON_DEMAND_LPM: 309 case RPC_LOC_IOCTL_GET_ON_DEMAND_LPM: 310 case RPC_LOC_IOCTL_DELETE_ASSIST_DATA: 311 case RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR: 312 case RPC_LOC_IOCTL_GET_CUSTOM_PDE_SERVER_ADDR: 313 default: 314 break; 315 } /* switch */ 316 } /* ioctl_data != NULL */ 317 318 rpc_loc_ioctl_rets rets; 319 enum clnt_stat stat = RPC_SUCCESS; 320 321 stat = RPC_FUNC_VERSION(rpc_loc_ioctl_, /* LOC_APIVERS */ 0x00040001)(&args, &rets, loc_api_clnt); 322 LOC_GLUE_CHECK_RESULT(stat, int32); 323 324 return (int32) rets.loc_ioctl_result; 325} 326 327/* Returns 0 if error */ 328int32 loc_api_null(void) 329{ 330 LOC_GLUE_CHECK_INIT(int32); 331 332 int32 rets; 333 enum clnt_stat stat = RPC_SUCCESS; 334 335 stat = RPC_FUNC_VERSION(rpc_loc_api_null_, LOC_APIVERS)(NULL, &rets, loc_api_clnt); 336 LOC_GLUE_CHECK_RESULT(stat, int32); 337 338 return (int32) rets; 339} 340