Merge "Add support for SUPL Emergency Services"
This commit is contained in:
commit
e100c681e1
16 changed files with 1576 additions and 88 deletions
|
@ -27,6 +27,7 @@ endif
|
|||
|
||||
ifeq ($(call is-board-platform-in-list,$(QMI_BOARD_PLATFORM_LIST)),true)
|
||||
GPS_DIR_LIST += $(LOCAL_PATH)/loc_api_v02/
|
||||
GPS_DIR_LIST += $(LOCAL_PATH)/ds_api/
|
||||
endif #is-board-platform-in-list
|
||||
|
||||
GPS_DIR_LIST += $(LOCAL_PATH)/libloc_api_50001/
|
||||
|
|
49
loc_api/ds_api/Android.mk
Normal file
49
loc_api/ds_api/Android.mk
Normal file
|
@ -0,0 +1,49 @@
|
|||
ifneq ($(BUILD_TINY_ANDROID),true)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libds_api
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libutils \
|
||||
libcutils \
|
||||
libqmi_cci \
|
||||
libqmi_csi \
|
||||
libqmi_common_so \
|
||||
libgps.utils \
|
||||
libdsi_netctrl \
|
||||
libqmiservices
|
||||
|
||||
|
||||
LOCAL_SRC_FILES += \
|
||||
ds_client.c
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
-fno-short-enums \
|
||||
-D_ANDROID_
|
||||
|
||||
LOCAL_COPY_HEADERS_TO:= ds_api/
|
||||
|
||||
LOCAL_COPY_HEADERS:= \
|
||||
ds_client.h
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,--export-dynamic
|
||||
|
||||
## Includes
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(TARGET_OUT_HEADERS)/libloc_eng \
|
||||
$(TARGET_OUT_HEADERS)/qmi-framework/inc \
|
||||
$(TARGET_OUT_HEADERS)/qmi/inc \
|
||||
$(TARGET_OUT_HEADERS)/gps.utils \
|
||||
$(TARGET_OUT_HEADERS)/data/inc
|
||||
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
endif # not BUILD_TINY_ANDROID
|
704
loc_api/ds_api/ds_client.c
Normal file
704
loc_api/ds_api/ds_client.c
Normal file
|
@ -0,0 +1,704 @@
|
|||
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "LocSvc_ds_client"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <wireless_data_service_v01.h>
|
||||
#include <utils/Log.h>
|
||||
#include <log_util.h>
|
||||
#include <loc_log.h>
|
||||
#include <qmi_client.h>
|
||||
#include <qmi_idl_lib.h>
|
||||
#include <qmi_cci_target_ext.h>
|
||||
#include <qmi_cci_target.h>
|
||||
#include <qmi_cci_common.h>
|
||||
#include <dsi_netctrl.h>
|
||||
#include <ds_client.h>
|
||||
|
||||
#include<sys/time.h>
|
||||
|
||||
//Timeout to wait for wds service notification from qmi
|
||||
#define DS_CLIENT_SERVICE_TIMEOUT (4000)
|
||||
//Max timeout for the service to come up
|
||||
#define DS_CLIENT_SERVICE_TIMEOUT_TOTAL (40000)
|
||||
//Timeout for the service to respond to sync msg
|
||||
#define DS_CLIENT_SYNC_MSG_TIMEOUT (5000)
|
||||
/*Request messages the WDS client can send to the WDS service*/
|
||||
typedef union
|
||||
{
|
||||
/*Requests the service for a list of all profiles present*/
|
||||
wds_get_profile_list_req_msg_v01 *p_get_profile_list_req;
|
||||
/*Requests the service for a profile's settings*/
|
||||
wds_get_profile_settings_req_msg_v01 *p_get_profile_settings_req;
|
||||
}ds_client_req_union_type;
|
||||
|
||||
/*Response indications that are sent by the WDS service*/
|
||||
typedef union
|
||||
{
|
||||
wds_get_profile_list_resp_msg_v01 *p_get_profile_list_resp;
|
||||
wds_get_profile_settings_resp_msg_v01 *p_get_profile_setting_resp;
|
||||
}ds_client_resp_union_type;
|
||||
|
||||
struct event_strings_s
|
||||
{
|
||||
char * str;
|
||||
dsi_net_evt_t evt;
|
||||
};
|
||||
|
||||
struct event_strings_s event_string_tbl[DSI_EVT_MAX] =
|
||||
{
|
||||
NAME_VAL(DSI_EVT_INVALID),
|
||||
NAME_VAL(DSI_EVT_NET_IS_CONN),
|
||||
NAME_VAL(DSI_EVT_NET_NO_NET),
|
||||
NAME_VAL(DSI_EVT_PHYSLINK_DOWN_STATE),
|
||||
NAME_VAL(DSI_EVT_PHYSLINK_UP_STATE),
|
||||
NAME_VAL(DSI_EVT_NET_RECONFIGURED),
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ds_client_event_ind_cb_type event_cb;
|
||||
void *caller_cookie;
|
||||
}ds_caller_data;
|
||||
|
||||
typedef struct {
|
||||
//Global dsi handle
|
||||
dsi_hndl_t dsi_net_handle;
|
||||
//Handle to caller's data
|
||||
ds_caller_data caller_data;
|
||||
} ds_client_session_data;
|
||||
|
||||
void net_ev_cb(dsi_hndl_t handle, void* user_data,
|
||||
dsi_net_evt_t evt, dsi_evt_payload_t *payload_ptr)
|
||||
{
|
||||
int i;
|
||||
(void)handle;
|
||||
(void)user_data;
|
||||
(void)payload_ptr;
|
||||
ds_caller_data *callback_data = (ds_caller_data *)user_data;
|
||||
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
|
||||
if(evt > DSI_EVT_INVALID && evt < DSI_EVT_MAX)
|
||||
{
|
||||
for(i=0;i<DSI_EVT_MAX;i++)
|
||||
{
|
||||
if(event_string_tbl[i].evt == evt)
|
||||
LOC_LOGE("%s:%d]: Callback received: %s",
|
||||
__func__, __LINE__, event_string_tbl[i].str);
|
||||
}
|
||||
switch(evt) {
|
||||
case DSI_EVT_NET_IS_CONN:
|
||||
{
|
||||
LOC_LOGD("%s:%d]: Emergency call started\n", __func__, __LINE__);
|
||||
callback_data->event_cb(E_DS_CLIENT_DATA_CALL_CONNECTED,
|
||||
callback_data->caller_cookie);
|
||||
break;
|
||||
}
|
||||
case DSI_EVT_NET_NO_NET:
|
||||
{
|
||||
LOC_LOGD("%s:%d]: Emergency call stopped\n", __func__, __LINE__);
|
||||
callback_data->event_cb(E_DS_CLIENT_DATA_CALL_DISCONNECTED,
|
||||
callback_data->caller_cookie);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOC_LOGD("%s:%d]: uninteresting event\n", __func__, __LINE__);
|
||||
}
|
||||
}
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
/*This function is called to obtain a handle to the QMI WDS service*/
|
||||
static ds_client_status_enum_type
|
||||
ds_client_qmi_ctrl_point_init(qmi_client_type *p_wds_qmi_client)
|
||||
{
|
||||
qmi_client_type wds_qmi_client, notifier = NULL;
|
||||
ds_client_status_enum_type status = E_DS_CLIENT_SUCCESS;
|
||||
qmi_service_info *p_service_info = NULL;
|
||||
uint32_t num_services = 0, num_entries = 0;
|
||||
qmi_client_error_type ret = QMI_NO_ERR;
|
||||
unsigned char no_signal = 0;
|
||||
qmi_client_os_params os_params;
|
||||
int timeout = 0;
|
||||
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
|
||||
//Get service object for QMI_WDS service
|
||||
qmi_idl_service_object_type ds_client_service_object =
|
||||
wds_get_service_object_v01();
|
||||
if(ds_client_service_object == NULL) {
|
||||
LOC_LOGE("%s:%d]: wds_get_service_object_v01 failed\n" ,
|
||||
__func__, __LINE__);
|
||||
status = E_DS_CLIENT_FAILURE_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
//get service addressing information
|
||||
ret = qmi_client_get_service_list(ds_client_service_object, NULL, NULL,
|
||||
&num_services);
|
||||
LOC_LOGD("%s:%d]: qmi_client_get_service_list() first try ret %d, "
|
||||
"num_services %d]\n", __func__, __LINE__, ret, num_services);
|
||||
if(ret != QMI_NO_ERR) {
|
||||
//Register for service notification
|
||||
ret = qmi_client_notifier_init(ds_client_service_object, &os_params, ¬ifier);
|
||||
if (ret != QMI_NO_ERR) {
|
||||
LOC_LOGE("%s:%d]: qmi_client_notifier_init failed %d\n",
|
||||
__func__, __LINE__, ret);
|
||||
status = E_DS_CLIENT_FAILURE_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
do {
|
||||
QMI_CCI_OS_SIGNAL_CLEAR(&os_params);
|
||||
ret = qmi_client_get_service_list(ds_client_service_object, NULL,
|
||||
NULL, &num_services);
|
||||
if(ret != QMI_NO_ERR) {
|
||||
QMI_CCI_OS_SIGNAL_WAIT(&os_params, DS_CLIENT_SERVICE_TIMEOUT);
|
||||
no_signal = QMI_CCI_OS_SIGNAL_TIMED_OUT(&os_params);
|
||||
if(!no_signal)
|
||||
ret = qmi_client_get_service_list(ds_client_service_object, NULL,
|
||||
NULL, &num_services);
|
||||
}
|
||||
timeout += DS_CLIENT_SERVICE_TIMEOUT;
|
||||
LOC_LOGV("%s:%d]: qmi_client_get_service_list() returned ret: %d,"
|
||||
"no_signal: %d, total timeout: %d\n", __func__, __LINE__,
|
||||
ret, no_signal, timeout);
|
||||
} while( (timeout < DS_CLIENT_SERVICE_TIMEOUT_TOTAL) &&
|
||||
no_signal &&
|
||||
(ret != QMI_NO_ERR) );
|
||||
}
|
||||
|
||||
//Handle failure cases
|
||||
if(num_services == 0 || ret != QMI_NO_ERR) {
|
||||
if(!no_signal) {
|
||||
LOC_LOGE("%s:%d]: qmi_client_get_service_list failed even though"
|
||||
"service is up! Error: %d \n", __func__, __LINE__, ret);
|
||||
status = E_DS_CLIENT_FAILURE_INTERNAL;
|
||||
}
|
||||
else {
|
||||
LOC_LOGE("%s:%d]: qmi_client_get_service_list failed after retries"
|
||||
"Error: %d \n", __func__, __LINE__, ret);
|
||||
status = E_DS_CLIENT_FAILURE_TIMEOUT;
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
|
||||
LOC_LOGD("%s:%d]: qmi_client_get_service_list succeeded\n", __func__, __LINE__);
|
||||
|
||||
//Success
|
||||
p_service_info = (qmi_service_info *)malloc(num_services * sizeof(qmi_service_info));
|
||||
if(p_service_info == NULL) {
|
||||
LOC_LOGE("%s:%d]: could not allocate memory for serviceInfo !!\n",
|
||||
__func__, __LINE__);
|
||||
status = E_DS_CLIENT_FAILURE_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
num_entries = num_services;
|
||||
|
||||
//Populate service info
|
||||
ret = qmi_client_get_service_list(ds_client_service_object, p_service_info,
|
||||
&num_entries, &num_services);
|
||||
if(ret != QMI_NO_ERR) {
|
||||
LOC_LOGE("%s:%d]: qmi_client_get_service_list failed. ret: %d \n",
|
||||
__func__, __LINE__, ret);
|
||||
status = E_DS_CLIENT_FAILURE_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
//Initialize wds_qmi_client
|
||||
LOC_LOGD("%s:%d]: Initializing WDS client with qmi_client_init\n", __func__,
|
||||
__LINE__);
|
||||
ret = qmi_client_init(&p_service_info[0], ds_client_service_object,
|
||||
NULL, NULL, NULL, &wds_qmi_client);
|
||||
if(ret != QMI_NO_ERR) {
|
||||
LOC_LOGE("%s:%d]: qmi_client_init Error. ret: %d\n", __func__, __LINE__, ret);
|
||||
status = E_DS_CLIENT_FAILURE_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
LOC_LOGD("%s:%d]: WDS client initialized with qmi_client_init\n", __func__,
|
||||
__LINE__);
|
||||
|
||||
//Store WDS QMI client handle in the parameter passed in
|
||||
*p_wds_qmi_client = wds_qmi_client;
|
||||
|
||||
status = E_DS_CLIENT_SUCCESS;
|
||||
LOC_LOGD("%s:%d]: init success\n", __func__, __LINE__);
|
||||
|
||||
if(notifier)
|
||||
qmi_client_release(notifier);
|
||||
|
||||
err:
|
||||
if(p_service_info)
|
||||
free(p_service_info);
|
||||
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*This function reads the error code from within the response struct*/
|
||||
static ds_client_status_enum_type ds_client_convert_qmi_response(
|
||||
uint32_t req_id,
|
||||
ds_client_resp_union_type *resp_union)
|
||||
{
|
||||
ds_client_status_enum_type ret = E_DS_CLIENT_FAILURE_GENERAL;
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
switch(req_id)
|
||||
{
|
||||
case QMI_WDS_GET_PROFILE_LIST_REQ_V01 :
|
||||
{
|
||||
if(resp_union->p_get_profile_list_resp->resp.error !=
|
||||
QMI_ERR_NONE_V01) {
|
||||
LOC_LOGE("%s:%d]: Response error: %d", __func__, __LINE__,
|
||||
resp_union->p_get_profile_list_resp->resp.error);
|
||||
}
|
||||
else
|
||||
ret = E_DS_CLIENT_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case QMI_WDS_GET_PROFILE_SETTINGS_REQ_V01 :
|
||||
{
|
||||
if(resp_union->p_get_profile_setting_resp->resp.error !=
|
||||
QMI_ERR_NONE_V01) {
|
||||
LOC_LOGE("%s:%d]: Response error: %d", __func__, __LINE__,
|
||||
resp_union->p_get_profile_setting_resp->resp.error);
|
||||
}
|
||||
else
|
||||
ret = E_DS_CLIENT_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("%s:%d]: Unknown request ID\n", __func__, __LINE__);
|
||||
}
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static ds_client_status_enum_type ds_client_send_qmi_sync_req(
|
||||
qmi_client_type *ds_client_handle,
|
||||
uint32_t req_id,
|
||||
ds_client_resp_union_type *resp_union,
|
||||
ds_client_req_union_type *req_union)
|
||||
{
|
||||
uint32_t req_len = 0;
|
||||
uint32_t resp_len = 0;
|
||||
ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS;
|
||||
qmi_client_error_type qmi_ret = QMI_NO_ERR;
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
switch(req_id)
|
||||
{
|
||||
case QMI_WDS_GET_PROFILE_LIST_REQ_V01 :
|
||||
{
|
||||
req_len = sizeof(wds_get_profile_list_req_msg_v01);
|
||||
resp_len = sizeof(wds_get_profile_list_resp_msg_v01);
|
||||
LOC_LOGD("%s:%d]: req_id = GET_PROFILE_LIST_REQ\n",
|
||||
__func__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
case QMI_WDS_GET_PROFILE_SETTINGS_REQ_V01 :
|
||||
{
|
||||
req_len = sizeof(wds_get_profile_settings_req_msg_v01);
|
||||
resp_len = sizeof(wds_get_profile_settings_resp_msg_v01);
|
||||
LOC_LOGD("%s:%d]: req_id = GET_PROFILE_SETTINGS_REQ\n",
|
||||
__func__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("%s:%d]: Error unknown req_id=%d\n", __func__, __LINE__,
|
||||
req_id);
|
||||
ret = E_DS_CLIENT_FAILURE_INVALID_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
LOC_LOGD("%s:%d]: req_id=%d, len = %d; resp_len= %d\n", __func__, __LINE__,
|
||||
req_id, req_len, resp_len);
|
||||
//Send msg through QCCI
|
||||
qmi_ret = qmi_client_send_msg_sync(
|
||||
*ds_client_handle,
|
||||
req_id,
|
||||
(void *)req_union->p_get_profile_list_req,
|
||||
req_len,
|
||||
(void *)resp_union->p_get_profile_list_resp,
|
||||
resp_len,
|
||||
DS_CLIENT_SYNC_MSG_TIMEOUT);
|
||||
LOC_LOGD("%s:%d]: qmi_client_send_msg_sync returned: %d", __func__, __LINE__, qmi_ret);
|
||||
|
||||
if(qmi_ret != QMI_NO_ERR) {
|
||||
ret = E_DS_CLIENT_FAILURE_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = ds_client_convert_qmi_response(req_id, resp_union);
|
||||
|
||||
err:
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*This function obtains the list of supported profiles*/
|
||||
static ds_client_status_enum_type ds_client_get_profile_list(
|
||||
qmi_client_type *ds_client_handle,
|
||||
ds_client_resp_union_type *profile_list_resp_msg,
|
||||
wds_profile_type_enum_v01 profile_type)
|
||||
{
|
||||
ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS;
|
||||
ds_client_req_union_type req_union;
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
|
||||
req_union.p_get_profile_list_req = NULL;
|
||||
req_union.p_get_profile_list_req = (wds_get_profile_list_req_msg_v01 *)
|
||||
calloc(1, sizeof(wds_get_profile_list_req_msg_v01));
|
||||
if(req_union.p_get_profile_list_req == NULL) {
|
||||
LOC_LOGE("%s:%d]: Could not allocate memory for"
|
||||
"wds_get_profile_list_req_msg_v01\n", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
//Populate required members of the request structure
|
||||
req_union.p_get_profile_list_req->profile_type_valid = 1;
|
||||
req_union.p_get_profile_list_req->profile_type = profile_type;
|
||||
ret = ds_client_send_qmi_sync_req(ds_client_handle,
|
||||
QMI_WDS_GET_PROFILE_LIST_REQ_V01,
|
||||
profile_list_resp_msg, &req_union);
|
||||
if(ret != E_DS_CLIENT_SUCCESS) {
|
||||
LOC_LOGE("%s:%d]: ds_client_send_qmi_req failed. ret: %d\n",
|
||||
__func__, __LINE__, ret);
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
if(req_union.p_get_profile_list_req)
|
||||
free(req_union.p_get_profile_list_req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*This function obtains settings for the profile specified by
|
||||
the profile_identifier*/
|
||||
static ds_client_status_enum_type ds_client_get_profile_settings(
|
||||
qmi_client_type *ds_client_handle,
|
||||
ds_client_resp_union_type *profile_settings_resp_msg,
|
||||
wds_profile_identifier_type_v01 *profile_identifier)
|
||||
{
|
||||
ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS;
|
||||
ds_client_req_union_type req_union;
|
||||
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
//Since it's a union containing a pointer to a structure,
|
||||
//following entities have the same address
|
||||
//- req_union
|
||||
//- req_union.p_get_profile_settings_req
|
||||
//- req_union.p_get_profile_settings_req->profile
|
||||
//so we can very well assign req_union = profile_identifier
|
||||
req_union.p_get_profile_settings_req =
|
||||
(wds_get_profile_settings_req_msg_v01 *)profile_identifier;
|
||||
ret = ds_client_send_qmi_sync_req(ds_client_handle,
|
||||
QMI_WDS_GET_PROFILE_SETTINGS_REQ_V01,
|
||||
profile_settings_resp_msg, &req_union);
|
||||
if(ret != E_DS_CLIENT_SUCCESS) {
|
||||
LOC_LOGE("%s:%d]: ds_client_send_qmi_req failed. ret: %d\n",
|
||||
__func__, __LINE__, ret);
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Starts data call using the handle and the profile index
|
||||
*/
|
||||
ds_client_status_enum_type
|
||||
ds_client_start_call(dsClientHandleType client_handle, int profile_index)
|
||||
{
|
||||
ds_client_status_enum_type ret = E_DS_CLIENT_FAILURE_GENERAL;
|
||||
dsi_call_param_value_t param_info;
|
||||
dsi_hndl_t dsi_handle;
|
||||
ds_client_session_data *ds_global_data = (ds_client_session_data *)client_handle;
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
if(ds_global_data == NULL) {
|
||||
LOC_LOGE("%s:%d]: Null callback parameter\n", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
dsi_handle = ds_global_data->dsi_net_handle;
|
||||
//Set profile index as call parameter
|
||||
param_info.buf_val = NULL;
|
||||
param_info.num_val = profile_index;
|
||||
dsi_set_data_call_param(dsi_handle,
|
||||
DSI_CALL_INFO_UMTS_PROFILE_IDX,
|
||||
¶m_info);
|
||||
LOC_LOGD("%s:%d]: Starting emergency call with profile index %d\n",
|
||||
__func__, __LINE__, param_info.num_val);
|
||||
if(dsi_start_data_call(dsi_handle) == DSI_SUCCESS) {
|
||||
LOC_LOGD("%s:%d]: Sent request to start data call\n",
|
||||
__func__, __LINE__);
|
||||
ret = E_DS_CLIENT_SUCCESS;
|
||||
}
|
||||
else {
|
||||
LOC_LOGE("%s:%d]: Could not send req to start data call \n", __func__, __LINE__);
|
||||
ret = E_DS_CLIENT_FAILURE_GENERAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/*Function to open an emergency call. Does the following things:
|
||||
- Obtains a handle to the WDS service
|
||||
- Obtains a list of profiles configured in the modem
|
||||
- Queries each profile and obtains settings to check if emergency calls
|
||||
are supported
|
||||
- Returns the profile index that supports emergency calls
|
||||
- Returns handle to dsi_netctrl*/
|
||||
ds_client_status_enum_type
|
||||
ds_client_open_call(dsClientHandleType *client_handle,
|
||||
ds_client_cb_data *callback,
|
||||
void *caller_cookie,
|
||||
int *profile_index)
|
||||
{
|
||||
ds_client_status_enum_type ret = E_DS_CLIENT_FAILURE_GENERAL;
|
||||
ds_client_resp_union_type profile_list_resp_msg;
|
||||
ds_client_resp_union_type profile_settings_resp_msg;
|
||||
wds_profile_identifier_type_v01 profile_identifier;
|
||||
uint32_t i=0;
|
||||
dsi_hndl_t dsi_handle;
|
||||
ds_client_session_data **ds_global_data = (ds_client_session_data **)client_handle;
|
||||
unsigned char call_profile_index_found = 0;
|
||||
uint32_t emergency_profile_index=0;
|
||||
qmi_client_type wds_qmi_client;
|
||||
|
||||
profile_list_resp_msg.p_get_profile_list_resp = NULL;
|
||||
profile_settings_resp_msg.p_get_profile_setting_resp = NULL;
|
||||
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
if(callback == NULL || ds_global_data == NULL) {
|
||||
LOC_LOGE("%s:%d]: Null callback parameter\n", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = ds_client_qmi_ctrl_point_init(&wds_qmi_client);
|
||||
if(ret != E_DS_CLIENT_SUCCESS) {
|
||||
LOC_LOGE("%s:%d]: ds_client_qmi_ctrl_point_init failed. ret: %d\n",
|
||||
__func__, __LINE__, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
//Allocate memory for the response msg to obtain a list of profiles
|
||||
profile_list_resp_msg.p_get_profile_list_resp = (wds_get_profile_list_resp_msg_v01 *)
|
||||
calloc(1, sizeof(wds_get_profile_list_resp_msg_v01));
|
||||
if(profile_list_resp_msg.p_get_profile_list_resp == NULL) {
|
||||
LOC_LOGE("%s:%d]: Could not allocate memory for"
|
||||
"p_get_profile_list_resp\n", __func__, __LINE__);
|
||||
ret = E_DS_CLIENT_FAILURE_NOT_ENOUGH_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
LOC_LOGD("%s:%d]: Getting profile list\n", __func__, __LINE__);
|
||||
ret = ds_client_get_profile_list(&wds_qmi_client,
|
||||
&profile_list_resp_msg,
|
||||
WDS_PROFILE_TYPE_3GPP_V01);
|
||||
if(ret != E_DS_CLIENT_SUCCESS) {
|
||||
LOC_LOGE("%s:%d]: ds_client_get_profile_list failed. ret: %d\n",
|
||||
__func__, __LINE__, ret);
|
||||
goto err;
|
||||
}
|
||||
LOC_LOGD("%s:%d]: Got profile list; length = %d\n", __func__, __LINE__,
|
||||
profile_list_resp_msg.p_get_profile_list_resp->profile_list_len);
|
||||
|
||||
//Allocate memory for the response msg to obtain profile settings
|
||||
//We allocate memory for only one response msg and keep re-using it
|
||||
profile_settings_resp_msg.p_get_profile_setting_resp =
|
||||
(wds_get_profile_settings_resp_msg_v01 *)
|
||||
calloc(1, sizeof(wds_get_profile_settings_resp_msg_v01));
|
||||
if(profile_settings_resp_msg.p_get_profile_setting_resp == NULL) {
|
||||
LOC_LOGE("%s:%d]: Could not allocate memory for"
|
||||
"p_get_profile_setting_resp\n", __func__, __LINE__);
|
||||
ret = E_DS_CLIENT_FAILURE_NOT_ENOUGH_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
//Loop over the list of profiles to find a profile that supports
|
||||
//emergency calls
|
||||
for(i=0; i < profile_list_resp_msg.p_get_profile_list_resp->profile_list_len; i++) {
|
||||
/*QMI_WDS_GET_PROFILE_SETTINGS_REQ requires an input data
|
||||
structure that is of type wds_profile_identifier_type_v01
|
||||
We have to fill that structure for each profile from the
|
||||
info obtained from the profile list*/
|
||||
//copy profile type
|
||||
profile_identifier.profile_type =
|
||||
profile_list_resp_msg.p_get_profile_list_resp->profile_list[i].profile_type;
|
||||
//copy profile index
|
||||
profile_identifier.profile_index =
|
||||
profile_list_resp_msg.p_get_profile_list_resp->profile_list[i].profile_index;
|
||||
|
||||
ret = ds_client_get_profile_settings(&wds_qmi_client,
|
||||
&profile_settings_resp_msg,
|
||||
&profile_identifier);
|
||||
if(ret != E_DS_CLIENT_SUCCESS) {
|
||||
LOC_LOGE("%s:%d]: ds_client_get_profile_settings failed. ret: %d\n",
|
||||
__func__, __LINE__, ret);
|
||||
goto err;
|
||||
}
|
||||
LOC_LOGD("%s:%d]: Got profile setting for profile %d\n", __func__, __LINE__, i);
|
||||
LOC_LOGD("%s:%d]: Profile name: %s\n", __func__, __LINE__,
|
||||
profile_settings_resp_msg.p_get_profile_setting_resp->profile_name);
|
||||
|
||||
if(profile_settings_resp_msg.p_get_profile_setting_resp->support_emergency_calls_valid) {
|
||||
if(profile_settings_resp_msg.p_get_profile_setting_resp->support_emergency_calls) {
|
||||
LOC_LOGD("%s:%d]: Found emergency profile in profile %d"
|
||||
, __func__, __LINE__, i);
|
||||
call_profile_index_found = 1;
|
||||
emergency_profile_index = profile_identifier.profile_index;
|
||||
break;
|
||||
}
|
||||
else
|
||||
LOC_LOGE("%s:%d]: Emergency profile valid but not supported in profile: %d "
|
||||
, __func__, __LINE__, i);
|
||||
}
|
||||
//Since this struct is loaded with settings for the next profile,
|
||||
//it is important to clear out the memory to avoid values/flags
|
||||
//from being carried over
|
||||
memset((void *)profile_settings_resp_msg.p_get_profile_setting_resp,
|
||||
0, sizeof(wds_get_profile_settings_resp_msg_v01));
|
||||
}
|
||||
|
||||
//Release qmi client handle
|
||||
if(qmi_client_release(wds_qmi_client) != QMI_NO_ERR) {
|
||||
LOC_LOGE("%s:%d]: Could not release qmi client handle\n",
|
||||
__func__, __LINE__);
|
||||
ret = E_DS_CLIENT_FAILURE_GENERAL;
|
||||
}
|
||||
|
||||
if(call_profile_index_found) {
|
||||
*profile_index = emergency_profile_index;
|
||||
*ds_global_data = (ds_client_session_data *)calloc(1, sizeof(ds_client_session_data));
|
||||
if(*ds_global_data == NULL) {
|
||||
LOC_LOGE("%s:%d]: Could not allocate memory for ds_global_data. Failing\n",
|
||||
__func__, __LINE__);
|
||||
ret = E_DS_CLIENT_FAILURE_NOT_ENOUGH_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
(*ds_global_data)->caller_data.event_cb = callback->event_cb;
|
||||
(*ds_global_data)->caller_data.caller_cookie = caller_cookie;
|
||||
dsi_handle = dsi_get_data_srvc_hndl(net_ev_cb, &(*ds_global_data)->caller_data);
|
||||
if(dsi_handle == NULL) {
|
||||
LOC_LOGE("%s:%d]: Could not get data handle. Retry Later\n",
|
||||
__func__, __LINE__);
|
||||
ret = E_DS_CLIENT_RETRY_LATER;
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
(*ds_global_data)->dsi_net_handle = dsi_handle;
|
||||
}
|
||||
else {
|
||||
LOC_LOGE("%s:%d]: Could not find a profile that supports emergency calls",
|
||||
__func__, __LINE__);
|
||||
ret = E_DS_CLIENT_FAILURE_GENERAL;
|
||||
}
|
||||
err:
|
||||
if(profile_list_resp_msg.p_get_profile_list_resp)
|
||||
free(profile_list_resp_msg.p_get_profile_list_resp);
|
||||
if(profile_settings_resp_msg.p_get_profile_setting_resp)
|
||||
free(profile_settings_resp_msg.p_get_profile_setting_resp);
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ds_client_status_enum_type ds_client_stop_call(dsClientHandleType client_handle)
|
||||
{
|
||||
ds_client_status_enum_type ret = E_DS_CLIENT_SUCCESS;
|
||||
ds_client_session_data *p_ds_global_data = (ds_client_session_data *)client_handle;
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
|
||||
if(client_handle == NULL) {
|
||||
LOC_LOGE("%s:%d]: Null argument received. Failing\n", __func__, __LINE__);
|
||||
ret = E_DS_CLIENT_FAILURE_GENERAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if(dsi_stop_data_call(p_ds_global_data->dsi_net_handle) == DSI_SUCCESS) {
|
||||
LOC_LOGD("%s:%d]: Sent request to stop data call\n", __func__, __LINE__);
|
||||
}
|
||||
else {
|
||||
LOC_LOGE("%s:%d]: Could not send request to stop data call\n",
|
||||
__func__, __LINE__);
|
||||
ret = E_DS_CLIENT_FAILURE_GENERAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Stops data call associated with the data handle
|
||||
*/
|
||||
void ds_client_close_call(dsClientHandleType *client_handle)
|
||||
{
|
||||
ds_client_session_data **ds_global_data = (ds_client_session_data **)client_handle;
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
if(client_handle == NULL || *client_handle == NULL) {
|
||||
LOC_LOGE("%s:%d]: Null argument received. Failing\n", __func__, __LINE__);
|
||||
goto err;
|
||||
}
|
||||
dsi_rel_data_srvc_hndl((*ds_global_data)->dsi_net_handle);
|
||||
(*ds_global_data)->dsi_net_handle = NULL;
|
||||
free(*ds_global_data);
|
||||
*ds_global_data = NULL;
|
||||
LOC_LOGD("%s:%d]: Released Data handle\n", __func__, __LINE__);
|
||||
err:
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
int ds_client_init()
|
||||
{
|
||||
int ret = 0;
|
||||
LOC_LOGD("%s:%d]:Enter\n", __func__, __LINE__);
|
||||
if(DSI_SUCCESS != dsi_init(DSI_MODE_GENERAL))
|
||||
{
|
||||
LOC_LOGE("%s:%d]:dsi_init failed\n", __func__, __LINE__);
|
||||
ret = -1;
|
||||
}
|
||||
LOC_LOGD("%s:%d]:Exit\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
142
loc_api/ds_api/ds_client.h
Normal file
142
loc_api/ds_api/ds_client.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DS_CLIENT_H_
|
||||
#define _DS_CLIENT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* dsClientHandleType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
E_DS_CLIENT_SUCCESS = 0,
|
||||
/**< Request was successful. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_GENERAL = 1,
|
||||
/**< Failed because of a general failure. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_UNSUPPORTED = 2,
|
||||
/**< Failed because the service does not support the command. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_INVALID_PARAMETER = 3,
|
||||
/**< Failed because the request contained invalid parameters. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_ENGINE_BUSY = 4,
|
||||
/**< Failed because the engine is busy. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_PHONE_OFFLINE = 5,
|
||||
/**< Failed because the phone is offline. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_TIMEOUT = 6,
|
||||
/**< Failed because of a timeout. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_SERVICE_NOT_PRESENT = 7,
|
||||
/**< Failed because the service is not present. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_SERVICE_VERSION_UNSUPPORTED = 8,
|
||||
/**< Failed because the service version is unsupported. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_CLIENT_VERSION_UNSUPPORTED = 9,
|
||||
/**< Failed because the service does not support client version. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_INVALID_HANDLE = 10,
|
||||
/**< Failed because an invalid handle was specified. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_INTERNAL = 11,
|
||||
/**< Failed because of an internal error in the service. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_NOT_INITIALIZED = 12,
|
||||
/**< Failed because the service has not been initialized. */
|
||||
|
||||
E_DS_CLIENT_FAILURE_NOT_ENOUGH_MEMORY = 13,
|
||||
/**< Failed because not rnough memory to do the operation.*/
|
||||
|
||||
E_DS_CLIENT_SERVICE_ALREADY_STARTED = 14,
|
||||
/*Service is already started*/
|
||||
|
||||
E_DS_CLIENT_DATA_CALL_CONNECTED = 15,
|
||||
|
||||
E_DS_CLIENT_DATA_CALL_DISCONNECTED = 16,
|
||||
|
||||
E_DS_CLIENT_RETRY_LATER = 17
|
||||
}ds_client_status_enum_type;
|
||||
|
||||
typedef enum {
|
||||
DATA_CALL_NONE = 0,
|
||||
DATA_CALL_OPEN,
|
||||
DATA_CALL_CLOSE
|
||||
}data_call_request_enum_type;
|
||||
|
||||
typedef void (*ds_client_event_ind_cb_type)(ds_client_status_enum_type result,
|
||||
void* loc_adapter_cookie);
|
||||
typedef struct {
|
||||
ds_client_event_ind_cb_type event_cb;
|
||||
}ds_client_cb_data;
|
||||
|
||||
/*
|
||||
This function is to be called as a first step by each process that
|
||||
needs to use data services. This call internally calls dsi_init()
|
||||
and prepares the module for making data calls.
|
||||
Needs to be called once for every process
|
||||
*/
|
||||
int ds_client_init();
|
||||
|
||||
/*
|
||||
Obtains a handle to the dsi_netctrl layer and looks up the profile
|
||||
to make the call. As of now. It only searches for profiles that
|
||||
support emergency calls
|
||||
*/
|
||||
ds_client_status_enum_type ds_client_open_call(dsClientHandleType *client_handle,
|
||||
ds_client_cb_data *callback,
|
||||
void *loc_adapter_cookie,
|
||||
int *profile_index);
|
||||
|
||||
/*
|
||||
Starts a data call using the profile number provided
|
||||
*/
|
||||
ds_client_status_enum_type ds_client_start_call(dsClientHandleType client_handle,
|
||||
int profile_index);
|
||||
|
||||
/*
|
||||
Stops a data call associated with the handle
|
||||
*/
|
||||
ds_client_status_enum_type ds_client_stop_call(dsClientHandleType client_handle);
|
||||
|
||||
/*
|
||||
Releases the handle used for making data calls
|
||||
*/
|
||||
void ds_client_close_call(dsClientHandleType *client_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -186,6 +186,18 @@ void LocApiAdapter::requestATL(int connHandle, AGpsType agps_type)
|
|||
locEngHandle.sendMsge(locEngHandle.owner, msg);
|
||||
}
|
||||
|
||||
void LocApiAdapter::requestSuplES(int connHandle)
|
||||
{
|
||||
loc_eng_msg_request_supl_es *msg(new loc_eng_msg_request_supl_es(locEngHandle.owner, connHandle));
|
||||
locEngHandle.sendMsge(locEngHandle.owner, msg);
|
||||
}
|
||||
|
||||
void LocApiAdapter::releaseDataHandle(void)
|
||||
{
|
||||
loc_eng_msg_close_data_call *msg(new loc_eng_msg_close_data_call(locEngHandle.owner));
|
||||
locEngHandle.sendMsge(locEngHandle.owner, msg);
|
||||
}
|
||||
|
||||
void LocApiAdapter::releaseATL(int connHandle)
|
||||
{
|
||||
loc_eng_msg_release_atl *msg(new loc_eng_msg_release_atl(locEngHandle.owner, connHandle));
|
||||
|
@ -234,3 +246,18 @@ void LocApiAdapter::handleEngineUpEvent()
|
|||
loc_eng_msg *msg(new loc_eng_msg(locEngHandle.owner, LOC_ENG_MSG_ENGINE_UP));
|
||||
locEngHandle.sendMsge(locEngHandle.owner, msg);
|
||||
}
|
||||
|
||||
void LocApiAdapter::reportDataCallOpened()
|
||||
{
|
||||
loc_eng_msg_atl_open_success *msg(new loc_eng_msg_atl_open_success(locEngHandle.owner,
|
||||
AGPS_TYPE_INVALID,
|
||||
NULL, 0, 0));
|
||||
locEngHandle.sendMsge(locEngHandle.owner, msg);
|
||||
}
|
||||
|
||||
void LocApiAdapter::reportDataCallClosed()
|
||||
{
|
||||
loc_eng_msg_atl_closed *msg(new loc_eng_msg_atl_closed(locEngHandle.owner,
|
||||
AGPS_TYPE_INVALID));
|
||||
locEngHandle.sendMsge(locEngHandle.owner, msg);
|
||||
}
|
||||
|
|
|
@ -141,7 +141,10 @@ public:
|
|||
void requestNiNotify(GpsNiNotification ¬ify, const void* data);
|
||||
void handleEngineDownEvent();
|
||||
void handleEngineUpEvent();
|
||||
|
||||
void requestSuplES(int connHandle);
|
||||
void releaseDataHandle(void);
|
||||
void reportDataCallOpened(void);
|
||||
void reportDataCallClosed(void);
|
||||
// All below functions are to be defined by adapter specific modules:
|
||||
// RPC, QMI, etc. The default implementation is empty.
|
||||
inline virtual enum loc_api_adapter_err
|
||||
|
@ -230,6 +233,15 @@ public:
|
|||
|
||||
inline bool isInSession() { return navigating; }
|
||||
inline virtual void setInSession(bool inSession) { navigating = inSession; }
|
||||
inline virtual int openAndStartDataCall()
|
||||
{LOC_LOGW("%s: default implementation invoked", __func__); return -1;}
|
||||
inline virtual void stopDataCall()
|
||||
{LOC_LOGW("%s: default implementation invoked", __func__);}
|
||||
inline virtual void closeDataCall()
|
||||
{LOC_LOGW("%s: default implementation invoked", __func__);}
|
||||
inline virtual int initDataServiceClient()
|
||||
{LOC_LOGW("%s: default implementation invoked", __func__); return -1;}
|
||||
|
||||
};
|
||||
|
||||
extern "C" LocApiAdapter* getLocApiAdapter(LocEng &locEng);
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
#include <loc_eng_nmea.h>
|
||||
#include <msg_q.h>
|
||||
#include <loc.h>
|
||||
|
||||
#include "log_util.h"
|
||||
#include "loc_eng_log.h"
|
||||
|
||||
|
@ -810,6 +809,38 @@ static void loc_inform_gps_status(loc_eng_data_s_type &loc_eng_data, GpsStatusVa
|
|||
EXIT_LOG(%s, VOID_RET);
|
||||
}
|
||||
|
||||
/*
|
||||
Callback function passed to Data Services State Machine
|
||||
This becomes part of the state machine's servicer and
|
||||
is used to send requests to the data services client
|
||||
*/
|
||||
static int dataCallCb(void *cb_data)
|
||||
{
|
||||
LOC_LOGD("Enter dataCallCb\n");
|
||||
int ret=0;
|
||||
if(cb_data != NULL) {
|
||||
dsCbData *cbData = (dsCbData *)cb_data;
|
||||
LocApiAdapter *locAdapter = (LocApiAdapter *)cbData->mAdapter;
|
||||
if(cbData->action == GPS_REQUEST_AGPS_DATA_CONN) {
|
||||
LOC_LOGD("dataCallCb GPS_REQUEST_AGPS_DATA_CONN\n");
|
||||
ret = locAdapter->openAndStartDataCall();
|
||||
}
|
||||
else if(cbData->action == GPS_RELEASE_AGPS_DATA_CONN) {
|
||||
LOC_LOGD("dataCallCb GPS_RELEASE_AGPS_DATA_CONN\n");
|
||||
locAdapter->stopDataCall();
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOC_LOGE("NULL argument received. Failing.\n");
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
LOC_LOGD("Exit dataCallCb ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION loc_eng_agps_reinit
|
||||
|
||||
|
@ -876,17 +907,27 @@ void loc_eng_agps_init(loc_eng_data_s_type &loc_eng_data, AGpsCallbacks* callbac
|
|||
}
|
||||
loc_eng_data.agps_status_cb = callbacks->status_cb;
|
||||
|
||||
loc_eng_data.agnss_nif = new AgpsStateMachine(loc_eng_data.agps_status_cb,
|
||||
loc_eng_data.agnss_nif = new AgpsStateMachine(servicerTypeAgps,
|
||||
(void *)loc_eng_data.agps_status_cb,
|
||||
AGPS_TYPE_SUPL,
|
||||
false);
|
||||
#ifdef FEATURE_IPV6
|
||||
loc_eng_data.internet_nif = new AgpsStateMachine(loc_eng_data.agps_status_cb,
|
||||
loc_eng_data.internet_nif = new AgpsStateMachine(servicerTypeAgps,
|
||||
(void *)loc_eng_data.agps_status_cb,
|
||||
AGPS_TYPE_WWAN_ANY,
|
||||
false);
|
||||
loc_eng_data.wifi_nif = new AgpsStateMachine(loc_eng_data.agps_status_cb,
|
||||
loc_eng_data.wifi_nif = new AgpsStateMachine(servicerTypeAgps,
|
||||
(void *)loc_eng_data.agps_status_cb,
|
||||
AGPS_TYPE_WIFI,
|
||||
true);
|
||||
#endif
|
||||
if(!loc_eng_data.client_handle->initDataServiceClient()) {
|
||||
LOC_LOGD("%s:%d]: Creating new ds state machine\n", __func__, __LINE__);
|
||||
loc_eng_data.ds_nif = new DSStateMachine(servicerTypeExt,
|
||||
(void *)dataCallCb,
|
||||
loc_eng_data.client_handle);
|
||||
LOC_LOGD("%s:%d]: Created new ds state machine\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
loc_eng_dmn_conn_loc_api_server_launch(callbacks->create_thread_cb,
|
||||
NULL, NULL, &loc_eng_data);
|
||||
|
@ -1741,14 +1782,27 @@ static void loc_eng_deferred_action_thread(void* arg)
|
|||
loc_eng_data_p->client_handle,
|
||||
false);
|
||||
// attempt to unsubscribe from agnss_nif first
|
||||
if (! loc_eng_data_p->agnss_nif->unsubscribeRsrc((Subscriber*)&s1)) {
|
||||
if (loc_eng_data_p->agnss_nif->unsubscribeRsrc((Subscriber*)&s1)) {
|
||||
#ifdef FEATURE_IPV6
|
||||
LOC_LOGD("%s:%d]: Unsubscribed from agnss_nif", __func__, __LINE__);
|
||||
}
|
||||
else {
|
||||
ATLSubscriber s2(arlMsg->handle,
|
||||
loc_eng_data_p->internet_nif,
|
||||
loc_eng_data_p->client_handle,
|
||||
false);
|
||||
// if unsuccessful, try internet_nif
|
||||
loc_eng_data_p->internet_nif->unsubscribeRsrc((Subscriber*)&s2);
|
||||
if(loc_eng_data_p->internet_nif->unsubscribeRsrc((Subscriber*)&s2)) {
|
||||
LOC_LOGD("%s:%d]: Unsubscribed from internet_nif", __func__, __LINE__);
|
||||
}
|
||||
else {
|
||||
DSSubscriber s3(loc_eng_data_p->ds_nif,
|
||||
arlMsg->handle);
|
||||
LOC_LOGD("%s:%d]: Request to stop Emergency call. Handle: %d\n",
|
||||
__func__, __LINE__, arlMsg->handle);
|
||||
loc_eng_data_p->ds_nif->unsubscribeRsrc((Subscriber*)&s3);
|
||||
LOC_LOGD("%s:%d]: Unsubscribed from ds_nif", __func__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1827,16 +1881,25 @@ static void loc_eng_deferred_action_thread(void* arg)
|
|||
loc_eng_msg_atl_open_success *aosMsg = (loc_eng_msg_atl_open_success*)msg;
|
||||
AgpsStateMachine* stateMachine;
|
||||
#ifdef FEATURE_IPV6
|
||||
LOC_LOGD("%s:%d]: AGPS_TYPE: %d\n", __func__, __LINE__, (int)aosMsg->agpsType);
|
||||
switch (aosMsg->agpsType) {
|
||||
case AGPS_TYPE_WIFI: {
|
||||
LOC_LOGD("%s:%d]: AGPS Type wifi\n", __func__, __LINE__);
|
||||
stateMachine = loc_eng_data_p->wifi_nif;
|
||||
break;
|
||||
}
|
||||
case AGPS_TYPE_SUPL: {
|
||||
LOC_LOGD("%s:%d]: AGPS Type supl\n", __func__, __LINE__);
|
||||
stateMachine = loc_eng_data_p->agnss_nif;
|
||||
break;
|
||||
}
|
||||
case AGPS_TYPE_INVALID: {
|
||||
stateMachine = loc_eng_data_p->ds_nif;
|
||||
LOC_LOGD("%s:%d]: AGPS Type invalid\n", __func__, __LINE__);
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
LOC_LOGD("%s:%d]: AGPS Type default internet\n", __func__, __LINE__);
|
||||
stateMachine = loc_eng_data_p->internet_nif;
|
||||
}
|
||||
}
|
||||
|
@ -1864,6 +1927,10 @@ static void loc_eng_deferred_action_thread(void* arg)
|
|||
stateMachine = loc_eng_data_p->agnss_nif;
|
||||
break;
|
||||
}
|
||||
case AGPS_TYPE_INVALID: {
|
||||
stateMachine = loc_eng_data_p->ds_nif;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
stateMachine = loc_eng_data_p->internet_nif;
|
||||
}
|
||||
|
@ -1928,7 +1995,7 @@ static void loc_eng_deferred_action_thread(void* arg)
|
|||
{
|
||||
loc_eng_msg_request_phone_context *contextReqMsg = (loc_eng_msg_request_phone_context*)msg;
|
||||
LOC_LOGD("Received phone context request from ULP.context_type 0x%x,request_type 0x%x ",
|
||||
contextReqMsg->contextRequest.context_type,contextReqMsg->contextRequest.request_type)
|
||||
contextReqMsg->contextRequest.context_type,contextReqMsg->contextRequest.request_type);
|
||||
if(loc_eng_data_p->ulp_phone_context_req_cb != NULL)
|
||||
{
|
||||
loc_eng_data_p->ulp_phone_context_req_cb((UlpPhoneContextRequest*)&(contextReqMsg->contextRequest));
|
||||
|
@ -1944,6 +2011,25 @@ static void loc_eng_deferred_action_thread(void* arg)
|
|||
}
|
||||
break;
|
||||
|
||||
case LOC_ENG_MSG_REQUEST_SUPL_ES:
|
||||
{
|
||||
loc_eng_msg_request_supl_es *reqMsg =
|
||||
(loc_eng_msg_request_supl_es *)msg;
|
||||
AgpsStateMachine *stateMachine = loc_eng_data_p->ds_nif;
|
||||
DSSubscriber subscriber(stateMachine, reqMsg->handle);
|
||||
LOC_LOGD("%s:%d]: Starting data call\n", __func__, __LINE__);
|
||||
stateMachine->subscribeRsrc((Subscriber *)&subscriber);
|
||||
}
|
||||
break;
|
||||
|
||||
case LOC_ENG_MSG_CLOSE_DATA_CALL:
|
||||
{
|
||||
loc_eng_data_p->client_handle->closeDataCall();
|
||||
LOC_LOGD("%s:%d]: Request to close data call\n",
|
||||
__func__, __LINE__);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("unsupported msgid = %d\n", msg->msgid);
|
||||
break;
|
||||
|
@ -2273,4 +2359,3 @@ int loc_eng_read_config(void)
|
|||
EXIT_LOG(%d, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,8 @@ typedef struct
|
|||
AgpsStateMachine* agnss_nif;
|
||||
AgpsStateMachine* internet_nif;
|
||||
AgpsStateMachine* wifi_nif;
|
||||
//State machine for Data Services
|
||||
AgpsStateMachine* ds_nif;
|
||||
|
||||
// GPS engine status
|
||||
GpsStatusValue engine_status;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <log_util.h>
|
||||
#include <loc_eng_dmn_conn_handler.h>
|
||||
#include <loc_eng_dmn_conn.h>
|
||||
#include<sys/time.h>
|
||||
|
||||
//======================================================================
|
||||
// C callbacks
|
||||
|
@ -84,8 +85,8 @@ static bool notifySubscriber(void* fromCaller, void* fromList)
|
|||
const int Notification::BROADCAST_ALL = 0x80000000;
|
||||
const int Notification::BROADCAST_ACTIVE = 0x80000001;
|
||||
const int Notification::BROADCAST_INACTIVE = 0x80000002;
|
||||
|
||||
|
||||
const unsigned char DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
|
||||
const unsigned int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
|
||||
//======================================================================
|
||||
// Subscriber: BITSubscriber / ATLSubscriber / WIFISubscriber
|
||||
//======================================================================
|
||||
|
@ -227,7 +228,29 @@ bool WIFISubscriber::notifyRsrcStatus(Notification ¬ification)
|
|||
return notify;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool DSSubscriber::notifyRsrcStatus(Notification ¬ification)
|
||||
{
|
||||
bool notify = forMe(notification);
|
||||
LOC_LOGD("DSSubscriber::notifyRsrcStatus. notify:%d \n",(int)(notify));
|
||||
if(notify) {
|
||||
switch(notification.rsrcStatus) {
|
||||
case RSRC_UNSUBSCRIBE:
|
||||
case RSRC_RELEASED:
|
||||
case RSRC_DENIED:
|
||||
case RSRC_GRANTED:
|
||||
((DSStateMachine *)mStateMachine)->informStatus(notification.rsrcStatus, ID);
|
||||
break;
|
||||
default:
|
||||
notify = false;
|
||||
}
|
||||
}
|
||||
return notify;
|
||||
}
|
||||
void DSSubscriber :: setInactive()
|
||||
{
|
||||
mIsInactive = true;
|
||||
((DSStateMachine *)mStateMachine)->informStatus(RSRC_UNSUBSCRIBE, ID);
|
||||
}
|
||||
//======================================================================
|
||||
// AgpsState: AgpsReleasedState / AgpsPendingState / AgpsAcquiredState
|
||||
//======================================================================
|
||||
|
@ -249,13 +272,14 @@ public:
|
|||
|
||||
AgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||
{
|
||||
LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event);
|
||||
if (mStateMachine->hasSubscribers()) {
|
||||
LOC_LOGE("Error: %s subscriber list not empty!!!", whoami());
|
||||
// I don't know how to recover from it. I am adding this rather
|
||||
// for debugging purpose.
|
||||
}
|
||||
|
||||
AgpsState* nextState = this;;
|
||||
AgpsState* nextState = this;
|
||||
switch (event)
|
||||
{
|
||||
case RSRC_SUBSCRIBE:
|
||||
|
@ -263,13 +287,16 @@ AgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
|||
// no notification until we get RSRC_GRANTED
|
||||
// but we need to add subscriber to the list
|
||||
mStateMachine->addSubscriber((Subscriber*)data);
|
||||
// move the state to PENDING
|
||||
nextState = mPendingState;
|
||||
|
||||
// request from connecivity service for NIF
|
||||
mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
|
||||
//The if condition is added so that if the data call setup fails
|
||||
//for DS State Machine, we want to retry in released state.
|
||||
//for AGps State Machine, sendRsrcRequest() will always return success
|
||||
if(!mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN)) {
|
||||
// move the state to PENDING
|
||||
nextState = mPendingState;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case RSRC_UNSUBSCRIBE:
|
||||
{
|
||||
|
@ -313,6 +340,7 @@ public:
|
|||
AgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||
{
|
||||
AgpsState* nextState = this;;
|
||||
LOC_LOGD("AgpsPendingState::onRsrcEvent; event:%d\n", (int)event);
|
||||
switch (event)
|
||||
{
|
||||
case RSRC_SUBSCRIBE:
|
||||
|
@ -351,7 +379,7 @@ AgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
|||
mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case RSRC_GRANTED:
|
||||
{
|
||||
|
@ -408,6 +436,7 @@ public:
|
|||
AgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||
{
|
||||
AgpsState* nextState = this;
|
||||
LOC_LOGD("AgpsAcquiredState::onRsrcEvent; event:%d\n", (int)event);
|
||||
switch (event)
|
||||
{
|
||||
case RSRC_SUBSCRIBE:
|
||||
|
@ -441,7 +470,8 @@ AgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
|||
|
||||
// tell connecivity service we can release NIF
|
||||
mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
|
||||
} else if (!mStateMachine->hasActiveSubscribers()) {
|
||||
}
|
||||
else if (!mStateMachine->hasActiveSubscribers()) {
|
||||
// only inactive subscribers, move to RELEASING state
|
||||
nextState = mReleasingState;
|
||||
|
||||
|
@ -500,7 +530,9 @@ public:
|
|||
AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||
{
|
||||
AgpsState* nextState = this;;
|
||||
switch (event)
|
||||
LOC_LOGD("AgpsReleasingState::onRsrcEvent; event:%d\n", (int)event);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case RSRC_SUBSCRIBE:
|
||||
{
|
||||
|
@ -541,7 +573,7 @@ AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
|||
// by setting false, we keep subscribers on the linked list
|
||||
mStateMachine->notifySubscribers(notification);
|
||||
|
||||
if (mStateMachine->hasSubscribers()) {
|
||||
if (mStateMachine->hasActiveSubscribers()) {
|
||||
nextState = mPendingState;
|
||||
// request from connecivity service for NIF
|
||||
mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
|
||||
|
@ -561,20 +593,58 @@ AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
|||
whoami(), nextState->whoami(), event);
|
||||
return nextState;
|
||||
}
|
||||
//======================================================================
|
||||
//Servicer
|
||||
//======================================================================
|
||||
Servicer* Servicer :: getServicer(servicerType type, void *cb_func)
|
||||
{
|
||||
LOC_LOGD(" Enter getServicer type:%d\n", (int)type);
|
||||
switch(type) {
|
||||
case servicerTypeNoCbParam:
|
||||
return (new Servicer(cb_func));
|
||||
case servicerTypeExt:
|
||||
return (new ExtServicer(cb_func));
|
||||
case servicerTypeAgps:
|
||||
return (new AGpsServicer(cb_func));
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int Servicer :: requestRsrc(void *cb_data)
|
||||
{
|
||||
callback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ExtServicer :: requestRsrc(void *cb_data)
|
||||
{
|
||||
int ret=-1;
|
||||
LOC_LOGD("Enter ExtServicer :: requestRsrc\n");
|
||||
ret = callbackExt(cb_data);
|
||||
LOC_LOGD("Exit ExtServicer :: requestRsrc\n");
|
||||
return(ret);
|
||||
}
|
||||
|
||||
int AGpsServicer :: requestRsrc(void *cb_data)
|
||||
{
|
||||
callbackAGps((AGpsStatus *)cb_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// AgpsStateMachine
|
||||
//======================================================================
|
||||
|
||||
AgpsStateMachine::AgpsStateMachine(void (*servicer)(AGpsStatus* status),
|
||||
AgpsStateMachine::AgpsStateMachine(servicerType servType,
|
||||
void *cb_func,
|
||||
AGpsType type,
|
||||
bool enforceSingleSubscriber) :
|
||||
mServicer(servicer), mType(type),
|
||||
mStatePtr(new AgpsReleasedState(this)),
|
||||
mStatePtr(new AgpsReleasedState(this)),mType(type),
|
||||
mAPN(NULL),
|
||||
mAPNLen(0),
|
||||
mEnforceSingleSubscriber(enforceSingleSubscriber)
|
||||
mEnforceSingleSubscriber(enforceSingleSubscriber),
|
||||
mServicer(Servicer :: getServicer(servType, (void *)cb_func))
|
||||
{
|
||||
linked_list_init(&mSubscribers);
|
||||
|
||||
|
@ -615,6 +685,7 @@ AgpsStateMachine::~AgpsStateMachine()
|
|||
delete releasedState;
|
||||
delete pendindState;
|
||||
delete releasingState;
|
||||
delete mServicer;
|
||||
linked_list_destroy(&mSubscribers);
|
||||
|
||||
if (NULL != mAPN) {
|
||||
|
@ -669,6 +740,7 @@ void AgpsStateMachine::notifySubscribers(Notification& notification) const
|
|||
// rest of the list unprocessed. So we need a loop.
|
||||
linked_list_search(mSubscribers, (void**)&s, notifySubscriber,
|
||||
(void*)¬ification, true);
|
||||
delete s;
|
||||
}
|
||||
} else {
|
||||
// no loop needed if it the last param sets to false, which
|
||||
|
@ -690,7 +762,7 @@ void AgpsStateMachine::addSubscriber(Subscriber* subscriber) const
|
|||
}
|
||||
}
|
||||
|
||||
void AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const
|
||||
int AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const
|
||||
{
|
||||
Subscriber* s = NULL;
|
||||
Notification notification(Notification::BROADCAST_ACTIVE);
|
||||
|
@ -722,8 +794,9 @@ void AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const
|
|||
#endif
|
||||
|
||||
CALLBACK_LOG_CALLFLOW("agps_cb", %s, loc_get_agps_status_name(action));
|
||||
(*mServicer)(&nifRequest);
|
||||
mServicer->requestRsrc((void *)&nifRequest);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AgpsStateMachine::subscribeRsrc(Subscriber *subscriber)
|
||||
|
@ -758,3 +831,163 @@ bool AgpsStateMachine::hasActiveSubscribers() const
|
|||
hasSubscriber, (void*)¬ification, false);
|
||||
return NULL != s;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// DSStateMachine
|
||||
//======================================================================
|
||||
void delay_callback(void *callbackData, int result)
|
||||
{
|
||||
if(callbackData) {
|
||||
DSStateMachine *DSSMInstance = (DSStateMachine *)callbackData;
|
||||
DSSMInstance->retryCallback();
|
||||
}
|
||||
else {
|
||||
LOC_LOGE(" NULL argument received. Failing.\n");
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
return;
|
||||
}
|
||||
|
||||
DSStateMachine :: DSStateMachine(servicerType type, void *cb_func,
|
||||
LocApiAdapter* adapterHandle):
|
||||
AgpsStateMachine(type, cb_func, AGPS_TYPE_INVALID,false),
|
||||
mLocAdapter(adapterHandle)
|
||||
{
|
||||
LOC_LOGD("%s:%d]: New DSStateMachine\n", __func__, __LINE__);
|
||||
mRetries = 0;
|
||||
}
|
||||
|
||||
void DSStateMachine :: retryCallback(void)
|
||||
{
|
||||
DSSubscriber *subscriber = NULL;
|
||||
Notification notification(Notification::BROADCAST_ACTIVE);
|
||||
linked_list_search(mSubscribers, (void**)&subscriber, hasSubscriber,
|
||||
(void*)¬ification, false);
|
||||
if(subscriber)
|
||||
mLocAdapter->requestSuplES(subscriber->ID);
|
||||
else
|
||||
LOC_LOGE("DSStateMachine :: retryCallback: No subscriber found." \
|
||||
"Cannot retry data call\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int DSStateMachine :: sendRsrcRequest(AGpsStatusValue action) const
|
||||
{
|
||||
DSSubscriber* s = NULL;
|
||||
dsCbData cbData;
|
||||
int ret=-1;
|
||||
int connHandle=-1;
|
||||
LOC_LOGD("Enter DSStateMachine :: sendRsrcRequest\n");
|
||||
Notification notification(Notification::BROADCAST_ACTIVE);
|
||||
linked_list_search(mSubscribers, (void**)&s, hasSubscriber,
|
||||
(void*)¬ification, false);
|
||||
if(s) {
|
||||
connHandle = s->ID;
|
||||
LOC_LOGD("DSStateMachine :: sendRsrcRequest - subscriber found\n");
|
||||
}
|
||||
else
|
||||
LOC_LOGD("DSStateMachine :: sendRsrcRequest - No subscriber found\n");
|
||||
|
||||
cbData.action = action;
|
||||
cbData.mAdapter = mLocAdapter;
|
||||
ret = mServicer->requestRsrc((void *)&cbData);
|
||||
//Only the request to start data call returns a success/failure
|
||||
//The request to stop data call will always succeed
|
||||
//Hence, the below block will only be executed when the
|
||||
//request to start the data call fails
|
||||
switch(ret) {
|
||||
case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
|
||||
LOC_LOGD("DSStateMachine :: sendRsrcRequest - Failure returned: %d\n",ret);
|
||||
((DSStateMachine *)this)->incRetries();
|
||||
if(mRetries > MAX_START_DATA_CALL_RETRIES) {
|
||||
LOC_LOGE(" Failed to start Data call. Fallback to normal ATL SUPL\n");
|
||||
informStatus(RSRC_DENIED, connHandle);
|
||||
}
|
||||
else {
|
||||
if(loc_timer_start(DATA_CALL_RETRY_DELAY_MSEC, delay_callback, (void *)this)) {
|
||||
LOC_LOGE("Error: Could not start delay thread\n");
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LOC_API_ADAPTER_ERR_UNSUPPORTED:
|
||||
LOC_LOGE("No profile found for emergency call. Fallback to normal SUPL ATL\n");
|
||||
informStatus(RSRC_DENIED, connHandle);
|
||||
break;
|
||||
case LOC_API_ADAPTER_ERR_SUCCESS:
|
||||
LOC_LOGD("%s:%d]: Request to start data call sent\n", __func__, __LINE__);
|
||||
break;
|
||||
case -1:
|
||||
//One of the ways this case can be encountered is if the callback function
|
||||
//receives a null argument, it just exits with -1 error
|
||||
LOC_LOGE("Error: Something went wrong somewhere. Falling back to normal SUPL ATL\n");
|
||||
informStatus(RSRC_DENIED, connHandle);
|
||||
break;
|
||||
default:
|
||||
LOC_LOGE("%s:%d]: Unrecognized return value\n", __func__, __LINE__);
|
||||
}
|
||||
err:
|
||||
LOC_LOGD("EXIT DSStateMachine :: sendRsrcRequest; ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DSStateMachine :: onRsrcEvent(AgpsRsrcStatus event)
|
||||
{
|
||||
void* currState = (void *)mStatePtr;
|
||||
LOC_LOGD("Enter DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
|
||||
switch (event)
|
||||
{
|
||||
case RSRC_GRANTED:
|
||||
LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_GRANTED\n");
|
||||
mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
|
||||
break;
|
||||
case RSRC_RELEASED:
|
||||
LOC_LOGD("DSStateMachine :: onRsrcEvent RSRC_RELEASED\n");
|
||||
mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
|
||||
//To handle the case where we get a RSRC_RELEASED in
|
||||
//pending state, we translate that to a RSRC_DENIED state
|
||||
//since the callback from DSI is either RSRC_GRANTED or RSRC_RELEASED
|
||||
//for when the call is connected or disconnected respectively.
|
||||
if((void *)mStatePtr != currState)
|
||||
break;
|
||||
else {
|
||||
event = RSRC_DENIED;
|
||||
LOC_LOGE(" Switching event to RSRC_DENIED\n");
|
||||
}
|
||||
case RSRC_DENIED:
|
||||
mStatePtr = mStatePtr->onRsrcEvent(event, NULL);
|
||||
break;
|
||||
default:
|
||||
LOC_LOGW("AgpsStateMachine: unrecognized event %d", event);
|
||||
break;
|
||||
}
|
||||
LOC_LOGD("Exit DSStateMachine :: onRsrcEvent. event = %d\n", (int)event);
|
||||
}
|
||||
|
||||
void DSStateMachine :: informStatus(AgpsRsrcStatus status, int ID) const
|
||||
{
|
||||
LOC_LOGD("DSStateMachine :: informStatus. Status=%d\n",(int)status);
|
||||
switch(status) {
|
||||
case RSRC_UNSUBSCRIBE:
|
||||
((LocApiAdapter*)mLocAdapter)->atlCloseStatus(ID, 1);
|
||||
break;
|
||||
case RSRC_RELEASED:
|
||||
((LocApiAdapter*)mLocAdapter)->releaseDataHandle();
|
||||
break;
|
||||
case RSRC_DENIED:
|
||||
((DSStateMachine *)this)->mRetries = 0;
|
||||
mLocAdapter->requestATL(ID, AGPS_TYPE_SUPL);
|
||||
break;
|
||||
case RSRC_GRANTED:
|
||||
((LocApiAdapter*)mLocAdapter)->atlOpenStatus(ID, 1,
|
||||
NULL,
|
||||
AGPS_APN_BEARER_INVALID,
|
||||
AGPS_TYPE_INVALID);
|
||||
break;
|
||||
default:
|
||||
LOC_LOGW("DSStateMachine :: informStatus - unknown status");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <linked_list.h>
|
||||
#include <LocApiAdapter.h>
|
||||
#include "loc_eng_msg.h"
|
||||
#include <loc_timer.h>
|
||||
|
||||
// forward declaration
|
||||
class AgpsStateMachine;
|
||||
|
@ -53,6 +54,18 @@ typedef enum {
|
|||
RSRC_STATUS_MAX
|
||||
} AgpsRsrcStatus;
|
||||
|
||||
typedef enum {
|
||||
servicerTypeNoCbParam,
|
||||
servicerTypeAgps,
|
||||
servicerTypeExt
|
||||
}servicerType;
|
||||
|
||||
//DS Callback struct
|
||||
typedef struct {
|
||||
LocApiAdapter *mAdapter;
|
||||
AGpsStatusValue action;
|
||||
}dsCbData;
|
||||
|
||||
// information bundle for subscribers
|
||||
struct Notification {
|
||||
// goes to every subscriber
|
||||
|
@ -101,7 +114,7 @@ class AgpsState {
|
|||
// no class members are public. We don't want
|
||||
// anyone but state machine to use state.
|
||||
friend class AgpsStateMachine;
|
||||
|
||||
friend class DSStateMachine;
|
||||
// state transitions are done here.
|
||||
// Each state implements its own transitions (of course).
|
||||
inline virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data) = 0;
|
||||
|
@ -129,21 +142,56 @@ public:
|
|||
inline virtual char* whoami() = 0;
|
||||
};
|
||||
|
||||
class Servicer {
|
||||
void (*callback)(void);
|
||||
public:
|
||||
static Servicer* getServicer(servicerType type, void *cb_func);
|
||||
virtual int requestRsrc(void *cb_data);
|
||||
Servicer() {}
|
||||
Servicer(void *cb_func)
|
||||
{ callback = (void(*)(void))(cb_func); }
|
||||
virtual ~Servicer(){}
|
||||
inline virtual char *whoami() {return (char*)"Servicer";}
|
||||
};
|
||||
|
||||
class ExtServicer : public Servicer {
|
||||
int (*callbackExt)(void *cb_data);
|
||||
public:
|
||||
int requestRsrc(void *cb_data);
|
||||
ExtServicer() {}
|
||||
ExtServicer(void *cb_func)
|
||||
{ callbackExt = (int(*)(void *))(cb_func); }
|
||||
virtual ~ExtServicer(){}
|
||||
inline virtual char *whoami() {return (char*)"ExtServicer";}
|
||||
};
|
||||
|
||||
class AGpsServicer : public Servicer {
|
||||
void (*callbackAGps)(AGpsStatus* status);
|
||||
public:
|
||||
int requestRsrc(void *cb_data);
|
||||
AGpsServicer() {}
|
||||
AGpsServicer(void *cb_func)
|
||||
{ callbackAGps = (void(*)(AGpsStatus *))(cb_func); }
|
||||
virtual ~AGpsServicer(){}
|
||||
inline virtual char *whoami() {return (char*)"AGpsServicer";}
|
||||
};
|
||||
|
||||
class AgpsStateMachine {
|
||||
protected:
|
||||
// a linked list of subscribers.
|
||||
void* mSubscribers;
|
||||
//handle to whoever provides the service
|
||||
Servicer *mServicer;
|
||||
// allows AgpsState to access private data
|
||||
// each state is really internal data to the
|
||||
// state machine, so it should be able to
|
||||
// access anything within the state machine.
|
||||
friend class AgpsState;
|
||||
|
||||
// handle to whoever provides the service
|
||||
void (* const mServicer)(AGpsStatus* status);
|
||||
// NIF type: AGNSS or INTERNET.
|
||||
const AGpsType mType;
|
||||
// pointer to the current state.
|
||||
AgpsState* mStatePtr;
|
||||
// a linked list of subscribers.
|
||||
void* mSubscribers;
|
||||
private:
|
||||
// NIF type: AGNSS or INTERNET.
|
||||
const AGpsType mType;
|
||||
// apn to the NIF. Each state machine tracks
|
||||
// resource state of a particular NIF. For each
|
||||
// NIF, there is also an active APN.
|
||||
|
@ -158,7 +206,8 @@ class AgpsStateMachine {
|
|||
bool mEnforceSingleSubscriber;
|
||||
|
||||
public:
|
||||
AgpsStateMachine(void (*servicer)(AGpsStatus* status), AGpsType type, bool enforceSingleSubscriber);
|
||||
AgpsStateMachine(servicerType servType, void *cb_func,
|
||||
AGpsType type, bool enforceSingleSubscriber);
|
||||
virtual ~AgpsStateMachine();
|
||||
|
||||
// self explanatory methods below
|
||||
|
@ -179,11 +228,15 @@ public:
|
|||
// add a subscriber in the linked list, if not already there.
|
||||
void addSubscriber(Subscriber* subscriber) const;
|
||||
|
||||
void onRsrcEvent(AgpsRsrcStatus event);
|
||||
virtual void onRsrcEvent(AgpsRsrcStatus event);
|
||||
|
||||
// put the data together and send the FW
|
||||
void sendRsrcRequest(AGpsStatusValue action) const;
|
||||
virtual int sendRsrcRequest(AGpsStatusValue action) const;
|
||||
|
||||
//if list is empty, linked_list_empty returns 1
|
||||
//else if list is not empty, returns 0
|
||||
//so hasSubscribers() returns 1 if list is not empty
|
||||
//and returns 0 if list is empty
|
||||
inline bool hasSubscribers() const
|
||||
{ return !linked_list_empty(mSubscribers); }
|
||||
|
||||
|
@ -194,6 +247,24 @@ public:
|
|||
|
||||
// private. Only a state gets to call this.
|
||||
void notifySubscribers(Notification& notification) const;
|
||||
|
||||
};
|
||||
|
||||
class DSStateMachine : public AgpsStateMachine {
|
||||
static const unsigned char MAX_START_DATA_CALL_RETRIES;
|
||||
static const unsigned int DATA_CALL_RETRY_DELAY_MSEC;
|
||||
LocApiAdapter* mLocAdapter;
|
||||
unsigned char mRetries;
|
||||
public:
|
||||
DSStateMachine(servicerType type,
|
||||
void *cb_func,
|
||||
LocApiAdapter* adapterHandle);
|
||||
int sendRsrcRequest(AGpsStatusValue action) const;
|
||||
void onRsrcEvent(AgpsRsrcStatus event);
|
||||
void retryCallback();
|
||||
void informStatus(AgpsRsrcStatus status, int ID) const;
|
||||
inline void incRetries() {mRetries++;}
|
||||
inline virtual char *whoami() {return (char*)"DSStateMachine";}
|
||||
};
|
||||
|
||||
// each subscriber is a AGPS client. In the case of ATL, there could be
|
||||
|
@ -252,7 +323,7 @@ struct BITSubscriber : public Subscriber {
|
|||
}
|
||||
|
||||
virtual bool equals(const Subscriber *s) const;
|
||||
|
||||
inline virtual ~BITSubscriber(){}
|
||||
private:
|
||||
char ipv6Addr[16];
|
||||
};
|
||||
|
@ -277,6 +348,7 @@ struct ATLSubscriber : public Subscriber {
|
|||
return new ATLSubscriber(ID, mStateMachine, mLocAdapter,
|
||||
mBackwardCompatibleMode);
|
||||
}
|
||||
inline virtual ~ATLSubscriber(){}
|
||||
};
|
||||
|
||||
#ifdef FEATURE_IPV6
|
||||
|
@ -325,7 +397,28 @@ struct WIFISubscriber : public Subscriber {
|
|||
{
|
||||
return new WIFISubscriber(mStateMachine, mSSID, mPassword, senderId);
|
||||
}
|
||||
inline virtual ~WIFISubscriber(){}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct DSSubscriber : public Subscriber {
|
||||
bool mIsInactive;
|
||||
inline DSSubscriber(const AgpsStateMachine *stateMachine,
|
||||
const int id) :
|
||||
Subscriber(id, stateMachine)
|
||||
{
|
||||
mIsInactive = false;
|
||||
}
|
||||
inline virtual void setIPAddresses(uint32_t &v4, char* v6) {}
|
||||
virtual Subscriber* clone()
|
||||
{return new DSSubscriber(mStateMachine, ID);}
|
||||
virtual bool notifyRsrcStatus(Notification ¬ification);
|
||||
inline virtual bool waitForCloseComplete() { return true; }
|
||||
virtual void setInactive();
|
||||
inline virtual bool isInactive()
|
||||
{ return mIsInactive; }
|
||||
inline virtual ~DSSubscriber(){}
|
||||
inline virtual char *whoami() {return (char*)"DSSubscriber";}
|
||||
};
|
||||
|
||||
#endif //__LOC_ENG_AGPS_H__
|
||||
|
|
|
@ -108,7 +108,9 @@ static loc_name_val_s_type loc_eng_msgs[] =
|
|||
NAME_VAL( LOC_ENG_MSG_LPP_CONFIG ),
|
||||
NAME_VAL( ULP_MSG_INJECT_RAW_COMMAND ),
|
||||
NAME_VAL( LOC_ENG_MSG_A_GLONASS_PROTOCOL ),
|
||||
NAME_VAL( LOC_ENG_MSG_LOC_INIT )
|
||||
NAME_VAL( LOC_ENG_MSG_LOC_INIT ),
|
||||
NAME_VAL( LOC_ENG_MSG_REQUEST_SUPL_ES ),
|
||||
NAME_VAL( LOC_ENG_MSG_CLOSE_DATA_CALL)
|
||||
};
|
||||
static int loc_eng_msgs_num = sizeof(loc_eng_msgs) / sizeof(loc_name_val_s_type);
|
||||
|
||||
|
|
|
@ -597,6 +597,23 @@ struct loc_eng_msg_request_atl : public loc_eng_msg {
|
|||
}
|
||||
};
|
||||
|
||||
struct loc_eng_msg_request_supl_es : public loc_eng_msg {
|
||||
const int handle;
|
||||
inline loc_eng_msg_request_supl_es(void* instance, int hndl) :
|
||||
loc_eng_msg(instance, LOC_ENG_MSG_REQUEST_SUPL_ES),
|
||||
handle(hndl)
|
||||
{
|
||||
LOC_LOGV("handle: %d\n", handle);
|
||||
}
|
||||
};
|
||||
|
||||
struct loc_eng_msg_close_data_call: public loc_eng_msg {
|
||||
inline loc_eng_msg_close_data_call(void *instance) :
|
||||
loc_eng_msg(instance, LOC_ENG_MSG_CLOSE_DATA_CALL)
|
||||
{
|
||||
LOC_LOGV("%s:%d]Close data call: ", __func__, __LINE__);
|
||||
}
|
||||
};
|
||||
struct loc_eng_msg_release_atl : public loc_eng_msg {
|
||||
const int handle;
|
||||
inline loc_eng_msg_release_atl(void* instance, int hndl) :
|
||||
|
@ -722,12 +739,12 @@ struct loc_eng_msg_inject_xtra_data : public loc_eng_msg {
|
|||
|
||||
#ifdef FEATURE_IPV6
|
||||
struct loc_eng_msg_atl_open_success : public loc_eng_msg {
|
||||
const AGpsStatusValue agpsType;
|
||||
const AGpsType agpsType;
|
||||
const int length;
|
||||
char* const apn;
|
||||
const AGpsBearerType bearerType;
|
||||
inline loc_eng_msg_atl_open_success(void* instance,
|
||||
AGpsStatusValue atype,
|
||||
AGpsType atype,
|
||||
const char* name,
|
||||
int len,
|
||||
AGpsBearerType btype) :
|
||||
|
@ -794,9 +811,9 @@ struct loc_eng_msg_atl_open_failed : public loc_eng_msg {
|
|||
|
||||
#ifdef FEATURE_IPV6
|
||||
struct loc_eng_msg_atl_closed : public loc_eng_msg {
|
||||
const AGpsStatusValue agpsType;
|
||||
const AGpsType agpsType;
|
||||
inline loc_eng_msg_atl_closed(void* instance,
|
||||
AGpsStatusValue atype) :
|
||||
AGpsType atype) :
|
||||
loc_eng_msg(instance, LOC_ENG_MSG_ATL_CLOSED),
|
||||
agpsType(atype)
|
||||
{
|
||||
|
|
|
@ -134,6 +134,12 @@ enum loc_eng_msg_ids_t {
|
|||
|
||||
//Message is sent by LOC to do LOC INIT
|
||||
LOC_ENG_MSG_LOC_INIT,
|
||||
|
||||
/*Message is sent by modem to request emergency call setup*/
|
||||
LOC_ENG_MSG_REQUEST_SUPL_ES,
|
||||
|
||||
/*Ask the DS client to close the data call by releasing the handle*/
|
||||
LOC_ENG_MSG_CLOSE_DATA_CALL,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -15,7 +15,8 @@ LOCAL_SHARED_LIBRARIES := \
|
|||
libqmi_csi \
|
||||
libqmi_common_so \
|
||||
libloc_adapter \
|
||||
libgps.utils
|
||||
libgps.utils \
|
||||
libds_api
|
||||
|
||||
LOCAL_SRC_FILES += \
|
||||
LocApiV02Adapter.cpp \
|
||||
|
@ -41,7 +42,8 @@ LOCAL_C_INCLUDES := \
|
|||
$(TARGET_OUT_HEADERS)/libloc_eng \
|
||||
$(TARGET_OUT_HEADERS)/qmi-framework/inc \
|
||||
$(TARGET_OUT_HEADERS)/qmi/inc \
|
||||
$(TARGET_OUT_HEADERS)/gps.utils
|
||||
$(TARGET_OUT_HEADERS)/gps.utils \
|
||||
$(TARGET_OUT_HEADERS)/ds_api
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "LocApiAdapter.h"
|
||||
#include "loc_util_log.h"
|
||||
|
||||
|
||||
/* Default session id ; TBD needs incrementing for each */
|
||||
#define LOC_API_V02_DEF_SESSION_ID (1)
|
||||
|
||||
|
@ -160,6 +159,7 @@ locClientCallbacksType globalCallbacks =
|
|||
|
||||
/* Constructor for LocApiV02Adapter */
|
||||
LocApiV02Adapter :: LocApiV02Adapter(LocEng &locEng):
|
||||
dsClientHandle(NULL),
|
||||
LocApiAdapter(locEng), clientHandle( LOC_CLIENT_INVALID_HANDLE_VALUE),
|
||||
eventMask(convertMask(locEng.eventMask))
|
||||
{
|
||||
|
@ -1059,28 +1059,36 @@ enum loc_api_adapter_err LocApiV02Adapter :: atlOpenStatus(
|
|||
{
|
||||
conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_SUCCESS_V02;
|
||||
|
||||
strlcpy(conn_status_req.apnProfile.apnName, apn,
|
||||
sizeof(conn_status_req.apnProfile.apnName) );
|
||||
if(apn != NULL)
|
||||
strlcpy(conn_status_req.apnProfile.apnName, apn,
|
||||
sizeof(conn_status_req.apnProfile.apnName) );
|
||||
|
||||
#ifdef FEATURE_IPV6
|
||||
switch(bear)
|
||||
{
|
||||
case AGPS_APN_BEARER_IPV4:
|
||||
case AGPS_APN_BEARER_IPV4:
|
||||
conn_status_req.apnProfile.pdnType =
|
||||
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4_V02;
|
||||
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4_V02;
|
||||
conn_status_req.apnProfile_valid = 1;
|
||||
break;
|
||||
|
||||
case AGPS_APN_BEARER_IPV6:
|
||||
case AGPS_APN_BEARER_IPV6:
|
||||
conn_status_req.apnProfile.pdnType =
|
||||
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV6_V02;
|
||||
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV6_V02;
|
||||
conn_status_req.apnProfile_valid = 1;
|
||||
break;
|
||||
|
||||
case AGPS_APN_BEARER_IPV4V6:
|
||||
case AGPS_APN_BEARER_IPV4V6:
|
||||
conn_status_req.apnProfile.pdnType =
|
||||
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4V6_V02;
|
||||
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4V6_V02;
|
||||
conn_status_req.apnProfile_valid = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
case AGPS_APN_BEARER_INVALID:
|
||||
conn_status_req.apnProfile_valid = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOC_LOGE("%s:%d]:invalid bearer type\n",__func__,__LINE__);
|
||||
return LOC_API_ADAPTER_ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
@ -1089,7 +1097,6 @@ enum loc_api_adapter_err LocApiV02Adapter :: atlOpenStatus(
|
|||
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4_V02;
|
||||
#endif
|
||||
|
||||
conn_status_req.apnProfile_valid = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1523,7 +1530,6 @@ enum loc_api_adapter_err LocApiV02Adapter :: setAGLONASSProtocol(unsigned long a
|
|||
return LOC_API_ADAPTER_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Convert event mask from loc eng to loc_api_v02 format */
|
||||
locClientEventMaskType LocApiV02Adapter :: convertMask(
|
||||
LOC_API_ADAPTER_EVENT_MASK_T mask)
|
||||
|
@ -1908,39 +1914,42 @@ void LocApiV02Adapter :: reportNmea (
|
|||
|
||||
/* convert and report an ATL request to loc engine */
|
||||
void LocApiV02Adapter :: reportAtlRequest(
|
||||
const qmiLocEventLocationServerConnectionReqIndMsgT_v02 * server_request_ptr)
|
||||
const qmiLocEventLocationServerConnectionReqIndMsgT_v02 * server_request_ptr)
|
||||
{
|
||||
uint32_t connHandle = server_request_ptr->connHandle;
|
||||
// service ATL open request; copy the WWAN type
|
||||
if(server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_OPEN_V02 )
|
||||
{
|
||||
AGpsType agpsType;
|
||||
#ifdef FEATURE_IPV6
|
||||
switch(server_request_ptr->wwanType)
|
||||
uint32_t connHandle = server_request_ptr->connHandle;
|
||||
// service ATL open request; copy the WWAN type
|
||||
if(server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_OPEN_V02 )
|
||||
{
|
||||
case eQMI_LOC_WWAN_TYPE_INTERNET_V02:
|
||||
agpsType = AGPS_TYPE_WWAN_ANY;
|
||||
break;
|
||||
|
||||
case eQMI_LOC_WWAN_TYPE_AGNSS_V02:
|
||||
agpsType = AGPS_TYPE_SUPL;
|
||||
break;
|
||||
|
||||
default:
|
||||
agpsType = AGPS_TYPE_WWAN_ANY;
|
||||
break;
|
||||
}
|
||||
AGpsType agpsType;
|
||||
#ifdef FEATURE_IPV6
|
||||
switch(server_request_ptr->wwanType)
|
||||
{
|
||||
case eQMI_LOC_WWAN_TYPE_INTERNET_V02:
|
||||
agpsType = AGPS_TYPE_WWAN_ANY;
|
||||
LocApiAdapter::requestATL(connHandle, agpsType);
|
||||
break;
|
||||
case eQMI_LOC_WWAN_TYPE_AGNSS_V02:
|
||||
agpsType = AGPS_TYPE_SUPL;
|
||||
LocApiAdapter::requestATL(connHandle, agpsType);
|
||||
break;
|
||||
case eQMI_LOC_WWAN_TYPE_AGNSS_EMERGENCY_V02:
|
||||
LocApiAdapter::requestSuplES(connHandle);
|
||||
break;
|
||||
default:
|
||||
agpsType = AGPS_TYPE_WWAN_ANY;
|
||||
LocApiAdapter::requestATL(connHandle, agpsType);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
agpsType = AGPS_TYPE_SUPL;
|
||||
agpsType = AGPS_TYPE_SUPL;
|
||||
LocApiAdapter::requestATL(connHandle, agpsType);
|
||||
#endif
|
||||
LocApiAdapter::requestATL(connHandle, agpsType);
|
||||
}
|
||||
|
||||
// service the ATL close request
|
||||
else if (server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_CLOSE_V02)
|
||||
{
|
||||
LocApiAdapter::releaseATL(connHandle);
|
||||
}
|
||||
}
|
||||
// service the ATL close request
|
||||
else if (server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_CLOSE_V02)
|
||||
{
|
||||
LocApiAdapter::releaseATL(connHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/* conver the NI report to loc eng format and send t loc engine */
|
||||
|
@ -2255,3 +2264,98 @@ LocApiAdapter* getLocApiAdapter(LocEng &locEng)
|
|||
{
|
||||
return(new LocApiV02Adapter(locEng));
|
||||
}
|
||||
|
||||
static void ds_client_global_event_cb(ds_client_status_enum_type result,
|
||||
void *loc_adapter_cookie)
|
||||
{
|
||||
LocApiV02Adapter *locApiV02AdapterInstance =
|
||||
(LocApiV02Adapter *)loc_adapter_cookie;
|
||||
locApiV02AdapterInstance->ds_client_event_cb(result);
|
||||
return;
|
||||
}
|
||||
|
||||
void LocApiV02Adapter::ds_client_event_cb(ds_client_status_enum_type result)
|
||||
{
|
||||
if(result == E_DS_CLIENT_DATA_CALL_CONNECTED) {
|
||||
LOC_LOGD("%s:%d]: Emergency call is up", __func__, __LINE__);
|
||||
LocApiAdapter::reportDataCallOpened();
|
||||
}
|
||||
else if(result == E_DS_CLIENT_DATA_CALL_DISCONNECTED) {
|
||||
LOC_LOGE("%s:%d]: Emergency call is stopped", __func__, __LINE__);
|
||||
LocApiAdapter::reportDataCallClosed();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ds_client_cb_data ds_client_cb{
|
||||
ds_client_global_event_cb
|
||||
};
|
||||
|
||||
int LocApiV02Adapter :: openAndStartDataCall()
|
||||
{
|
||||
enum loc_api_adapter_err ret;
|
||||
int profile_index;
|
||||
ds_client_status_enum_type result = ds_client_open_call(&dsClientHandle,
|
||||
&ds_client_cb,
|
||||
(void *)this,
|
||||
&profile_index);
|
||||
if(result == E_DS_CLIENT_SUCCESS) {
|
||||
result = ds_client_start_call(dsClientHandle, profile_index);
|
||||
|
||||
if(result == E_DS_CLIENT_SUCCESS) {
|
||||
LOC_LOGD("%s:%d]: Request to start Emergency call sent\n",
|
||||
__func__, __LINE__);
|
||||
ret = LOC_API_ADAPTER_ERR_SUCCESS;
|
||||
}
|
||||
else {
|
||||
LOC_LOGE("%s:%d]: Unable to bring up emergency call using DS. ret = %d",
|
||||
__func__, __LINE__, (int)ret);
|
||||
ret = LOC_API_ADAPTER_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
else if(result == E_DS_CLIENT_RETRY_LATER) {
|
||||
LOC_LOGE("%s:%d]: Could not start emergency call. Retry after delay\n",
|
||||
__func__, __LINE__);
|
||||
ret = LOC_API_ADAPTER_ERR_ENGINE_BUSY;
|
||||
}
|
||||
else {
|
||||
LOC_LOGE("%s:%d]: Unable to bring up emergency call using DS. ret = %d",
|
||||
__func__, __LINE__, (int)ret);
|
||||
ret = LOC_API_ADAPTER_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
void LocApiV02Adapter :: stopDataCall()
|
||||
{
|
||||
ds_client_status_enum_type ret =
|
||||
ds_client_stop_call(dsClientHandle);
|
||||
if (ret == E_DS_CLIENT_SUCCESS) {
|
||||
LOC_LOGD("%s:%d]: Request to Close SUPL ES call sent\n", __func__, __LINE__);
|
||||
}
|
||||
else {
|
||||
if (ret == E_DS_CLIENT_FAILURE_INVALID_HANDLE) {
|
||||
LOC_LOGE("%s:%d]: Conn handle not found for SUPL ES",
|
||||
__func__, __LINE__);
|
||||
}
|
||||
LOC_LOGE("%s:%d]: Could not close SUPL ES call. Ret: %d\n"
|
||||
,__func__, __LINE__, ret);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void LocApiV02Adapter :: closeDataCall()
|
||||
{
|
||||
ds_client_close_call(&dsClientHandle);
|
||||
LOC_LOGD("%s:%d]: Release data client handle\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
int LocApiV02Adapter :: initDataServiceClient()
|
||||
{
|
||||
int ret=0;
|
||||
ret = ds_client_init();
|
||||
LOC_LOGD("%s:%d]: ret = %d\n", __func__, __LINE__,ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "loc_api_v02_client.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "ds_client.h"
|
||||
|
||||
/* This class derives from the LocApiAdapter class.
|
||||
The members of this class are responsible for converting
|
||||
|
@ -40,6 +41,8 @@
|
|||
This class also implements some of the virtual functions that
|
||||
handle the requests from loc engine. */
|
||||
class LocApiV02Adapter : public LocApiAdapter {
|
||||
/*ds client handle*/
|
||||
dsClientHandleType dsClientHandle;
|
||||
|
||||
/* loc api v02 handle*/
|
||||
locClientHandleType clientHandle;
|
||||
|
@ -110,6 +113,12 @@ public:
|
|||
void errorCb(locClientHandleType handle,
|
||||
locClientErrorEnumType errorId);
|
||||
|
||||
void ds_client_event_cb(ds_client_status_enum_type result);
|
||||
int openAndStartDataCall();
|
||||
void stopDataCall();
|
||||
void closeDataCall();
|
||||
int initDataServiceClient();
|
||||
|
||||
virtual enum loc_api_adapter_err reinit();
|
||||
|
||||
virtual enum loc_api_adapter_err startFix();
|
||||
|
|
Loading…
Reference in a new issue