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)
|
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)/loc_api_v02/
|
||||||
|
GPS_DIR_LIST += $(LOCAL_PATH)/ds_api/
|
||||||
endif #is-board-platform-in-list
|
endif #is-board-platform-in-list
|
||||||
|
|
||||||
GPS_DIR_LIST += $(LOCAL_PATH)/libloc_api_50001/
|
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);
|
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)
|
void LocApiAdapter::releaseATL(int connHandle)
|
||||||
{
|
{
|
||||||
loc_eng_msg_release_atl *msg(new loc_eng_msg_release_atl(locEngHandle.owner, 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));
|
loc_eng_msg *msg(new loc_eng_msg(locEngHandle.owner, LOC_ENG_MSG_ENGINE_UP));
|
||||||
locEngHandle.sendMsge(locEngHandle.owner, msg);
|
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 requestNiNotify(GpsNiNotification ¬ify, const void* data);
|
||||||
void handleEngineDownEvent();
|
void handleEngineDownEvent();
|
||||||
void handleEngineUpEvent();
|
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:
|
// All below functions are to be defined by adapter specific modules:
|
||||||
// RPC, QMI, etc. The default implementation is empty.
|
// RPC, QMI, etc. The default implementation is empty.
|
||||||
inline virtual enum loc_api_adapter_err
|
inline virtual enum loc_api_adapter_err
|
||||||
|
@ -230,6 +233,15 @@ public:
|
||||||
|
|
||||||
inline bool isInSession() { return navigating; }
|
inline bool isInSession() { return navigating; }
|
||||||
inline virtual void setInSession(bool inSession) { navigating = inSession; }
|
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);
|
extern "C" LocApiAdapter* getLocApiAdapter(LocEng &locEng);
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
#include <loc_eng_nmea.h>
|
#include <loc_eng_nmea.h>
|
||||||
#include <msg_q.h>
|
#include <msg_q.h>
|
||||||
#include <loc.h>
|
#include <loc.h>
|
||||||
|
|
||||||
#include "log_util.h"
|
#include "log_util.h"
|
||||||
#include "loc_eng_log.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);
|
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
|
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.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,
|
AGPS_TYPE_SUPL,
|
||||||
false);
|
false);
|
||||||
#ifdef FEATURE_IPV6
|
#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,
|
AGPS_TYPE_WWAN_ANY,
|
||||||
false);
|
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,
|
AGPS_TYPE_WIFI,
|
||||||
true);
|
true);
|
||||||
#endif
|
#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,
|
loc_eng_dmn_conn_loc_api_server_launch(callbacks->create_thread_cb,
|
||||||
NULL, NULL, &loc_eng_data);
|
NULL, NULL, &loc_eng_data);
|
||||||
|
@ -1741,14 +1782,27 @@ static void loc_eng_deferred_action_thread(void* arg)
|
||||||
loc_eng_data_p->client_handle,
|
loc_eng_data_p->client_handle,
|
||||||
false);
|
false);
|
||||||
// attempt to unsubscribe from agnss_nif first
|
// 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
|
#ifdef FEATURE_IPV6
|
||||||
|
LOC_LOGD("%s:%d]: Unsubscribed from agnss_nif", __func__, __LINE__);
|
||||||
|
}
|
||||||
|
else {
|
||||||
ATLSubscriber s2(arlMsg->handle,
|
ATLSubscriber s2(arlMsg->handle,
|
||||||
loc_eng_data_p->internet_nif,
|
loc_eng_data_p->internet_nif,
|
||||||
loc_eng_data_p->client_handle,
|
loc_eng_data_p->client_handle,
|
||||||
false);
|
false);
|
||||||
// if unsuccessful, try internet_nif
|
// 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
|
#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;
|
loc_eng_msg_atl_open_success *aosMsg = (loc_eng_msg_atl_open_success*)msg;
|
||||||
AgpsStateMachine* stateMachine;
|
AgpsStateMachine* stateMachine;
|
||||||
#ifdef FEATURE_IPV6
|
#ifdef FEATURE_IPV6
|
||||||
|
LOC_LOGD("%s:%d]: AGPS_TYPE: %d\n", __func__, __LINE__, (int)aosMsg->agpsType);
|
||||||
switch (aosMsg->agpsType) {
|
switch (aosMsg->agpsType) {
|
||||||
case AGPS_TYPE_WIFI: {
|
case AGPS_TYPE_WIFI: {
|
||||||
|
LOC_LOGD("%s:%d]: AGPS Type wifi\n", __func__, __LINE__);
|
||||||
stateMachine = loc_eng_data_p->wifi_nif;
|
stateMachine = loc_eng_data_p->wifi_nif;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AGPS_TYPE_SUPL: {
|
case AGPS_TYPE_SUPL: {
|
||||||
|
LOC_LOGD("%s:%d]: AGPS Type supl\n", __func__, __LINE__);
|
||||||
stateMachine = loc_eng_data_p->agnss_nif;
|
stateMachine = loc_eng_data_p->agnss_nif;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case AGPS_TYPE_INVALID: {
|
||||||
|
stateMachine = loc_eng_data_p->ds_nif;
|
||||||
|
LOC_LOGD("%s:%d]: AGPS Type invalid\n", __func__, __LINE__);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default: {
|
default: {
|
||||||
|
LOC_LOGD("%s:%d]: AGPS Type default internet\n", __func__, __LINE__);
|
||||||
stateMachine = loc_eng_data_p->internet_nif;
|
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;
|
stateMachine = loc_eng_data_p->agnss_nif;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case AGPS_TYPE_INVALID: {
|
||||||
|
stateMachine = loc_eng_data_p->ds_nif;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
stateMachine = loc_eng_data_p->internet_nif;
|
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_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 ",
|
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)
|
if(loc_eng_data_p->ulp_phone_context_req_cb != NULL)
|
||||||
{
|
{
|
||||||
loc_eng_data_p->ulp_phone_context_req_cb((UlpPhoneContextRequest*)&(contextReqMsg->contextRequest));
|
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;
|
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:
|
default:
|
||||||
LOC_LOGE("unsupported msgid = %d\n", msg->msgid);
|
LOC_LOGE("unsupported msgid = %d\n", msg->msgid);
|
||||||
break;
|
break;
|
||||||
|
@ -2273,4 +2359,3 @@ int loc_eng_read_config(void)
|
||||||
EXIT_LOG(%d, 0);
|
EXIT_LOG(%d, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,8 @@ typedef struct
|
||||||
AgpsStateMachine* agnss_nif;
|
AgpsStateMachine* agnss_nif;
|
||||||
AgpsStateMachine* internet_nif;
|
AgpsStateMachine* internet_nif;
|
||||||
AgpsStateMachine* wifi_nif;
|
AgpsStateMachine* wifi_nif;
|
||||||
|
//State machine for Data Services
|
||||||
|
AgpsStateMachine* ds_nif;
|
||||||
|
|
||||||
// GPS engine status
|
// GPS engine status
|
||||||
GpsStatusValue engine_status;
|
GpsStatusValue engine_status;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <log_util.h>
|
#include <log_util.h>
|
||||||
#include <loc_eng_dmn_conn_handler.h>
|
#include <loc_eng_dmn_conn_handler.h>
|
||||||
#include <loc_eng_dmn_conn.h>
|
#include <loc_eng_dmn_conn.h>
|
||||||
|
#include<sys/time.h>
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// C callbacks
|
// C callbacks
|
||||||
|
@ -84,8 +85,8 @@ static bool notifySubscriber(void* fromCaller, void* fromList)
|
||||||
const int Notification::BROADCAST_ALL = 0x80000000;
|
const int Notification::BROADCAST_ALL = 0x80000000;
|
||||||
const int Notification::BROADCAST_ACTIVE = 0x80000001;
|
const int Notification::BROADCAST_ACTIVE = 0x80000001;
|
||||||
const int Notification::BROADCAST_INACTIVE = 0x80000002;
|
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
|
// Subscriber: BITSubscriber / ATLSubscriber / WIFISubscriber
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
@ -227,7 +228,29 @@ bool WIFISubscriber::notifyRsrcStatus(Notification ¬ification)
|
||||||
return notify;
|
return notify;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
// AgpsState: AgpsReleasedState / AgpsPendingState / AgpsAcquiredState
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
@ -249,13 +272,14 @@ public:
|
||||||
|
|
||||||
AgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
AgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||||
{
|
{
|
||||||
|
LOC_LOGD("AgpsReleasedState::onRsrcEvent; event:%d\n", (int)event);
|
||||||
if (mStateMachine->hasSubscribers()) {
|
if (mStateMachine->hasSubscribers()) {
|
||||||
LOC_LOGE("Error: %s subscriber list not empty!!!", whoami());
|
LOC_LOGE("Error: %s subscriber list not empty!!!", whoami());
|
||||||
// I don't know how to recover from it. I am adding this rather
|
// I don't know how to recover from it. I am adding this rather
|
||||||
// for debugging purpose.
|
// for debugging purpose.
|
||||||
}
|
}
|
||||||
|
|
||||||
AgpsState* nextState = this;;
|
AgpsState* nextState = this;
|
||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case RSRC_SUBSCRIBE:
|
case RSRC_SUBSCRIBE:
|
||||||
|
@ -263,11 +287,14 @@ AgpsState* AgpsReleasedState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||||
// no notification until we get RSRC_GRANTED
|
// no notification until we get RSRC_GRANTED
|
||||||
// but we need to add subscriber to the list
|
// but we need to add subscriber to the list
|
||||||
mStateMachine->addSubscriber((Subscriber*)data);
|
mStateMachine->addSubscriber((Subscriber*)data);
|
||||||
|
// request from connecivity service for NIF
|
||||||
|
//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
|
// move the state to PENDING
|
||||||
nextState = mPendingState;
|
nextState = mPendingState;
|
||||||
|
}
|
||||||
// request from connecivity service for NIF
|
|
||||||
mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -313,6 +340,7 @@ public:
|
||||||
AgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
AgpsState* AgpsPendingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||||
{
|
{
|
||||||
AgpsState* nextState = this;;
|
AgpsState* nextState = this;;
|
||||||
|
LOC_LOGD("AgpsPendingState::onRsrcEvent; event:%d\n", (int)event);
|
||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case RSRC_SUBSCRIBE:
|
case RSRC_SUBSCRIBE:
|
||||||
|
@ -408,6 +436,7 @@ public:
|
||||||
AgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
AgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||||
{
|
{
|
||||||
AgpsState* nextState = this;
|
AgpsState* nextState = this;
|
||||||
|
LOC_LOGD("AgpsAcquiredState::onRsrcEvent; event:%d\n", (int)event);
|
||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case RSRC_SUBSCRIBE:
|
case RSRC_SUBSCRIBE:
|
||||||
|
@ -441,7 +470,8 @@ AgpsState* AgpsAcquiredState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||||
|
|
||||||
// tell connecivity service we can release NIF
|
// tell connecivity service we can release NIF
|
||||||
mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
|
mStateMachine->sendRsrcRequest(GPS_RELEASE_AGPS_DATA_CONN);
|
||||||
} else if (!mStateMachine->hasActiveSubscribers()) {
|
}
|
||||||
|
else if (!mStateMachine->hasActiveSubscribers()) {
|
||||||
// only inactive subscribers, move to RELEASING state
|
// only inactive subscribers, move to RELEASING state
|
||||||
nextState = mReleasingState;
|
nextState = mReleasingState;
|
||||||
|
|
||||||
|
@ -500,6 +530,8 @@ public:
|
||||||
AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||||
{
|
{
|
||||||
AgpsState* nextState = this;;
|
AgpsState* nextState = this;;
|
||||||
|
LOC_LOGD("AgpsReleasingState::onRsrcEvent; event:%d\n", (int)event);
|
||||||
|
|
||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case RSRC_SUBSCRIBE:
|
case RSRC_SUBSCRIBE:
|
||||||
|
@ -541,7 +573,7 @@ AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||||
// by setting false, we keep subscribers on the linked list
|
// by setting false, we keep subscribers on the linked list
|
||||||
mStateMachine->notifySubscribers(notification);
|
mStateMachine->notifySubscribers(notification);
|
||||||
|
|
||||||
if (mStateMachine->hasSubscribers()) {
|
if (mStateMachine->hasActiveSubscribers()) {
|
||||||
nextState = mPendingState;
|
nextState = mPendingState;
|
||||||
// request from connecivity service for NIF
|
// request from connecivity service for NIF
|
||||||
mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
|
mStateMachine->sendRsrcRequest(GPS_REQUEST_AGPS_DATA_CONN);
|
||||||
|
@ -561,20 +593,58 @@ AgpsState* AgpsReleasingState::onRsrcEvent(AgpsRsrcStatus event, void* data)
|
||||||
whoami(), nextState->whoami(), event);
|
whoami(), nextState->whoami(), event);
|
||||||
return nextState;
|
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::AgpsStateMachine(void (*servicer)(AGpsStatus* status),
|
AgpsStateMachine::AgpsStateMachine(servicerType servType,
|
||||||
|
void *cb_func,
|
||||||
AGpsType type,
|
AGpsType type,
|
||||||
bool enforceSingleSubscriber) :
|
bool enforceSingleSubscriber) :
|
||||||
mServicer(servicer), mType(type),
|
mStatePtr(new AgpsReleasedState(this)),mType(type),
|
||||||
mStatePtr(new AgpsReleasedState(this)),
|
|
||||||
mAPN(NULL),
|
mAPN(NULL),
|
||||||
mAPNLen(0),
|
mAPNLen(0),
|
||||||
mEnforceSingleSubscriber(enforceSingleSubscriber)
|
mEnforceSingleSubscriber(enforceSingleSubscriber),
|
||||||
|
mServicer(Servicer :: getServicer(servType, (void *)cb_func))
|
||||||
{
|
{
|
||||||
linked_list_init(&mSubscribers);
|
linked_list_init(&mSubscribers);
|
||||||
|
|
||||||
|
@ -615,6 +685,7 @@ AgpsStateMachine::~AgpsStateMachine()
|
||||||
delete releasedState;
|
delete releasedState;
|
||||||
delete pendindState;
|
delete pendindState;
|
||||||
delete releasingState;
|
delete releasingState;
|
||||||
|
delete mServicer;
|
||||||
linked_list_destroy(&mSubscribers);
|
linked_list_destroy(&mSubscribers);
|
||||||
|
|
||||||
if (NULL != mAPN) {
|
if (NULL != mAPN) {
|
||||||
|
@ -669,6 +740,7 @@ void AgpsStateMachine::notifySubscribers(Notification& notification) const
|
||||||
// rest of the list unprocessed. So we need a loop.
|
// rest of the list unprocessed. So we need a loop.
|
||||||
linked_list_search(mSubscribers, (void**)&s, notifySubscriber,
|
linked_list_search(mSubscribers, (void**)&s, notifySubscriber,
|
||||||
(void*)¬ification, true);
|
(void*)¬ification, true);
|
||||||
|
delete s;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no loop needed if it the last param sets to false, which
|
// 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;
|
Subscriber* s = NULL;
|
||||||
Notification notification(Notification::BROADCAST_ACTIVE);
|
Notification notification(Notification::BROADCAST_ACTIVE);
|
||||||
|
@ -722,8 +794,9 @@ void AgpsStateMachine::sendRsrcRequest(AGpsStatusValue action) const
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CALLBACK_LOG_CALLFLOW("agps_cb", %s, loc_get_agps_status_name(action));
|
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)
|
void AgpsStateMachine::subscribeRsrc(Subscriber *subscriber)
|
||||||
|
@ -758,3 +831,163 @@ bool AgpsStateMachine::hasActiveSubscribers() const
|
||||||
hasSubscriber, (void*)¬ification, false);
|
hasSubscriber, (void*)¬ification, false);
|
||||||
return NULL != s;
|
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 <linked_list.h>
|
||||||
#include <LocApiAdapter.h>
|
#include <LocApiAdapter.h>
|
||||||
#include "loc_eng_msg.h"
|
#include "loc_eng_msg.h"
|
||||||
|
#include <loc_timer.h>
|
||||||
|
|
||||||
// forward declaration
|
// forward declaration
|
||||||
class AgpsStateMachine;
|
class AgpsStateMachine;
|
||||||
|
@ -53,6 +54,18 @@ typedef enum {
|
||||||
RSRC_STATUS_MAX
|
RSRC_STATUS_MAX
|
||||||
} AgpsRsrcStatus;
|
} AgpsRsrcStatus;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
servicerTypeNoCbParam,
|
||||||
|
servicerTypeAgps,
|
||||||
|
servicerTypeExt
|
||||||
|
}servicerType;
|
||||||
|
|
||||||
|
//DS Callback struct
|
||||||
|
typedef struct {
|
||||||
|
LocApiAdapter *mAdapter;
|
||||||
|
AGpsStatusValue action;
|
||||||
|
}dsCbData;
|
||||||
|
|
||||||
// information bundle for subscribers
|
// information bundle for subscribers
|
||||||
struct Notification {
|
struct Notification {
|
||||||
// goes to every subscriber
|
// goes to every subscriber
|
||||||
|
@ -101,7 +114,7 @@ class AgpsState {
|
||||||
// no class members are public. We don't want
|
// no class members are public. We don't want
|
||||||
// anyone but state machine to use state.
|
// anyone but state machine to use state.
|
||||||
friend class AgpsStateMachine;
|
friend class AgpsStateMachine;
|
||||||
|
friend class DSStateMachine;
|
||||||
// state transitions are done here.
|
// state transitions are done here.
|
||||||
// Each state implements its own transitions (of course).
|
// Each state implements its own transitions (of course).
|
||||||
inline virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data) = 0;
|
inline virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data) = 0;
|
||||||
|
@ -129,21 +142,56 @@ public:
|
||||||
inline virtual char* whoami() = 0;
|
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 {
|
class AgpsStateMachine {
|
||||||
|
protected:
|
||||||
|
// a linked list of subscribers.
|
||||||
|
void* mSubscribers;
|
||||||
|
//handle to whoever provides the service
|
||||||
|
Servicer *mServicer;
|
||||||
// allows AgpsState to access private data
|
// allows AgpsState to access private data
|
||||||
// each state is really internal data to the
|
// each state is really internal data to the
|
||||||
// state machine, so it should be able to
|
// state machine, so it should be able to
|
||||||
// access anything within the state machine.
|
// access anything within the state machine.
|
||||||
friend class AgpsState;
|
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.
|
// pointer to the current state.
|
||||||
AgpsState* mStatePtr;
|
AgpsState* mStatePtr;
|
||||||
// a linked list of subscribers.
|
private:
|
||||||
void* mSubscribers;
|
// NIF type: AGNSS or INTERNET.
|
||||||
|
const AGpsType mType;
|
||||||
// apn to the NIF. Each state machine tracks
|
// apn to the NIF. Each state machine tracks
|
||||||
// resource state of a particular NIF. For each
|
// resource state of a particular NIF. For each
|
||||||
// NIF, there is also an active APN.
|
// NIF, there is also an active APN.
|
||||||
|
@ -158,7 +206,8 @@ class AgpsStateMachine {
|
||||||
bool mEnforceSingleSubscriber;
|
bool mEnforceSingleSubscriber;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AgpsStateMachine(void (*servicer)(AGpsStatus* status), AGpsType type, bool enforceSingleSubscriber);
|
AgpsStateMachine(servicerType servType, void *cb_func,
|
||||||
|
AGpsType type, bool enforceSingleSubscriber);
|
||||||
virtual ~AgpsStateMachine();
|
virtual ~AgpsStateMachine();
|
||||||
|
|
||||||
// self explanatory methods below
|
// self explanatory methods below
|
||||||
|
@ -179,11 +228,15 @@ public:
|
||||||
// add a subscriber in the linked list, if not already there.
|
// add a subscriber in the linked list, if not already there.
|
||||||
void addSubscriber(Subscriber* subscriber) const;
|
void addSubscriber(Subscriber* subscriber) const;
|
||||||
|
|
||||||
void onRsrcEvent(AgpsRsrcStatus event);
|
virtual void onRsrcEvent(AgpsRsrcStatus event);
|
||||||
|
|
||||||
// put the data together and send the FW
|
// 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
|
inline bool hasSubscribers() const
|
||||||
{ return !linked_list_empty(mSubscribers); }
|
{ return !linked_list_empty(mSubscribers); }
|
||||||
|
|
||||||
|
@ -194,6 +247,24 @@ public:
|
||||||
|
|
||||||
// private. Only a state gets to call this.
|
// private. Only a state gets to call this.
|
||||||
void notifySubscribers(Notification& notification) const;
|
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
|
// 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;
|
virtual bool equals(const Subscriber *s) const;
|
||||||
|
inline virtual ~BITSubscriber(){}
|
||||||
private:
|
private:
|
||||||
char ipv6Addr[16];
|
char ipv6Addr[16];
|
||||||
};
|
};
|
||||||
|
@ -277,6 +348,7 @@ struct ATLSubscriber : public Subscriber {
|
||||||
return new ATLSubscriber(ID, mStateMachine, mLocAdapter,
|
return new ATLSubscriber(ID, mStateMachine, mLocAdapter,
|
||||||
mBackwardCompatibleMode);
|
mBackwardCompatibleMode);
|
||||||
}
|
}
|
||||||
|
inline virtual ~ATLSubscriber(){}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef FEATURE_IPV6
|
#ifdef FEATURE_IPV6
|
||||||
|
@ -325,7 +397,28 @@ struct WIFISubscriber : public Subscriber {
|
||||||
{
|
{
|
||||||
return new WIFISubscriber(mStateMachine, mSSID, mPassword, senderId);
|
return new WIFISubscriber(mStateMachine, mSSID, mPassword, senderId);
|
||||||
}
|
}
|
||||||
|
inline virtual ~WIFISubscriber(){}
|
||||||
};
|
};
|
||||||
#endif
|
#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__
|
#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( LOC_ENG_MSG_LPP_CONFIG ),
|
||||||
NAME_VAL( ULP_MSG_INJECT_RAW_COMMAND ),
|
NAME_VAL( ULP_MSG_INJECT_RAW_COMMAND ),
|
||||||
NAME_VAL( LOC_ENG_MSG_A_GLONASS_PROTOCOL ),
|
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);
|
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 {
|
struct loc_eng_msg_release_atl : public loc_eng_msg {
|
||||||
const int handle;
|
const int handle;
|
||||||
inline loc_eng_msg_release_atl(void* instance, int hndl) :
|
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
|
#ifdef FEATURE_IPV6
|
||||||
struct loc_eng_msg_atl_open_success : public loc_eng_msg {
|
struct loc_eng_msg_atl_open_success : public loc_eng_msg {
|
||||||
const AGpsStatusValue agpsType;
|
const AGpsType agpsType;
|
||||||
const int length;
|
const int length;
|
||||||
char* const apn;
|
char* const apn;
|
||||||
const AGpsBearerType bearerType;
|
const AGpsBearerType bearerType;
|
||||||
inline loc_eng_msg_atl_open_success(void* instance,
|
inline loc_eng_msg_atl_open_success(void* instance,
|
||||||
AGpsStatusValue atype,
|
AGpsType atype,
|
||||||
const char* name,
|
const char* name,
|
||||||
int len,
|
int len,
|
||||||
AGpsBearerType btype) :
|
AGpsBearerType btype) :
|
||||||
|
@ -794,9 +811,9 @@ struct loc_eng_msg_atl_open_failed : public loc_eng_msg {
|
||||||
|
|
||||||
#ifdef FEATURE_IPV6
|
#ifdef FEATURE_IPV6
|
||||||
struct loc_eng_msg_atl_closed : public loc_eng_msg {
|
struct loc_eng_msg_atl_closed : public loc_eng_msg {
|
||||||
const AGpsStatusValue agpsType;
|
const AGpsType agpsType;
|
||||||
inline loc_eng_msg_atl_closed(void* instance,
|
inline loc_eng_msg_atl_closed(void* instance,
|
||||||
AGpsStatusValue atype) :
|
AGpsType atype) :
|
||||||
loc_eng_msg(instance, LOC_ENG_MSG_ATL_CLOSED),
|
loc_eng_msg(instance, LOC_ENG_MSG_ATL_CLOSED),
|
||||||
agpsType(atype)
|
agpsType(atype)
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,6 +134,12 @@ enum loc_eng_msg_ids_t {
|
||||||
|
|
||||||
//Message is sent by LOC to do LOC INIT
|
//Message is sent by LOC to do LOC INIT
|
||||||
LOC_ENG_MSG_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
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -15,7 +15,8 @@ LOCAL_SHARED_LIBRARIES := \
|
||||||
libqmi_csi \
|
libqmi_csi \
|
||||||
libqmi_common_so \
|
libqmi_common_so \
|
||||||
libloc_adapter \
|
libloc_adapter \
|
||||||
libgps.utils
|
libgps.utils \
|
||||||
|
libds_api
|
||||||
|
|
||||||
LOCAL_SRC_FILES += \
|
LOCAL_SRC_FILES += \
|
||||||
LocApiV02Adapter.cpp \
|
LocApiV02Adapter.cpp \
|
||||||
|
@ -41,7 +42,8 @@ LOCAL_C_INCLUDES := \
|
||||||
$(TARGET_OUT_HEADERS)/libloc_eng \
|
$(TARGET_OUT_HEADERS)/libloc_eng \
|
||||||
$(TARGET_OUT_HEADERS)/qmi-framework/inc \
|
$(TARGET_OUT_HEADERS)/qmi-framework/inc \
|
||||||
$(TARGET_OUT_HEADERS)/qmi/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
|
LOCAL_PRELINK_MODULE := false
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
#include "LocApiAdapter.h"
|
#include "LocApiAdapter.h"
|
||||||
#include "loc_util_log.h"
|
#include "loc_util_log.h"
|
||||||
|
|
||||||
|
|
||||||
/* Default session id ; TBD needs incrementing for each */
|
/* Default session id ; TBD needs incrementing for each */
|
||||||
#define LOC_API_V02_DEF_SESSION_ID (1)
|
#define LOC_API_V02_DEF_SESSION_ID (1)
|
||||||
|
|
||||||
|
@ -160,6 +159,7 @@ locClientCallbacksType globalCallbacks =
|
||||||
|
|
||||||
/* Constructor for LocApiV02Adapter */
|
/* Constructor for LocApiV02Adapter */
|
||||||
LocApiV02Adapter :: LocApiV02Adapter(LocEng &locEng):
|
LocApiV02Adapter :: LocApiV02Adapter(LocEng &locEng):
|
||||||
|
dsClientHandle(NULL),
|
||||||
LocApiAdapter(locEng), clientHandle( LOC_CLIENT_INVALID_HANDLE_VALUE),
|
LocApiAdapter(locEng), clientHandle( LOC_CLIENT_INVALID_HANDLE_VALUE),
|
||||||
eventMask(convertMask(locEng.eventMask))
|
eventMask(convertMask(locEng.eventMask))
|
||||||
{
|
{
|
||||||
|
@ -1059,6 +1059,7 @@ enum loc_api_adapter_err LocApiV02Adapter :: atlOpenStatus(
|
||||||
{
|
{
|
||||||
conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_SUCCESS_V02;
|
conn_status_req.statusType = eQMI_LOC_SERVER_REQ_STATUS_SUCCESS_V02;
|
||||||
|
|
||||||
|
if(apn != NULL)
|
||||||
strlcpy(conn_status_req.apnProfile.apnName, apn,
|
strlcpy(conn_status_req.apnProfile.apnName, apn,
|
||||||
sizeof(conn_status_req.apnProfile.apnName) );
|
sizeof(conn_status_req.apnProfile.apnName) );
|
||||||
|
|
||||||
|
@ -1068,16 +1069,23 @@ enum loc_api_adapter_err LocApiV02Adapter :: atlOpenStatus(
|
||||||
case AGPS_APN_BEARER_IPV4:
|
case AGPS_APN_BEARER_IPV4:
|
||||||
conn_status_req.apnProfile.pdnType =
|
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;
|
break;
|
||||||
|
|
||||||
case AGPS_APN_BEARER_IPV6:
|
case AGPS_APN_BEARER_IPV6:
|
||||||
conn_status_req.apnProfile.pdnType =
|
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;
|
break;
|
||||||
|
|
||||||
case AGPS_APN_BEARER_IPV4V6:
|
case AGPS_APN_BEARER_IPV4V6:
|
||||||
conn_status_req.apnProfile.pdnType =
|
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;
|
||||||
|
|
||||||
|
case AGPS_APN_BEARER_INVALID:
|
||||||
|
conn_status_req.apnProfile_valid = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1089,7 +1097,6 @@ enum loc_api_adapter_err LocApiV02Adapter :: atlOpenStatus(
|
||||||
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4_V02;
|
eQMI_LOC_APN_PROFILE_PDN_TYPE_IPV4_V02;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
conn_status_req.apnProfile_valid = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1523,7 +1530,6 @@ enum loc_api_adapter_err LocApiV02Adapter :: setAGLONASSProtocol(unsigned long a
|
||||||
return LOC_API_ADAPTER_ERR_SUCCESS;
|
return LOC_API_ADAPTER_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Convert event mask from loc eng to loc_api_v02 format */
|
/* Convert event mask from loc eng to loc_api_v02 format */
|
||||||
locClientEventMaskType LocApiV02Adapter :: convertMask(
|
locClientEventMaskType LocApiV02Adapter :: convertMask(
|
||||||
LOC_API_ADAPTER_EVENT_MASK_T mask)
|
LOC_API_ADAPTER_EVENT_MASK_T mask)
|
||||||
|
@ -1920,22 +1926,25 @@ void LocApiV02Adapter :: reportAtlRequest(
|
||||||
{
|
{
|
||||||
case eQMI_LOC_WWAN_TYPE_INTERNET_V02:
|
case eQMI_LOC_WWAN_TYPE_INTERNET_V02:
|
||||||
agpsType = AGPS_TYPE_WWAN_ANY;
|
agpsType = AGPS_TYPE_WWAN_ANY;
|
||||||
|
LocApiAdapter::requestATL(connHandle, agpsType);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case eQMI_LOC_WWAN_TYPE_AGNSS_V02:
|
case eQMI_LOC_WWAN_TYPE_AGNSS_V02:
|
||||||
agpsType = AGPS_TYPE_SUPL;
|
agpsType = AGPS_TYPE_SUPL;
|
||||||
|
LocApiAdapter::requestATL(connHandle, agpsType);
|
||||||
|
break;
|
||||||
|
case eQMI_LOC_WWAN_TYPE_AGNSS_EMERGENCY_V02:
|
||||||
|
LocApiAdapter::requestSuplES(connHandle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
agpsType = AGPS_TYPE_WWAN_ANY;
|
agpsType = AGPS_TYPE_WWAN_ANY;
|
||||||
|
LocApiAdapter::requestATL(connHandle, agpsType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
agpsType = AGPS_TYPE_SUPL;
|
agpsType = AGPS_TYPE_SUPL;
|
||||||
#endif
|
|
||||||
LocApiAdapter::requestATL(connHandle, agpsType);
|
LocApiAdapter::requestATL(connHandle, agpsType);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// service the ATL close request
|
// service the ATL close request
|
||||||
else if (server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_CLOSE_V02)
|
else if (server_request_ptr->requestType == eQMI_LOC_SERVER_REQUEST_CLOSE_V02)
|
||||||
{
|
{
|
||||||
|
@ -2255,3 +2264,98 @@ LocApiAdapter* getLocApiAdapter(LocEng &locEng)
|
||||||
{
|
{
|
||||||
return(new LocApiV02Adapter(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 "loc_api_v02_client.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "ds_client.h"
|
||||||
|
|
||||||
/* This class derives from the LocApiAdapter class.
|
/* This class derives from the LocApiAdapter class.
|
||||||
The members of this class are responsible for converting
|
The members of this class are responsible for converting
|
||||||
|
@ -40,6 +41,8 @@
|
||||||
This class also implements some of the virtual functions that
|
This class also implements some of the virtual functions that
|
||||||
handle the requests from loc engine. */
|
handle the requests from loc engine. */
|
||||||
class LocApiV02Adapter : public LocApiAdapter {
|
class LocApiV02Adapter : public LocApiAdapter {
|
||||||
|
/*ds client handle*/
|
||||||
|
dsClientHandleType dsClientHandle;
|
||||||
|
|
||||||
/* loc api v02 handle*/
|
/* loc api v02 handle*/
|
||||||
locClientHandleType clientHandle;
|
locClientHandleType clientHandle;
|
||||||
|
@ -110,6 +113,12 @@ public:
|
||||||
void errorCb(locClientHandleType handle,
|
void errorCb(locClientHandleType handle,
|
||||||
locClientErrorEnumType errorId);
|
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 reinit();
|
||||||
|
|
||||||
virtual enum loc_api_adapter_err startFix();
|
virtual enum loc_api_adapter_err startFix();
|
||||||
|
|
Loading…
Reference in a new issue