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