1 /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation, nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*=====================================================================
30
31 INCLUDE FILES FOR MODULE
32
33 ======================================================================*/
34 #include <stdio.h>
35 #include <pthread.h>
36 #include <errno.h>
37 #include <string.h>
38 #include <sys/select.h>
39 #include <sys/time.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <fcntl.h>
43 #include <sys/mman.h>
44 #include <unistd.h>
45 #include <stdlib.h>
46 #include <assert.h>
47 #include <loc_api_log.h>
48
49 #include <rpc/rpc.h>
50
51 /* Include RPC headers */
52 #include "rpc_inc/loc_api_rpc_glue.h"
53
54 /* Callback init */
55 #include "rpc_inc/loc_apicb_appinit.h"
56
57 /* Logging */
58 #define LOG_TAG "LocSvc_api_rpc_glue"
59 #define LOG_NDDEBUG 0
60 #ifndef USE_GLIB
61 #include <utils/Log.h>
62 #endif /* USE_GLIB */
63
64 /* Logging Improvement */
65 #include "log_util.h"
66 #include "platform_lib_includes.h"
67 /*Maximum number of Modem init*/
68 #define RPC_TRY_NUM 10
69
70 /*Maximum number of Modem init*/
71 #define RPC_TRY_NUM 10
72
73 /* Uncomment to force ALOGD messages */
74 // #define ALOGD ALOGI
75
76 /*=====================================================================
77 External declarations
78 ======================================================================*/
79
80 CLIENT* loc_api_clnt = NULL;
81
82 /* Callback ID and pointer */
83 #define LOC_API_CB_MAX_CLIENTS 16
84 typedef struct
85 {
86 uint32 cb_id; /* same as rpc/types.h */
87 loc_event_cb_f_type *cb_func; /* callback func */
88 loc_reset_notif_cb_f_type *rpc_cb; /* callback from RPC */
89 rpc_loc_client_handle_type handle; /* stores handle for client closing */
90 void* user; /* user's own data handle */
91 } loc_glue_cb_entry_s_type;
92
93 loc_glue_cb_entry_s_type loc_glue_callback_table[LOC_API_CB_MAX_CLIENTS];
94
95 #define RPC_FUNC_VERSION_BASE(a,b) a ## b
96 #define RPC_FUNC_VERSION(a,b) RPC_FUNC_VERSION_BASE(a,b)
97
98 #define RPC_CALLBACK_FUNC_VERSION_BASE(a,v,b) a ## v ## b
99 #define RPC_CALLBACK_FUNC_VERSION(a,v,b) RPC_CALLBACK_FUNC_VERSION_BASE(a,v,b)
100
101 #define LOC_GLUE_CHECK_INIT(ret_type) \
102 if (loc_api_clnt == NULL) { EXIT_LOG_CALLFLOW(%d, RPC_LOC_API_RPC_FAILURE); return (ret_type) RPC_LOC_API_RPC_FAILURE; }
103
104 #define LOC_GLUE_CHECK_RESULT(stat, ret_type) \
105 if (stat != RPC_SUCCESS) { \
106 LOC_LOGE("%s:%d] failure code %d", __func__, __LINE__, stat); \
107 return (ret_type)((stat == RPC_SUBSYSTEM_RESTART) ? \
108 RPC_LOC_API_RPC_MODEM_RESTART : RPC_LOC_API_RPC_FAILURE); \
109 }
110
111 /* Callback functions */
112 /* Returns 1 if successful */
rpc_loc_event_cb_f_type_svc(rpc_loc_event_cb_f_type_args * argp,rpc_loc_event_cb_f_type_rets * ret,struct svc_req * req)113 bool_t rpc_loc_event_cb_f_type_svc(
114 rpc_loc_event_cb_f_type_args *argp,
115 rpc_loc_event_cb_f_type_rets *ret,
116 struct svc_req *req)
117 {
118 // The lower word of cd_id is the index
119 int index = argp->cb_id & 0xFFFF;
120
121 /* Callback not registered, or unexpected ID (shouldn't happen) */
122 if (index >= LOC_API_CB_MAX_CLIENTS || loc_glue_callback_table[index].cb_func == NULL)
123 {
124 LOC_LOGE("Warning: No callback handler %d.\n", index);
125 ret->loc_event_cb_f_type_result = 0;
126 return 1; /* simply return */
127 }
128
129 LOC_LOGV("proc: %x prog: %x vers: %x\n",
130 (int) req->rq_proc,
131 (int) req->rq_prog,
132 (int) req->rq_vers);
133
134 LOC_LOGV("Callback received: %x (cb_id=%p handle=%d ret_ptr=%d)\n",
135 (int) argp->loc_event,
136 argp->cb_id,
137 (int) argp->loc_handle,
138 (int) ret);
139
140 /* Forward callback to real callback procedure */
141 rpc_loc_client_handle_type loc_handle = argp->loc_handle;
142 rpc_loc_event_mask_type loc_event = argp->loc_event;
143 const rpc_loc_event_payload_u_type* loc_event_payload =
144 (const rpc_loc_event_payload_u_type*) argp->loc_event_payload;
145
146 /* Gives control to synchronous call handler */
147 loc_api_callback_process_sync_call(loc_handle, loc_event, loc_event_payload);
148
149 int32 rc = (loc_glue_callback_table[index].cb_func)(loc_glue_callback_table[index].user,
150 loc_handle, loc_event, loc_event_payload);
151
152 LOC_LOGV("cb_func=%p", loc_glue_callback_table[index].cb_func);
153
154 ret->loc_event_cb_f_type_result = rc;
155
156 return 1; /* ok */
157 }
158
loc_apicbprog_freeresult(SVCXPRT * transp,xdrproc_t xdr_result,caddr_t result)159 int loc_apicbprog_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
160 {
161 xdr_free (xdr_result, result);
162
163 /*
164 * Insert additional freeing code here, if needed
165 */
166 // LOC_LOGD("***** loc_apicbprog_freeresult\n");
167
168 return 1;
169 }
170
171 /*===========================================================================
172
173 FUNCTION rpc_loc_event_cb_f_type_<version>_svc (MACRO)
174
175 DESCRIPTION
176 Callback function for Loc API
177
178 RETURN VALUE
179 1 for success
180 0 for failure
181
182 ===========================================================================*/
RPC_CALLBACK_FUNC_VERSION(rpc_loc_event_cb_f_type_,RPC_LOC_EVENT_CB_F_TYPE_VERSION,_svc)183 bool_t RPC_CALLBACK_FUNC_VERSION(rpc_loc_event_cb_f_type_, RPC_LOC_EVENT_CB_F_TYPE_VERSION, _svc) (
184 rpc_loc_event_cb_f_type_args *argp,
185 rpc_loc_event_cb_f_type_rets *ret,
186 struct svc_req *req)
187 {
188 return rpc_loc_event_cb_f_type_svc(argp, ret, req);
189 }
190
191 /*===========================================================================
192
193 FUNCTION loc_apicbprog_<version>_freeresult (MACRO)
194
195 DESCRIPTION
196 Free up RPC data structure
197
198 RETURN VALUE
199 1 for success
200 0 for failure
201
202 ===========================================================================*/
203 #define VERSION_CONCAT(MAJOR,MINOR) MAJOR##MINOR
204 #define loc_apicb_prog_VER_freeresult(M,N) \
205 int RPC_CALLBACK_FUNC_VERSION(loc_apicbprog_, VERSION_CONCAT(M,N), _freeresult) \
206 (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result) \
207 { \
208 return loc_apicbprog_freeresult(transp, xdr_result, result); \
209 }
210
211 /* Define all of the possible minors */
212 loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0001);
213 loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0002);
214 loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0003);
215 loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0004);
216 loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0005);
217 loc_apicb_prog_VER_freeresult(RPC_LOC_API_API_MAJOR_NUM, 0006);
218
219 /*===========================================================================
220
221 FUNCTION rpc_loc_api_cb_null_<version>_svc (MACRO) [Patch for wrong RPCGEN stubs]
222
223 DESCRIPTION
224 Null callback function for Loc API
225
226 RETURN VALUE
227 1 for success
228
229 ===========================================================================*/
230 #define rpc_loc_api_cb_null_VER_svc(M,N) \
231 bool_t RPC_CALLBACK_FUNC_VERSION(rpc_loc_api_cb_null_, VERSION_CONCAT(M,N), _svc) ( \
232 void *a, int *b, struct svc_req *req) \
233 { \
234 return 1; \
235 }
236
237 /* Define all of the possible minors */
238 rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0001);
239 rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0002);
240 rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0003);
241 rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0004);
242 rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0005);
243 rpc_loc_api_cb_null_VER_svc(RPC_LOC_API_API_MAJOR_NUM, 0006);
244
loc_api_glue_rpc_cb(CLIENT * client,enum rpc_reset_event event)245 static void loc_api_glue_rpc_cb(CLIENT* client, enum rpc_reset_event event)
246 {
247 int i;
248 for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++) {
249 if (NULL != loc_glue_callback_table[i].rpc_cb) {
250 loc_glue_callback_table[i].rpc_cb(loc_glue_callback_table[i].user, client, event);
251 }
252 }
253 }
254
255 /*===========================================================================
256
257 FUNCTION loc_api_glue_init
258
259 DESCRIPTION
260 Initiates the RPC client
261
262 RETURN VALUE
263 1 for success
264 0 for failure
265
266 ===========================================================================*/
loc_api_glue_init(void)267 int loc_api_glue_init(void)
268 {
269 if (loc_api_clnt == NULL)
270 {
271 /* Initialize data */
272 int i;
273 int pid = getpid();
274 for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++)
275 {
276 loc_glue_callback_table[i].cb_id = i | (pid << 16);
277 loc_glue_callback_table[i].cb_func = NULL;
278 loc_glue_callback_table[i].handle = -1;
279 loc_glue_callback_table[i].rpc_cb = NULL;
280 loc_glue_callback_table[i].user = NULL;
281 }
282
283 /* Print msg */
284 LOC_LOGV("Trying to create RPC client...\n");
285 loc_api_clnt = clnt_create(NULL, LOC_APIPROG, LOC_APIVERS, NULL);
286 LOC_LOGV("Created loc_api_clnt ---- %x\n", (unsigned int)loc_api_clnt);
287
288 if (loc_api_clnt == NULL)
289 {
290 LOC_LOGE("Error: cannot create RPC client.\n");
291 return 0;
292 }
293
294 /* Init RPC callbacks */
295 loc_api_sync_call_init();
296
297 int rc = loc_apicb_app_init();
298 if (rc >= 0)
299 {
300 LOC_LOGD("Loc API RPC client initialized.\n");
301 clnt_register_reset_notification_cb(loc_api_clnt, loc_api_glue_rpc_cb);
302 }
303 else {
304 LOC_LOGE("Loc API callback initialization failed.\n");
305 return 0;
306 }
307 }
308
309 return 1;
310 }
311
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)312 rpc_loc_client_handle_type loc_open (
313 rpc_loc_event_mask_type event_reg_mask,
314 loc_event_cb_f_type *event_callback,
315 loc_reset_notif_cb_f_type *rpc_cb,
316 void* userData
317 )
318 {
319 int try_num = RPC_TRY_NUM;
320 ENTRY_LOG();
321 LOC_GLUE_CHECK_INIT(rpc_loc_client_handle_type);
322
323 rpc_loc_client_handle_type ret_val;
324
325 rpc_loc_open_args args;
326 args.event_reg_mask = event_reg_mask;
327
328 int i, j = LOC_API_CB_MAX_CLIENTS;
329 for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++)
330 {
331 if (loc_glue_callback_table[i].user == userData)
332 {
333 LOC_LOGW("Client already opened service (callback=%p)...\n",
334 event_callback);
335 break;
336 } else if (j == LOC_API_CB_MAX_CLIENTS &&
337 loc_glue_callback_table[i].user == NULL) {
338 j = i;
339 }
340 }
341
342 if (i == LOC_API_CB_MAX_CLIENTS)
343 {
344 i = j;
345 }
346
347 if (i == LOC_API_CB_MAX_CLIENTS)
348 {
349 LOC_LOGE("Too many clients opened at once...\n");
350 return RPC_LOC_CLIENT_HANDLE_INVALID;
351 }
352
353 loc_glue_callback_table[i].cb_func = event_callback;
354 loc_glue_callback_table[i].rpc_cb = rpc_cb;
355 loc_glue_callback_table[i].user = userData;
356
357 args.event_callback = loc_glue_callback_table[i].cb_id;
358 LOC_LOGV("cb_id=%d, func=0x%x", i, (unsigned int) event_callback);
359
360 rpc_loc_open_rets rets;
361 enum clnt_stat stat = RPC_SUCCESS;
362
363 EXIT_LOG_CALLFLOW(%s, "loc client open");
364
365 /*try more for rpc_loc_open_xx()*/
366
367 do
368 {
369 stat = RPC_FUNC_VERSION(rpc_loc_open_, RPC_LOC_OPEN_VERSION)(&args, &rets, loc_api_clnt);
370 ret_val = (rpc_loc_client_handle_type) rets.loc_open_result;
371 try_num--;
372
373 }while( (RPC_SUCCESS != stat||0 > ret_val) && 0 != try_num );
374
375 LOC_GLUE_CHECK_RESULT(stat, int32);
376
377 /* save the handle in the table */
378 loc_glue_callback_table[i].handle = (rpc_loc_client_handle_type) rets.loc_open_result;
379
380 return ret_val;
381
382 }
383
loc_close(rpc_loc_client_handle_type handle)384 int32 loc_close
385 (
386 rpc_loc_client_handle_type handle
387 )
388 {
389 ENTRY_LOG();
390 LOC_GLUE_CHECK_INIT(int32);
391
392 int32 ret_val;
393
394 rpc_loc_close_args args;
395 args.handle = handle;
396
397 rpc_loc_close_rets rets;
398 enum clnt_stat stat = RPC_SUCCESS;
399
400 EXIT_LOG_CALLFLOW(%s, "loc client close");
401 stat = RPC_FUNC_VERSION(rpc_loc_close_, RPC_LOC_CLOSE_VERSION)(&args, &rets, loc_api_clnt);
402
403 loc_clear(handle);
404
405 LOC_GLUE_CHECK_RESULT(stat, int32);
406 ret_val = (int32) rets.loc_close_result;
407
408 return ret_val;
409 }
410
loc_clear(rpc_loc_client_handle_type handle)411 void loc_clear(rpc_loc_client_handle_type handle) {
412 /* Clean the client's callback function in callback table */
413 int i;
414 for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++)
415 {
416 if (loc_glue_callback_table[i].handle == handle)
417 {
418 /* Found the client */
419 loc_glue_callback_table[i].cb_func = NULL;
420 loc_glue_callback_table[i].rpc_cb = NULL;
421 loc_glue_callback_table[i].handle = -1;
422 loc_glue_callback_table[i].user = NULL;
423 break;
424 }
425 }
426
427 if (i == LOC_API_CB_MAX_CLIENTS)
428 {
429 LOC_LOGW("Handle not found (handle=%d)...\n", (int) handle);
430 }
431 }
432
loc_start_fix(rpc_loc_client_handle_type handle)433 int32 loc_start_fix
434 (
435 rpc_loc_client_handle_type handle
436 )
437 {
438 ENTRY_LOG();
439 LOC_GLUE_CHECK_INIT(int32);
440
441 int32 ret_val;
442
443 rpc_loc_start_fix_args args;
444 args.handle = handle;
445
446 rpc_loc_start_fix_rets rets;
447 enum clnt_stat stat = RPC_SUCCESS;
448
449 EXIT_LOG_CALLFLOW(%s, "loc start fix");
450 stat = RPC_FUNC_VERSION(rpc_loc_start_fix_, RPC_LOC_START_FIX_VERSION)(&args, &rets, loc_api_clnt);
451 LOC_GLUE_CHECK_RESULT(stat, int32);
452
453 ret_val = (int32) rets.loc_start_fix_result;
454
455 return ret_val;
456 }
457
loc_stop_fix(rpc_loc_client_handle_type handle)458 int32 loc_stop_fix
459 (
460 rpc_loc_client_handle_type handle
461 )
462 {
463 ENTRY_LOG();
464 LOC_GLUE_CHECK_INIT(int32);
465
466 int32 ret_val;
467
468 rpc_loc_stop_fix_args args;
469 args.handle = handle;
470
471 rpc_loc_stop_fix_rets rets;
472 enum clnt_stat stat = RPC_SUCCESS;
473
474 EXIT_LOG_CALLFLOW(%s, "loc stop fix");
475 stat = RPC_FUNC_VERSION(rpc_loc_stop_fix_, RPC_LOC_STOP_FIX_VERSION)(&args, &rets, loc_api_clnt);
476 LOC_GLUE_CHECK_RESULT(stat, int32);
477
478 ret_val = (int32) rets.loc_stop_fix_result;
479
480 return ret_val;
481 }
482
loc_ioctl(rpc_loc_client_handle_type handle,rpc_loc_ioctl_e_type ioctl_type,rpc_loc_ioctl_data_u_type * ioctl_data)483 int32 loc_ioctl
484 (
485 rpc_loc_client_handle_type handle,
486 rpc_loc_ioctl_e_type ioctl_type,
487 rpc_loc_ioctl_data_u_type* ioctl_data
488 )
489 {
490 ENTRY_LOG();
491 LOC_GLUE_CHECK_INIT(int32);
492
493 int32 ret_val;
494
495 rpc_loc_ioctl_args args;
496 args.handle = handle;
497 args.ioctl_data = ioctl_data;
498 args.ioctl_type = ioctl_type;
499 if (ioctl_data != NULL)
500 {
501 /* Assign ioctl union discriminator */
502 ioctl_data->disc = ioctl_type;
503
504 /* In case the user hasn't filled in other disc fields,
505 automatically fill them in here */
506 switch (ioctl_type)
507 {
508 case RPC_LOC_IOCTL_GET_API_VERSION:
509 break;
510 case RPC_LOC_IOCTL_SET_FIX_CRITERIA:
511 break;
512 case RPC_LOC_IOCTL_GET_FIX_CRITERIA:
513 break;
514 case RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE:
515 break;
516 case RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA:
517 break;
518 case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_VALIDITY:
519 break;
520 case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE:
521 break;
522 case RPC_LOC_IOCTL_SET_PREDICTED_ORBITS_DATA_AUTO_DOWNLOAD:
523 break;
524 case RPC_LOC_IOCTL_INJECT_UTC_TIME:
525 break;
526 case RPC_LOC_IOCTL_INJECT_RTC_VALUE:
527 break;
528 case RPC_LOC_IOCTL_INJECT_POSITION:
529 break;
530 case RPC_LOC_IOCTL_QUERY_ENGINE_STATE:
531 break;
532 case RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS:
533 break;
534 case RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS:
535 break;
536 case RPC_LOC_IOCTL_SET_ENGINE_LOCK:
537 break;
538 case RPC_LOC_IOCTL_GET_ENGINE_LOCK:
539 break;
540 case RPC_LOC_IOCTL_SET_SBAS_CONFIG:
541 break;
542 case RPC_LOC_IOCTL_GET_SBAS_CONFIG:
543 break;
544 case RPC_LOC_IOCTL_SET_NMEA_TYPES:
545 break;
546 case RPC_LOC_IOCTL_GET_NMEA_TYPES:
547 break;
548 case RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR:
549 case RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR:
550 case RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR:
551 case RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR:
552 args.ioctl_data->rpc_loc_ioctl_data_u_type_u.server_addr.addr_info.disc =
553 args.ioctl_data->rpc_loc_ioctl_data_u_type_u.server_addr.addr_type;
554 break;
555 case RPC_LOC_IOCTL_GET_CDMA_PDE_SERVER_ADDR:
556 case RPC_LOC_IOCTL_GET_CDMA_MPC_SERVER_ADDR:
557 case RPC_LOC_IOCTL_GET_UMTS_SLP_SERVER_ADDR:
558 case RPC_LOC_IOCTL_GET_CUSTOM_PDE_SERVER_ADDR:
559 break;
560 case RPC_LOC_IOCTL_SET_ON_DEMAND_LPM:
561 break;
562 case RPC_LOC_IOCTL_GET_ON_DEMAND_LPM:
563 break;
564 case RPC_LOC_IOCTL_DELETE_ASSIST_DATA:
565 break;
566 default:
567 break;
568 } /* switch */
569 } /* ioctl_data != NULL */
570
571 rpc_loc_ioctl_rets rets;
572 enum clnt_stat stat = RPC_SUCCESS;
573
574 EXIT_LOG_CALLFLOW(%s, loc_get_ioctl_type_name(ioctl_type));
575 stat = RPC_FUNC_VERSION(rpc_loc_ioctl_, RPC_LOC_IOCTL_VERSION)(&args, &rets, loc_api_clnt);
576 LOC_GLUE_CHECK_RESULT(stat, int32);
577
578 ret_val = (int32) rets.loc_ioctl_result;
579
580 return ret_val;
581 }
582
583 /* Returns 0 if error */
loc_api_null(void)584 int32 loc_api_null(void)
585 {
586 LOC_GLUE_CHECK_INIT(int32);
587
588 int32 rets;
589 enum clnt_stat stat = RPC_SUCCESS;
590
591 clnt_unregister_reset_notification_cb(loc_api_clnt);
592 stat = RPC_FUNC_VERSION(rpc_loc_api_null_, RPC_LOC_API_NULL_VERSION)(NULL, &rets, loc_api_clnt);
593 LOC_GLUE_CHECK_RESULT(stat, int32);
594
595 return (int32) rets;
596 }
597
598 /*===========================================================================
599
600 FUNCTION loc_eng_ioctl
601
602 DESCRIPTION
603 This function calls loc_ioctl and waits for the callback result before
604 returning back to the user.
605
606 DEPENDENCIES
607 N/A
608
609 RETURN VALUE
610 TRUE if successful
611 FALSE if failed
612
613 SIDE EFFECTS
614 N/A
615
616 ===========================================================================*/
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)617 int loc_eng_ioctl
618 (
619 rpc_loc_client_handle_type handle,
620 rpc_loc_ioctl_e_type ioctl_type,
621 rpc_loc_ioctl_data_u_type* ioctl_data_ptr,
622 uint32 timeout_msec,
623 rpc_loc_ioctl_callback_s_type *cb_data_ptr
624 )
625 {
626 int ret_val = RPC_LOC_API_SUCCESS;
627
628 ret_val = loc_api_sync_ioctl(handle, ioctl_type, ioctl_data_ptr, timeout_msec, cb_data_ptr);
629
630 LOC_LOGD("loc_eng_ioctl result: client = %d, ioctl_type = %s, returt %s\n",
631 (int32) handle,
632 loc_get_ioctl_type_name(ioctl_type),
633 loc_get_ioctl_status_name(ret_val) );
634
635 return ret_val;
636 }
637