コード例 #1
0
/*===========================================================================

FUNCTION    loc_api_sync_ioctl

DESCRIPTION
   Synchronous IOCTL call (reentrant version)

DEPENDENCIES
   N/A

RETURN VALUE
   Loc API error code (0 = success)

SIDE EFFECTS
   N/A

===========================================================================*/
int loc_api_sync_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                              rc = RPC_LOC_API_ENGINE_BUSY;
   int                              select_id;
   rpc_loc_ioctl_callback_s_type    callback_data;

   // Select the callback we are waiting for
   select_id = loc_api_select_callback(handle, 0, ioctl_type);

   if (select_id >= 0)
   {
      pthread_mutex_lock(&loc_sync_data.lock);
      rc = loc_ioctl(handle, ioctl_type, ioctl_data_ptr);
      while (rc == RPC_LOC_API_ENGINE_BUSY)
      {
         /* TODO: Use timeout? */
         ALOGD("loc_api_sync_ioctl: select_id = %d, engine busy, waiting...\n", select_id);
         pthread_cond_wait(&loc_sync_data.loc_cb_arrived_cond, &loc_sync_data.lock);
         rc = loc_ioctl(handle, ioctl_type, ioctl_data_ptr);
      }
      pthread_mutex_unlock(&loc_sync_data.lock);
      ALOGV("loc_api_sync_ioctl: select_id = %d, loc_ioctl returned %d\n", select_id, rc);

      if (rc != RPC_LOC_API_SUCCESS)
      {
         ALOGE("loc_api_sync_ioctl: select_id = %d, loc_ioctl returned %d\n", select_id, rc);
         loc_free_slot(select_id);
      }
      else {
         // Wait for the callback of loc_ioctl
         if ((rc = loc_api_wait_callback(select_id, timeout_msec / 1000, NULL, &callback_data)) != 0)
         {
            // Callback waiting failed
            ALOGE("loc_api_sync_ioctl: loc_api_wait_callback failed, returned %d (select id %d)\n", rc, select_id);
         }
         else
         {
            if (cb_data_ptr) memcpy(cb_data_ptr, &callback_data, sizeof *cb_data_ptr);
            if (callback_data.status != RPC_LOC_API_SUCCESS)
            {
               rc = callback_data.status;
               ALOGE("loc_api_sync_ioctl: IOCTL result failed, result: %d (select id %d)\n", rc, select_id);
            }
         } /* wait callback */
      } /* loc_ioctl */
   } /* select id */

   return rc;
}
コード例 #2
0
/*===========================================================================

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

===========================================================================*/
boolean 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
    )
{
    boolean                    ret_val;
    int                        rpc_ret_val;
    loc_eng_ioctl_data_s_type *ioctl_cb_data_ptr;

    LOGV ("loc_eng_ioctl: client = %d, ioctl_type = %d, cb_data =0x%x\n", (int32) handle, ioctl_type, (uint32) cb_data_ptr);

    ioctl_cb_data_ptr = &(loc_eng_data.ioctl_data);
    // Select the callback we are waiting for
    ret_val = loc_eng_ioctl_setup_cb (handle, ioctl_type);

    if (ret_val == TRUE) 
    {
        rpc_ret_val =  loc_ioctl (handle,
                                    ioctl_type,
                                    ioctl_data_ptr);

        LOGV ("loc_eng_ioctl: loc_ioctl returned %d \n", rpc_ret_val);

        if (rpc_ret_val == RPC_LOC_API_SUCCESS)
        {
            // Wait for the callback of loc_ioctl
            ret_val = loc_eng_ioctl_wait_cb (timeout_msec, cb_data_ptr);
        }
        else
        {
            ret_val = FALSE;
        }
    }

    // Reset the state when we are done
    pthread_mutex_lock(&ioctl_cb_data_ptr->cb_data_mutex);
    ioctl_cb_data_ptr->cb_is_selected = FALSE;
    ioctl_cb_data_ptr->cb_is_waiting  = FALSE;
    ioctl_cb_data_ptr->cb_has_arrived = FALSE;
    pthread_mutex_unlock(&ioctl_cb_data_ptr->cb_data_mutex);

    return ret_val;
}
コード例 #3
0
/*===========================================================================
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;
}
コード例 #4
0
/*===========================================================================
FUNCTION    qct_loc_eng_inject_xtra_data

DESCRIPTION
   Injects XTRA file into the engine. 

DEPENDENCIES
   N/A

RETURN VALUE
   0: success
   >0: failure

SIDE EFFECTS
   N/A

===========================================================================*/
static int qct_loc_eng_inject_xtra_data(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_predicted_orbits_data_s_type *predicted_orbits_data_ptr;

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

    ioctl_data.disc = RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_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 / XTRA_BLOCK_SIZE);
    if ((total_parts % XTRA_BLOCK_SIZE) != 0)
    {
        total_parts += 1;
    }
    predicted_orbits_data_ptr->total_parts = total_parts;

    len_injected = 0; // O bytes injected
    // 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;

        LOGV ("qct_loc_eng_inject_xtra_data, inject part = %d, len = %d, len = %d\n", predicted_orbits_data_ptr->part, predicted_orbits_data_ptr->part_len, predicted_orbits_data_ptr->data_ptr.data_ptr_len);
        LOGV ("qct_loc_eng_inject_xtra_data, total part = %d, len = %d \n", predicted_orbits_data_ptr->part, predicted_orbits_data_ptr->part_len);

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

            if (rpc_ret_val != RPC_LOC_API_SUCCESS)
            {
                LOGE ("loc_ioctl for xtra returned %d \n", rpc_ret_val);
                ret_val = EINVAL; // return error
                break;
            }
        }
        else // part == total_parts
        {
            // Last part injection, will need to wait for callback
            ret_val = loc_eng_ioctl (loc_eng_data.client_handle,
                                  RPC_LOC_IOCTL_INJECT_PREDICTED_ORBITS_DATA,
                                  &ioctl_data,
                                  LOC_XTRA_INJECT_DEFAULT_TIMEOUT,
                                  NULL /* No output information is expected*/);
            break; // done with injection
        }

        len_injected += predicted_orbits_data_ptr->part_len;
        LOGV ("loc_ioctl for xtra len injected %d \n", len_injected);
    }

    return ret_val;
}