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 -----------------------------------------------------------------------------
9 Copyright (c) 2009, QUALCOMM USA, INC.
10
11 All rights reserved.
12
13 Redistribution 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
21 THIS 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
30 when who what, where, why
31 -------- --- -------------------------------------------------------
32 03/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 LOGD
71 #define LOGD(...) {}
72
73 /*=====================================================================
74 External declarations
75 ======================================================================*/
76
77 CLIENT* loc_api_clnt = NULL;
78
79 /* Callback ID and pointer */
80 #define LOC_API_CB_ID 1
81 loc_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 */
rpc_loc_event_cb_f_type_0x00010001_svc(rpc_loc_event_cb_f_type_args * argp,rpc_loc_event_cb_f_type_rets * ret,struct svc_req * req)94 bool_t rpc_loc_event_cb_f_type_0x00010001_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 LOGD("Warning: No callback handler.\n");
103 ret->loc_event_cb_f_type_result = 0;
104 return 1; /* simply return */
105 }
106
107 LOGD("proc: %x prog: %x vers: %x\n",
108 (int) req->rq_proc,
109 (int) req->rq_prog,
110 (int) req->rq_vers);
111
112 LOGD("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
loc_apicbprog_freeresult(SVCXPRT * transp,xdrproc_t xdr_result,caddr_t result)129 int 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 // LOGD("***** loc_apicbprog_freeresult\n");
137
138 return 1;
139 }
140
loc_apicbprog_0x00010001_freeresult(SVCXPRT * transp,xdrproc_t xdr_result,caddr_t result)141 int loc_apicbprog_0x00010001_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
142 {
143 return loc_apicbprog_freeresult (transp, xdr_result, result);
144 }
145
146 /*===========================================================================
147
148 FUNCTION loc_api_glue_init
149
150 DESCRIPTION
151 Initiates the RPC client
152
153 RETURN VALUE
154 1 for success
155 0 for failure
156
157 ===========================================================================*/
loc_api_glue_init(void)158 int loc_api_glue_init(void)
159 {
160 if (loc_api_clnt == NULL)
161 {
162 /* Print msg */
163 LOGD("Trying to create RPC client...\n");
164 loc_api_clnt = clnt_create(NULL, LOC_APIPROG, /*LOC_APIVERS*/ 0x00010000, NULL);
165 LOGD("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 LOGD("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
loc_open(rpc_loc_event_mask_type event_reg_mask,loc_event_cb_f_type * event_callback)187 rpc_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)(&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
loc_close(rpc_loc_client_handle_type handle)208 int32 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)(&args, &rets, loc_api_clnt);
219 LOC_GLUE_CHECK_RESULT(stat, int32);
220
221 return (int32) rets.loc_close_result;
222 }
223
loc_start_fix(rpc_loc_client_handle_type handle)224 int32 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)(&args, &rets, loc_api_clnt);
235 LOC_GLUE_CHECK_RESULT(stat, int32);
236
237 return (int32) rets.loc_start_fix_result;
238 }
239
loc_stop_fix(rpc_loc_client_handle_type handle)240 int32 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)(&args, &rets, loc_api_clnt);
251 LOC_GLUE_CHECK_RESULT(stat, int32);
252
253 return (int32) rets.loc_stop_fix_result;
254 }
255
loc_ioctl(rpc_loc_client_handle_type handle,rpc_loc_ioctl_e_type ioctl_type,rpc_loc_ioctl_data_u_type * ioctl_data)256 int32 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)(&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 */
loc_api_null(void)328 int32 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