int32 loc_close
(
      rpc_loc_client_handle_type handle
)
{
    ENTRY_LOG();
    LOC_GLUE_CHECK_INIT(int32);

    int32 ret_val;

    rpc_loc_close_args args;
    args.handle = handle;

    rpc_loc_close_rets rets;
    enum clnt_stat stat = RPC_SUCCESS;

    EXIT_LOG_CALLFLOW(%s, "loc client close");
    stat = RPC_FUNC_VERSION(rpc_loc_close_, RPC_LOC_CLOSE_VERSION)(&args, &rets, loc_api_clnt);

    loc_clear(handle);

    LOC_GLUE_CHECK_RESULT(stat, int32);
    ret_val = (int32) rets.loc_close_result;

    return ret_val;
}
/* Returns 0 if error */
int32 loc_api_null(void)
{
    LOC_GLUE_CHECK_INIT(int32);

    int32 rets;
    enum clnt_stat stat = RPC_SUCCESS;

    stat = RPC_FUNC_VERSION(rpc_loc_api_null_, LOC_APIVERS)(NULL, &rets, loc_api_clnt);
    LOC_GLUE_CHECK_RESULT(stat, int32);

    return (int32) rets;
}
rpc_loc_client_handle_type loc_open (
      rpc_loc_event_mask_type       event_reg_mask,
      loc_event_cb_f_type      *event_callback
)
{
   LOC_GLUE_CHECK_INIT(rpc_loc_client_handle_type);

   rpc_loc_open_args args;
   args.event_reg_mask = event_reg_mask;

   int i;
   for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++)
   {
          if (loc_glue_callback_table[i].cb_func == event_callback)
          {
              LOGW("Client already opened service (callback=0x%X)...\n",
                (unsigned int) event_callback);
              break;
          }
   }

   if (i == LOC_API_CB_MAX_CLIENTS)
   {
       for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++)
       {
           if (loc_glue_callback_table[i].cb_func == NULL)
           {
               loc_glue_callback_table[i].cb_func = event_callback;
               break;
           }
       }
   }

   if (i == LOC_API_CB_MAX_CLIENTS)
   {
      LOGE("Too many clients opened at once...\n");
      return RPC_LOC_CLIENT_HANDLE_INVALID;
   }

   args.event_callback = loc_glue_callback_table[i].cb_id;
   LOGV("cb_id=%d, func=0x%x", i, (unsigned int) event_callback);

   rpc_loc_open_rets rets;
   enum clnt_stat stat = RPC_SUCCESS;

   stat = RPC_FUNC_VERSION(rpc_loc_open_, RPC_LOC_OPEN_VERSION)(&args, &rets, loc_api_clnt);
   LOC_GLUE_CHECK_RESULT(stat, int32);

   /* save the handle in the table */
   loc_glue_callback_table[i].handle = (rpc_loc_client_handle_type) rets.loc_open_result;

   return (rpc_loc_client_handle_type) rets.loc_open_result;
}
/* Returns 0 if error */
int32 loc_api_null(void)
{
    LOC_GLUE_CHECK_INIT(int32);

    int32 rets;
    enum clnt_stat stat = RPC_SUCCESS;

    clnt_unregister_reset_notification_cb(loc_api_clnt);
    stat = RPC_FUNC_VERSION(rpc_loc_api_null_, RPC_LOC_API_NULL_VERSION)(NULL, &rets, loc_api_clnt);
    LOC_GLUE_CHECK_RESULT(stat, int32);

    return (int32) rets;
}
int32 loc_stop_fix(rpc_loc_client_handle_type handle)
{
    LOC_GLUE_CHECK_INIT(int32);

    rpc_loc_stop_fix_args args;
    args.handle = handle;

    rpc_loc_stop_fix_rets rets;
    enum clnt_stat stat = RPC_SUCCESS;

    stat = RPC_FUNC_VERSION(rpc_loc_stop_fix_, LOC_APIVERS)(&args, &rets, loc_api_clnt);
    LOC_GLUE_CHECK_RESULT(stat, int32);

    return (int32) rets.loc_stop_fix_result;
}
rpc_loc_client_handle_type loc_open (
        rpc_loc_event_mask_type  event_reg_mask,
        loc_event_cb_f_type      *event_callback
    )
{
    LOC_GLUE_CHECK_INIT(rpc_loc_client_handle_type);

    rpc_loc_open_args args;
    args.event_reg_mask = event_reg_mask;
    args.event_callback = LOC_API_CB_ID;
    loc_api_saved_cb = event_callback;

    rpc_loc_open_rets rets;
    enum clnt_stat stat = RPC_SUCCESS;

    stat = RPC_FUNC_VERSION(rpc_loc_open_, LOC_APIVERS)(&args, &rets, loc_api_clnt);
    LOC_GLUE_CHECK_RESULT(stat, int32);

    return (rpc_loc_client_handle_type) rets.loc_open_result;
}
int32 loc_close(rpc_loc_client_handle_type handle)
{
    LOC_GLUE_CHECK_INIT(int32);

    rpc_loc_close_args args;
    args.handle = handle;

    rpc_loc_close_rets rets;
    enum clnt_stat stat = RPC_SUCCESS;

    stat = RPC_FUNC_VERSION(rpc_loc_close_, LOC_APIVERS)(&args, &rets, loc_api_clnt);
    LOC_GLUE_CHECK_RESULT(stat, int32);

    if (loc_api_clnt != NULL)
        clnt_destroy(loc_api_clnt);

    loc_api_clnt = NULL;

    return (int32) rets.loc_close_result;
}
int32 loc_stop_fix
(
      rpc_loc_client_handle_type handle
)
{
    ENTRY_LOG();
    LOC_GLUE_CHECK_INIT(int32);

    int32 ret_val;

    rpc_loc_stop_fix_args args;
    args.handle = handle;

    rpc_loc_stop_fix_rets rets;
    enum clnt_stat stat = RPC_SUCCESS;

    EXIT_LOG_CALLFLOW(%s, "loc stop fix");
    stat = RPC_FUNC_VERSION(rpc_loc_stop_fix_, RPC_LOC_STOP_FIX_VERSION)(&args, &rets, loc_api_clnt);
    LOC_GLUE_CHECK_RESULT(stat, int32);

    ret_val = (int32) rets.loc_stop_fix_result;

    return ret_val;
}
int32 loc_close
(
      rpc_loc_client_handle_type handle
)
{
   LOC_GLUE_CHECK_INIT(int32);

   rpc_loc_close_args args;
   args.handle = handle;

   rpc_loc_close_rets rets;
   enum clnt_stat stat = RPC_SUCCESS;

   stat = RPC_FUNC_VERSION(rpc_loc_close_, RPC_LOC_CLOSE_VERSION)(&args, &rets, loc_api_clnt);

   /* Clean the client's callback function in callback table */
   int i;
   for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++)
   {
          if (loc_glue_callback_table[i].handle == handle)
          {
              /* Found the client */
              loc_glue_callback_table[i].cb_func = NULL;
              loc_glue_callback_table[i].handle = -1;
              break;
          }
   }

   if (i == LOC_API_CB_MAX_CLIENTS)
   {
       LOGW("Handle not found (handle=%d)...\n", (int) handle);
   }

   LOC_GLUE_CHECK_RESULT(stat, int32);
   return (int32) rets.loc_close_result;
}
int32 loc_ioctl
(
      rpc_loc_client_handle_type           handle,
      rpc_loc_ioctl_e_type                 ioctl_type,
      rpc_loc_ioctl_data_u_type*           ioctl_data
)
{
    ENTRY_LOG();
    LOC_GLUE_CHECK_INIT(int32);

    int32 ret_val;

    rpc_loc_ioctl_args args;
    args.handle = handle;
    args.ioctl_data = ioctl_data;
    args.ioctl_type = ioctl_type;
    if (ioctl_data != NULL)
    {
        /* Assign ioctl union discriminator */
        ioctl_data->disc = ioctl_type;

        /* In case the user hasn't filled in other disc fields,
           automatically fill them in here */
        switch (ioctl_type)
        {
        case RPC_LOC_IOCTL_GET_API_VERSION:
            break;
        case RPC_LOC_IOCTL_SET_FIX_CRITERIA:
            break;
        case RPC_LOC_IOCTL_GET_FIX_CRITERIA:
            break;
        case RPC_LOC_IOCTL_INFORM_NI_USER_RESPONSE:
            break;
        case RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA:
            break;
        case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_VALIDITY:
            break;
        case RPC_LOC_IOCTL_QUERY_PREDICTED_ORBITS_DATA_SOURCE:
            break;
        case RPC_LOC_IOCTL_SET_PREDICTED_ORBITS_DATA_AUTO_DOWNLOAD:
            break;
        case RPC_LOC_IOCTL_INJECT_UTC_TIME:
            break;
        case RPC_LOC_IOCTL_INJECT_RTC_VALUE:
            break;
        case RPC_LOC_IOCTL_INJECT_POSITION:
            break;
        case RPC_LOC_IOCTL_QUERY_ENGINE_STATE:
            break;
        case RPC_LOC_IOCTL_INFORM_SERVER_OPEN_STATUS:
            break;
        case RPC_LOC_IOCTL_INFORM_SERVER_CLOSE_STATUS:
            break;
        case RPC_LOC_IOCTL_SET_ENGINE_LOCK:
            break;
        case RPC_LOC_IOCTL_GET_ENGINE_LOCK:
            break;
        case RPC_LOC_IOCTL_SET_SBAS_CONFIG:
            break;
        case RPC_LOC_IOCTL_GET_SBAS_CONFIG:
            break;
        case RPC_LOC_IOCTL_SET_NMEA_TYPES:
            break;
        case RPC_LOC_IOCTL_GET_NMEA_TYPES:
            break;
        case RPC_LOC_IOCTL_SET_CDMA_PDE_SERVER_ADDR:
        case RPC_LOC_IOCTL_SET_CDMA_MPC_SERVER_ADDR:
        case RPC_LOC_IOCTL_SET_UMTS_SLP_SERVER_ADDR:
        case RPC_LOC_IOCTL_SET_CUSTOM_PDE_SERVER_ADDR:
            args.ioctl_data->rpc_loc_ioctl_data_u_type_u.server_addr.addr_info.disc =
                args.ioctl_data->rpc_loc_ioctl_data_u_type_u.server_addr.addr_type;
            break;
        case RPC_LOC_IOCTL_GET_CDMA_PDE_SERVER_ADDR:
        case RPC_LOC_IOCTL_GET_CDMA_MPC_SERVER_ADDR:
        case RPC_LOC_IOCTL_GET_UMTS_SLP_SERVER_ADDR:
        case RPC_LOC_IOCTL_GET_CUSTOM_PDE_SERVER_ADDR:
            break;
        case RPC_LOC_IOCTL_SET_ON_DEMAND_LPM:
            break;
        case RPC_LOC_IOCTL_GET_ON_DEMAND_LPM:
            break;
        case RPC_LOC_IOCTL_DELETE_ASSIST_DATA:
            break;
        default:
            break;
        } /* switch */
    } /* ioctl_data != NULL */

    rpc_loc_ioctl_rets rets;
    enum clnt_stat stat = RPC_SUCCESS;

    EXIT_LOG_CALLFLOW(%s, loc_get_ioctl_type_name(ioctl_type));
    stat = RPC_FUNC_VERSION(rpc_loc_ioctl_, RPC_LOC_IOCTL_VERSION)(&args, &rets, loc_api_clnt);
    LOC_GLUE_CHECK_RESULT(stat, int32);

    ret_val = (int32) rets.loc_ioctl_result;

    return ret_val;
}
rpc_loc_client_handle_type 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
)
{
    int try_num = RPC_TRY_NUM;
    ENTRY_LOG();
    LOC_GLUE_CHECK_INIT(rpc_loc_client_handle_type);

    rpc_loc_client_handle_type ret_val;

    rpc_loc_open_args args;
    args.event_reg_mask = event_reg_mask;

    int i, j = LOC_API_CB_MAX_CLIENTS;
    for (i = 0; i < LOC_API_CB_MAX_CLIENTS; i++)
    {
        if (loc_glue_callback_table[i].user == userData)
        {
            LOC_LOGW("Client already opened service (callback=%p)...\n",
                  event_callback);
            break;
        } else if (j == LOC_API_CB_MAX_CLIENTS &&
                   loc_glue_callback_table[i].user == NULL) {
            j = i;
        }
    }

    if (i == LOC_API_CB_MAX_CLIENTS)
    {
        i = j;
    }

    if (i == LOC_API_CB_MAX_CLIENTS)
    {
        LOC_LOGE("Too many clients opened at once...\n");
        return RPC_LOC_CLIENT_HANDLE_INVALID;
    }

    loc_glue_callback_table[i].cb_func = event_callback;
    loc_glue_callback_table[i].rpc_cb = rpc_cb;
    loc_glue_callback_table[i].user = userData;

    args.event_callback = loc_glue_callback_table[i].cb_id;
    LOC_LOGV("cb_id=%d, func=0x%x", i, (unsigned int) event_callback);

    rpc_loc_open_rets rets;
    enum clnt_stat stat = RPC_SUCCESS;

    EXIT_LOG_CALLFLOW(%s, "loc client open");

     /*try more for rpc_loc_open_xx()*/

    do
    {
        stat = RPC_FUNC_VERSION(rpc_loc_open_, RPC_LOC_OPEN_VERSION)(&args, &rets, loc_api_clnt);
        ret_val = (rpc_loc_client_handle_type) rets.loc_open_result;
        try_num--;

    }while( (RPC_SUCCESS != stat||0 > ret_val) && 0 != try_num );

    LOC_GLUE_CHECK_RESULT(stat, int32);

    /* save the handle in the table */
    loc_glue_callback_table[i].handle = (rpc_loc_client_handle_type) rets.loc_open_result;

    return ret_val;

}