/*===========================================================================

FUNCTION    loc_eng_ioctl

DESCRIPTION
   This function calls loc_ioctl and waits for the callback result before
   returning back to the user.

DEPENDENCIES
   N/A

RETURN VALUE
   TRUE                 if successful
   FALSE                if failed

SIDE EFFECTS
   N/A

===========================================================================*/
int 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
)
{
    int ret_val = RPC_LOC_API_SUCCESS;

    ret_val = loc_api_sync_ioctl(handle, ioctl_type, ioctl_data_ptr, timeout_msec, cb_data_ptr);

    LOC_LOGD("loc_eng_ioctl result: client = %d, ioctl_type = %s, returt %s\n",
             (int32) handle,
             loc_get_ioctl_type_name(ioctl_type),
             loc_get_ioctl_status_name(ret_val) );

    return ret_val;
}
/*===========================================================================
FUNCTION    qct_loc_eng_inject_xtra_data

DESCRIPTION
   Injects XTRA file into the engine.

DEPENDENCIES
   N/A

RETURN VALUE
   0: success
   error code > 0

SIDE EFFECTS
   N/A

===========================================================================*/
static int qct_loc_eng_inject_xtra_data_one(char* data, int length)
{
   int     rpc_ret_val = RPC_LOC_API_GENERAL_FAILURE;
   boolean ret_val = 0;
   int     total_parts;
   uint8   part;
   uint16  part_len;
   uint16  len_injected;
   rpc_loc_ioctl_data_u_type            ioctl_data;
   rpc_loc_ioctl_e_type                 ioctl_type = RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA;
   rpc_loc_predicted_orbits_data_s_type *predicted_orbits_data_ptr;

   LOC_LOGD("qct_loc_eng_inject_xtra_data, xtra size = %d, data ptr = 0x%x\n", length, (int) data);

   predicted_orbits_data_ptr = &ioctl_data.rpc_loc_ioctl_data_u_type_u.predicted_orbits_data;
   predicted_orbits_data_ptr->format_type = RPC_LOC_PREDICTED_ORBITS_XTRA;
   predicted_orbits_data_ptr->total_size = length;
   total_parts = (length - 1) / XTRA_BLOCK_SIZE + 1;
   predicted_orbits_data_ptr->total_parts = total_parts;

   len_injected = 0; // O bytes injected
   ioctl_data.disc = ioctl_type;

   // XTRA injection starts with part 1
   for (part = 1; part <= total_parts; part++)
   {
      predicted_orbits_data_ptr->part = part;
      predicted_orbits_data_ptr->part_len = XTRA_BLOCK_SIZE;
      if (XTRA_BLOCK_SIZE > (length - len_injected))
      {
         predicted_orbits_data_ptr->part_len = length - len_injected;
      }
      predicted_orbits_data_ptr->data_ptr.data_ptr_len = predicted_orbits_data_ptr->part_len;
      predicted_orbits_data_ptr->data_ptr.data_ptr_val = data + len_injected;

      LOC_LOGD("qct_loc_eng_inject_xtra_data, part %d/%d, len = %d, total = %d\n",
            predicted_orbits_data_ptr->part,
            total_parts,
            predicted_orbits_data_ptr->part_len,
            len_injected);

      if (part < total_parts)
      {
         // No callback in this case
         rpc_ret_val = loc_ioctl (loc_eng_data.client_handle,
                                  ioctl_type,
                                  &ioctl_data);

         if (rpc_ret_val != RPC_LOC_API_SUCCESS)
         {
            ret_val = EIO; // return error
            LOC_LOGE("loc_ioctl for xtra error: %s\n", loc_get_ioctl_status_name(rpc_ret_val));
            break;
         }
      }
      else // part == total_parts
      {
         // Last part injection, will need to wait for callback
         if (!loc_eng_ioctl(loc_eng_data.client_handle,
                                  ioctl_type,
                                  &ioctl_data,
                                  LOC_XTRA_INJECT_DEFAULT_TIMEOUT,
                                  NULL))
         {
            ret_val = EIO;
            LOC_LOGE("loc_eng_ioctl for xtra error\n");
         }
         break; // done with injection
      }

      len_injected += predicted_orbits_data_ptr->part_len;
      LOC_LOGD("loc_ioctl XTRA injected length: %d\n", len_injected);
   }

   return ret_val;
}