aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaghuram Subramani <raghus2247@gmail.com>2024-10-14 20:38:19 +0530
committerRaghuram Subramani <raghus2247@gmail.com>2024-10-14 20:38:19 +0530
commit86a968c3f424cb70e03cccb24cabf9751f6f636d (patch)
tree5aedd15a754e4c0de8a015a4fd2c2e5c0698a22b
parentea30e6e77df9c7a651f22bcc5797b8a3f33703dc (diff)
update gps stack
-rw-r--r--BoardConfigCommon.mk5
-rw-r--r--gps/Android.mk1
-rw-r--r--gps/CleanSpec.mk50
-rw-r--r--gps/Makefile.am10
-rw-r--r--gps/android/1.0/AGnss.cpp (renamed from gps/android/AGnss.cpp)2
-rw-r--r--gps/android/1.0/AGnss.h (renamed from gps/android/AGnss.h)0
-rw-r--r--gps/android/1.0/AGnssRil.cpp (renamed from gps/android/AGnssRil.cpp)25
-rw-r--r--gps/android/1.0/AGnssRil.h (renamed from gps/android/AGnssRil.h)0
-rw-r--r--gps/android/1.0/Android.mk99
-rw-r--r--gps/android/1.0/Gnss.cpp (renamed from gps/android/Gnss.cpp)27
-rw-r--r--gps/android/1.0/Gnss.h (renamed from gps/android/Gnss.h)6
-rw-r--r--gps/android/1.0/GnssBatching.cpp (renamed from gps/android/GnssBatching.cpp)0
-rw-r--r--gps/android/1.0/GnssBatching.h (renamed from gps/android/GnssBatching.h)0
-rw-r--r--gps/android/1.0/GnssConfiguration.cpp (renamed from gps/android/GnssConfiguration.cpp)3
-rw-r--r--gps/android/1.0/GnssConfiguration.h (renamed from gps/android/GnssConfiguration.h)0
-rw-r--r--gps/android/1.0/GnssDebug.cpp (renamed from gps/android/GnssDebug.cpp)17
-rw-r--r--gps/android/1.0/GnssDebug.h (renamed from gps/android/GnssDebug.h)0
-rw-r--r--gps/android/1.0/GnssGeofencing.cpp (renamed from gps/android/GnssGeofencing.cpp)0
-rw-r--r--gps/android/1.0/GnssGeofencing.h (renamed from gps/android/GnssGeofencing.h)0
-rw-r--r--gps/android/1.0/GnssMeasurement.cpp (renamed from gps/android/GnssMeasurement.cpp)0
-rw-r--r--gps/android/1.0/GnssMeasurement.h (renamed from gps/android/GnssMeasurement.h)0
-rw-r--r--gps/android/1.0/GnssNi.cpp (renamed from gps/android/GnssNi.cpp)0
-rw-r--r--gps/android/1.0/GnssNi.h (renamed from gps/android/GnssNi.h)0
-rw-r--r--gps/android/1.0/android.hardware.gnss@1.0-service-qti.rc (renamed from gps/android/android.hardware.gnss@1.0-service-qti.rc)2
-rw-r--r--gps/android/1.0/android.hardware.gnss@1.0-service-qti.xml35
-rw-r--r--gps/android/1.0/location_api/BatchingAPIClient.cpp (renamed from gps/android/location_api/BatchingAPIClient.cpp)0
-rw-r--r--gps/android/1.0/location_api/BatchingAPIClient.h (renamed from gps/android/location_api/BatchingAPIClient.h)0
-rw-r--r--gps/android/1.0/location_api/GeofenceAPIClient.cpp (renamed from gps/android/location_api/GeofenceAPIClient.cpp)0
-rw-r--r--gps/android/1.0/location_api/GeofenceAPIClient.h (renamed from gps/android/location_api/GeofenceAPIClient.h)0
-rw-r--r--gps/android/1.0/location_api/GnssAPIClient.cpp (renamed from gps/android/location_api/GnssAPIClient.cpp)107
-rw-r--r--gps/android/1.0/location_api/GnssAPIClient.h (renamed from gps/android/location_api/GnssAPIClient.h)7
-rw-r--r--gps/android/1.0/location_api/LocationUtil.cpp (renamed from gps/android/location_api/LocationUtil.cpp)86
-rw-r--r--gps/android/1.0/location_api/LocationUtil.h (renamed from gps/android/location_api/LocationUtil.h)0
-rw-r--r--gps/android/1.0/location_api/MeasurementAPIClient.cpp (renamed from gps/android/location_api/MeasurementAPIClient.cpp)9
-rw-r--r--gps/android/1.0/location_api/MeasurementAPIClient.h (renamed from gps/android/location_api/MeasurementAPIClient.h)1
-rw-r--r--gps/android/1.0/service.cpp85
-rw-r--r--gps/android/1.1/AGnss.cpp203
-rw-r--r--gps/android/1.1/AGnss.h79
-rw-r--r--gps/android/1.1/AGnssRil.cpp114
-rw-r--r--gps/android/1.1/AGnssRil.h83
-rw-r--r--gps/android/1.1/Android.mk101
-rw-r--r--gps/android/1.1/Gnss.cpp477
-rw-r--r--gps/android/1.1/Gnss.h154
-rw-r--r--gps/android/1.1/GnssBatching.cpp130
-rw-r--r--gps/android/1.1/GnssBatching.h80
-rw-r--r--gps/android/1.1/GnssConfiguration.cpp313
-rw-r--r--gps/android/1.1/GnssConfiguration.h78
-rw-r--r--gps/android/1.1/GnssDebug.cpp175
-rw-r--r--gps/android/1.1/GnssDebug.h59
-rw-r--r--gps/android/1.1/GnssGeofencing.cpp141
-rw-r--r--gps/android/1.1/GnssGeofencing.h91
-rw-r--r--gps/android/1.1/GnssMeasurement.cpp134
-rw-r--r--gps/android/1.1/GnssMeasurement.h83
-rw-r--r--gps/android/1.1/GnssNi.cpp85
-rw-r--r--gps/android/1.1/GnssNi.h75
-rw-r--r--gps/android/1.1/android.hardware.gnss@1.1-service-qti.rc4
-rw-r--r--gps/android/1.1/android.hardware.gnss@1.1-service-qti.xml35
-rw-r--r--gps/android/1.1/location_api/BatchingAPIClient.cpp196
-rw-r--r--gps/android/1.1/location_api/BatchingAPIClient.h74
-rw-r--r--gps/android/1.1/location_api/GeofenceAPIClient.cpp275
-rw-r--r--gps/android/1.1/location_api/GeofenceAPIClient.h76
-rw-r--r--gps/android/1.1/location_api/GnssAPIClient.cpp566
-rw-r--r--gps/android/1.1/location_api/GnssAPIClient.h109
-rw-r--r--gps/android/1.1/location_api/LocationUtil.cpp206
-rw-r--r--gps/android/1.1/location_api/LocationUtil.h55
-rw-r--r--gps/android/1.1/location_api/MeasurementAPIClient.cpp332
-rw-r--r--gps/android/1.1/location_api/MeasurementAPIClient.h84
-rw-r--r--gps/android/1.1/service.cpp85
-rw-r--r--gps/android/2.0/AGnss.cpp209
-rw-r--r--gps/android/2.0/AGnss.h77
-rw-r--r--gps/android/2.0/AGnssRil.cpp133
-rw-r--r--gps/android/2.0/AGnssRil.h84
-rw-r--r--gps/android/2.0/Android.mk112
-rw-r--r--gps/android/2.0/Gnss.cpp671
-rw-r--r--gps/android/2.0/Gnss.h187
-rw-r--r--gps/android/2.0/GnssBatching.cpp163
-rw-r--r--gps/android/2.0/GnssBatching.h84
-rw-r--r--gps/android/2.0/GnssConfiguration.cpp321
-rw-r--r--gps/android/2.0/GnssConfiguration.h80
-rw-r--r--gps/android/2.0/GnssDebug.cpp299
-rw-r--r--gps/android/2.0/GnssDebug.h62
-rw-r--r--gps/android/2.0/GnssGeofencing.cpp141
-rw-r--r--gps/android/2.0/GnssGeofencing.h91
-rw-r--r--gps/android/2.0/GnssMeasurement.cpp165
-rw-r--r--gps/android/2.0/GnssMeasurement.h86
-rw-r--r--gps/android/2.0/GnssNi.cpp85
-rw-r--r--gps/android/2.0/GnssNi.h75
-rw-r--r--gps/android/2.0/android.hardware.gnss@2.0-service-qti.rc4
-rw-r--r--gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml36
-rw-r--r--gps/android/2.0/location_api/BatchingAPIClient.cpp250
-rw-r--r--gps/android/2.0/location_api/BatchingAPIClient.h81
-rw-r--r--gps/android/2.0/location_api/GeofenceAPIClient.cpp275
-rw-r--r--gps/android/2.0/location_api/GeofenceAPIClient.h76
-rw-r--r--gps/android/2.0/location_api/GnssAPIClient.cpp728
-rw-r--r--gps/android/2.0/location_api/GnssAPIClient.h114
-rw-r--r--gps/android/2.0/location_api/LocationUtil.cpp311
-rw-r--r--gps/android/2.0/location_api/LocationUtil.h58
-rw-r--r--gps/android/2.0/location_api/MeasurementAPIClient.cpp474
-rw-r--r--gps/android/2.0/location_api/MeasurementAPIClient.h89
-rw-r--r--gps/android/2.0/service.cpp85
-rw-r--r--gps/android/Android.mk98
-rw-r--r--gps/android/measurement_corrections/1.0/MeasurementCorrections.cpp71
-rw-r--r--gps/android/measurement_corrections/1.0/MeasurementCorrections.h76
-rw-r--r--gps/android/utils/Android.mk38
-rw-r--r--gps/android/utils/battery_listener.cpp273
-rw-r--r--gps/android/utils/battery_listener.h32
-rw-r--r--gps/android/visibility_control/1.0/GnssVisibilityControl.cpp169
-rw-r--r--gps/android/visibility_control/1.0/GnssVisibilityControl.h90
-rw-r--r--gps/batching/Android.mk39
-rw-r--r--gps/batching/BatchingAdapter.cpp1050
-rw-r--r--gps/batching/BatchingAdapter.h152
-rw-r--r--gps/batching/location_batching.cpp134
-rw-r--r--gps/build/target_specific_features.mk72
-rw-r--r--gps/configure.ac87
-rw-r--r--gps/core/Android.mk11
-rw-r--r--gps/core/ContextBase.cpp236
-rw-r--r--gps/core/ContextBase.h142
-rw-r--r--gps/core/EngineHubProxyBase.h127
-rw-r--r--gps/core/LBSProxyBase.h12
-rw-r--r--gps/core/LocAdapterBase.cpp283
-rw-r--r--gps/core/LocAdapterBase.h119
-rw-r--r--gps/core/LocAdapterProxyBase.h5
-rw-r--r--gps/core/LocApiBase.cpp583
-rw-r--r--gps/core/LocApiBase.h323
-rw-r--r--gps/core/LocContext.cpp98
-rw-r--r--gps/core/LocContext.h (renamed from gps/core/LocDualContext.h)32
-rw-r--r--gps/core/LocDualContext.cpp150
-rw-r--r--gps/core/Makefile.am66
-rw-r--r--gps/core/SystemStatus.cpp77
-rw-r--r--gps/core/SystemStatus.h149
-rw-r--r--gps/core/SystemStatusOsObserver.cpp20
-rw-r--r--gps/core/UlpProxyBase.h124
-rw-r--r--gps/core/configure.ac82
-rw-r--r--gps/core/data-items/DataItemConcreteTypesBase.h88
-rw-r--r--gps/core/loc-core.pc.in10
-rw-r--r--gps/core/loc_core_log.cpp7
-rw-r--r--gps/core/observer/IOsObserver.h4
-rw-r--r--gps/etc/flp.conf60
-rw-r--r--gps/etc/gps.conf306
-rw-r--r--gps/etc/izat.conf247
-rw-r--r--gps/etc/lowi.conf27
-rw-r--r--gps/etc/sap.conf161
-rw-r--r--gps/etc/xtwifi.conf78
-rw-r--r--gps/geofence/Android.mk38
-rw-r--r--gps/geofence/GeofenceAdapter.cpp870
-rw-r--r--gps/geofence/GeofenceAdapter.h136
-rw-r--r--gps/geofence/location_geofence.cpp145
-rw-r--r--gps/gnss/Agps.cpp337
-rw-r--r--gps/gnss/Agps.h133
-rw-r--r--gps/gnss/Android.mk3
-rw-r--r--gps/gnss/GnssAdapter.cpp3852
-rw-r--r--gps/gnss/GnssAdapter.h298
-rw-r--r--gps/gnss/Makefile.am31
-rw-r--r--gps/gnss/XtraSystemStatusObserver.cpp164
-rw-r--r--gps/gnss/XtraSystemStatusObserver.h39
-rw-r--r--gps/gnss/location_gnss.cpp135
-rw-r--r--gps/gnsspps/Android.mk3
-rw-r--r--gps/gnsspps/Makefile.am37
-rw-r--r--gps/gnsspps/configure.ac70
-rw-r--r--gps/gnsspps/gnsspps.c231
-rw-r--r--gps/gnsspps/gnsspps.pc.in10
-rw-r--r--gps/loc-hal.pc.in10
-rw-r--r--gps/location/Android.mk3
-rw-r--r--gps/location/ILocationAPI.h194
-rw-r--r--gps/location/LocationAPI.cpp326
-rw-r--r--gps/location/LocationAPI.h816
-rw-r--r--gps/location/LocationAPIClientBase.cpp122
-rw-r--r--gps/location/LocationAPIClientBase.h47
-rw-r--r--gps/location/LocationDataTypes.h1465
-rw-r--r--gps/location/Makefile.am38
-rw-r--r--gps/location/configure.ac82
-rw-r--r--gps/location/location-api.pc.in10
-rw-r--r--gps/location/location_interface.h54
-rw-r--r--gps/pla/Android.mk15
-rw-r--r--gps/pla/android/loc_pla.h8
-rw-r--r--gps/pla/oe/loc_pla.h35
-rw-r--r--gps/utils/Android.mk4
-rw-r--r--gps/utils/LocIpc.cpp481
-rw-r--r--gps/utils/LocIpc.h209
-rw-r--r--gps/utils/LocSharedLock.h20
-rw-r--r--gps/utils/LocThread.cpp4
-rw-r--r--gps/utils/Makefile.am70
-rw-r--r--gps/utils/MsgTask.cpp7
-rw-r--r--gps/utils/configure.ac82
-rw-r--r--gps/utils/gps-utils.pc.in10
-rw-r--r--gps/utils/gps_extended.h14
-rw-r--r--gps/utils/gps_extended_c.h1362
-rw-r--r--gps/utils/linked_list.h2
-rw-r--r--gps/utils/loc_cfg.cpp317
-rw-r--r--gps/utils/loc_cfg.h23
-rw-r--r--gps/utils/loc_gps.h22
-rw-r--r--gps/utils/loc_misc_utils.cpp31
-rw-r--r--gps/utils/loc_misc_utils.h28
-rw-r--r--gps/utils/loc_nmea.cpp1347
-rw-r--r--gps/utils/loc_nmea.h39
-rw-r--r--gps/utils/loc_target.cpp57
-rw-r--r--gps/utils/loc_target.h4
-rw-r--r--gps/utils/log_util.h33
-rw-r--r--gps/utils/msg_q.c45
-rw-r--r--gps/utils/msg_q.h23
-rw-r--r--manifest.xml18
-rwxr-xr-xmsm8996.mk14
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/Android.bp182
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/THREADING.README35
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy-lazy.rc14
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy.rc12
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy.xml11
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioHardwareBase.h66
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioHardwareInterface.h296
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioPolicyInterface.h249
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioPolicyManagerBase.h567
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioSystemLegacy.h358
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/IMountService.h65
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/audio_policy_conf.h54
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/gscan.h427
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/link_layer_stats.h285
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/power.h40
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/roam.h57
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/rtt.h314
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/tdls.h84
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/uevent.h35
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_cached_scan_results.h92
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_config.h44
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_hal.h1020
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_logger.h650
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_nan.h2726
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_offload.h30
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_twt.h156
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hidl_callback_util.h122
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hidl_return_util.h118
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hidl_struct_util.cpp3007
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hidl_struct_util.h204
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hidl_sync_util.cpp39
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/hidl_sync_util.h37
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/ringbuffer.cpp64
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/ringbuffer.h62
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/service.cpp71
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi.cpp294
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi.h105
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_ap_iface.cpp204
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_ap_iface.h89
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_chip.cpp2109
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_chip.h322
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_feature_flags.cpp247
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_feature_flags.h58
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_iface_util.cpp176
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_iface_util.h87
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal.cpp1654
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal.h739
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_factory.cpp254
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_factory.h66
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_stubs.cpp178
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_stubs.h (renamed from gps/android/service.cpp)30
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_mode_controller.cpp89
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_mode_controller.h63
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_nan_iface.cpp1018
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_nan_iface.h208
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_p2p_iface.cpp69
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_p2p_iface.h66
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_rtt_controller.cpp377
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_rtt_controller.h138
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_sta_iface.cpp592
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_sta_iface.h157
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_status_util.cpp106
-rw-r--r--wifi/wifi_legacy_service/1.0-legacy/wifi_status_util.h44
265 files changed, 47003 insertions, 5195 deletions
diff --git a/BoardConfigCommon.mk b/BoardConfigCommon.mk
index d027ba1..4b6aaee 100644
--- a/BoardConfigCommon.mk
+++ b/BoardConfigCommon.mk
@@ -103,9 +103,8 @@ EXCLUDE_SERIF_FONTS := true
TARGET_FS_CONFIG_GEN := $(VENDOR_PATH)/config.fs
# GPS
-BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE := msm8996
-BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET := true
-DEVICE_SPECIFIC_GPS_PATH := $(VENDOR_PATH)/gps
+BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE := default
+LOC_HIDL_VERSION := 3.0
# HIDL
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE := \
diff --git a/gps/Android.mk b/gps/Android.mk
index 23b2a66..f1088a4 100644
--- a/gps/Android.mk
+++ b/gps/Android.mk
@@ -1,6 +1,5 @@
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
LOCAL_PATH := $(call my-dir)
include $(LOCAL_PATH)/build/target_specific_features.mk
-
include $(call all-makefiles-under,$(LOCAL_PATH))
endif
diff --git a/gps/CleanSpec.mk b/gps/CleanSpec.mk
deleted file mode 100644
index dd1849d..0000000
--- a/gps/CleanSpec.mk
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# If you don't need to do a full clean build but would like to touch
-# a file or delete some intermediate files, add a clean step to the end
-# of the list. These steps will only be run once, if they haven't been
-# run before.
-#
-# E.g.:
-# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
-# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
-#
-# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
-# files that are missing or have been moved.
-#
-# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
-# Use $(OUT_DIR) to refer to the "out" directory.
-#
-# If you need to re-do something that's already mentioned, just copy
-# the command and add it to the bottom of the list. E.g., if a change
-# that you made last week required touching a file and a change you
-# made today requires touching the same file, just copy the old
-# touch step and add it to the end of the list.
-#
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
-
-# For example:
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
-#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
-#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
-
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
-$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libloc_api*)
diff --git a/gps/Makefile.am b/gps/Makefile.am
deleted file mode 100644
index cd4a731..0000000
--- a/gps/Makefile.am
+++ /dev/null
@@ -1,10 +0,0 @@
-# Makefile.am - Automake script for gps loc_api
-#
-
-ACLOCAL_AMFLAGS = -I m4
-
-SUBDIRS = gnss
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = loc-hal.pc
-EXTRA_DIST = $(pkgconfig_DATA)
diff --git a/gps/android/AGnss.cpp b/gps/android/1.0/AGnss.cpp
index faaf75e..79f665c 100644
--- a/gps/android/AGnss.cpp
+++ b/gps/android/1.0/AGnss.cpp
@@ -105,7 +105,7 @@ Return<void> AGnss::setCallback(const sp<IAGnssCallback>& callback) {
AgpsCbInfo cbInfo = {};
cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
- cbInfo.cbPriority = AGPS_CB_PRIORITY_LOW;
+ cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES;
mGnss->getGnssInterface()->agpsInit(cbInfo);
return Void();
diff --git a/gps/android/AGnss.h b/gps/android/1.0/AGnss.h
index cdd5931..cdd5931 100644
--- a/gps/android/AGnss.h
+++ b/gps/android/1.0/AGnss.h
diff --git a/gps/android/AGnssRil.cpp b/gps/android/1.0/AGnssRil.cpp
index f4b9849..0437cf1 100644
--- a/gps/android/AGnssRil.cpp
+++ b/gps/android/1.0/AGnssRil.cpp
@@ -50,6 +50,10 @@ AGnssRil::~AGnssRil() {
Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool /*roaming*/) {
ENTRY_LOG_CALLFLOW();
+ // Extra NetworkTypes not available in IAgnssRil enums
+ const int NetworkType_BLUETOOTH = 7;
+ const int NetworkType_ETHERNET = 9;
+ const int NetworkType_PROXY = 16;
// for XTRA
if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
@@ -78,10 +82,27 @@ Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool
typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
break;
default:
- typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ {
+ int networkType = (int) type;
+ // Handling network types not available in IAgnssRil
+ switch(networkType)
+ {
+ case NetworkType_BLUETOOTH:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_BLUETOOTH;
+ break;
+ case NetworkType_ETHERNET:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_ETHERNET;
+ break;
+ case NetworkType_PROXY:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_PROXY;
+ break;
+ default:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ }
+ }
break;
}
- mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout);
+ mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
}
return true;
}
diff --git a/gps/android/AGnssRil.h b/gps/android/1.0/AGnssRil.h
index 7f18c57..7f18c57 100644
--- a/gps/android/AGnssRil.h
+++ b/gps/android/1.0/AGnssRil.h
diff --git a/gps/android/1.0/Android.mk b/gps/android/1.0/Android.mk
new file mode 100644
index 0000000..797ecce
--- /dev/null
+++ b/gps/android/1.0/Android.mk
@@ -0,0 +1,99 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@1.0-impl-qti
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ AGnss.cpp \
+ Gnss.cpp \
+ GnssBatching.cpp \
+ GnssGeofencing.cpp \
+ GnssMeasurement.cpp \
+ GnssNi.cpp \
+ GnssConfiguration.cpp \
+ GnssDebug.cpp \
+ AGnssRil.cpp
+
+LOCAL_SRC_FILES += \
+ location_api/LocationUtil.cpp \
+ location_api/GnssAPIClient.cpp \
+ location_api/GeofenceAPIClient.cpp \
+ location_api/BatchingAPIClient.cpp \
+ location_api/MeasurementAPIClient.cpp \
+
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/location_api
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers \
+ liblocbatterylistener_headers
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libhidlbase \
+ libcutils \
+ libutils \
+ android.hardware.gnss@1.0 \
+ android.hardware.health@1.0 \
+ android.hardware.health@2.0 \
+ android.hardware.power@1.2 \
+ libbase
+
+LOCAL_SHARED_LIBRARIES += \
+ libloc_core \
+ libgps.utils \
+ libdl \
+ liblocation_api \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+LOCAL_STATIC_LIBRARIES := liblocbatterylistener
+LOCAL_STATIC_LIBRARIES += libhealthhalutils
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@1.0-service-qti
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@1.0-service-qti.xml
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_INIT_RC := android.hardware.gnss@1.0-service-qti.rc
+LOCAL_SRC_FILES := \
+ service.cpp \
+
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/location_api
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils \
+ libdl \
+ libbase \
+ libutils \
+ libgps.utils \
+ libqti_vndfwk_detect \
+
+LOCAL_SHARED_LIBRARIES += \
+ libhidlbase \
+ android.hardware.gnss@1.0 \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+
+ifneq ($(LOC_HIDL_VERSION),)
+LOCAL_CFLAGS += -DLOC_HIDL_VERSION='"$(LOC_HIDL_VERSION)"'
+endif
+
+include $(BUILD_EXECUTABLE)
diff --git a/gps/android/Gnss.cpp b/gps/android/1.0/Gnss.cpp
index c844118..d85e0a4 100644
--- a/gps/android/Gnss.cpp
+++ b/gps/android/1.0/Gnss.cpp
@@ -19,6 +19,7 @@
*/
#define LOG_TAG "LocSvc_GnssInterface"
+#define LOG_NDEBUG 0
#include <fstream>
#include <log_util.h>
@@ -26,8 +27,9 @@
#include <cutils/properties.h>
#include "Gnss.h"
#include <LocationUtil.h>
+#include "battery_listener.h"
-typedef void* (getLocationInterface)();
+typedef const GnssInterface* (getLocationInterface)();
namespace android {
namespace hardware {
@@ -35,6 +37,7 @@ namespace gnss {
namespace V1_0 {
namespace implementation {
+static sp<Gnss> sGnss;
void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
@@ -44,8 +47,17 @@ void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who
}
}
+void location_on_battery_status_changed(bool charging) {
+ LOC_LOGd("battery status changed to %s charging", charging ? "" : "not ");
+ if (sGnss != nullptr) {
+ sGnss->getGnssInterface()->updateBatteryStatus(charging);
+ }
+}
Gnss::Gnss() {
ENTRY_LOG_CALLFLOW();
+ sGnss = this;
+ // register health client to listen on battery change
+ loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
// clear pending GnssConfig
memset(&mPendingConfig, 0, sizeof(GnssConfig));
@@ -58,6 +70,7 @@ Gnss::~Gnss() {
delete mApi;
mApi = nullptr;
}
+ sGnss = nullptr;
}
GnssAPIClient* Gnss::getApi() {
@@ -84,7 +97,7 @@ GnssAPIClient* Gnss::getApi() {
return mApi;
}
-GnssInterface* Gnss::getGnssInterface() {
+const GnssInterface* Gnss::getGnssInterface() {
static bool getGnssInterfaceFailed = false;
if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
@@ -105,7 +118,7 @@ GnssInterface* Gnss::getGnssInterface() {
if (NULL == getter) {
getGnssInterfaceFailed = true;
} else {
- mGnssInterface = (GnssInterface*)(*getter)();
+ mGnssInterface = (const GnssInterface*)(*getter)();
}
}
return mGnssInterface;
@@ -196,6 +209,10 @@ Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
}
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
+ }
}
return true;
}
@@ -234,7 +251,7 @@ Return<bool> Gnss::injectLocation(double latitudeDegrees,
double longitudeDegrees,
float accuracyMeters) {
ENTRY_LOG_CALLFLOW();
- GnssInterface* gnssInterface = getGnssInterface();
+ const GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
return true;
@@ -246,7 +263,7 @@ Return<bool> Gnss::injectLocation(double latitudeDegrees,
Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
int32_t uncertaintyMs) {
ENTRY_LOG_CALLFLOW();
- GnssInterface* gnssInterface = getGnssInterface();
+ const GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
return true;
diff --git a/gps/android/Gnss.h b/gps/android/1.0/Gnss.h
index 03ef170..900a510 100644
--- a/gps/android/Gnss.h
+++ b/gps/android/1.0/Gnss.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018-2018-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
* Not a Contribution
*/
/*
@@ -99,7 +99,7 @@ struct Gnss : public IGnss {
GnssAPIClient* getApi();
Return<bool> setGnssNiCb(const sp<IGnssNiCallback>& niCb);
Return<bool> updateConfiguration(GnssConfig& gnssConfig);
- GnssInterface* getGnssInterface();
+ const GnssInterface* getGnssInterface();
// Callback for ODCPI request
void odcpiRequestCb(const OdcpiRequestInfo& request);
@@ -129,7 +129,7 @@ struct Gnss : public IGnss {
sp<V1_0::IGnssCallback> mGnssCbIface = nullptr;
sp<V1_0::IGnssNiCallback> mGnssNiCbIface = nullptr;
GnssConfig mPendingConfig;
- GnssInterface* mGnssInterface = nullptr;
+ const GnssInterface* mGnssInterface = nullptr;
};
extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
diff --git a/gps/android/GnssBatching.cpp b/gps/android/1.0/GnssBatching.cpp
index 3e5a9f4..3e5a9f4 100644
--- a/gps/android/GnssBatching.cpp
+++ b/gps/android/1.0/GnssBatching.cpp
diff --git a/gps/android/GnssBatching.h b/gps/android/1.0/GnssBatching.h
index 8fab857..8fab857 100644
--- a/gps/android/GnssBatching.h
+++ b/gps/android/1.0/GnssBatching.h
diff --git a/gps/android/GnssConfiguration.cpp b/gps/android/1.0/GnssConfiguration.cpp
index 15153dd..0b62249 100644
--- a/gps/android/GnssConfiguration.cpp
+++ b/gps/android/1.0/GnssConfiguration.cpp
@@ -23,6 +23,7 @@
#include <log_util.h>
#include "Gnss.h"
#include "GnssConfiguration.h"
+#include <android/hardware/gnss/1.0/types.h>
namespace android {
namespace hardware {
@@ -30,6 +31,8 @@ namespace gnss {
namespace V1_0 {
namespace implementation {
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+
GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
}
diff --git a/gps/android/GnssConfiguration.h b/gps/android/1.0/GnssConfiguration.h
index 1629e06..1629e06 100644
--- a/gps/android/GnssConfiguration.h
+++ b/gps/android/1.0/GnssConfiguration.h
diff --git a/gps/android/GnssDebug.cpp b/gps/android/1.0/GnssDebug.cpp
index 3d8e055..ead72e1 100644
--- a/gps/android/GnssDebug.cpp
+++ b/gps/android/1.0/GnssDebug.cpp
@@ -114,23 +114,6 @@ Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)
data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG;
}
- if (data.position.horizontalAccuracyMeters <= 0 ||
- data.position.horizontalAccuracyMeters > GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS) {
- data.position.horizontalAccuracyMeters = GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS;
- }
- if (data.position.verticalAccuracyMeters <= 0 ||
- data.position.verticalAccuracyMeters > GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS) {
- data.position.verticalAccuracyMeters = GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS;
- }
- if (data.position.speedAccuracyMetersPerSecond <= 0 ||
- data.position.speedAccuracyMetersPerSecond > GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC) {
- data.position.speedAccuracyMetersPerSecond = GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC;
- }
- if (data.position.bearingAccuracyDegrees <= 0 ||
- data.position.bearingAccuracyDegrees > GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG) {
- data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG;
- }
-
// time block
if (reports.mTime.mValid) {
data.time.timeEstimate = reports.mTime.timeEstimate;
diff --git a/gps/android/GnssDebug.h b/gps/android/1.0/GnssDebug.h
index a7116cb..a7116cb 100644
--- a/gps/android/GnssDebug.h
+++ b/gps/android/1.0/GnssDebug.h
diff --git a/gps/android/GnssGeofencing.cpp b/gps/android/1.0/GnssGeofencing.cpp
index 2a8ff88..2a8ff88 100644
--- a/gps/android/GnssGeofencing.cpp
+++ b/gps/android/1.0/GnssGeofencing.cpp
diff --git a/gps/android/GnssGeofencing.h b/gps/android/1.0/GnssGeofencing.h
index db5f9d2..db5f9d2 100644
--- a/gps/android/GnssGeofencing.h
+++ b/gps/android/1.0/GnssGeofencing.h
diff --git a/gps/android/GnssMeasurement.cpp b/gps/android/1.0/GnssMeasurement.cpp
index 1c65bd6..1c65bd6 100644
--- a/gps/android/GnssMeasurement.cpp
+++ b/gps/android/1.0/GnssMeasurement.cpp
diff --git a/gps/android/GnssMeasurement.h b/gps/android/1.0/GnssMeasurement.h
index 4247dbf..4247dbf 100644
--- a/gps/android/GnssMeasurement.h
+++ b/gps/android/1.0/GnssMeasurement.h
diff --git a/gps/android/GnssNi.cpp b/gps/android/1.0/GnssNi.cpp
index d06cc20..d06cc20 100644
--- a/gps/android/GnssNi.cpp
+++ b/gps/android/1.0/GnssNi.cpp
diff --git a/gps/android/GnssNi.h b/gps/android/1.0/GnssNi.h
index 90f62d5..90f62d5 100644
--- a/gps/android/GnssNi.h
+++ b/gps/android/1.0/GnssNi.h
diff --git a/gps/android/android.hardware.gnss@1.0-service-qti.rc b/gps/android/1.0/android.hardware.gnss@1.0-service-qti.rc
index b5da6f9..1fbd893 100644
--- a/gps/android/android.hardware.gnss@1.0-service-qti.rc
+++ b/gps/android/1.0/android.hardware.gnss@1.0-service-qti.rc
@@ -1,4 +1,4 @@
service gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service-qti
class hal
user gps
- group system gps radio
+ group system gps radio vendor_qti_diag
diff --git a/gps/android/1.0/android.hardware.gnss@1.0-service-qti.xml b/gps/android/1.0/android.hardware.gnss@1.0-service-qti.xml
new file mode 100644
index 0000000..46bcffb
--- /dev/null
+++ b/gps/android/1.0/android.hardware.gnss@1.0-service-qti.xml
@@ -0,0 +1,35 @@
+<!-- Copyright (c) 2019, 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.
+-->
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.gnss</name>
+ <transport>hwbinder</transport>
+ <fqname>@1.0::IGnss/default</fqname>
+ </hal>
+</manifest>
+
diff --git a/gps/android/location_api/BatchingAPIClient.cpp b/gps/android/1.0/location_api/BatchingAPIClient.cpp
index 264ab83..264ab83 100644
--- a/gps/android/location_api/BatchingAPIClient.cpp
+++ b/gps/android/1.0/location_api/BatchingAPIClient.cpp
diff --git a/gps/android/location_api/BatchingAPIClient.h b/gps/android/1.0/location_api/BatchingAPIClient.h
index 5d64df3..5d64df3 100644
--- a/gps/android/location_api/BatchingAPIClient.h
+++ b/gps/android/1.0/location_api/BatchingAPIClient.h
diff --git a/gps/android/location_api/GeofenceAPIClient.cpp b/gps/android/1.0/location_api/GeofenceAPIClient.cpp
index 774a049..774a049 100644
--- a/gps/android/location_api/GeofenceAPIClient.cpp
+++ b/gps/android/1.0/location_api/GeofenceAPIClient.cpp
diff --git a/gps/android/location_api/GeofenceAPIClient.h b/gps/android/1.0/location_api/GeofenceAPIClient.h
index dc99ddd..dc99ddd 100644
--- a/gps/android/location_api/GeofenceAPIClient.h
+++ b/gps/android/1.0/location_api/GeofenceAPIClient.h
diff --git a/gps/android/location_api/GnssAPIClient.cpp b/gps/android/1.0/location_api/GnssAPIClient.cpp
index 320ae15..b9fe2b2 100644
--- a/gps/android/location_api/GnssAPIClient.cpp
+++ b/gps/android/1.0/location_api/GnssAPIClient.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -29,13 +29,14 @@
#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_GnssAPIClient"
+#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
#include <log_util.h>
#include <loc_cfg.h>
#include "LocationUtil.h"
#include "GnssAPIClient.h"
-#include <LocDualContext.h>
+#include <LocContext.h>
namespace android {
namespace hardware {
@@ -62,11 +63,11 @@ GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb,
LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
// set default LocationOptions.
- memset(&mLocationOptions, 0, sizeof(LocationOptions));
- mLocationOptions.size = sizeof(LocationOptions);
- mLocationOptions.minInterval = 1000;
- mLocationOptions.minDistance = 0;
- mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+ memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+ mTrackingOptions.size = sizeof(TrackingOptions);
+ mTrackingOptions.minInterval = 1000;
+ mTrackingOptions.minDistance = 0;
+ mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
gnssUpdateCallbacks(gpsCb, niCb);
}
@@ -109,9 +110,9 @@ void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
locationCallbacks.gnssNiCb = nullptr;
loc_core::ContextBase* context =
- loc_core::LocDualContext::getLocFgContext(
+ loc_core::LocContext::getLocContext(
NULL, NULL,
- loc_core::LocDualContext::mLocationHalName, false);
+ loc_core::LocContext::mLocationHalName, false);
if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
LOC_LOGD("Registering NI CB");
locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
@@ -142,7 +143,7 @@ bool GnssAPIClient::gnssStart()
{
LOC_LOGD("%s]: ()", __FUNCTION__);
bool retVal = true;
- locAPIStartTracking(mLocationOptions);
+ locAPIStartTracking(mTrackingOptions);
return retVal;
}
@@ -156,30 +157,39 @@ bool GnssAPIClient::gnssStop()
bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
- uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs)
+ uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
{
- LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__,
- (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs);
+ LOC_LOGD("%s]: (%d %d %d %d %d %d %d)", __FUNCTION__,
+ (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters,
+ preferredTimeMs, (int)powerMode, timeBetweenMeasurement);
bool retVal = true;
- memset(&mLocationOptions, 0, sizeof(LocationOptions));
- mLocationOptions.size = sizeof(LocationOptions);
- mLocationOptions.minInterval = minIntervalMs;
- mLocationOptions.minDistance = preferredAccuracyMeters;
- if (IGnss::GnssPositionRecurrence::RECURRENCE_SINGLE == recurrence) {
- mLocationOptions.minInterval =
- std::numeric_limits<decltype(mLocationOptions.minInterval)>::max();
+ memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+ mTrackingOptions.size = sizeof(TrackingOptions);
+ mTrackingOptions.minInterval = minIntervalMs;
+ if (IGnss::GnssPositionMode::MS_ASSISTED == mode ||
+ IGnss::GnssPositionRecurrence::RECURRENCE_SINGLE == recurrence) {
+ // We set a very large interval to simulate SINGLE mode. Once we report a fix,
+ // the caller should take the responsibility to stop the session.
+ // For MSA, we always treat it as SINGLE mode.
+ mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC;
}
+ mTrackingOptions.minDistance = preferredAccuracyMeters;
if (mode == IGnss::GnssPositionMode::STANDALONE)
- mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+ mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
else if (mode == IGnss::GnssPositionMode::MS_BASED)
- mLocationOptions.mode = GNSS_SUPL_MODE_MSB;
+ mTrackingOptions.mode = GNSS_SUPL_MODE_MSB;
else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
- mLocationOptions.mode = GNSS_SUPL_MODE_MSA;
+ mTrackingOptions.mode = GNSS_SUPL_MODE_MSA;
else {
LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
retVal = false;
}
- locAPIUpdateTrackingOptions(mLocationOptions);
+ if (GNSS_POWER_MODE_INVALID != powerMode) {
+ mTrackingOptions.powerMode = powerMode;
+ mTrackingOptions.tbm = timeBetweenMeasurement;
+ }
+ locAPIUpdateTrackingOptions(mTrackingOptions);
return retVal;
}
@@ -188,17 +198,22 @@ void GnssAPIClient::gnssNiRespond(int32_t notifId,
IGnssNiCallback::GnssUserResponseType userResponse)
{
LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
- GnssNiResponse data = GNSS_NI_RESPONSE_IGNORE;
- if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT)
+ GnssNiResponse data;
+ switch (userResponse) {
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT:
data = GNSS_NI_RESPONSE_ACCEPT;
- else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY)
+ break;
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY:
data = GNSS_NI_RESPONSE_DENY;
- else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP)
+ break;
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP:
data = GNSS_NI_RESPONSE_NO_RESPONSE;
- else {
- LOC_LOGD("%s]: invalid GnssUserResponseType: %d", __FUNCTION__, (int)userResponse);
- return;
+ break;
+ default:
+ data = GNSS_NI_RESPONSE_IGNORE;
+ break;
}
+
locAPIGnssNiResponse(notifId, data);
}
@@ -216,6 +231,7 @@ void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT;
+ data.posEngineMask = STANDARD_POSITIONING_ENGINE;
if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
data.deleteAll = true;
@@ -317,7 +333,10 @@ void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
}
if (gnssCbIface != nullptr) {
IGnssCallback::GnssSystemInfo gnssInfo;
- if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
+ if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
+ capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
+ gnssInfo.yearOfHw = 2018;
+ } else if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
gnssInfo.yearOfHw = 2017;
} else if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
gnssInfo.yearOfHw = 2016;
@@ -451,13 +470,20 @@ void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
mMutex.unlock();
if (gnssCbIface != nullptr) {
- android::hardware::hidl_string nmeaString;
- nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length);
- auto r = gnssCbIface->gnssNmeaCb(
- static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
- if (!r.isOk()) {
- LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__,
- gnssNmeaNotification.nmea, gnssNmeaNotification.length, r.description().c_str());
+ const std::string s(gnssNmeaNotification.nmea);
+ std::stringstream ss(s);
+ std::string each;
+ while(std::getline(ss, each, '\n')) {
+ each += '\n';
+ android::hardware::hidl_string nmeaString;
+ nmeaString.setToExternal(each.c_str(), each.length());
+ auto r = gnssCbIface->gnssNmeaCb(
+ static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__,
+ gnssNmeaNotification.nmea, gnssNmeaNotification.length,
+ r.description().c_str());
+ }
}
}
}
@@ -520,6 +546,7 @@ static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvSta
info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
info.elevationDegrees = in.gnssSvs[i].elevation;
info.azimuthDegrees = in.gnssSvs[i].azimuth;
+ info.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
@@ -527,6 +554,8 @@ static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvSta
info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+ info.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
}
}
diff --git a/gps/android/location_api/GnssAPIClient.h b/gps/android/1.0/location_api/GnssAPIClient.h
index 923cb48..4e4b4a9 100644
--- a/gps/android/location_api/GnssAPIClient.h
+++ b/gps/android/1.0/location_api/GnssAPIClient.h
@@ -63,7 +63,9 @@ public:
V1_0::IGnss::GnssPositionRecurrence recurrence,
uint32_t minIntervalMs,
uint32_t preferredAccuracyMeters,
- uint32_t preferredTimeMs);
+ uint32_t preferredTimeMs,
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = 0);
// for GpsNiInterface
void gnssNiRespond(int32_t notifId, V1_0::IGnssNiCallback::GnssUserResponseType userResponse);
@@ -96,8 +98,7 @@ private:
LocationAPIControlClient* mControlClient;
LocationCapabilitiesMask mLocationCapabilitiesMask;
bool mLocationCapabilitiesCached;
-
- LocationOptions mLocationOptions;
+ TrackingOptions mTrackingOptions;
};
} // namespace implementation
diff --git a/gps/android/location_api/LocationUtil.cpp b/gps/android/1.0/location_api/LocationUtil.cpp
index 89681f2..102593b 100644
--- a/gps/android/location_api/LocationUtil.cpp
+++ b/gps/android/1.0/location_api/LocationUtil.cpp
@@ -42,62 +42,80 @@ using ::android::hardware::gnss::V1_0::GnssLocationFlags;
void convertGnssLocation(Location& in, GnssLocation& out)
{
memset(&out, 0, sizeof(GnssLocation));
- if (in.flags & LOCATION_HAS_LAT_LONG_BIT)
+ if (in.flags & LOCATION_HAS_LAT_LONG_BIT) {
out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
- if (in.flags & LOCATION_HAS_ALTITUDE_BIT)
+ out.latitudeDegrees = in.latitude;
+ out.longitudeDegrees = in.longitude;
+ }
+ if (in.flags & LOCATION_HAS_ALTITUDE_BIT) {
out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
- if (in.flags & LOCATION_HAS_SPEED_BIT)
+ out.altitudeMeters = in.altitude;
+ }
+ if (in.flags & LOCATION_HAS_SPEED_BIT) {
out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
- if (in.flags & LOCATION_HAS_BEARING_BIT)
+ out.speedMetersPerSec = in.speed;
+ }
+ if (in.flags & LOCATION_HAS_BEARING_BIT) {
out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
- if (in.flags & LOCATION_HAS_ACCURACY_BIT)
+ out.bearingDegrees = in.bearing;
+ }
+ if (in.flags & LOCATION_HAS_ACCURACY_BIT) {
out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
- if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT)
+ out.horizontalAccuracyMeters = in.accuracy;
+ }
+ if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) {
out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
- if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT)
+ out.verticalAccuracyMeters = in.verticalAccuracy;
+ }
+ if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) {
out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
- if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT)
+ out.speedAccuracyMetersPerSecond = in.speedAccuracy;
+ }
+ if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) {
out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
- out.latitudeDegrees = in.latitude;
- out.longitudeDegrees = in.longitude;
- out.altitudeMeters = in.altitude;
- out.speedMetersPerSec = in.speed;
- out.bearingDegrees = in.bearing;
- out.horizontalAccuracyMeters = in.accuracy;
- out.verticalAccuracyMeters = in.verticalAccuracy;
- out.speedAccuracyMetersPerSecond = in.speedAccuracy;
- out.bearingAccuracyDegrees = in.bearingAccuracy;
+ out.bearingAccuracyDegrees = in.bearingAccuracy;
+ }
+
out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
}
void convertGnssLocation(const GnssLocation& in, Location& out)
{
memset(&out, 0, sizeof(out));
- if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG)
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) {
out.flags |= LOCATION_HAS_LAT_LONG_BIT;
- if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE)
+ out.latitude = in.latitudeDegrees;
+ out.longitude = in.longitudeDegrees;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE) {
out.flags |= LOCATION_HAS_ALTITUDE_BIT;
- if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED)
+ out.altitude = in.altitudeMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED) {
out.flags |= LOCATION_HAS_SPEED_BIT;
- if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING)
+ out.speed = in.speedMetersPerSec;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
out.flags |= LOCATION_HAS_BEARING_BIT;
- if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY)
+ out.bearing = in.bearingDegrees;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
out.flags |= LOCATION_HAS_ACCURACY_BIT;
- if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY)
+ out.accuracy = in.horizontalAccuracyMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
- if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY)
+ out.verticalAccuracy = in.verticalAccuracyMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
- if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY)
+ out.speedAccuracy = in.speedAccuracyMetersPerSecond;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
- out.latitude = in.latitudeDegrees;
- out.longitude = in.longitudeDegrees;
- out.altitude = in.altitudeMeters;
- out.speed = in.speedMetersPerSec;
- out.bearing = in.bearingDegrees;
- out.accuracy = in.horizontalAccuracyMeters;
- out.verticalAccuracy = in.verticalAccuracyMeters;
- out.speedAccuracy = in.speedAccuracyMetersPerSecond;
- out.bearingAccuracy = in.bearingAccuracyDegrees;
+ out.bearingAccuracy = in.bearingAccuracyDegrees;
+ }
+
out.timestamp = static_cast<uint64_t>(in.timestamp);
}
diff --git a/gps/android/location_api/LocationUtil.h b/gps/android/1.0/location_api/LocationUtil.h
index 9e0cd36..9e0cd36 100644
--- a/gps/android/location_api/LocationUtil.h
+++ b/gps/android/1.0/location_api/LocationUtil.h
diff --git a/gps/android/location_api/MeasurementAPIClient.cpp b/gps/android/1.0/location_api/MeasurementAPIClient.cpp
index 823851d..73709e3 100644
--- a/gps/android/location_api/MeasurementAPIClient.cpp
+++ b/gps/android/1.0/location_api/MeasurementAPIClient.cpp
@@ -101,15 +101,16 @@ MeasurementAPIClient::startTracking()
}
locAPISetCallbacks(locationCallbacks);
- LocationOptions options;
- memset(&options, 0, sizeof(LocationOptions));
- options.size = sizeof(LocationOptions);
+
+ TrackingOptions options = {};
+ memset(&options, 0, sizeof(TrackingOptions));
+ options.size = sizeof(TrackingOptions);
options.minInterval = 1000;
options.mode = GNSS_SUPL_MODE_STANDALONE;
+
mTracking = true;
LOC_LOGD("%s]: start tracking session", __FUNCTION__);
locAPIStartTracking(options);
-
return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
}
diff --git a/gps/android/location_api/MeasurementAPIClient.h b/gps/android/1.0/location_api/MeasurementAPIClient.h
index 08b4811..c357313 100644
--- a/gps/android/location_api/MeasurementAPIClient.h
+++ b/gps/android/1.0/location_api/MeasurementAPIClient.h
@@ -35,6 +35,7 @@
#include <android/hardware/gnss/1.0/IGnssMeasurementCallback.h>
#include <LocationAPIClientBase.h>
#include <hidl/Status.h>
+#include <gps_extended_c.h>
namespace android {
namespace hardware {
diff --git a/gps/android/1.0/service.cpp b/gps/android/1.0/service.cpp
new file mode 100644
index 0000000..2a6f60f
--- /dev/null
+++ b/gps/android/1.0/service.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.gnss@1.0-service-qti"
+
+#include <android/hardware/gnss/1.0/IGnss.h>
+#include <hidl/LegacySupport.h>
+#include "loc_cfg.h"
+#include "loc_misc_utils.h"
+
+extern "C" {
+#include "vndfwk-detect.h"
+}
+
+#ifdef ARCH_ARM_32
+#define DEFAULT_HW_BINDER_MEM_SIZE 65536
+#endif
+
+using android::hardware::gnss::V1_0::IGnss;
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+
+using android::status_t;
+using android::OK;
+
+typedef int vendorEnhancedServiceMain(int /* argc */, char* /* argv */ []);
+
+int main() {
+
+ ALOGI("%s", __FUNCTION__);
+
+ int vendorInfo = getVendorEnhancedInfo();
+ bool vendorEnhanced = ( 1 == vendorInfo || 3 == vendorInfo );
+ setVendorEnhanced(vendorEnhanced);
+
+#ifdef ARCH_ARM_32
+ android::hardware::ProcessState::initWithMmapSize((size_t)(DEFAULT_HW_BINDER_MEM_SIZE));
+#endif
+ configureRpcThreadpool(1, true);
+ status_t status;
+
+ status = registerPassthroughServiceImplementation<IGnss>();
+ if (status == OK) {
+ if (vendorEnhanced) {
+ #ifdef LOC_HIDL_VERSION
+ #define VENDOR_ENHANCED_LIB "vendor.qti.gnss@" LOC_HIDL_VERSION "-service.so"
+
+ void* libHandle = NULL;
+ vendorEnhancedServiceMain* vendorEnhancedMainMethod = (vendorEnhancedServiceMain*)
+ dlGetSymFromLib(libHandle, VENDOR_ENHANCED_LIB, "main");
+ if (NULL != vendorEnhancedMainMethod) {
+ (*vendorEnhancedMainMethod)(0, NULL);
+ }
+ #else
+ ALOGE("LOC_HIDL_VERSION not defined.");
+ #endif
+ }
+
+ joinRpcThreadpool();
+
+ } else {
+ ALOGE("Error while registering IGnss 1.0 service: %d", status);
+ }
+
+ return 0;
+}
diff --git a/gps/android/1.1/AGnss.cpp b/gps/android/1.1/AGnss.cpp
new file mode 100644
index 0000000..d8f9706
--- /dev/null
+++ b/gps/android/1.1/AGnss.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_AGnssInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "AGnss.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+static AGnss* spAGnss = nullptr;
+
+AGnss::AGnss(Gnss* gnss) : mGnss(gnss) {
+ spAGnss = this;
+}
+
+AGnss::~AGnss() {
+ spAGnss = nullptr;
+}
+
+void AGnss::agnssStatusIpV4Cb(AGnssExtStatusIpV4 status){
+ if (nullptr != spAGnss) {
+ spAGnss->statusIpV4Cb(status);
+ }
+}
+
+void AGnss::statusIpV4Cb(AGnssExtStatusIpV4 status) {
+ IAGnssCallback::AGnssStatusIpV4 st = {};
+
+ switch (status.type) {
+ case LOC_AGPS_TYPE_SUPL:
+ st.type = IAGnssCallback::AGnssType::TYPE_SUPL;
+ break;
+ case LOC_AGPS_TYPE_C2K:
+ st.type = IAGnssCallback::AGnssType::TYPE_C2K;
+ break;
+ default:
+ LOC_LOGE("invalid type: %d", status.type);
+ return;
+ }
+
+ switch (status.status) {
+ case LOC_GPS_REQUEST_AGPS_DATA_CONN:
+ st.status = IAGnssCallback::AGnssStatusValue::REQUEST_AGNSS_DATA_CONN;
+ break;
+ case LOC_GPS_RELEASE_AGPS_DATA_CONN:
+ st.status = IAGnssCallback::AGnssStatusValue::RELEASE_AGNSS_DATA_CONN;
+ break;
+ case LOC_GPS_AGPS_DATA_CONNECTED:
+ st.status = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONNECTED;
+ break;
+ case LOC_GPS_AGPS_DATA_CONN_DONE:
+ st.status = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_DONE;
+ break;
+ case LOC_GPS_AGPS_DATA_CONN_FAILED:
+ st.status = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_FAILED;
+ break;
+ default:
+ LOC_LOGE("invalid status: %d", status.status);
+ return;
+ }
+ st.ipV4Addr = status.ipV4Addr;
+
+ if (mAGnssCbIface != nullptr) {
+ auto r = mAGnssCbIface->agnssStatusIpV4Cb(st);
+ if (!r.isOk()) {
+ LOC_LOGw("Error invoking AGNSS status cb %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGw("setCallback has not been called yet");
+ }
+}
+
+Return<void> AGnss::setCallback(const sp<IAGnssCallback>& callback) {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return Void();
+ }
+
+ // Save the interface
+ mAGnssCbIface = callback;
+
+ AgpsCbInfo cbInfo = {};
+ cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
+ cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES;
+
+ mGnss->getGnssInterface()->agpsInit(cbInfo);
+ return Void();
+}
+
+Return<bool> AGnss::dataConnClosed() {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return false;
+ }
+
+ mGnss->getGnssInterface()->agpsDataConnClosed(LOC_AGPS_TYPE_SUPL);
+ return true;
+}
+
+Return<bool> AGnss::dataConnFailed() {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return false;
+ }
+
+ mGnss->getGnssInterface()->agpsDataConnFailed(LOC_AGPS_TYPE_SUPL);
+ return true;
+}
+
+Return<bool> AGnss::dataConnOpen(const hidl_string& apn,
+ IAGnss::ApnIpType apnIpType) {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return false;
+ }
+
+ /* Validate */
+ if(apn.empty()){
+ LOC_LOGE("Invalid APN");
+ return false;
+ }
+
+ LOC_LOGD("dataConnOpen APN name = [%s]", apn.c_str());
+
+ AGpsBearerType bearerType;
+ switch (apnIpType) {
+ case IAGnss::ApnIpType::IPV4:
+ bearerType = AGPS_APN_BEARER_IPV4;
+ break;
+ case IAGnss::ApnIpType::IPV6:
+ bearerType = AGPS_APN_BEARER_IPV6;
+ break;
+ case IAGnss::ApnIpType::IPV4V6:
+ bearerType = AGPS_APN_BEARER_IPV4V6;
+ break;
+ default:
+ bearerType = AGPS_APN_BEARER_IPV4;
+ break;
+ }
+
+ mGnss->getGnssInterface()->agpsDataConnOpen(
+ LOC_AGPS_TYPE_SUPL, apn.c_str(), apn.size(), (int)bearerType);
+ return true;
+}
+
+Return<bool> AGnss::setServer(IAGnssCallback::AGnssType type,
+ const hidl_string& hostname,
+ int32_t port) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
+ config.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
+ if (type == IAGnssCallback::AGnssType::TYPE_SUPL) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL;
+ } else if (type == IAGnssCallback::AGnssType::TYPE_C2K) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_C2K;
+ } else {
+ LOC_LOGE("%s]: invalid AGnssType: %d", __FUNCTION__, static_cast<int>(type));
+ return false;
+ }
+ config.assistanceServer.hostName = strdup(hostname.c_str());
+ config.assistanceServer.port = port;
+ return mGnss->updateConfiguration(config);
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/AGnss.h b/gps/android/1.1/AGnss.h
new file mode 100644
index 0000000..4b599b9
--- /dev/null
+++ b/gps/android/1.1/AGnss.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H
+#define ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H
+
+#include <android/hardware/gnss/1.0/IAGnss.h>
+#include <hidl/Status.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IAGnss;
+using ::android::hardware::gnss::V1_0::IAGnssCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+struct AGnss : public IAGnss {
+
+ AGnss(Gnss* gnss);
+ ~AGnss();
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IAGnss interface follow.
+ * These declarations were generated from IAGnss.hal.
+ */
+ Return<void> setCallback(const sp<IAGnssCallback>& callback) override;
+
+ Return<bool> dataConnClosed() override;
+
+ Return<bool> dataConnFailed() override;
+
+ Return<bool> dataConnOpen(const hidl_string& apn,
+ IAGnss::ApnIpType apnIpType) override;
+
+ Return<bool> setServer(IAGnssCallback::AGnssType type,
+ const hidl_string& hostname, int32_t port) override;
+
+ void statusIpV4Cb(AGnssExtStatusIpV4 status);
+
+ /* Data call setup callback passed down to GNSS HAL implementation */
+ static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 status);
+
+ private:
+ Gnss* mGnss = nullptr;
+ sp<IAGnssCallback> mAGnssCbIface = nullptr;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H
diff --git a/gps/android/1.1/AGnssRil.cpp b/gps/android/1.1/AGnssRil.cpp
new file mode 100644
index 0000000..1e774f1
--- /dev/null
+++ b/gps/android/1.1/AGnssRil.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc__AGnssRilInterface"
+
+#include <log_util.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sstream>
+#include <string>
+#include "Gnss.h"
+#include "AGnssRil.h"
+#include <DataItemConcreteTypesBase.h>
+
+typedef void* (getLocationInterface)();
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+
+AGnssRil::AGnssRil(Gnss* gnss) : mGnss(gnss) {
+ ENTRY_LOG_CALLFLOW();
+}
+
+AGnssRil::~AGnssRil() {
+ ENTRY_LOG_CALLFLOW();
+}
+
+Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool /*roaming*/) {
+ ENTRY_LOG_CALLFLOW();
+ // Extra NetworkTypes not available in IAgnssRil enums
+ const int NetworkType_BLUETOOTH = 7;
+ const int NetworkType_ETHERNET = 9;
+ const int NetworkType_PROXY = 16;
+
+ // for XTRA
+ if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
+ int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ switch(type)
+ {
+ case IAGnssRil::NetworkType::MOBILE:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+ break;
+ case IAGnssRil::NetworkType::WIFI:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+ break;
+ case IAGnssRil::NetworkType::MMS:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_MMS;
+ break;
+ case IAGnssRil::NetworkType::SUPL:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_SUPL;
+ break;
+ case IAGnssRil::NetworkType::DUN:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_DUN;
+ break;
+ case IAGnssRil::NetworkType::HIPRI:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_HIPRI;
+ break;
+ case IAGnssRil::NetworkType::WIMAX:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
+ break;
+ default:
+ {
+ int networkType = (int) type;
+ // Handling network types not available in IAgnssRil
+ switch(networkType)
+ {
+ case NetworkType_BLUETOOTH:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_BLUETOOTH;
+ break;
+ case NetworkType_ETHERNET:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_ETHERNET;
+ break;
+ case NetworkType_PROXY:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_PROXY;
+ break;
+ default:
+ typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+ }
+ }
+ break;
+ }
+ mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
+ }
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/AGnssRil.h b/gps/android/1.1/AGnssRil.h
new file mode 100644
index 0000000..5c9298a
--- /dev/null
+++ b/gps/android/1.1/AGnssRil.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_0_AGNSSRIL_H_
+#define ANDROID_HARDWARE_GNSS_V1_0_AGNSSRIL_H_
+
+#include <android/hardware/gnss/1.0/IAGnssRil.h>
+#include <hidl/Status.h>
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IAGnssRil;
+using ::android::hardware::gnss::V1_0::IAGnssRilCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+/*
+ * Extended interface for AGNSS RIL support. An Assisted GNSS Radio Interface Layer interface
+ * allows the GNSS chipset to request radio interface layer information from Android platform.
+ * Examples of such information are reference location, unique subscriber ID, phone number string
+ * and network availability changes. Also contains wrapper methods to allow methods from
+ * IAGnssiRilCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+struct AGnssRil : public IAGnssRil {
+ AGnssRil(Gnss* gnss);
+ ~AGnssRil();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+ * These declarations were generated from IAGnssRil.hal.
+ */
+ Return<void> setCallback(const sp<IAGnssRilCallback>& /*callback*/) override {
+ return Void();
+ }
+ Return<void> setRefLocation(const IAGnssRil::AGnssRefLocation& /*agnssReflocation*/) override {
+ return Void();
+ }
+ Return<bool> setSetId(IAGnssRil::SetIDType /*type*/, const hidl_string& /*setid*/) override {
+ return false;
+ }
+ Return<bool> updateNetworkAvailability(bool /*available*/,
+ const hidl_string& /*apn*/) override {
+ return false;
+ }
+ Return<bool> updateNetworkState(bool connected, NetworkType type, bool roaming) override;
+
+ private:
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_0_AGNSSRIL_H_
diff --git a/gps/android/1.1/Android.mk b/gps/android/1.1/Android.mk
new file mode 100644
index 0000000..66abd06
--- /dev/null
+++ b/gps/android/1.1/Android.mk
@@ -0,0 +1,101 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@1.1-impl-qti
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ AGnss.cpp \
+ Gnss.cpp \
+ GnssBatching.cpp \
+ GnssGeofencing.cpp \
+ GnssMeasurement.cpp \
+ GnssNi.cpp \
+ GnssConfiguration.cpp \
+ GnssDebug.cpp \
+ AGnssRil.cpp
+
+LOCAL_SRC_FILES += \
+ location_api/LocationUtil.cpp \
+ location_api/GnssAPIClient.cpp \
+ location_api/GeofenceAPIClient.cpp \
+ location_api/BatchingAPIClient.cpp \
+ location_api/MeasurementAPIClient.cpp \
+
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/location_api
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers \
+ liblocbatterylistener_headers
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libhidlbase \
+ libcutils \
+ libutils \
+ android.hardware.gnss@1.0 \
+ android.hardware.gnss@1.1 \
+ android.hardware.health@1.0 \
+ android.hardware.health@2.0 \
+ android.hardware.power@1.2 \
+ libbase
+
+LOCAL_SHARED_LIBRARIES += \
+ libloc_core \
+ libgps.utils \
+ libdl \
+ liblocation_api \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+LOCAL_STATIC_LIBRARIES := liblocbatterylistener
+LOCAL_STATIC_LIBRARIES += libhealthhalutils
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@1.1-service-qti
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@1.1-service-qti.xml
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_INIT_RC := android.hardware.gnss@1.1-service-qti.rc
+LOCAL_SRC_FILES := \
+ service.cpp \
+
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/location_api
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils \
+ libdl \
+ libbase \
+ libutils \
+ libgps.utils \
+ libqti_vndfwk_detect \
+
+LOCAL_SHARED_LIBRARIES += \
+ libhidlbase \
+ android.hardware.gnss@1.0 \
+ android.hardware.gnss@1.1 \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+
+ifneq ($(LOC_HIDL_VERSION),)
+LOCAL_CFLAGS += -DLOC_HIDL_VERSION='"$(LOC_HIDL_VERSION)"'
+endif
+
+include $(BUILD_EXECUTABLE)
diff --git a/gps/android/1.1/Gnss.cpp b/gps/android/1.1/Gnss.cpp
new file mode 100644
index 0000000..bea556f
--- /dev/null
+++ b/gps/android/1.1/Gnss.cpp
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssInterface"
+#define LOG_NDEBUG 0
+
+#include <fstream>
+#include <log_util.h>
+#include <dlfcn.h>
+#include <cutils/properties.h>
+#include "Gnss.h"
+#include <LocationUtil.h>
+
+#include "battery_listener.h"
+
+typedef const GnssInterface* (getLocationInterface)();
+
+#define IMAGES_INFO_FILE "/sys/devices/soc0/images"
+#define DELIMITER ";"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+static sp<Gnss> sGnss;
+static std::string getVersionString() {
+ static std::string version;
+ if (!version.empty())
+ return version;
+
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.hardware", value, "unknown");
+ version.append(value).append(DELIMITER);
+
+ std::ifstream in(IMAGES_INFO_FILE);
+ std::string s;
+ while(getline(in, s)) {
+ std::size_t found = s.find("CRM:");
+ if (std::string::npos == found) {
+ continue;
+ }
+
+ // skip over space characters after "CRM:"
+ const char* substr = s.c_str();
+ found += 4;
+ while (0 != substr[found] && isspace(substr[found])) {
+ found++;
+ }
+ if (s.find("11:") != found) {
+ continue;
+ }
+ s.erase(0, found + 3);
+
+ found = s.find_first_of("\r\n");
+ if (std::string::npos != found) {
+ s.erase(s.begin() + found, s.end());
+ }
+ version.append(s).append(DELIMITER);
+ }
+ return version;
+}
+
+void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnss != nullptr) {
+ mGnss->stop();
+ mGnss->cleanup();
+ }
+}
+
+void location_on_battery_status_changed(bool charging) {
+ LOC_LOGd("battery status changed to %s charging", charging ? "" : "not");
+ if (sGnss != nullptr) {
+ sGnss->getGnssInterface()->updateBatteryStatus(charging);
+ }
+}
+Gnss::Gnss() {
+ ENTRY_LOG_CALLFLOW();
+ sGnss = this;
+ // register health client to listen on battery change
+ loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
+ // clear pending GnssConfig
+ memset(&mPendingConfig, 0, sizeof(GnssConfig));
+
+ mGnssDeathRecipient = new GnssDeathRecipient(this);
+}
+
+Gnss::~Gnss() {
+ ENTRY_LOG_CALLFLOW();
+ if (mApi != nullptr) {
+ delete mApi;
+ mApi = nullptr;
+ }
+ sGnss = nullptr;
+}
+
+GnssAPIClient* Gnss::getApi() {
+ if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
+ mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
+ return mApi;
+ }
+
+ if (mPendingConfig.size == sizeof(GnssConfig)) {
+ // we have pending GnssConfig
+ mApi->gnssConfigurationUpdate(mPendingConfig);
+ // clear size to invalid mPendingConfig
+ mPendingConfig.size = 0;
+ if (mPendingConfig.assistanceServer.hostName != nullptr) {
+ free((void*)mPendingConfig.assistanceServer.hostName);
+ }
+ }
+ }
+ if (mApi == nullptr) {
+ LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
+ }
+ return mApi;
+}
+
+const GnssInterface* Gnss::getGnssInterface() {
+ static bool getGnssInterfaceFailed = false;
+ if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
+ LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
+ getLocationInterface* getter = NULL;
+ const char *error = NULL;
+ dlerror();
+ void *handle = dlopen("libgnss.so", RTLD_NOW);
+ if (NULL == handle || (error = dlerror()) != NULL) {
+ LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
+ } else {
+ getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
+ if ((error = dlerror()) != NULL) {
+ LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
+ getter = NULL;
+ }
+ }
+
+ if (NULL == getter) {
+ getGnssInterfaceFailed = true;
+ } else {
+ mGnssInterface = (const GnssInterface*)(*getter)();
+ }
+ }
+ return mGnssInterface;
+}
+
+Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+ }
+ mGnssCbIface = callback;
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+ }
+
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
+ api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+ api->requestCapabilities();
+ }
+ return true;
+}
+
+Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ mGnssNiCbIface = callback;
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
+ }
+ return true;
+}
+
+Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
+ ENTRY_LOG_CALLFLOW();
+ GnssAPIClient* api = getApi();
+ if (api) {
+ api->gnssConfigurationUpdate(gnssConfig);
+ } else if (gnssConfig.flags != 0) {
+ // api is not ready yet, update mPendingConfig with gnssConfig
+ mPendingConfig.size = sizeof(GnssConfig);
+
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
+ mPendingConfig.gpsLock = gnssConfig.gpsLock;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
+ mPendingConfig.suplVersion = gnssConfig.suplVersion;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
+ mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
+ mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
+ if (mPendingConfig.assistanceServer.hostName != nullptr) {
+ free((void*)mPendingConfig.assistanceServer.hostName);
+ mPendingConfig.assistanceServer.hostName =
+ strdup(gnssConfig.assistanceServer.hostName);
+ }
+ mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+ mPendingConfig.lppProfile = gnssConfig.lppProfile;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
+ mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
+ mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+ mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
+ mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
+ mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
+ mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
+ }
+ }
+ return true;
+}
+
+Return<bool> Gnss::start() {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ retVal = api->gnssStart();
+ }
+ return retVal;
+}
+
+Return<bool> Gnss::stop() {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ retVal = api->gnssStop();
+ }
+ return retVal;
+}
+
+Return<void> Gnss::cleanup() {
+ ENTRY_LOG_CALLFLOW();
+
+ if (mApi != nullptr) {
+ mApi->gnssDisable();
+ }
+
+ return Void();
+}
+
+Return<bool> Gnss::injectLocation(double latitudeDegrees,
+ double longitudeDegrees,
+ float accuracyMeters) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
+ int32_t uncertaintyMs) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) {
+ ENTRY_LOG_CALLFLOW();
+ GnssAPIClient* api = getApi();
+ if (api) {
+ api->gnssDeleteAidingData(aidingDataFlags);
+ }
+ return Void();
+}
+
+Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
+ preferredAccuracyMeters, preferredTimeMs);
+ }
+ return retVal;
+}
+
+Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
+ ENTRY_LOG_CALLFLOW();
+ mAGnssIface = new AGnss(this);
+ return mAGnssIface;
+}
+
+Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssNi = new GnssNi(this);
+ return mGnssNi;
+}
+
+Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssMeasurement == nullptr)
+ mGnssMeasurement = new GnssMeasurement();
+ return mGnssMeasurement;
+}
+
+Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssConfig = new GnssConfiguration(this);
+ return mGnssConfig;
+}
+
+Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssGeofencingIface = new GnssGeofencing();
+ return mGnssGeofencingIface;
+}
+
+Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
+ mGnssBatching = new GnssBatching();
+ return mGnssBatching;
+}
+
+Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssDebug = new GnssDebug(this);
+ return mGnssDebug;
+}
+
+Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
+ mGnssRil = new AGnssRil(this);
+ return mGnssRil;
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ callback->gnssNameCb(getVersionString());
+ mGnssCbIface_1_1 = callback;
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
+ odcpiRequestCb(odcpiRequest);
+ };
+ gnssInterface->odcpiInit(cb);
+ }
+ return setCallback(callback);
+}
+
+Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs,
+ bool lowPowerMode) {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ GnssPowerMode powerMode = lowPowerMode?
+ GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2;
+ retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
+ preferredAccuracyMeters, preferredTimeMs, powerMode, minIntervalMs);
+ }
+ return retVal;
+}
+
+Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssMeasurement == nullptr)
+ mGnssMeasurement = new GnssMeasurement();
+ return mGnssMeasurement;
+}
+
+Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssConfig == nullptr)
+ mGnssConfig = new GnssConfiguration(this);
+ return mGnssConfig;
+}
+
+Return<bool> Gnss::injectBestLocation(const GnssLocation& gnssLocation) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ Location location = {};
+ convertGnssLocation(gnssLocation, location);
+ gnssInterface->odcpiInject(location);
+ }
+ return true;
+}
+
+void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssCbIface_1_1 != nullptr) {
+ // For emergency mode, request DBH (Device based hybrid) location
+ // Mark Independent from GNSS flag to false.
+ if (ODCPI_REQUEST_TYPE_START == request.type) {
+ auto r = mGnssCbIface_1_1->gnssRequestLocationCb(!request.isEmergencyMode);
+ if (!r.isOk()) {
+ LOC_LOGe("Error invoking gnssRequestLocationCb %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
+ }
+ } else {
+ LOC_LOGe("ODCPI request not supported.");
+ }
+}
+
+V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
+ ENTRY_LOG_CALLFLOW();
+ V1_0::IGnss* iface = nullptr;
+ iface = new Gnss();
+ if (iface == nullptr) {
+ LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
+ }
+ return iface;
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/Gnss.h b/gps/android/1.1/Gnss.h
new file mode 100644
index 0000000..15645eb
--- /dev/null
+++ b/gps/android/1.1/Gnss.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2017-2018-2018-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSS_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSS_H
+
+#include <AGnss.h>
+#include <AGnssRil.h>
+#include <GnssBatching.h>
+#include <GnssConfiguration.h>
+#include <GnssGeofencing.h>
+#include <GnssMeasurement.h>
+#include <GnssNi.h>
+#include <GnssDebug.h>
+
+#include <android/hardware/gnss/1.1/IGnss.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <GnssAPIClient.h>
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+struct Gnss : public IGnss {
+ Gnss();
+ ~Gnss();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+ * These declarations were generated from Gnss.hal.
+ */
+ Return<bool> setCallback(const sp<V1_0::IGnssCallback>& callback) override;
+ Return<bool> start() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+ Return<bool> injectLocation(double latitudeDegrees,
+ double longitudeDegrees,
+ float accuracyMeters) override;
+ Return<bool> injectTime(int64_t timeMs,
+ int64_t timeReferenceMs,
+ int32_t uncertaintyMs) override;
+ Return<void> deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override;
+ Return<bool> setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) override;
+ Return<sp<V1_0::IAGnss>> getExtensionAGnss() override;
+ Return<sp<V1_0::IGnssNi>> getExtensionGnssNi() override;
+ Return<sp<V1_0::IGnssMeasurement>> getExtensionGnssMeasurement() override;
+ Return<sp<V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() override;
+ Return<sp<V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() override;
+ Return<sp<V1_0::IGnssBatching>> getExtensionGnssBatching() override;
+
+ Return<sp<V1_0::IAGnssRil>> getExtensionAGnssRil() override;
+
+ inline Return<sp<V1_0::IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override {
+ return nullptr;
+ }
+
+ inline Return<sp<V1_0::IGnssXtra>> getExtensionXtra() override {
+ return nullptr;
+ }
+
+ Return<sp<V1_0::IGnssDebug>> getExtensionGnssDebug() override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+ Return<bool> setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) override;
+ Return<bool> setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs, bool lowPowerMode) override;
+ Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
+ Return<sp<V1_1::IGnssConfiguration>> getExtensionGnssConfiguration_1_1() override;
+ Return<bool> injectBestLocation(const GnssLocation& location) override;
+
+ // These methods are not part of the IGnss base class.
+ GnssAPIClient* getApi();
+ Return<bool> setGnssNiCb(const sp<IGnssNiCallback>& niCb);
+ Return<bool> updateConfiguration(GnssConfig& gnssConfig);
+ const GnssInterface* getGnssInterface();
+
+ // Callback for ODCPI request
+ void odcpiRequestCb(const OdcpiRequestInfo& request);
+
+ private:
+ struct GnssDeathRecipient : hidl_death_recipient {
+ GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) {
+ }
+ ~GnssDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<Gnss> mGnss;
+ };
+
+ private:
+ sp<GnssDeathRecipient> mGnssDeathRecipient = nullptr;
+
+ sp<AGnss> mAGnssIface = nullptr;
+ sp<GnssNi> mGnssNi = nullptr;
+ sp<GnssMeasurement> mGnssMeasurement = nullptr;
+ sp<GnssConfiguration> mGnssConfig = nullptr;
+ sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
+ sp<GnssBatching> mGnssBatching = nullptr;
+ sp<IGnssDebug> mGnssDebug = nullptr;
+ sp<AGnssRil> mGnssRil = nullptr;
+
+ GnssAPIClient* mApi = nullptr;
+ sp<V1_0::IGnssCallback> mGnssCbIface = nullptr;
+ sp<V1_1::IGnssCallback> mGnssCbIface_1_1 = nullptr;
+ sp<V1_0::IGnssNiCallback> mGnssNiCbIface = nullptr;
+ GnssConfig mPendingConfig;
+ const GnssInterface* mGnssInterface = nullptr;
+};
+
+extern "C" V1_0::IGnss* HIDL_FETCH_IGnss(const char* name);
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSS_H
diff --git a/gps/android/1.1/GnssBatching.cpp b/gps/android/1.1/GnssBatching.cpp
new file mode 100644
index 0000000..9701aff
--- /dev/null
+++ b/gps/android/1.1/GnssBatching.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssBatchingInterface"
+
+#include <log_util.h>
+#include <BatchingAPIClient.h>
+#include "GnssBatching.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+void GnssBatching::GnssBatchingDeathRecipient::serviceDied(
+ uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnssBatching != nullptr) {
+ mGnssBatching->stop();
+ mGnssBatching->cleanup();
+ }
+}
+
+GnssBatching::GnssBatching() : mApi(nullptr) {
+ mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this);
+}
+
+GnssBatching::~GnssBatching() {
+ if (mApi != nullptr) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) {
+ if (mApi != nullptr) {
+ LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
+ delete mApi;
+ mApi = nullptr;
+ }
+
+ mApi = new BatchingAPIClient(callback);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+ return false;
+ }
+
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+ }
+ mGnssBatchingCbIface = callback;
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->linkToDeath(mGnssBatchingDeathRecipient, 0 /*cookie*/);
+ }
+
+ return true;
+}
+
+Return<uint16_t> GnssBatching::getBatchSize() {
+ uint16_t ret = 0;
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ ret = mApi->getBatchSize();
+ }
+ return ret;
+}
+
+Return<bool> GnssBatching::start(const IGnssBatching::Options& options) {
+ bool ret = false;
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ ret = mApi->startSession(options);
+ }
+ return ret;
+}
+
+Return<void> GnssBatching::flush() {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->flushBatchedLocations();
+ }
+ return Void();
+}
+
+Return<bool> GnssBatching::stop() {
+ bool ret = false;
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ ret = mApi->stopSession();
+ }
+ return ret;
+}
+
+Return<void> GnssBatching::cleanup() {
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/GnssBatching.h b/gps/android/1.1/GnssBatching.h
new file mode 100644
index 0000000..8e235d8
--- /dev/null
+++ b/gps/android/1.1/GnssBatching.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H
+
+#include <android/hardware/gnss/1.0/IGnssBatching.h>
+#include <hidl/Status.h>
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssBatching;
+using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+class BatchingAPIClient;
+struct GnssBatching : public IGnssBatching {
+ GnssBatching();
+ ~GnssBatching();
+
+ // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+ Return<bool> init(const sp<IGnssBatchingCallback>& callback) override;
+ Return<uint16_t> getBatchSize() override;
+ Return<bool> start(const IGnssBatching::Options& options ) override;
+ Return<void> flush() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+
+ private:
+ struct GnssBatchingDeathRecipient : hidl_death_recipient {
+ GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) :
+ mGnssBatching(gnssBatching) {
+ }
+ ~GnssBatchingDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssBatching> mGnssBatching;
+ };
+
+ private:
+ sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr;
+ sp<IGnssBatchingCallback> mGnssBatchingCbIface = nullptr;
+ BatchingAPIClient* mApi = nullptr;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H
diff --git a/gps/android/1.1/GnssConfiguration.cpp b/gps/android/1.1/GnssConfiguration.cpp
new file mode 100644
index 0000000..93f9645
--- /dev/null
+++ b/gps/android/1.1/GnssConfiguration.cpp
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssConfigurationInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssConfiguration.h"
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+
+GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
+}
+
+// Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enabled) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
+ config.suplEmergencyServices = (enabled ?
+ GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_YES :
+ GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO);
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t version) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
+ switch (version) {
+ case 0x00020002:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_2;
+ break;
+ case 0x00020000:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_0;
+ break;
+ case 0x00010000:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_1_0_0;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setSuplMode(uint8_t mode) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
+ switch (mode) {
+ case 0:
+ config.suplModeMask = 0; // STANDALONE ONLY
+ break;
+ case 1:
+ config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT;
+ break;
+ case 2:
+ config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+ break;
+ case 3:
+ config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+ switch (lppProfile) {
+ case 0:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE;
+ break;
+ case 1:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE;
+ break;
+ case 2:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE;
+ break;
+ case 3:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid lppProfile: %d.", __FUNCTION__, lppProfile);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+
+ config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+ if (protocol & (1<<0)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT;
+ }
+ if (protocol & (1<<1)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT;
+ }
+ if (protocol & (1<<2)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT;
+ }
+ if (protocol & (1<<3)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
+ switch (lock) {
+ case 0:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+ break;
+ case 1:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO;
+ break;
+ case 2:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI;
+ break;
+ case 3:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
+ config.emergencyPdnForEmergencySupl = (enabled ?
+ GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES :
+ GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO);
+
+ return mGnss->updateConfiguration(config);
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+ const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) {
+
+ ENTRY_LOG_CALLFLOW();
+ if (nullptr == mGnss) {
+ LOC_LOGe("mGnss is null");
+ return false;
+ }
+
+ // blValid is true if blacklist is empty, i.e. clearing the BL;
+ // if blacklist is not empty, blValid is initialied to false, and later
+ // updated in the for loop to become true only if there is at least
+ // one {constellation, svid} in the list that is valid.
+ bool blValid = (0 == blacklist.size());
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ config.blacklistedSvIds.clear();
+
+ GnssSvIdSource source = {};
+ for (int idx = 0; idx < (int)blacklist.size(); idx++) {
+ // Set blValid true if any one source is valid
+ blValid = setBlacklistedSource(source, blacklist[idx]) || blValid;
+ config.blacklistedSvIds.push_back(source);
+ }
+
+ // Update configuration only if blValid is true
+ // i.e. only if atleast one source is valid for blacklisting
+ return (blValid && mGnss->updateConfiguration(config));
+}
+
+bool GnssConfiguration::setBlacklistedSource(
+ GnssSvIdSource& copyToSource,
+ const GnssConfiguration::BlacklistedSource& copyFromSource) {
+
+ bool retVal = true;
+ uint16_t svIdOffset = 0;
+ copyToSource.size = sizeof(GnssSvIdSource);
+ copyToSource.svId = copyFromSource.svid;
+
+ switch(copyFromSource.constellation) {
+ case GnssConstellationType::GPS:
+ copyToSource.constellation = GNSS_SV_TYPE_GPS;
+ LOC_LOGe("GPS SVs can't be blacklisted.");
+ retVal = false;
+ break;
+ case GnssConstellationType::SBAS:
+ copyToSource.constellation = GNSS_SV_TYPE_SBAS;
+ LOC_LOGe("SBAS SVs can't be blacklisted.");
+ retVal = false;
+ break;
+ case GnssConstellationType::GLONASS:
+ copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
+ svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
+ break;
+ case GnssConstellationType::QZSS:
+ copyToSource.constellation = GNSS_SV_TYPE_QZSS;
+ svIdOffset = 0;
+ break;
+ case GnssConstellationType::BEIDOU:
+ copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
+ svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
+ break;
+ case GnssConstellationType::GALILEO:
+ copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
+ svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
+ break;
+ default:
+ copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
+ LOC_LOGe("Invalid constellation %d", copyFromSource.constellation);
+ retVal = false;
+ break;
+ }
+
+ if (copyToSource.svId > 0 && svIdOffset > 0) {
+ copyToSource.svId += svIdOffset;
+ }
+
+ return retVal;
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/GnssConfiguration.h b/gps/android/1.1/GnssConfiguration.h
new file mode 100644
index 0000000..96681b6
--- /dev/null
+++ b/gps/android/1.1/GnssConfiguration.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+
+ /* Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/1.1/IGnssConfiguration.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_1::IGnssConfiguration;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Interface for passing GNSS configuration info from platform to HAL.
+ */
+struct Gnss;
+struct GnssConfiguration : public IGnssConfiguration {
+ GnssConfiguration(Gnss* gnss);
+ ~GnssConfiguration() = default;
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+ * These declarations were generated from IGnssConfiguration.hal.
+ */
+ Return<bool> setSuplVersion(uint32_t version) override;
+ Return<bool> setSuplMode(uint8_t mode) override;
+ Return<bool> setSuplEs(bool enabled) override;
+ Return<bool> setLppProfile(uint8_t lppProfile) override;
+ Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
+ Return<bool> setEmergencySuplPdn(bool enable) override;
+ Return<bool> setGpsLock(uint8_t lock) override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist(
+ const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ private:
+ Gnss* mGnss = nullptr;
+ bool setBlacklistedSource(
+ GnssSvIdSource& copyToSource,
+ const GnssConfiguration::BlacklistedSource& copyFromSource);
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
diff --git a/gps/android/1.1/GnssDebug.cpp b/gps/android/1.1/GnssDebug.cpp
new file mode 100644
index 0000000..f164c54
--- /dev/null
+++ b/gps/android/1.1/GnssDebug.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssDebugInterface"
+
+#include <log/log.h>
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssDebug.h"
+#include "LocationUtil.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+
+#define GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS (20000000)
+#define GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS (20000)
+#define GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC (500)
+#define GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG (180)
+
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME (1483228800000LL) // 1/1/2017 00:00 GMT
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MIN (999) // 999 ns
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX (1.57783680E17) // 5 years in ns
+#define GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC (2.0e5) // ppm
+
+GnssDebug::GnssDebug(Gnss* gnss) : mGnss(gnss)
+{
+}
+
+/*
+ * This methods requests position, time and satellite ephemeris debug information
+ * from the HAL.
+ *
+ * @return void
+*/
+Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ DebugData data = { };
+
+ if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
+ LOC_LOGE("GnssDebug - Null GNSS interface");
+ _hidl_cb(data);
+ return Void();
+ }
+
+ // get debug report snapshot via hal interface
+ GnssDebugReport reports = { };
+ mGnss->getGnssInterface()->getDebugReport(reports);
+
+ // location block
+ if (reports.mLocation.mValid) {
+ data.position.valid = true;
+ data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
+ data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
+ data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
+
+ data.position.speedMetersPerSec =
+ (double)(reports.mLocation.mLocation.speed);
+ data.position.bearingDegrees =
+ (double)(reports.mLocation.mLocation.bearing);
+ data.position.horizontalAccuracyMeters =
+ (double)(reports.mLocation.mLocation.accuracy);
+ data.position.verticalAccuracyMeters =
+ reports.mLocation.verticalAccuracyMeters;
+ data.position.speedAccuracyMetersPerSecond =
+ reports.mLocation.speedAccuracyMetersPerSecond;
+ data.position.bearingAccuracyDegrees =
+ reports.mLocation.bearingAccuracyDegrees;
+
+ timeval tv_now, tv_report;
+ tv_report.tv_sec = reports.mLocation.mUtcReported.tv_sec;
+ tv_report.tv_usec = reports.mLocation.mUtcReported.tv_nsec / 1000ULL;
+ gettimeofday(&tv_now, NULL);
+ data.position.ageSeconds =
+ (tv_now.tv_sec - tv_report.tv_sec) +
+ (float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
+ }
+ else {
+ data.position.valid = false;
+ }
+
+ if (data.position.horizontalAccuracyMeters <= 0 ||
+ data.position.horizontalAccuracyMeters > GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS) {
+ data.position.horizontalAccuracyMeters = GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS;
+ }
+ if (data.position.verticalAccuracyMeters <= 0 ||
+ data.position.verticalAccuracyMeters > GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS) {
+ data.position.verticalAccuracyMeters = GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS;
+ }
+ if (data.position.speedAccuracyMetersPerSecond <= 0 ||
+ data.position.speedAccuracyMetersPerSecond > GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC) {
+ data.position.speedAccuracyMetersPerSecond = GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC;
+ }
+ if (data.position.bearingAccuracyDegrees <= 0 ||
+ data.position.bearingAccuracyDegrees > GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG) {
+ data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG;
+ }
+
+ // time block
+ if (reports.mTime.mValid) {
+ data.time.timeEstimate = reports.mTime.timeEstimate;
+ data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
+ data.time.frequencyUncertaintyNsPerSec =
+ reports.mTime.frequencyUncertaintyNsPerSec;
+ }
+
+ if (data.time.timeEstimate < GNSS_DEBUG_UNKNOWN_UTC_TIME) {
+ data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME;
+ }
+ if (data.time.timeUncertaintyNs <= 0) {
+ data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MIN;
+ } else if (data.time.timeUncertaintyNs > GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX) {
+ data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX;
+ }
+ if (data.time.frequencyUncertaintyNsPerSec <= 0 ||
+ data.time.frequencyUncertaintyNsPerSec > (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC) {
+ data.time.frequencyUncertaintyNsPerSec = (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC;
+ }
+
+ // satellite data block
+ SatelliteData s = { };
+ std::vector<SatelliteData> s_array = { };
+
+ for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
+ memset(&s, 0, sizeof(s));
+ s.svid = reports.mSatelliteInfo[i].svid;
+ convertGnssConstellationType(
+ reports.mSatelliteInfo[i].constellation, s.constellation);
+ convertGnssEphemerisType(
+ reports.mSatelliteInfo[i].mEphemerisType, s.ephemerisType);
+ convertGnssEphemerisSource(
+ reports.mSatelliteInfo[i].mEphemerisSource, s.ephemerisSource);
+ convertGnssEphemerisHealth(
+ reports.mSatelliteInfo[i].mEphemerisHealth, s.ephemerisHealth);
+
+ s.ephemerisAgeSeconds =
+ reports.mSatelliteInfo[i].ephemerisAgeSeconds;
+ s.serverPredictionIsAvailable =
+ reports.mSatelliteInfo[i].serverPredictionIsAvailable;
+ s.serverPredictionAgeSeconds =
+ reports.mSatelliteInfo[i].serverPredictionAgeSeconds;
+
+ s_array.push_back(s);
+ }
+ data.satelliteDataArray = s_array;
+
+ // callback HIDL with collected debug data
+ _hidl_cb(data);
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/GnssDebug.h b/gps/android/1.1/GnssDebug.h
new file mode 100644
index 0000000..cb818ac
--- /dev/null
+++ b/gps/android/1.1/GnssDebug.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
+
+
+#include <android/hardware/gnss/1.0/IGnssDebug.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssDebug;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/* Interface for GNSS Debug support. */
+struct Gnss;
+struct GnssDebug : public IGnssDebug {
+ GnssDebug(Gnss* gnss);
+ ~GnssDebug() {};
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+ * These declarations were generated from IGnssDebug.hal.
+ */
+ Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
+
+private:
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSDEBUG_H
diff --git a/gps/android/1.1/GnssGeofencing.cpp b/gps/android/1.1/GnssGeofencing.cpp
new file mode 100644
index 0000000..d57a666
--- /dev/null
+++ b/gps/android/1.1/GnssGeofencing.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHal_GnssGeofencing"
+
+#include <log_util.h>
+#include <GeofenceAPIClient.h>
+#include "GnssGeofencing.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied(
+ uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnssGeofencing != nullptr) {
+ mGnssGeofencing->removeAllGeofences();
+ }
+}
+
+GnssGeofencing::GnssGeofencing() : mApi(nullptr) {
+ mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this);
+}
+
+GnssGeofencing::~GnssGeofencing() {
+ if (mApi != nullptr) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) {
+ if (mApi != nullptr) {
+ LOC_LOGd("mApi is NOT nullptr");
+ return Void();
+ }
+
+ mApi = new GeofenceAPIClient(callback);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+ }
+
+ if (mGnssGeofencingCbIface != nullptr) {
+ mGnssGeofencingCbIface->unlinkToDeath(mGnssGeofencingDeathRecipient);
+ }
+ mGnssGeofencingCbIface = callback;
+ if (mGnssGeofencingCbIface != nullptr) {
+ mGnssGeofencingCbIface->linkToDeath(mGnssGeofencingDeathRecipient, 0 /*cookie*/);
+ }
+
+ return Void();
+}
+
+Return<void> GnssGeofencing::addGeofence(
+ int32_t geofenceId,
+ double latitudeDegrees,
+ double longitudeDegrees,
+ double radiusMeters,
+ IGnssGeofenceCallback::GeofenceTransition lastTransition,
+ int32_t monitorTransitions,
+ uint32_t notificationResponsivenessMs,
+ uint32_t unknownTimerMs) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofenceAdd(
+ geofenceId,
+ latitudeDegrees,
+ longitudeDegrees,
+ radiusMeters,
+ static_cast<int32_t>(lastTransition),
+ monitorTransitions,
+ notificationResponsivenessMs,
+ unknownTimerMs);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofencePause(geofenceId);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofenceResume(geofenceId, monitorTransitions);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofenceRemove(geofenceId);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::removeAllGeofences() {
+ if (mApi == nullptr) {
+ LOC_LOGD("%s]: mApi is nullptr, do nothing", __FUNCTION__);
+ } else {
+ mApi->geofenceRemoveAll();
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/GnssGeofencing.h b/gps/android/1.1/GnssGeofencing.h
new file mode 100644
index 0000000..94a73de
--- /dev/null
+++ b/gps/android/1.1/GnssGeofencing.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H
+
+#include <android/hardware/gnss/1.0/IGnssGeofencing.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using ::android::hardware::gnss::V1_0::IGnssGeofencing;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class GeofenceAPIClient;
+struct GnssGeofencing : public IGnssGeofencing {
+ GnssGeofencing();
+ ~GnssGeofencing();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+ * These declarations were generated from IGnssGeofencing.hal.
+ */
+ Return<void> setCallback(const sp<IGnssGeofenceCallback>& callback) override;
+ Return<void> addGeofence(int32_t geofenceId,
+ double latitudeDegrees,
+ double longitudeDegrees,
+ double radiusMeters,
+ IGnssGeofenceCallback::GeofenceTransition lastTransition,
+ int32_t monitorTransitions,
+ uint32_t notificationResponsivenessMs,
+ uint32_t unknownTimerMs) override;
+
+ Return<void> pauseGeofence(int32_t geofenceId) override;
+ Return<void> resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) override;
+ Return<void> removeGeofence(int32_t geofenceId) override;
+
+ private:
+ // This method is not part of the IGnss base class.
+ // It is called by GnssGeofencingDeathRecipient to remove all geofences added so far.
+ Return<void> removeAllGeofences();
+
+ private:
+ struct GnssGeofencingDeathRecipient : hidl_death_recipient {
+ GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) :
+ mGnssGeofencing(gnssGeofencing) {
+ }
+ ~GnssGeofencingDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssGeofencing> mGnssGeofencing;
+ };
+
+ private:
+ sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr;
+ sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr;
+ GeofenceAPIClient* mApi = nullptr;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H
diff --git a/gps/android/1.1/GnssMeasurement.cpp b/gps/android/1.1/GnssMeasurement.cpp
new file mode 100644
index 0000000..ffe5c52
--- /dev/null
+++ b/gps/android/1.1/GnssMeasurement.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssMeasurementInterface"
+
+#include <log_util.h>
+#include <MeasurementAPIClient.h>
+#include "GnssMeasurement.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied(
+ uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnssMeasurement != nullptr) {
+ mGnssMeasurement->close();
+ }
+}
+
+GnssMeasurement::GnssMeasurement() {
+ mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this);
+ mApi = new MeasurementAPIClient();
+}
+
+GnssMeasurement::~GnssMeasurement() {
+ if (mApi) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+
+Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback) {
+
+ Return<IGnssMeasurement::GnssMeasurementStatus> ret =
+ IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+ if (mGnssMeasurementCbIface != nullptr) {
+ LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+ return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+ }
+
+ if (callback == nullptr) {
+ LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+ return ret;
+ }
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return ret;
+ }
+
+ mGnssMeasurementCbIface = callback;
+ mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ return mApi->measurementSetCallback(callback);
+
+}
+
+Return<void> GnssMeasurement::close() {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ if (mGnssMeasurementCbIface != nullptr) {
+ mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
+ mGnssMeasurementCbIface = nullptr;
+ }
+ if (mGnssMeasurementCbIface_1_1 != nullptr) {
+ mGnssMeasurementCbIface_1_1->unlinkToDeath(mGnssMeasurementDeathRecipient);
+ mGnssMeasurementCbIface_1_1 = nullptr;
+ }
+ mApi->measurementClose();
+
+ return Void();
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
+ const sp<IGnssMeasurementCallback>& callback, bool enableFullTracking) {
+
+ Return<IGnssMeasurement::GnssMeasurementStatus> ret =
+ IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+ if (mGnssMeasurementCbIface_1_1 != nullptr) {
+ LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+ return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+ }
+
+ if (callback == nullptr) {
+ LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+ return ret;
+ }
+ if (nullptr == mApi) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return ret;
+ }
+
+ mGnssMeasurementCbIface_1_1 = callback;
+ mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ GnssPowerMode powerMode = enableFullTracking?
+ GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
+
+ return mApi->measurementSetCallback_1_1(callback, powerMode);
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/GnssMeasurement.h b/gps/android/1.1/GnssMeasurement.h
new file mode 100644
index 0000000..373f0d0
--- /dev/null
+++ b/gps/android/1.1/GnssMeasurement.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
+
+#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_1::IGnssMeasurement;
+using ::android::hardware::gnss::V1_1::IGnssMeasurementCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class MeasurementAPIClient;
+struct GnssMeasurement : public IGnssMeasurement {
+ GnssMeasurement();
+ ~GnssMeasurement();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+ * These declarations were generated from IGnssMeasurement.hal.
+ */
+ Return<GnssMeasurement::GnssMeasurementStatus> setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback) override;
+ Return<void> close() override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+ Return<GnssMeasurement::GnssMeasurementStatus> setCallback_1_1(
+ const sp<IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) override;
+
+ private:
+ struct GnssMeasurementDeathRecipient : hidl_death_recipient {
+ GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) :
+ mGnssMeasurement(gnssMeasurement) {
+ }
+ ~GnssMeasurementDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssMeasurement> mGnssMeasurement;
+ };
+
+ private:
+ sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
+ sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
+ sp<IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr;
+ MeasurementAPIClient* mApi;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H
diff --git a/gps/android/1.1/GnssNi.cpp b/gps/android/1.1/GnssNi.cpp
new file mode 100644
index 0000000..5ce9569
--- /dev/null
+++ b/gps/android/1.1/GnssNi.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssNiInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssNi.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ // we do nothing here
+ // Gnss::GnssDeathRecipient will stop the session
+}
+
+GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) {
+ mGnssNiDeathRecipient = new GnssNiDeathRecipient(this);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ mGnss->setGnssNiCb(callback);
+
+ if (mGnssNiCbIface != nullptr) {
+ mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient);
+ }
+ mGnssNiCbIface = callback;
+ if (mGnssNiCbIface != nullptr) {
+ mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/);
+ }
+
+ return Void();
+}
+
+Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ GnssAPIClient* api = mGnss->getApi();
+ if (api == nullptr) {
+ LOC_LOGE("%s]: api is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ api->gnssNiRespond(notifId, userResponse);
+
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/GnssNi.h b/gps/android/1.1/GnssNi.h
new file mode 100644
index 0000000..6733e5b
--- /dev/null
+++ b/gps/android/1.1/GnssNi.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H
+#define ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H
+
+#include <android/hardware/gnss/1.0/IGnssNi.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssNi;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+struct GnssNi : public IGnssNi {
+ GnssNi(Gnss* gnss);
+ ~GnssNi() = default;
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+ * These declarations were generated from IGnssNi.hal.
+ */
+ Return<void> setCallback(const sp<IGnssNiCallback>& callback) override;
+ Return<void> respond(int32_t notifId,
+ IGnssNiCallback::GnssUserResponseType userResponse) override;
+
+ private:
+ struct GnssNiDeathRecipient : hidl_death_recipient {
+ GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) {
+ }
+ ~GnssNiDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssNi> mGnssNi;
+ };
+
+ private:
+ sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr;
+ sp<IGnssNiCallback> mGnssNiCbIface = nullptr;
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H
diff --git a/gps/android/1.1/android.hardware.gnss@1.1-service-qti.rc b/gps/android/1.1/android.hardware.gnss@1.1-service-qti.rc
new file mode 100644
index 0000000..bd65584
--- /dev/null
+++ b/gps/android/1.1/android.hardware.gnss@1.1-service-qti.rc
@@ -0,0 +1,4 @@
+service gnss_service /vendor/bin/hw/android.hardware.gnss@1.1-service-qti
+ class hal
+ user gps
+ group system gps radio vendor_qti_diag
diff --git a/gps/android/1.1/android.hardware.gnss@1.1-service-qti.xml b/gps/android/1.1/android.hardware.gnss@1.1-service-qti.xml
new file mode 100644
index 0000000..c9c83fb
--- /dev/null
+++ b/gps/android/1.1/android.hardware.gnss@1.1-service-qti.xml
@@ -0,0 +1,35 @@
+<!-- Copyright (c) 2019, 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.
+-->
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.gnss</name>
+ <transport>hwbinder</transport>
+ <fqname>@1.1::IGnss/default</fqname>
+ </hal>
+</manifest>
+
diff --git a/gps/android/1.1/location_api/BatchingAPIClient.cpp b/gps/android/1.1/location_api/BatchingAPIClient.cpp
new file mode 100644
index 0000000..82a803f
--- /dev/null
+++ b/gps/android/1.1/location_api/BatchingAPIClient.cpp
@@ -0,0 +1,196 @@
+/* Copyright (c) 2017-2018, 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_BatchingAPIClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "BatchingAPIClient.h"
+
+#include "limits.h"
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssBatching;
+using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
+ LocationCapabilitiesMask mask);
+
+BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) :
+ LocationAPIClientBase(),
+ mGnssBatchingCbIface(callback),
+ mDefaultId(UINT_MAX),
+ mLocationCapabilitiesMask(0)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = nullptr;
+ if (mGnssBatchingCbIface != nullptr) {
+ locationCallbacks.batchingCb = [this](size_t count, Location* location,
+ BatchingOptions batchOptions) {
+ onBatchingCb(count, location, batchOptions);
+ };
+ }
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssNmeaCb = nullptr;
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+BatchingAPIClient::~BatchingAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+int BatchingAPIClient::getBatchSize()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ return locAPIGetBatchSize();
+}
+
+int BatchingAPIClient::startSession(const IGnssBatching::Options& opts)
+{
+ LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
+ static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
+ int retVal = -1;
+ LocationOptions options;
+ convertBatchOption(opts, options, mLocationCapabilitiesMask);
+ uint32_t mode = 0;
+ if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
+ mode = SESSION_MODE_ON_FULL;
+ }
+ if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
+ retVal = 1;
+ }
+ return retVal;
+}
+
+int BatchingAPIClient::updateSessionOptions(const IGnssBatching::Options& opts)
+{
+ LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
+ static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
+ int retVal = -1;
+ LocationOptions options;
+ convertBatchOption(opts, options, mLocationCapabilitiesMask);
+
+ uint32_t mode = 0;
+ if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
+ mode = SESSION_MODE_ON_FULL;
+ }
+ if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
+ retVal = 1;
+ }
+ return retVal;
+}
+
+int BatchingAPIClient::stopSession()
+{
+ LOC_LOGD("%s]: ", __FUNCTION__);
+ int retVal = -1;
+ if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
+ retVal = 1;
+ }
+ return retVal;
+}
+
+void BatchingAPIClient::getBatchedLocation(int last_n_locations)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
+ locAPIGetBatchedLocations(mDefaultId, last_n_locations);
+}
+
+void BatchingAPIClient::flushBatchedLocations()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
+}
+
+void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
+{
+ LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ mLocationCapabilitiesMask = capabilitiesMask;
+}
+
+void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
+ BatchingOptions /*batchOptions*/)
+{
+ LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
+ if (mGnssBatchingCbIface != nullptr && count > 0) {
+ hidl_vec<GnssLocation> locationVec;
+ locationVec.resize(count);
+ for (size_t i = 0; i < count; i++) {
+ convertGnssLocation(location[i], locationVec[i]);
+ }
+ auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
+ LocationCapabilitiesMask mask)
+{
+ memset(&out, 0, sizeof(LocationOptions));
+ out.size = sizeof(LocationOptions);
+ out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
+ out.minDistance = 0;
+ out.mode = GNSS_SUPL_MODE_STANDALONE;
+ if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
+ out.mode = GNSS_SUPL_MODE_MSA;
+ if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
+ out.mode = GNSS_SUPL_MODE_MSB;
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/location_api/BatchingAPIClient.h b/gps/android/1.1/location_api/BatchingAPIClient.h
new file mode 100644
index 0000000..64d47a0
--- /dev/null
+++ b/gps/android/1.1/location_api/BatchingAPIClient.h
@@ -0,0 +1,74 @@
+/* Copyright (c) 2017-2018, 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 BATCHING_API_CLINET_H
+#define BATCHING_API_CLINET_H
+
+#include <android/hardware/gnss/1.0/IGnssBatching.h>
+#include <android/hardware/gnss/1.0/IGnssBatchingCallback.h>
+#include <pthread.h>
+
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+class BatchingAPIClient : public LocationAPIClientBase
+{
+public:
+ BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback);
+ ~BatchingAPIClient();
+ int getBatchSize();
+ int startSession(const V1_0::IGnssBatching::Options& options);
+ int updateSessionOptions(const V1_0::IGnssBatching::Options& options);
+ int stopSession();
+ void getBatchedLocation(int last_n_locations);
+ void flushBatchedLocations();
+
+ inline LocationCapabilitiesMask getCapabilities() { return mLocationCapabilitiesMask; }
+
+ // callbacks
+ void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
+ void onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions) final;
+
+private:
+ sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
+ uint32_t mDefaultId;
+ LocationCapabilitiesMask mLocationCapabilitiesMask;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // BATCHING_API_CLINET_H
diff --git a/gps/android/1.1/location_api/GeofenceAPIClient.cpp b/gps/android/1.1/location_api/GeofenceAPIClient.cpp
new file mode 100644
index 0000000..93d175e
--- /dev/null
+++ b/gps/android/1.1/location_api/GeofenceAPIClient.cpp
@@ -0,0 +1,275 @@
+/* Copyright (c) 2017-2018, 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_GeofenceApiClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "GeofenceAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) :
+ LocationAPIClientBase(),
+ mGnssGeofencingCbIface(callback)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = nullptr;
+
+ locationCallbacks.geofenceBreachCb = nullptr;
+ if (mGnssGeofencingCbIface != nullptr) {
+ locationCallbacks.geofenceBreachCb =
+ [this](GeofenceBreachNotification geofenceBreachNotification) {
+ onGeofenceBreachCb(geofenceBreachNotification);
+ };
+
+ locationCallbacks.geofenceStatusCb =
+ [this](GeofenceStatusNotification geofenceStatusNotification) {
+ onGeofenceStatusCb(geofenceStatusNotification);
+ };
+ }
+
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssNmeaCb = nullptr;
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
+ double radius_meters, int32_t last_transition, int32_t monitor_transitions,
+ uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms)
+{
+ LOC_LOGD("%s]: (%d %f %f %f %d %d %d %d)", __FUNCTION__,
+ geofence_id, latitude, longitude, radius_meters,
+ last_transition, monitor_transitions, notification_responsiveness_ms, unknown_timer_ms);
+
+ GeofenceOption options;
+ memset(&options, 0, sizeof(GeofenceOption));
+ options.size = sizeof(GeofenceOption);
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
+ options.breachTypeMask |= GEOFENCE_BREACH_ENTER_BIT;
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
+ options.breachTypeMask |= GEOFENCE_BREACH_EXIT_BIT;
+ options.responsiveness = notification_responsiveness_ms;
+
+ GeofenceInfo data;
+ data.size = sizeof(GeofenceInfo);
+ data.latitude = latitude;
+ data.longitude = longitude;
+ data.radius = radius_meters;
+
+ LocationError err = (LocationError)locAPIAddGeofences(1, &geofence_id, &options, &data);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ onAddGeofencesCb(1, &err, &geofence_id);
+ }
+}
+
+void GeofenceAPIClient::geofencePause(uint32_t geofence_id)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
+ locAPIPauseGeofences(1, &geofence_id);
+}
+
+void GeofenceAPIClient::geofenceResume(uint32_t geofence_id, int32_t monitor_transitions)
+{
+ LOC_LOGD("%s]: (%d %d)", __FUNCTION__, geofence_id, monitor_transitions);
+ GeofenceBreachTypeMask mask = 0;
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
+ mask |= GEOFENCE_BREACH_ENTER_BIT;
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
+ mask |= GEOFENCE_BREACH_EXIT_BIT;
+ locAPIResumeGeofences(1, &geofence_id, &mask);
+}
+
+void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
+ locAPIRemoveGeofences(1, &geofence_id);
+}
+
+void GeofenceAPIClient::geofenceRemoveAll()
+{
+ LOC_LOGD("%s]", __FUNCTION__);
+ // TODO locAPIRemoveAllGeofences();
+}
+
+// callbacks
+void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < geofenceBreachNotification.count; i++) {
+ GnssLocation gnssLocation;
+ convertGnssLocation(geofenceBreachNotification.location, gnssLocation);
+
+ IGnssGeofenceCallback::GeofenceTransition transition;
+ if (geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER)
+ transition = IGnssGeofenceCallback::GeofenceTransition::ENTERED;
+ else if (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT)
+ transition = IGnssGeofenceCallback::GeofenceTransition::EXITED;
+ else {
+ // continue with other breach if transition is
+ // nether GPS_GEOFENCE_ENTERED nor GPS_GEOFENCE_EXITED
+ continue;
+ }
+
+ auto r = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
+ geofenceBreachNotification.ids[i], gnssLocation, transition,
+ static_cast<V1_0::GnssUtcTime>(geofenceBreachNotification.timestamp));
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceTransitionCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available);
+ if (mGnssGeofencingCbIface != nullptr) {
+ IGnssGeofenceCallback::GeofenceAvailability status =
+ IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE;
+ if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) {
+ status = IGnssGeofenceCallback::GeofenceAvailability::AVAILABLE;
+ }
+ GnssLocation gnssLocation;
+ memset(&gnssLocation, 0, sizeof(GnssLocation));
+ auto r = mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_EXISTS)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS;
+ auto r = mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+ auto r = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+ auto r = mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+ auto r = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/location_api/GeofenceAPIClient.h b/gps/android/1.1/location_api/GeofenceAPIClient.h
new file mode 100644
index 0000000..c74a59a
--- /dev/null
+++ b/gps/android/1.1/location_api/GeofenceAPIClient.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2017-2018, 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 GEOFENCE_API_CLINET_H
+#define GEOFENCE_API_CLINET_H
+
+
+#include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h>
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::sp;
+
+class GeofenceAPIClient : public LocationAPIClientBase
+{
+public:
+ GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback);
+ virtual ~GeofenceAPIClient() = default;
+
+ void geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
+ double radius_meters, int32_t last_transition, int32_t monitor_transitions,
+ uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms);
+ void geofencePause(uint32_t geofence_id);
+ void geofenceResume(uint32_t geofence_id, int32_t monitor_transitions);
+ void geofenceRemove(uint32_t geofence_id);
+ void geofenceRemoveAll();
+
+ // callbacks
+ void onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) final;
+ void onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) final;
+ void onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+ void onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+ void onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+ void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+
+private:
+ sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // GEOFENCE_API_CLINET_H
diff --git a/gps/android/1.1/location_api/GnssAPIClient.cpp b/gps/android/1.1/location_api/GnssAPIClient.cpp
new file mode 100644
index 0000000..9a95fdf
--- /dev/null
+++ b/gps/android/1.1/location_api/GnssAPIClient.cpp
@@ -0,0 +1,566 @@
+/* Copyright (c) 2017-2019, 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_GnssAPIClient"
+#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "GnssAPIClient.h"
+#include <LocContext.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnss;
+using ::android::hardware::gnss::V1_0::IGnssCallback;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out);
+
+GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb,
+ const sp<IGnssNiCallback>& niCb) :
+ LocationAPIClientBase(),
+ mGnssCbIface(nullptr),
+ mGnssNiCbIface(nullptr),
+ mControlClient(new LocationAPIControlClient()),
+ mLocationCapabilitiesMask(0),
+ mLocationCapabilitiesCached(false)
+{
+ LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
+
+ // set default LocationOptions.
+ memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+ mTrackingOptions.size = sizeof(TrackingOptions);
+ mTrackingOptions.minInterval = 1000;
+ mTrackingOptions.minDistance = 0;
+ mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+
+ gnssUpdateCallbacks(gpsCb, niCb);
+}
+
+GnssAPIClient::~GnssAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ if (mControlClient) {
+ delete mControlClient;
+ mControlClient = nullptr;
+ }
+}
+
+// for GpsInterface
+void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
+ const sp<IGnssNiCallback>& niCb)
+{
+ LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
+
+ mMutex.lock();
+ mGnssCbIface = gpsCb;
+ mGnssNiCbIface = niCb;
+ mMutex.unlock();
+
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ if (mGnssCbIface != nullptr) {
+ locationCallbacks.trackingCb = [this](Location location) {
+ onTrackingCb(location);
+ };
+ }
+
+ locationCallbacks.batchingCb = nullptr;
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+
+ locationCallbacks.gnssNiCb = nullptr;
+ loc_core::ContextBase* context =
+ loc_core::LocContext::getLocContext(
+ NULL, NULL,
+ loc_core::LocContext::mLocationHalName, false);
+ if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
+ LOC_LOGD("Registering NI CB");
+ locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
+ onGnssNiCb(id, gnssNiNotification);
+ };
+ }
+
+ locationCallbacks.gnssSvCb = nullptr;
+ if (mGnssCbIface != nullptr) {
+ locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
+ onGnssSvCb(gnssSvNotification);
+ };
+ }
+
+ locationCallbacks.gnssNmeaCb = nullptr;
+ if (mGnssCbIface != nullptr) {
+ locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
+ onGnssNmeaCb(gnssNmeaNotification);
+ };
+ }
+
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+bool GnssAPIClient::gnssStart()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ bool retVal = true;
+ locAPIStartTracking(mTrackingOptions);
+ return retVal;
+}
+
+bool GnssAPIClient::gnssStop()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ bool retVal = true;
+ locAPIStopTracking();
+ return retVal;
+}
+
+bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
+ IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LOC_LOGD("%s]: (%d %d %d %d %d %d %d)", __FUNCTION__,
+ (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters,
+ preferredTimeMs, (int)powerMode, timeBetweenMeasurement);
+ bool retVal = true;
+ memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+ mTrackingOptions.size = sizeof(TrackingOptions);
+ mTrackingOptions.minInterval = minIntervalMs;
+ if (IGnss::GnssPositionMode::MS_ASSISTED == mode ||
+ IGnss::GnssPositionRecurrence::RECURRENCE_SINGLE == recurrence) {
+ // We set a very large interval to simulate SINGLE mode. Once we report a fix,
+ // the caller should take the responsibility to stop the session.
+ // For MSA, we always treat it as SINGLE mode.
+ mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC;
+ }
+ mTrackingOptions.minDistance = preferredAccuracyMeters;
+ if (mode == IGnss::GnssPositionMode::STANDALONE)
+ mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+ else if (mode == IGnss::GnssPositionMode::MS_BASED)
+ mTrackingOptions.mode = GNSS_SUPL_MODE_MSB;
+ else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
+ mTrackingOptions.mode = GNSS_SUPL_MODE_MSA;
+ else {
+ LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
+ retVal = false;
+ }
+ if (GNSS_POWER_MODE_INVALID != powerMode) {
+ mTrackingOptions.powerMode = powerMode;
+ mTrackingOptions.tbm = timeBetweenMeasurement;
+ }
+ locAPIUpdateTrackingOptions(mTrackingOptions);
+ return retVal;
+}
+
+// for GpsNiInterface
+void GnssAPIClient::gnssNiRespond(int32_t notifId,
+ IGnssNiCallback::GnssUserResponseType userResponse)
+{
+ LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
+ GnssNiResponse data;
+ switch (userResponse) {
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT:
+ data = GNSS_NI_RESPONSE_ACCEPT;
+ break;
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY:
+ data = GNSS_NI_RESPONSE_DENY;
+ break;
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP:
+ data = GNSS_NI_RESPONSE_NO_RESPONSE;
+ break;
+ default:
+ data = GNSS_NI_RESPONSE_IGNORE;
+ break;
+ }
+
+ locAPIGnssNiResponse(notifId, data);
+}
+
+// these apis using LocationAPIControlClient
+void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
+{
+ LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ GnssAidingData data;
+ memset(&data, 0, sizeof (GnssAidingData));
+ data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT;
+ data.posEngineMask = STANDARD_POSITIONING_ENGINE;
+
+ if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
+ data.deleteAll = true;
+ else {
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
+ }
+ mControlClient->locAPIGnssDeleteAidingData(data);
+}
+
+void GnssAPIClient::gnssEnable(LocationTechnologyType techType)
+{
+ LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ mControlClient->locAPIEnable(techType);
+}
+
+void GnssAPIClient::gnssDisable()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ mControlClient->locAPIDisable();
+}
+
+void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
+{
+ LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ mControlClient->locAPIGnssUpdateConfig(gnssConfig);
+}
+
+void GnssAPIClient::requestCapabilities() {
+ // only send capablities if it's already cached, otherwise the first time LocationAPI
+ // is initialized, capabilities will be sent by LocationAPI
+ if (mLocationCapabilitiesCached) {
+ onCapabilitiesCb(mLocationCapabilitiesMask);
+ }
+}
+
+// callbacks
+void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
+{
+ LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ mLocationCapabilitiesMask = capabilitiesMask;
+ mLocationCapabilitiesCached = true;
+
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr) {
+ uint32_t data = 0;
+ if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
+ (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
+ (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
+ (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
+ data |= IGnssCallback::Capabilities::SCHEDULING;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
+ data |= IGnssCallback::Capabilities::GEOFENCING;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
+ data |= IGnssCallback::Capabilities::MEASUREMENTS;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
+ data |= IGnssCallback::Capabilities::MSB;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
+ data |= IGnssCallback::Capabilities::MSA;
+ auto r = gnssCbIface->gnssSetCapabilitesCb(data);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ if (gnssCbIface != nullptr) {
+ IGnssCallback::GnssSystemInfo gnssInfo;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
+ capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
+ gnssInfo.yearOfHw = 2018;
+ } else if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
+ gnssInfo.yearOfHw = 2017;
+ } else if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
+ gnssInfo.yearOfHw = 2016;
+ } else {
+ gnssInfo.yearOfHw = 2015;
+ }
+ LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
+ auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GnssAPIClient::onTrackingCb(Location location)
+{
+ LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr) {
+ GnssLocation gnssLocation;
+ convertGnssLocation(location, gnssLocation);
+ auto r = gnssCbIface->gnssLocationCb(gnssLocation);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
+{
+ LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
+ mMutex.lock();
+ auto gnssNiCbIface(mGnssNiCbIface);
+ mMutex.unlock();
+
+ if (gnssNiCbIface == nullptr) {
+ LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
+ return;
+ }
+
+ IGnssNiCallback::GnssNiNotification notificationGnss = {};
+
+ notificationGnss.notificationId = id;
+
+ if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
+ else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
+ else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
+ else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
+
+ if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
+ notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
+ if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
+ notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
+ if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
+ notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
+
+ notificationGnss.timeoutSec = gnssNiNotification.timeout;
+
+ if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
+ notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
+ else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
+ notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
+ else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
+ gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
+ notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
+
+ notificationGnss.requestorId = gnssNiNotification.requestor;
+
+ notificationGnss.notificationMessage = gnssNiNotification.message;
+
+ if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
+ else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
+ else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
+ else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
+
+ if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
+ else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
+ else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
+ else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
+
+ gnssNiCbIface->niNotifyCb(notificationGnss);
+}
+
+void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
+{
+ LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr) {
+ IGnssCallback::GnssSvStatus svStatus;
+ convertGnssSvStatus(gnssSvNotification, svStatus);
+ auto r = gnssCbIface->gnssSvStatusCb(svStatus);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
+{
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr) {
+ const std::string s(gnssNmeaNotification.nmea);
+ std::stringstream ss(s);
+ std::string each;
+ while(std::getline(ss, each, '\n')) {
+ each += '\n';
+ android::hardware::hidl_string nmeaString;
+ nmeaString.setToExternal(each.c_str(), each.length());
+ auto r = gnssCbIface->gnssNmeaCb(
+ static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__,
+ gnssNmeaNotification.nmea, gnssNmeaNotification.length,
+ r.description().c_str());
+ }
+ }
+ }
+}
+
+void GnssAPIClient::onStartTrackingCb(LocationError error)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GnssAPIClient::onStopTrackingCb(LocationError error)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ mMutex.unlock();
+
+ if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out)
+{
+ memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
+ out.numSvs = in.count;
+ if (out.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+ LOC_LOGW("%s]: Too many satellites %u. Clamps to %d.",
+ __FUNCTION__, out.numSvs, V1_0::GnssMax::SVS_COUNT);
+ out.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
+ }
+ for (size_t i = 0; i < out.numSvs; i++) {
+ IGnssCallback::GnssSvInfo& info = out.gnssSvList[i];
+ info.svid = in.gnssSvs[i].svId;
+ convertGnssConstellationType(in.gnssSvs[i].type, info.constellation);
+ info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
+ info.elevationDegrees = in.gnssSvs[i].elevation;
+ info.azimuthDegrees = in.gnssSvs[i].azimuth;
+ info.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
+ info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
+ info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
+ info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
+ info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+ info.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+ }
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/location_api/GnssAPIClient.h b/gps/android/1.1/location_api/GnssAPIClient.h
new file mode 100644
index 0000000..82f8fbf
--- /dev/null
+++ b/gps/android/1.1/location_api/GnssAPIClient.h
@@ -0,0 +1,109 @@
+/* Copyright (c) 2017-2018, 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 GNSS_API_CLINET_H
+#define GNSS_API_CLINET_H
+
+
+#include <mutex>
+#include <android/hardware/gnss/1.1/IGnss.h>
+#include <android/hardware/gnss/1.1/IGnssCallback.h>
+#include <android/hardware/gnss/1.0/IGnssNiCallback.h>
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::sp;
+
+class GnssAPIClient : public LocationAPIClientBase
+{
+public:
+ GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<V1_0::IGnssNiCallback>& niCb);
+ virtual ~GnssAPIClient();
+ GnssAPIClient(const GnssAPIClient&) = delete;
+ GnssAPIClient& operator=(const GnssAPIClient&) = delete;
+
+ // for GpsInterface
+ void gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<V1_0::IGnssNiCallback>& niCb);
+ bool gnssStart();
+ bool gnssStop();
+ bool gnssSetPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs,
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = 0);
+
+ // for GpsNiInterface
+ void gnssNiRespond(int32_t notifId, V1_0::IGnssNiCallback::GnssUserResponseType userResponse);
+
+ // these apis using LocationAPIControlClient
+ void gnssDeleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags);
+ void gnssEnable(LocationTechnologyType techType);
+ void gnssDisable();
+ void gnssConfigurationUpdate(const GnssConfig& gnssConfig);
+
+ inline LocationCapabilitiesMask gnssGetCapabilities() const {
+ return mLocationCapabilitiesMask;
+ }
+ void requestCapabilities();
+
+ // callbacks we are interested in
+ void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
+ void onTrackingCb(Location location) final;
+ void onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) final;
+ void onGnssSvCb(GnssSvNotification gnssSvNotification) final;
+ void onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) final;
+
+ void onStartTrackingCb(LocationError error) final;
+ void onStopTrackingCb(LocationError error) final;
+
+private:
+ sp<V1_0::IGnssCallback> mGnssCbIface;
+ sp<V1_0::IGnssNiCallback> mGnssNiCbIface;
+ std::mutex mMutex;
+ LocationAPIControlClient* mControlClient;
+ LocationCapabilitiesMask mLocationCapabilitiesMask;
+ bool mLocationCapabilitiesCached;
+ TrackingOptions mTrackingOptions;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // GNSS_API_CLINET_H
diff --git a/gps/android/1.1/location_api/LocationUtil.cpp b/gps/android/1.1/location_api/LocationUtil.cpp
new file mode 100644
index 0000000..f1d051c
--- /dev/null
+++ b/gps/android/1.1/location_api/LocationUtil.cpp
@@ -0,0 +1,206 @@
+/* Copyright (c) 2017-2018, 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.
+ *
+ */
+
+#include <LocationUtil.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+using ::android::hardware::gnss::V1_0::GnssLocationFlags;
+
+void convertGnssLocation(Location& in, GnssLocation& out)
+{
+ memset(&out, 0, sizeof(GnssLocation));
+ if (in.flags & LOCATION_HAS_LAT_LONG_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
+ out.latitudeDegrees = in.latitude;
+ out.longitudeDegrees = in.longitude;
+ }
+ if (in.flags & LOCATION_HAS_ALTITUDE_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
+ out.altitudeMeters = in.altitude;
+ }
+ if (in.flags & LOCATION_HAS_SPEED_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
+ out.speedMetersPerSec = in.speed;
+ }
+ if (in.flags & LOCATION_HAS_BEARING_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
+ out.bearingDegrees = in.bearing;
+ }
+ if (in.flags & LOCATION_HAS_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
+ out.horizontalAccuracyMeters = in.accuracy;
+ }
+ if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
+ out.verticalAccuracyMeters = in.verticalAccuracy;
+ }
+ if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
+ out.speedAccuracyMetersPerSecond = in.speedAccuracy;
+ }
+ if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
+ out.bearingAccuracyDegrees = in.bearingAccuracy;
+ }
+
+ out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
+}
+
+void convertGnssLocation(const GnssLocation& in, Location& out)
+{
+ memset(&out, 0, sizeof(out));
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) {
+ out.flags |= LOCATION_HAS_LAT_LONG_BIT;
+ out.latitude = in.latitudeDegrees;
+ out.longitude = in.longitudeDegrees;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE) {
+ out.flags |= LOCATION_HAS_ALTITUDE_BIT;
+ out.altitude = in.altitudeMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED) {
+ out.flags |= LOCATION_HAS_SPEED_BIT;
+ out.speed = in.speedMetersPerSec;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+ out.flags |= LOCATION_HAS_BEARING_BIT;
+ out.bearing = in.bearingDegrees;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
+ out.flags |= LOCATION_HAS_ACCURACY_BIT;
+ out.accuracy = in.horizontalAccuracyMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+ out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
+ out.verticalAccuracy = in.verticalAccuracyMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
+ out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
+ out.speedAccuracy = in.speedAccuracyMetersPerSecond;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
+ out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
+ out.bearingAccuracy = in.bearingAccuracyDegrees;
+ }
+
+ out.timestamp = static_cast<uint64_t>(in.timestamp);
+}
+
+void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out)
+{
+ switch(in) {
+ case GNSS_SV_TYPE_GPS:
+ out = GnssConstellationType::GPS;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = GnssConstellationType::SBAS;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ out = GnssConstellationType::GLONASS;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = GnssConstellationType::QZSS;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = GnssConstellationType::BEIDOU;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = GnssConstellationType::GALILEO;
+ break;
+ case GNSS_SV_TYPE_UNKNOWN:
+ default:
+ out = GnssConstellationType::UNKNOWN;
+ break;
+ }
+}
+
+void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
+{
+ switch(in) {
+ case GNSS_EPH_TYPE_EPHEMERIS:
+ out = GnssDebug::SatelliteEphemerisType::EPHEMERIS;
+ break;
+ case GNSS_EPH_TYPE_ALMANAC:
+ out = GnssDebug::SatelliteEphemerisType::ALMANAC_ONLY;
+ break;
+ case GNSS_EPH_TYPE_UNKNOWN:
+ default:
+ out = GnssDebug::SatelliteEphemerisType::NOT_AVAILABLE;
+ break;
+ }
+}
+
+void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out)
+{
+ switch(in) {
+ case GNSS_EPH_SOURCE_DEMODULATED:
+ out = GnssDebug::SatelliteEphemerisSource::DEMODULATED;
+ break;
+ case GNSS_EPH_SOURCE_SUPL_PROVIDED:
+ out = GnssDebug::SatelliteEphemerisSource::SUPL_PROVIDED;
+ break;
+ case GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED:
+ out = GnssDebug::SatelliteEphemerisSource::OTHER_SERVER_PROVIDED;
+ break;
+ case GNSS_EPH_SOURCE_LOCAL:
+ case GNSS_EPH_SOURCE_UNKNOWN:
+ default:
+ out = GnssDebug::SatelliteEphemerisSource::OTHER;
+ break;
+ }
+}
+
+void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out)
+{
+ switch(in) {
+ case GNSS_EPH_HEALTH_GOOD:
+ out = GnssDebug::SatelliteEphemerisHealth::GOOD;
+ break;
+ case GNSS_EPH_HEALTH_BAD:
+ out = GnssDebug::SatelliteEphemerisHealth::BAD;
+ break;
+ case GNSS_EPH_HEALTH_UNKNOWN:
+ default:
+ out = GnssDebug::SatelliteEphemerisHealth::UNKNOWN;
+ break;
+ }
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/location_api/LocationUtil.h b/gps/android/1.1/location_api/LocationUtil.h
new file mode 100644
index 0000000..63f4f6f
--- /dev/null
+++ b/gps/android/1.1/location_api/LocationUtil.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2017-2018, 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 LOCATION_UTIL_H
+#define LOCATION_UTIL_H
+
+#include <android/hardware/gnss/1.0/types.h>
+#include <LocationAPI.h>
+#include <GnssDebug.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+void convertGnssLocation(Location& in, V1_0::GnssLocation& out);
+void convertGnssLocation(const V1_0::GnssLocation& in, Location& out);
+void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out);
+void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
+void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
+void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // LOCATION_UTIL_H
diff --git a/gps/android/1.1/location_api/MeasurementAPIClient.cpp b/gps/android/1.1/location_api/MeasurementAPIClient.cpp
new file mode 100644
index 0000000..6f25067
--- /dev/null
+++ b/gps/android/1.1/location_api/MeasurementAPIClient.cpp
@@ -0,0 +1,332 @@
+/* Copyright (c) 2017-2018, 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_MeasurementAPIClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "MeasurementAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssMeasurement;
+using ::android::hardware::gnss::V1_1::IGnssMeasurementCallback;
+
+static void convertGnssData(GnssMeasurementsNotification& in,
+ V1_0::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssData_1_1(GnssMeasurementsNotification& in,
+ IGnssMeasurementCallback::GnssData& out);
+static void convertGnssMeasurement(GnssMeasurementsData& in,
+ V1_0::IGnssMeasurementCallback::GnssMeasurement& out);
+static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out);
+
+MeasurementAPIClient::MeasurementAPIClient() :
+ mGnssMeasurementCbIface(nullptr),
+ mGnssMeasurementCbIface_1_1(nullptr),
+ mTracking(false)
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+MeasurementAPIClient::~MeasurementAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+// for GpsInterface
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ mMutex.lock();
+ mGnssMeasurementCbIface = callback;
+ mMutex.unlock();
+
+ return startTracking();
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback_1_1(
+ const sp<IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
+ __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
+
+ mMutex.lock();
+ mGnssMeasurementCbIface_1_1 = callback;
+ mMutex.unlock();
+
+ return startTracking(powerMode, timeBetweenMeasurement);
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::startTracking(
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = nullptr;
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssNmeaCb = nullptr;
+
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+ if (mGnssMeasurementCbIface_1_1 != nullptr || mGnssMeasurementCbIface != nullptr) {
+ locationCallbacks.gnssMeasurementsCb =
+ [this](GnssMeasurementsNotification gnssMeasurementsNotification) {
+ onGnssMeasurementsCb(gnssMeasurementsNotification);
+ };
+ }
+
+ locAPISetCallbacks(locationCallbacks);
+
+ TrackingOptions options = {};
+ memset(&options, 0, sizeof(TrackingOptions));
+ options.size = sizeof(TrackingOptions);
+ options.minInterval = 1000;
+ options.mode = GNSS_SUPL_MODE_STANDALONE;
+ if (GNSS_POWER_MODE_INVALID != powerMode) {
+ options.powerMode = powerMode;
+ options.tbm = timeBetweenMeasurement;
+ }
+
+ mTracking = true;
+ LOC_LOGD("%s]: start tracking session", __FUNCTION__);
+ locAPIStartTracking(options);
+ return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
+}
+
+// for GpsMeasurementInterface
+void MeasurementAPIClient::measurementClose() {
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ mTracking = false;
+ locAPIStopTracking();
+}
+
+// callbacks
+void MeasurementAPIClient::onGnssMeasurementsCb(
+ GnssMeasurementsNotification gnssMeasurementsNotification)
+{
+ LOC_LOGD("%s]: (count: %zu active: %d)",
+ __FUNCTION__, gnssMeasurementsNotification.count, mTracking);
+ if (mTracking) {
+ mMutex.lock();
+ sp<V1_0::IGnssMeasurementCallback> gnssMeasurementCbIface = nullptr;
+ sp<IGnssMeasurementCallback> gnssMeasurementCbIface_1_1 = nullptr;
+ if (mGnssMeasurementCbIface_1_1 != nullptr) {
+ gnssMeasurementCbIface_1_1 = mGnssMeasurementCbIface_1_1;
+ } else if (mGnssMeasurementCbIface != nullptr) {
+ gnssMeasurementCbIface = mGnssMeasurementCbIface;
+ }
+ mMutex.unlock();
+
+ if (gnssMeasurementCbIface_1_1 != nullptr) {
+ IGnssMeasurementCallback::GnssData gnssData;
+ convertGnssData_1_1(gnssMeasurementsNotification, gnssData);
+ auto r = gnssMeasurementCbIface_1_1->gnssMeasurementCb(gnssData);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssMeasurementCbIface != nullptr) {
+ V1_0::IGnssMeasurementCallback::GnssData gnssData;
+ convertGnssData(gnssMeasurementsNotification, gnssData);
+ auto r = gnssMeasurementCbIface->GnssMeasurementCb(gnssData);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from GnssMeasurementCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+static void convertGnssMeasurement(GnssMeasurementsData& in,
+ V1_0::IGnssMeasurementCallback::GnssMeasurement& out)
+{
+ memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssMeasurement));
+ if (in.flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SNR;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_FREQUENCY;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_CYCLES;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL;
+ out.svid = in.svId;
+ convertGnssConstellationType(in.svType, out.constellation);
+ out.timeOffsetNs = in.timeOffsetNs;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC;
+ out.receivedSvTimeInNs = in.receivedSvTimeNs;
+ out.receivedSvTimeUncertaintyInNs = in.receivedSvTimeUncertaintyNs;
+ out.cN0DbHz = in.carrierToNoiseDbHz;
+ out.pseudorangeRateMps = in.pseudorangeRateMps;
+ out.pseudorangeRateUncertaintyMps = in.pseudorangeRateUncertaintyMps;
+ if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ out.accumulatedDeltaRangeM = in.adrMeters;
+ out.accumulatedDeltaRangeUncertaintyM = in.adrUncertaintyMeters;
+ out.carrierFrequencyHz = in.carrierFrequencyHz;
+ out.carrierCycles = in.carrierCycles;
+ out.carrierPhase = in.carrierPhase;
+ out.carrierPhaseUncertainty = in.carrierPhaseUncertainty;
+ uint8_t indicator =
+ static_cast<uint8_t>(IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN);
+ if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT)
+ indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_PRESENT;
+ if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT)
+ indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATIOR_NOT_PRESENT;
+ out.multipathIndicator =
+ static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(indicator);
+ out.snrDb = in.signalToNoiseRatioDb;
+ out.agcLevelDb = in.agcLevelDb;
+}
+
+static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out)
+{
+ memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssClock));
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_LEAP_SECOND;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_TIME_UNCERTAINTY;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_FULL_BIAS;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS_UNCERTAINTY;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT_UNCERTAINTY;
+ out.leapSecond = in.leapSecond;
+ out.timeNs = in.timeNs;
+ out.timeUncertaintyNs = in.timeUncertaintyNs;
+ out.fullBiasNs = in.fullBiasNs;
+ out.biasNs = in.biasNs;
+ out.biasUncertaintyNs = in.biasUncertaintyNs;
+ out.driftNsps = in.driftNsps;
+ out.driftUncertaintyNsps = in.driftUncertaintyNsps;
+ out.hwClockDiscontinuityCount = in.hwClockDiscontinuityCount;
+}
+
+static void convertGnssData(GnssMeasurementsNotification& in,
+ V1_0::IGnssMeasurementCallback::GnssData& out)
+{
+ out.measurementCount = in.count;
+ if (out.measurementCount > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+ LOC_LOGW("%s]: Too many measurement %u. Clamps to %d.",
+ __FUNCTION__, out.measurementCount, V1_0::GnssMax::SVS_COUNT);
+ out.measurementCount = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
+ }
+ for (size_t i = 0; i < out.measurementCount; i++) {
+ convertGnssMeasurement(in.measurements[i], out.measurements[i]);
+ }
+ convertGnssClock(in.clock, out.clock);
+}
+
+static void convertGnssData_1_1(GnssMeasurementsNotification& in,
+ IGnssMeasurementCallback::GnssData& out)
+{
+ out.measurements.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_0);
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_HALF_CYCLE_RESOLVED;
+ }
+ convertGnssClock(in.clock, out.clock);
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/1.1/location_api/MeasurementAPIClient.h b/gps/android/1.1/location_api/MeasurementAPIClient.h
new file mode 100644
index 0000000..38811c5
--- /dev/null
+++ b/gps/android/1.1/location_api/MeasurementAPIClient.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2017-2018, 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 MEASUREMENT_API_CLINET_H
+#define MEASUREMENT_API_CLINET_H
+
+#include <mutex>
+#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
+#include <android/hardware/gnss/1.1/IGnssMeasurementCallback.h>
+#include <LocationAPIClientBase.h>
+#include <hidl/Status.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::sp;
+
+class MeasurementAPIClient : public LocationAPIClientBase
+{
+public:
+ MeasurementAPIClient();
+ virtual ~MeasurementAPIClient();
+ MeasurementAPIClient(const MeasurementAPIClient&) = delete;
+ MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
+
+ // for GpsMeasurementInterface
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback);
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_1_1(
+ const sp<IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+ void measurementClose();
+ Return<IGnssMeasurement::GnssMeasurementStatus> startTracking(
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+
+ // callbacks we are interested in
+ void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
+
+private:
+ std::mutex mMutex;
+ sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface;
+ sp<IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1;
+
+ bool mTracking;
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // MEASUREMENT_API_CLINET_H
diff --git a/gps/android/1.1/service.cpp b/gps/android/1.1/service.cpp
new file mode 100644
index 0000000..0cb91f7
--- /dev/null
+++ b/gps/android/1.1/service.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.gnss@1.1-service-qti"
+
+#include <android/hardware/gnss/1.1/IGnss.h>
+#include <hidl/LegacySupport.h>
+#include "loc_cfg.h"
+#include "loc_misc_utils.h"
+
+extern "C" {
+#include "vndfwk-detect.h"
+}
+
+#ifdef ARCH_ARM_32
+#define DEFAULT_HW_BINDER_MEM_SIZE 65536
+#endif
+
+using android::hardware::gnss::V1_1::IGnss;
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+
+using android::status_t;
+using android::OK;
+
+typedef int vendorEnhancedServiceMain(int /* argc */, char* /* argv */ []);
+
+int main() {
+
+ ALOGI("%s", __FUNCTION__);
+
+ int vendorInfo = getVendorEnhancedInfo();
+ bool vendorEnhanced = ( 1 == vendorInfo || 3 == vendorInfo );
+ setVendorEnhanced(vendorEnhanced);
+
+#ifdef ARCH_ARM_32
+ android::hardware::ProcessState::initWithMmapSize((size_t)(DEFAULT_HW_BINDER_MEM_SIZE));
+#endif
+ configureRpcThreadpool(1, true);
+ status_t status;
+
+ status = registerPassthroughServiceImplementation<IGnss>();
+ if (status == OK) {
+ if (vendorEnhanced) {
+ #ifdef LOC_HIDL_VERSION
+ #define VENDOR_ENHANCED_LIB "vendor.qti.gnss@" LOC_HIDL_VERSION "-service.so"
+
+ void* libHandle = NULL;
+ vendorEnhancedServiceMain* vendorEnhancedMainMethod = (vendorEnhancedServiceMain*)
+ dlGetSymFromLib(libHandle, VENDOR_ENHANCED_LIB, "main");
+ if (NULL != vendorEnhancedMainMethod) {
+ (*vendorEnhancedMainMethod)(0, NULL);
+ }
+ #else
+ ALOGE("LOC_HIDL_VERSION not defined.");
+ #endif
+ }
+
+ joinRpcThreadpool();
+
+ } else {
+ ALOGE("Error while registering IGnss 1.1 service: %d", status);
+ }
+
+ return 0;
+}
diff --git a/gps/android/2.0/AGnss.cpp b/gps/android/2.0/AGnss.cpp
new file mode 100644
index 0000000..a48f1a0
--- /dev/null
+++ b/gps/android/2.0/AGnss.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_AGnssInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "AGnss.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+static AGnss* spAGnss = nullptr;
+
+AGnss::AGnss(Gnss* gnss) : mGnss(gnss) {
+ spAGnss = this;
+}
+
+AGnss::~AGnss() {
+ spAGnss = nullptr;
+}
+
+void AGnss::agnssStatusIpV4Cb(AGnssExtStatusIpV4 status) {
+ if (nullptr != spAGnss) {
+ spAGnss->statusCb(status.type, status.status);
+ }
+}
+
+void AGnss::statusCb(AGpsExtType type, LocAGpsStatusValue status) {
+
+ V2_0::IAGnssCallback::AGnssType aType;
+ IAGnssCallback::AGnssStatusValue aStatus;
+
+ switch (type) {
+ case LOC_AGPS_TYPE_SUPL:
+ aType = IAGnssCallback::AGnssType::SUPL;
+ break;
+ case LOC_AGPS_TYPE_SUPL_ES:
+ aType = IAGnssCallback::AGnssType::SUPL_EIMS;
+ break;
+ default:
+ LOC_LOGE("invalid type: %d", type);
+ return;
+ }
+
+ switch (status) {
+ case LOC_GPS_REQUEST_AGPS_DATA_CONN:
+ aStatus = IAGnssCallback::AGnssStatusValue::REQUEST_AGNSS_DATA_CONN;
+ break;
+ case LOC_GPS_RELEASE_AGPS_DATA_CONN:
+ aStatus = IAGnssCallback::AGnssStatusValue::RELEASE_AGNSS_DATA_CONN;
+ break;
+ case LOC_GPS_AGPS_DATA_CONNECTED:
+ aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONNECTED;
+ break;
+ case LOC_GPS_AGPS_DATA_CONN_DONE:
+ aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_DONE;
+ break;
+ case LOC_GPS_AGPS_DATA_CONN_FAILED:
+ aStatus = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_FAILED;
+ break;
+ default:
+ LOC_LOGE("invalid status: %d", status);
+ return;
+ }
+
+ if (mAGnssCbIface != nullptr) {
+ auto r = mAGnssCbIface->agnssStatusCb(aType, aStatus);
+ if (!r.isOk()) {
+ LOC_LOGw("Error invoking AGNSS status cb %s", r.description().c_str());
+ }
+ }
+ else {
+ LOC_LOGw("setCallback has not been called yet");
+ }
+}
+
+Return<void> AGnss::setCallback(const sp<V2_0::IAGnssCallback>& callback) {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return Void();
+ }
+
+ // Save the interface
+ mAGnssCbIface = callback;
+
+ AgpsCbInfo cbInfo = {};
+ cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb;
+ cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES;
+
+ mGnss->getGnssInterface()->agpsInit(cbInfo);
+ return Void();
+}
+
+Return<bool> AGnss::dataConnClosed() {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return false;
+ }
+
+ mGnss->getGnssInterface()->agpsDataConnClosed(LOC_AGPS_TYPE_SUPL);
+ return true;
+}
+
+Return<bool> AGnss::dataConnFailed() {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return false;
+ }
+
+ mGnss->getGnssInterface()->agpsDataConnFailed(LOC_AGPS_TYPE_SUPL);
+ return true;
+}
+
+Return<bool> AGnss::dataConnOpen(uint64_t /*networkHandle*/, const hidl_string& apn,
+ V2_0::IAGnss::ApnIpType apnIpType) {
+
+ if(mGnss == nullptr || mGnss->getGnssInterface() == nullptr){
+ LOC_LOGE("Null GNSS interface");
+ return false;
+ }
+
+ /* Validate */
+ if(apn.empty()){
+ LOC_LOGE("Invalid APN");
+ return false;
+ }
+
+ LOC_LOGD("dataConnOpen APN name = [%s]", apn.c_str());
+
+ AGpsBearerType bearerType;
+ switch (apnIpType) {
+ case IAGnss::ApnIpType::IPV4:
+ bearerType = AGPS_APN_BEARER_IPV4;
+ break;
+ case IAGnss::ApnIpType::IPV6:
+ bearerType = AGPS_APN_BEARER_IPV6;
+ break;
+ case IAGnss::ApnIpType::IPV4V6:
+ bearerType = AGPS_APN_BEARER_IPV4V6;
+ break;
+ default:
+ bearerType = AGPS_APN_BEARER_IPV4;
+ break;
+ }
+
+ mGnss->getGnssInterface()->agpsDataConnOpen(
+ LOC_AGPS_TYPE_SUPL, apn.c_str(), apn.size(), (int)bearerType);
+ return true;
+}
+
+Return<bool> AGnss::setServer(V2_0::IAGnssCallback::AGnssType type,
+ const hidl_string& hostname,
+ int32_t port) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
+ config.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
+ if (type == IAGnssCallback::AGnssType::SUPL) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL;
+ } else if (type == IAGnssCallback::AGnssType::C2K) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_C2K;
+ } else if (type == IAGnssCallback::AGnssType::SUPL_EIMS) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL_EIMS;
+ } else if (type == IAGnssCallback::AGnssType::SUPL_IMS) {
+ config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL_IMS;
+ } else {
+ LOC_LOGE("%s]: invalid AGnssType: %d", __FUNCTION__, static_cast<uint8_t>(type));
+ return false;
+ }
+ config.assistanceServer.hostName = strdup(hostname.c_str());
+ config.assistanceServer.port = port;
+ return mGnss->updateConfiguration(config);
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/AGnss.h b/gps/android/2.0/AGnss.h
new file mode 100644
index 0000000..c442327
--- /dev/null
+++ b/gps/android/2.0/AGnss.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
+#define ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
+
+#include <android/hardware/gnss/2.0/IAGnss.h>
+#include <hidl/Status.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+struct AGnss : public V2_0::IAGnss {
+
+ AGnss(Gnss* gnss);
+ ~AGnss();
+ /*
+ * Methods from ::android::hardware::gnss::V2_0::IAGnss interface follow.
+ * These declarations were generated from IAGnss.hal.
+ */
+ Return<void> setCallback(const sp<V2_0::IAGnssCallback>& callback) override;
+
+ Return<bool> dataConnClosed() override;
+
+ Return<bool> dataConnFailed() override;
+
+ Return<bool> dataConnOpen(uint64_t networkHandle, const hidl_string& apn,
+ V2_0::IAGnss::ApnIpType apnIpType) override;
+
+ Return<bool> setServer(V2_0::IAGnssCallback::AGnssType type,
+ const hidl_string& hostname, int32_t port) override;
+
+ void statusCb(AGpsExtType type, LocAGpsStatusValue status);
+
+ /* Data call setup callback passed down to GNSS HAL implementation */
+ static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 status);
+
+ private:
+ Gnss* mGnss = nullptr;
+ sp<IAGnssCallback> mAGnssCbIface = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
diff --git a/gps/android/2.0/AGnssRil.cpp b/gps/android/2.0/AGnssRil.cpp
new file mode 100644
index 0000000..a477fc2
--- /dev/null
+++ b/gps/android/2.0/AGnssRil.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc__AGnssRilInterface"
+
+#include <log_util.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sstream>
+#include <string>
+#include "Gnss.h"
+#include "AGnssRil.h"
+#include <DataItemConcreteTypesBase.h>
+
+typedef void* (getLocationInterface)();
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+
+AGnssRil::AGnssRil(Gnss* gnss) : mGnss(gnss) {
+ ENTRY_LOG_CALLFLOW();
+}
+
+AGnssRil::~AGnssRil() {
+ ENTRY_LOG_CALLFLOW();
+}
+
+Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool /*roaming*/) {
+ ENTRY_LOG_CALLFLOW();
+ // Extra NetworkTypes not available in IAgnssRil enums
+ const int NetworkType_BLUETOOTH = 7;
+ const int NetworkType_ETHERNET = 9;
+ const int NetworkType_PROXY = 16;
+
+ // for XTRA
+ if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
+ int8_t typeout = loc_core::TYPE_UNKNOWN;
+ switch(type)
+ {
+ case IAGnssRil::NetworkType::MOBILE:
+ typeout = loc_core::TYPE_MOBILE;
+ break;
+ case IAGnssRil::NetworkType::WIFI:
+ typeout = loc_core::TYPE_WIFI;
+ break;
+ case IAGnssRil::NetworkType::MMS:
+ typeout = loc_core::TYPE_MMS;
+ break;
+ case IAGnssRil::NetworkType::SUPL:
+ typeout = loc_core::TYPE_SUPL;
+ break;
+ case IAGnssRil::NetworkType::DUN:
+ typeout = loc_core::TYPE_DUN;
+ break;
+ case IAGnssRil::NetworkType::HIPRI:
+ typeout = loc_core::TYPE_HIPRI;
+ break;
+ case IAGnssRil::NetworkType::WIMAX:
+ typeout = loc_core::TYPE_WIMAX;
+ break;
+ default:
+ {
+ int networkType = (int) type;
+ // Handling network types not available in IAgnssRil
+ switch(networkType)
+ {
+ case NetworkType_BLUETOOTH:
+ typeout = loc_core::TYPE_BLUETOOTH;
+ break;
+ case NetworkType_ETHERNET:
+ typeout = loc_core::TYPE_ETHERNET;
+ break;
+ case NetworkType_PROXY:
+ typeout = loc_core::TYPE_PROXY;
+ break;
+ default:
+ typeout = loc_core::TYPE_UNKNOWN;
+ }
+ }
+ break;
+ }
+ mGnss->getGnssInterface()->updateConnectionStatus(connected, false, typeout, 0);
+ }
+ return true;
+}
+Return<bool> AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) {
+ ENTRY_LOG_CALLFLOW();
+
+ if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) {
+ int8_t typeout = loc_core::TYPE_UNKNOWN;
+ bool roaming = false;
+ if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_METERED) {
+ typeout = loc_core::TYPE_WIFI;
+ } else {
+ typeout = loc_core::TYPE_MOBILE;
+ }
+ if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_ROAMING) {
+ roaming = false;
+ }
+ mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected,
+ typeout, roaming, (NetworkHandle) attributes.networkHandle);
+ }
+ return true;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/AGnssRil.h b/gps/android/2.0/AGnssRil.h
new file mode 100644
index 0000000..a04d8aa
--- /dev/null
+++ b/gps/android/2.0/AGnssRil.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
+#define ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
+
+#include <android/hardware/gnss/2.0/IAGnssRil.h>
+#include <hidl/Status.h>
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+/*
+ * Extended interface for AGNSS RIL support. An Assisted GNSS Radio Interface Layer interface
+ * allows the GNSS chipset to request radio interface layer information from Android platform.
+ * Examples of such information are reference location, unique subscriber ID, phone number string
+ * and network availability changes. Also contains wrapper methods to allow methods from
+ * IAGnssiRilCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+struct AGnssRil : public V2_0::IAGnssRil {
+ AGnssRil(Gnss* gnss);
+ ~AGnssRil();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+ * These declarations were generated from IAGnssRil.hal.
+ */
+ Return<void> setCallback(const sp<V1_0::IAGnssRilCallback>& /*callback*/) override {
+ return Void();
+ }
+ Return<void> setRefLocation(const V1_0::IAGnssRil::AGnssRefLocation& /*agnssReflocation*/) override {
+ return Void();
+ }
+ Return<bool> setSetId(V1_0::IAGnssRil::SetIDType /*type*/, const hidl_string& /*setid*/) override {
+ return false;
+ }
+ Return<bool> updateNetworkAvailability(bool /*available*/,
+ const hidl_string& /*apn*/) override {
+ return false;
+ }
+ Return<bool> updateNetworkState(bool connected, V1_0::IAGnssRil::NetworkType type, bool roaming) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IAGnssRil follow
+ Return<bool> updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) override;
+
+ private:
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
diff --git a/gps/android/2.0/Android.mk b/gps/android/2.0/Android.mk
new file mode 100644
index 0000000..b6790c5
--- /dev/null
+++ b/gps/android/2.0/Android.mk
@@ -0,0 +1,112 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@2.0-impl-qti
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ AGnss.cpp \
+ Gnss.cpp \
+ AGnssRil.cpp \
+ GnssMeasurement.cpp \
+ GnssConfiguration.cpp \
+ GnssBatching.cpp \
+ GnssGeofencing.cpp \
+ GnssNi.cpp \
+ GnssDebug.cpp \
+ ../measurement_corrections/1.0/MeasurementCorrections.cpp \
+ ../visibility_control/1.0/GnssVisibilityControl.cpp
+
+LOCAL_SRC_FILES += \
+ location_api/GnssAPIClient.cpp \
+ location_api/MeasurementAPIClient.cpp \
+ location_api/GeofenceAPIClient.cpp \
+ location_api/BatchingAPIClient.cpp \
+ location_api/LocationUtil.cpp \
+
+ifeq ($(GNSS_HIDL_LEGACY_MEASURMENTS),true)
+LOCAL_CFLAGS += \
+ -DGNSS_HIDL_LEGACY_MEASURMENTS
+endif
+
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/location_api \
+ $(LOCAL_PATH)/../measurement_corrections/1.0 \
+ $(LOCAL_PATH)/../visibility_control/1.0
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers \
+ liblocbatterylistener_headers
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libhidlbase \
+ libcutils \
+ libutils \
+ android.hardware.gnss@1.0 \
+ android.hardware.gnss@1.1 \
+ android.hardware.gnss@2.0 \
+ android.hardware.gnss.measurement_corrections@1.0 \
+ android.hardware.gnss.visibility_control@1.0 \
+ android.hardware.health@1.0 \
+ android.hardware.health@2.0 \
+ android.hardware.power@1.2 \
+ libbase
+
+LOCAL_SHARED_LIBRARIES += \
+ libloc_core \
+ libgps.utils \
+ libdl \
+ liblocation_api \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+LOCAL_STATIC_LIBRARIES := liblocbatterylistener
+LOCAL_STATIC_LIBRARIES += libhealthhalutils
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@2.0-service-qti
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@2.0-service-qti.xml
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_INIT_RC := android.hardware.gnss@2.0-service-qti.rc
+LOCAL_SRC_FILES := \
+ service.cpp \
+
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils \
+ libdl \
+ libbase \
+ libutils \
+ libgps.utils \
+ libqti_vndfwk_detect \
+
+LOCAL_SHARED_LIBRARIES += \
+ libhidlbase \
+ android.hardware.gnss@1.0 \
+ android.hardware.gnss@1.1 \
+ android.hardware.gnss@2.0 \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+
+ifneq ($(LOC_HIDL_VERSION),)
+LOCAL_CFLAGS += -DLOC_HIDL_VERSION='"$(LOC_HIDL_VERSION)"'
+endif
+
+include $(BUILD_EXECUTABLE)
diff --git a/gps/android/2.0/Gnss.cpp b/gps/android/2.0/Gnss.cpp
new file mode 100644
index 0000000..af76b72
--- /dev/null
+++ b/gps/android/2.0/Gnss.cpp
@@ -0,0 +1,671 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssInterface"
+#define LOG_NDEBUG 0
+
+#include <fstream>
+#include <log_util.h>
+#include <dlfcn.h>
+#include <cutils/properties.h>
+#include "Gnss.h"
+#include "LocationUtil.h"
+#include "battery_listener.h"
+
+typedef const GnssInterface* (getLocationInterface)();
+
+#define IMAGES_INFO_FILE "/sys/devices/soc0/images"
+#define DELIMITER ";"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl;
+static sp<Gnss> sGnss;
+static std::string getVersionString() {
+ static std::string version;
+ if (!version.empty())
+ return version;
+
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.hardware", value, "unknown");
+ version.append(value).append(DELIMITER);
+
+ std::ifstream in(IMAGES_INFO_FILE);
+ std::string s;
+ while(getline(in, s)) {
+ std::size_t found = s.find("CRM:");
+ if (std::string::npos == found) {
+ continue;
+ }
+
+ // skip over space characters after "CRM:"
+ const char* substr = s.c_str();
+ found += 4;
+ while (0 != substr[found] && isspace(substr[found])) {
+ found++;
+ }
+ if (s.find("11:") != found) {
+ continue;
+ }
+ s.erase(0, found + 3);
+
+ found = s.find_first_of("\r\n");
+ if (std::string::npos != found) {
+ s.erase(s.begin() + found, s.end());
+ }
+ version.append(s).append(DELIMITER);
+ }
+ return version;
+}
+
+void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnss != nullptr) {
+ mGnss->cleanup();
+ }
+}
+
+void location_on_battery_status_changed(bool charging) {
+ LOC_LOGd("battery status changed to %s charging", charging ? "" : "not");
+ if (sGnss != nullptr) {
+ sGnss->getGnssInterface()->updateBatteryStatus(charging);
+ }
+}
+Gnss::Gnss() {
+ ENTRY_LOG_CALLFLOW();
+ sGnss = this;
+ // register health client to listen on battery change
+ loc_extn_battery_properties_listener_init(location_on_battery_status_changed);
+ // clear pending GnssConfig
+ memset(&mPendingConfig, 0, sizeof(GnssConfig));
+ mGnssDeathRecipient = new GnssDeathRecipient(this);
+}
+
+Gnss::~Gnss() {
+ ENTRY_LOG_CALLFLOW();
+ if (mApi != nullptr) {
+ delete mApi;
+ mApi = nullptr;
+ }
+ sGnss = nullptr;
+}
+
+GnssAPIClient* Gnss::getApi() {
+ if (mApi != nullptr) {
+ return mApi;
+ }
+
+ if (mGnssCbIface_2_0 != nullptr) {
+ mApi = new GnssAPIClient(mGnssCbIface_2_0);
+ } else if (mGnssCbIface_1_1 != nullptr) {
+ mApi = new GnssAPIClient(mGnssCbIface_1_1, mGnssNiCbIface);
+ } else if (mGnssCbIface != nullptr) {
+ mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
+ } else {
+ LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
+ return mApi;
+ }
+
+ if (mPendingConfig.size == sizeof(GnssConfig)) {
+ // we have pending GnssConfig
+ mApi->gnssConfigurationUpdate(mPendingConfig);
+ // clear size to invalid mPendingConfig
+ mPendingConfig.size = 0;
+ if (mPendingConfig.assistanceServer.hostName != nullptr) {
+ free((void*)mPendingConfig.assistanceServer.hostName);
+ }
+ }
+
+ return mApi;
+}
+
+const GnssInterface* Gnss::getGnssInterface() {
+ static bool getGnssInterfaceFailed = false;
+ if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
+ LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
+ getLocationInterface* getter = NULL;
+ const char *error = NULL;
+ dlerror();
+ void *handle = dlopen("libgnss.so", RTLD_NOW);
+ if (NULL == handle || (error = dlerror()) != NULL) {
+ LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
+ } else {
+ getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
+ if ((error = dlerror()) != NULL) {
+ LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
+ getter = NULL;
+ }
+ }
+
+ if (NULL == getter) {
+ getGnssInterfaceFailed = true;
+ } else {
+ mGnssInterface = (const GnssInterface*)(*getter)();
+ }
+ }
+ return mGnssInterface;
+}
+
+Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+
+ // In case where previous call to setCallback_1_1 or setCallback_2_0, then
+ // we need to cleanup these interfaces/callbacks here since we no longer
+ // do so in cleanup() function to keep callbacks around after cleanup()
+ if (mApi != nullptr) {
+ mApi->gnssUpdateCallbacks_2_0(nullptr);
+ }
+ if (mGnssCbIface_1_1 != nullptr) {
+ mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_1_1 = nullptr;
+ }
+ if (mGnssCbIface_2_0 != nullptr) {
+ mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_2_0 = nullptr;
+ }
+
+
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+ }
+ mGnssCbIface = callback;
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+ }
+
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
+ api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+ api->requestCapabilities();
+ }
+ return true;
+}
+
+Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ mGnssNiCbIface = callback;
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
+ }
+ return true;
+}
+
+Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
+ ENTRY_LOG_CALLFLOW();
+ GnssAPIClient* api = getApi();
+ if (api) {
+ api->gnssConfigurationUpdate(gnssConfig);
+ } else if (gnssConfig.flags != 0) {
+ // api is not ready yet, update mPendingConfig with gnssConfig
+ mPendingConfig.size = sizeof(GnssConfig);
+
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
+ mPendingConfig.gpsLock = gnssConfig.gpsLock;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
+ mPendingConfig.suplVersion = gnssConfig.suplVersion;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
+ mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
+ mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
+ if (mPendingConfig.assistanceServer.hostName != nullptr) {
+ free((void*)mPendingConfig.assistanceServer.hostName);
+ mPendingConfig.assistanceServer.hostName =
+ strdup(gnssConfig.assistanceServer.hostName);
+ }
+ mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+ mPendingConfig.lppProfile = gnssConfig.lppProfile;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
+ mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
+ mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+ mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
+ mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
+ mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
+ mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
+ }
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT;
+ mPendingConfig.emergencyExtensionSeconds = gnssConfig.emergencyExtensionSeconds;
+ }
+ }
+ return true;
+}
+
+Return<bool> Gnss::start() {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ retVal = api->gnssStart();
+ }
+ return retVal;
+}
+
+Return<bool> Gnss::stop() {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ retVal = api->gnssStop();
+ }
+ return retVal;
+}
+
+Return<void> Gnss::cleanup() {
+ ENTRY_LOG_CALLFLOW();
+
+ if (mApi != nullptr) {
+ mApi->gnssStop();
+ mApi->gnssDisable();
+ }
+
+ return Void();
+}
+
+Return<bool> Gnss::injectLocation(double latitudeDegrees,
+ double longitudeDegrees,
+ float accuracyMeters) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
+ int32_t uncertaintyMs) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) {
+ ENTRY_LOG_CALLFLOW();
+ GnssAPIClient* api = getApi();
+ if (api) {
+ api->gnssDeleteAidingData(aidingDataFlags);
+ }
+ return Void();
+}
+
+Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
+ preferredAccuracyMeters, preferredTimeMs);
+ }
+ return retVal;
+}
+
+Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
+ ENTRY_LOG_CALLFLOW();
+ // deprecated function. Must return nullptr to pass VTS
+ return nullptr;
+}
+
+Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
+ ENTRY_LOG_CALLFLOW();
+ // deprecated function. Must return nullptr to pass VTS
+ return nullptr;
+}
+
+Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssMeasurement == nullptr)
+ mGnssMeasurement = new GnssMeasurement();
+ return mGnssMeasurement;
+}
+
+Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssConfig = new GnssConfiguration(this);
+ return mGnssConfig;
+}
+
+Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssGeofencingIface = new GnssGeofencing();
+ return mGnssGeofencingIface;
+}
+
+Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssBatching = new GnssBatching();
+ return mGnssBatching;
+}
+
+Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssDebug = new GnssDebug(this);
+ return mGnssDebug;
+}
+
+Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssRil = new AGnssRil(this);
+ return mGnssRil;
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ auto r = callback->gnssNameCb(getVersionString());
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNameCb description=%s",
+ __func__, r.description().c_str());
+ }
+
+ // In case where previous call to setCallback or setCallback_2_1, then
+ // we need to cleanup these interfaces/callbacks here since we no longer
+ // do so in cleanup() function to keep callbacks around after cleanup()
+ if (mApi != nullptr) {
+ mApi->gnssUpdateCallbacks_2_0(nullptr);
+ }
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface = nullptr;
+ }
+ if (mGnssCbIface_2_0 != nullptr) {
+ mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_2_0 = nullptr;
+ }
+
+
+ if (mGnssCbIface_1_1 != nullptr) {
+ mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
+ }
+ mGnssCbIface_1_1 = callback;
+ if (mGnssCbIface_1_1 != nullptr) {
+ mGnssCbIface_1_1->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+ }
+
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
+ odcpiRequestCb(odcpiRequest);
+ };
+ gnssInterface->odcpiInit(cb);
+ }
+
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks(mGnssCbIface_1_1, mGnssNiCbIface);
+ api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+ api->requestCapabilities();
+ }
+
+ return true;
+}
+
+Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs,
+ bool lowPowerMode) {
+ ENTRY_LOG_CALLFLOW();
+ bool retVal = false;
+ GnssAPIClient* api = getApi();
+ if (api) {
+ GnssPowerMode powerMode = lowPowerMode?
+ GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2;
+ retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
+ preferredAccuracyMeters, preferredTimeMs, powerMode, minIntervalMs);
+ }
+ return retVal;
+}
+
+Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
+ ENTRY_LOG_CALLFLOW();
+#ifdef GNSS_HIDL_LEGACY_MEASURMENTS
+ return nullptr;
+#else
+ if (mGnssMeasurement == nullptr)
+ mGnssMeasurement = new GnssMeasurement();
+ return mGnssMeasurement;
+#endif
+}
+
+Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnssConfig == nullptr)
+ mGnssConfig = new GnssConfiguration(this);
+ return mGnssConfig;
+}
+
+Return<bool> Gnss::injectBestLocation(const GnssLocation& gnssLocation) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ Location location = {};
+ convertGnssLocation(gnssLocation, location);
+ gnssInterface->odcpiInject(location);
+ }
+ return true;
+}
+
+void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
+ ENTRY_LOG_CALLFLOW();
+
+ if (mGnssCbIface_2_0 != nullptr) {
+ // For emergency mode, request DBH (Device based hybrid) location
+ // Mark Independent from GNSS flag to false.
+ if (ODCPI_REQUEST_TYPE_START == request.type) {
+ LOC_LOGd("gnssRequestLocationCb_2_0 isUserEmergency = %d", request.isEmergencyMode);
+ auto r = mGnssCbIface_2_0->gnssRequestLocationCb_2_0(!request.isEmergencyMode,
+ request.isEmergencyMode);
+ if (!r.isOk()) {
+ LOC_LOGe("Error invoking gnssRequestLocationCb_2_0 %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
+ }
+ } else if (mGnssCbIface_1_1 != nullptr) {
+ // For emergency mode, request DBH (Device based hybrid) location
+ // Mark Independent from GNSS flag to false.
+ if (ODCPI_REQUEST_TYPE_START == request.type) {
+ auto r = mGnssCbIface_1_1->gnssRequestLocationCb(!request.isEmergencyMode);
+ if (!r.isOk()) {
+ LOC_LOGe("Error invoking gnssRequestLocationCb %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
+ }
+ } else {
+ LOC_LOGe("ODCPI request not supported.");
+ }
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnss follow.
+Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
+ ENTRY_LOG_CALLFLOW();
+ auto r = callback->gnssNameCb(getVersionString());
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNameCb description=%s",
+ __func__, r.description().c_str());
+ }
+
+ // In case where previous call to setCallback or setCallback_1_1, then
+ // we need to cleanup these interfaces/callbacks here since we no longer
+ // do so in cleanup() function to keep callbacks around after cleanup()
+ if (mApi != nullptr) {
+ mApi->gnssUpdateCallbacks(nullptr, nullptr);
+ }
+ mGnssNiCbIface = nullptr;
+ if (mGnssCbIface != nullptr) {
+ mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface = nullptr;
+ }
+ if (mGnssCbIface_1_1 != nullptr) {
+ mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
+ mGnssCbIface_1_1 = nullptr;
+ }
+
+ if (mGnssCbIface_2_0 != nullptr) {
+ mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
+ }
+ mGnssCbIface_2_0 = callback;
+ if (mGnssCbIface_2_0 != nullptr) {
+ mGnssCbIface_2_0->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+ }
+
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
+ odcpiRequestCb(odcpiRequest);
+ };
+ gnssInterface->odcpiInit(cb);
+ }
+
+ GnssAPIClient* api = getApi();
+ if (api != nullptr) {
+ api->gnssUpdateCallbacks_2_0(mGnssCbIface_2_0);
+ api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+ api->requestCapabilities();
+ }
+
+ return true;
+}
+
+Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ mAGnssIface_2_0 = new AGnss(this);
+ return mAGnssIface_2_0;
+}
+Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
+ mGnssRil = new AGnssRil(this);
+ return mGnssRil;
+}
+
+Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssConfig = new GnssConfiguration(this);
+ return mGnssConfig;
+}
+Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
+ ENTRY_LOG_CALLFLOW();
+#ifdef GNSS_HIDL_LEGACY_MEASURMENTS
+ return nullptr;
+#else
+ if (mGnssMeasurement == nullptr)
+ mGnssMeasurement = new GnssMeasurement();
+ return mGnssMeasurement;
+#endif
+}
+Return<sp<::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections>>
+ Gnss::getExtensionMeasurementCorrections() {
+ // We do not support, so return nullptr to pass VTS
+ return nullptr;
+}
+Return<sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>>
+ Gnss::getExtensionVisibilityControl() {
+ ENTRY_LOG_CALLFLOW();
+ if (mVisibCtrl == nullptr) {
+ mVisibCtrl = new GnssVisibilityControl(this);
+ }
+ return mVisibCtrl;
+}
+
+Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation& gnssLocation) {
+ ENTRY_LOG_CALLFLOW();
+ const GnssInterface* gnssInterface = getGnssInterface();
+ if (nullptr != gnssInterface) {
+ Location location = {};
+ convertGnssLocation(gnssLocation, location);
+ gnssInterface->odcpiInject(location);
+ }
+ return true;
+}
+
+Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssDebug = new GnssDebug(this);
+ return mGnssDebug;
+}
+
+Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
+ ENTRY_LOG_CALLFLOW();
+ mGnssBatching = new GnssBatching();
+ return mGnssBatching;
+}
+
+V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
+ ENTRY_LOG_CALLFLOW();
+ V1_0::IGnss* iface = nullptr;
+ iface = new Gnss();
+ if (iface == nullptr) {
+ LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
+ }
+ return iface;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/Gnss.h b/gps/android/2.0/Gnss.h
new file mode 100644
index 0000000..a403d61
--- /dev/null
+++ b/gps/android/2.0/Gnss.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
+
+#include <AGnss.h>
+#include <AGnssRil.h>
+#include <GnssConfiguration.h>
+#include <GnssMeasurement.h>
+#include <GnssBatching.h>
+#include <GnssGeofencing.h>
+#include <GnssNi.h>
+#include <GnssDebug.h>
+
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <MeasurementCorrections.h>
+#include <GnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include "GnssAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
+using ::android::hardware::gnss::measurement_corrections::V1_0::implementation::MeasurementCorrections;
+using ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
+
+struct Gnss : public IGnss {
+ Gnss();
+ ~Gnss();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+ * These declarations were generated from Gnss.hal.
+ */
+ Return<bool> setCallback(const sp<V1_0::IGnssCallback>& callback) override;
+ Return<bool> start() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+ Return<bool> injectLocation(double latitudeDegrees,
+ double longitudeDegrees,
+ float accuracyMeters) override;
+ Return<bool> injectTime(int64_t timeMs,
+ int64_t timeReferenceMs,
+ int32_t uncertaintyMs) override;
+ Return<void> deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override;
+ Return<bool> setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) override;
+ Return<sp<V1_0::IAGnss>> getExtensionAGnss() override;
+ Return<sp<V1_0::IGnssNi>> getExtensionGnssNi() override;
+ Return<sp<V1_0::IGnssMeasurement>> getExtensionGnssMeasurement() override;
+ Return<sp<V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() override;
+ Return<sp<V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() override;
+ Return<sp<V1_0::IGnssBatching>> getExtensionGnssBatching() override;
+
+ Return<sp<V1_0::IAGnssRil>> getExtensionAGnssRil() override;
+
+ inline Return<sp<V1_0::IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override {
+ return nullptr;
+ }
+
+ inline Return<sp<V1_0::IGnssXtra>> getExtensionXtra() override {
+ return nullptr;
+ }
+
+ Return<sp<V1_0::IGnssDebug>> getExtensionGnssDebug() override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+ Return<bool> setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) override;
+ Return<bool> setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs, bool lowPowerMode) override;
+ Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
+ Return<sp<V1_1::IGnssConfiguration>> getExtensionGnssConfiguration_1_1() override;
+ Return<bool> injectBestLocation(const GnssLocation& location) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnss follow.
+ Return<bool> setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) override;
+ Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
+ Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
+
+ Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
+ Return<sp<::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections>>
+ getExtensionMeasurementCorrections() override;
+ Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
+
+ Return<bool> injectBestLocation_2_0(const ::android::hardware::gnss::V2_0::GnssLocation& location) override;
+
+ Return<sp<V2_0::IGnssBatching>> getExtensionGnssBatching_2_0() override;
+ Return<sp<V2_0::IGnssDebug>> getExtensionGnssDebug_2_0() override;
+
+
+ /**
+ * This method returns the IGnssVisibilityControl interface.
+ *
+ * @return visibilityControlIface Handle to the IGnssVisibilityControl interface.
+ */
+ Return<sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>>
+ getExtensionVisibilityControl() override;
+
+
+ // These methods are not part of the IGnss base class.
+ GnssAPIClient* getApi();
+ Return<bool> setGnssNiCb(const sp<IGnssNiCallback>& niCb);
+ Return<bool> updateConfiguration(GnssConfig& gnssConfig);
+ const GnssInterface* getGnssInterface();
+
+ // Callback for ODCPI request
+ void odcpiRequestCb(const OdcpiRequestInfo& request);
+
+ private:
+ struct GnssDeathRecipient : hidl_death_recipient {
+ GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) {
+ }
+ ~GnssDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<Gnss> mGnss;
+ };
+
+ private:
+ sp<GnssDeathRecipient> mGnssDeathRecipient = nullptr;
+
+ sp<V1_0::IGnssNi> mGnssNi = nullptr;
+ sp<V1_0::IGnssGeofencing> mGnssGeofencingIface = nullptr;
+ sp<V1_0::IAGnss> mAGnssIface = nullptr;
+ sp<V1_0::IGnssCallback> mGnssCbIface = nullptr;
+ sp<V1_0::IGnssNiCallback> mGnssNiCbIface = nullptr;
+ sp<V1_1::IGnssCallback> mGnssCbIface_1_1 = nullptr;
+ sp<V2_0::IAGnss> mAGnssIface_2_0 = nullptr;
+ sp<V2_0::IAGnssRil> mGnssRil = nullptr;
+ sp<V2_0::IGnssMeasurement> mGnssMeasurement = nullptr;
+ sp<V2_0::IGnssConfiguration> mGnssConfig = nullptr;
+ sp<V2_0::IGnssBatching> mGnssBatching = nullptr;
+ sp<V2_0::IGnssDebug> mGnssDebug = nullptr;
+ sp<V2_0::IGnssCallback> mGnssCbIface_2_0 = nullptr;
+ sp<IMeasurementCorrections> mGnssMeasCorr = nullptr;
+ sp<IGnssVisibilityControl> mVisibCtrl = nullptr;
+
+ GnssAPIClient* mApi = nullptr;
+ GnssConfig mPendingConfig;
+ const GnssInterface* mGnssInterface = nullptr;
+};
+
+extern "C" V1_0::IGnss* HIDL_FETCH_IGnss(const char* name);
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
diff --git a/gps/android/2.0/GnssBatching.cpp b/gps/android/2.0/GnssBatching.cpp
new file mode 100644
index 0000000..7a937fc
--- /dev/null
+++ b/gps/android/2.0/GnssBatching.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssBatchingInterface"
+
+#include <log_util.h>
+#include <BatchingAPIClient.h>
+#include "GnssBatching.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssBatching::GnssBatchingDeathRecipient::serviceDied(
+ uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnssBatching != nullptr) {
+ mGnssBatching->stop();
+ mGnssBatching->cleanup();
+ }
+}
+
+GnssBatching::GnssBatching() : mApi(nullptr) {
+ mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this);
+}
+
+GnssBatching::~GnssBatching() {
+ if (mApi != nullptr) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+Return<bool> GnssBatching::init(const sp<V1_0::IGnssBatchingCallback>& callback) {
+ if (mApi != nullptr) {
+ LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
+ delete mApi;
+ mApi = nullptr;
+ }
+
+ mApi = new BatchingAPIClient(callback);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+ return false;
+ }
+
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+ }
+ mGnssBatchingCbIface = callback;
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->linkToDeath(mGnssBatchingDeathRecipient, 0 /*cookie*/);
+ }
+
+ return true;
+}
+
+Return<uint16_t> GnssBatching::getBatchSize() {
+ uint16_t ret = 0;
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ ret = mApi->getBatchSize();
+ }
+ return ret;
+}
+
+Return<bool> GnssBatching::start(const IGnssBatching::Options& options) {
+ bool ret = false;
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ ret = mApi->startSession(options);
+ }
+ return ret;
+}
+
+Return<void> GnssBatching::flush() {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->flushBatchedLocations();
+ }
+ return Void();
+}
+
+Return<bool> GnssBatching::stop() {
+ bool ret = false;
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ ret = mApi->stopSession();
+ }
+ return ret;
+}
+
+Return<void> GnssBatching::cleanup() {
+ if (mApi != nullptr) {
+ mApi->stopSession();
+ }
+ if (mGnssBatchingCbIface != nullptr) {
+ mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+ mGnssBatchingCbIface = nullptr;
+ }
+ if (mGnssBatchingCbIface_2_0 != nullptr) {
+ mGnssBatchingCbIface_2_0->unlinkToDeath(mGnssBatchingDeathRecipient);
+ mGnssBatchingCbIface_2_0 = nullptr;
+ }
+ return Void();
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnssBatching follow.
+Return<bool> GnssBatching::init_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) {
+ if (mApi != nullptr) {
+ LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
+ delete mApi;
+ mApi = nullptr;
+ }
+
+ mApi = new BatchingAPIClient(callback);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+ return false;
+ }
+
+ if (mGnssBatchingCbIface_2_0 != nullptr) {
+ mGnssBatchingCbIface_2_0->unlinkToDeath(mGnssBatchingDeathRecipient);
+ }
+ mGnssBatchingCbIface_2_0 = callback;
+ if (mGnssBatchingCbIface_2_0 != nullptr) {
+ mGnssBatchingCbIface_2_0->linkToDeath(mGnssBatchingDeathRecipient, 0 /*cookie*/);
+ }
+
+ return true;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/GnssBatching.h b/gps/android/2.0/GnssBatching.h
new file mode 100644
index 0000000..4c8d1db
--- /dev/null
+++ b/gps/android/2.0/GnssBatching.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
+
+#include <android/hardware/gnss/2.0/IGnssBatching.h>
+#include <hidl/Status.h>
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_0::IGnssBatching;
+using ::android::hardware::gnss::V2_0::IGnssBatchingCallback;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+class BatchingAPIClient;
+struct GnssBatching : public IGnssBatching {
+ GnssBatching();
+ ~GnssBatching();
+
+ // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+ Return<bool> init(const sp<V1_0::IGnssBatchingCallback>& callback) override;
+ Return<uint16_t> getBatchSize() override;
+ Return<bool> start(const IGnssBatching::Options& options ) override;
+ Return<void> flush() override;
+ Return<bool> stop() override;
+ Return<void> cleanup() override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssBatching follow.
+ Return<bool> init_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) override;
+
+ private:
+ struct GnssBatchingDeathRecipient : hidl_death_recipient {
+ GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) :
+ mGnssBatching(gnssBatching) {
+ }
+ ~GnssBatchingDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssBatching> mGnssBatching;
+ };
+
+ private:
+ sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr;
+ sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface = nullptr;
+ BatchingAPIClient* mApi = nullptr;
+ sp<V2_0::IGnssBatchingCallback> mGnssBatchingCbIface_2_0 = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
diff --git a/gps/android/2.0/GnssConfiguration.cpp b/gps/android/2.0/GnssConfiguration.cpp
new file mode 100644
index 0000000..363d2b1
--- /dev/null
+++ b/gps/android/2.0/GnssConfiguration.cpp
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssConfigurationInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssConfiguration.h"
+#include "ContextBase.h"
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+using namespace loc_core;
+
+GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
+}
+
+// Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enabled) {
+ // deprecated function. Must return false to pass VTS
+ return false;
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t version) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
+ switch (version) {
+ case 0x00020002:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_2;
+ break;
+ case 0x00020000:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_0;
+ break;
+ case 0x00010000:
+ config.suplVersion = GNSS_CONFIG_SUPL_VERSION_1_0_0;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setSuplMode(uint8_t mode) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
+ switch (mode) {
+ case 0:
+ config.suplModeMask = 0; // STANDALONE ONLY
+ break;
+ case 1:
+ config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT;
+ break;
+ case 2:
+ config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+ break;
+ case 3:
+ config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config = {};
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+ switch (lppProfile) {
+ case 0:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE;
+ break;
+ case 1:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE;
+ break;
+ case 2:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE;
+ break;
+ case 3:
+ config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid lppProfile: %d.", __FUNCTION__, lppProfile);
+ return false;
+ break;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+
+ config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+ if (protocol & (1<<0)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT;
+ }
+ if (protocol & (1<<1)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT;
+ }
+ if (protocol & (1<<2)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT;
+ }
+ if (protocol & (1<<3)) {
+ config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT;
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
+
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config = {};
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
+ switch (lock) {
+ case 0:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+ break;
+ case 1:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO;
+ break;
+ case 2:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI;
+ break;
+ case 3:
+ config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
+ break;
+ default:
+ LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
+ return false;
+ break;
+ }
+
+ mGnss->updateConfiguration(config);
+ // Must return false to pass VTS
+ return false;
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
+ config.emergencyPdnForEmergencySupl = (enabled ?
+ GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES :
+ GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO);
+
+ return mGnss->updateConfiguration(config);
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+ const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) {
+
+ ENTRY_LOG_CALLFLOW();
+ if (nullptr == mGnss) {
+ LOC_LOGe("mGnss is null");
+ return false;
+ }
+
+ // blValid is true if blacklist is empty, i.e. clearing the BL;
+ // if blacklist is not empty, blValid is initialied to false, and later
+ // updated in the for loop to become true only if there is at least
+ // one {constellation, svid} in the list that is valid.
+ bool blValid = (0 == blacklist.size());
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ config.blacklistedSvIds.clear();
+
+ GnssSvIdSource source = {};
+ for (int idx = 0; idx < (int)blacklist.size(); idx++) {
+ // Set blValid true if any one source is valid
+ blValid = setBlacklistedSource(source, blacklist[idx]) || blValid;
+ config.blacklistedSvIds.push_back(source);
+ }
+
+ // Update configuration only if blValid is true
+ // i.e. only if atleast one source is valid for blacklisting
+ return (blValid && mGnss->updateConfiguration(config));
+}
+
+bool GnssConfiguration::setBlacklistedSource(
+ GnssSvIdSource& copyToSource,
+ const GnssConfiguration::BlacklistedSource& copyFromSource) {
+
+ bool retVal = true;
+ uint16_t svIdOffset = 0;
+ copyToSource.size = sizeof(GnssSvIdSource);
+ copyToSource.svId = copyFromSource.svid;
+
+ switch(copyFromSource.constellation) {
+ case GnssConstellationType::GPS:
+ copyToSource.constellation = GNSS_SV_TYPE_GPS;
+ LOC_LOGe("GPS SVs can't be blacklisted.");
+ retVal = false;
+ break;
+ case GnssConstellationType::SBAS:
+ copyToSource.constellation = GNSS_SV_TYPE_SBAS;
+ LOC_LOGe("SBAS SVs can't be blacklisted.");
+ retVal = false;
+ break;
+ case GnssConstellationType::GLONASS:
+ copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
+ svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
+ break;
+ case GnssConstellationType::QZSS:
+ copyToSource.constellation = GNSS_SV_TYPE_QZSS;
+ svIdOffset = 0;
+ break;
+ case GnssConstellationType::BEIDOU:
+ copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
+ svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
+ break;
+ case GnssConstellationType::GALILEO:
+ copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
+ svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
+ break;
+ default:
+ copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
+ LOC_LOGe("Invalid constellation %hhu", copyFromSource.constellation);
+ retVal = false;
+ break;
+ }
+
+ if (copyToSource.svId > 0 && svIdOffset > 0) {
+ copyToSource.svId += svIdOffset;
+ }
+
+ return retVal;
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
+ ENTRY_LOG_CALLFLOW();
+ if (mGnss == nullptr) {
+ LOC_LOGe("mGnss is nullptr");
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT;
+ config.emergencyExtensionSeconds = emergencyExtensionSeconds;
+
+ return mGnss->updateConfiguration(config);
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/GnssConfiguration.h b/gps/android/2.0/GnssConfiguration.h
new file mode 100644
index 0000000..202a9fd
--- /dev/null
+++ b/gps/android/2.0/GnssConfiguration.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+
+ /* Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/2.0/IGnssConfiguration.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Interface for passing GNSS configuration info from platform to HAL.
+ */
+struct Gnss;
+struct GnssConfiguration : public V2_0::IGnssConfiguration {
+ GnssConfiguration(Gnss* gnss);
+ ~GnssConfiguration() = default;
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+ * These declarations were generated from IGnssConfiguration.hal.
+ */
+ Return<bool> setSuplVersion(uint32_t version) override;
+ Return<bool> setSuplMode(uint8_t mode) override;
+ Return<bool> setSuplEs(bool enabled) override;
+ Return<bool> setLppProfile(uint8_t lppProfile) override;
+ Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
+ Return<bool> setEmergencySuplPdn(bool enable) override;
+ Return<bool> setGpsLock(uint8_t lock) override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+ Return<bool> setBlacklist(
+ const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+ Return<bool> setEsExtensionSec(uint32_t emergencyExtensionSeconds) override;
+
+ private:
+ Gnss* mGnss = nullptr;
+ bool setBlacklistedSource(
+ GnssSvIdSource& copyToSource,
+ const GnssConfiguration::BlacklistedSource& copyFromSource);
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
diff --git a/gps/android/2.0/GnssDebug.cpp b/gps/android/2.0/GnssDebug.cpp
new file mode 100644
index 0000000..dc0d9f4
--- /dev/null
+++ b/gps/android/2.0/GnssDebug.cpp
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssDebugInterface"
+
+#include <log/log.h>
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssDebug.h"
+#include "LocationUtil.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::gnss::V2_0::IGnssDebug;
+
+#define GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS (20000000)
+#define GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS (20000)
+#define GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC (500)
+#define GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG (180)
+
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME (1483228800000LL) // 1/1/2017 00:00 GMT
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MIN (999) // 999 ns
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX (1.57783680E17) // 5 years in ns
+#define GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC (2.0e5) // ppm
+
+GnssDebug::GnssDebug(Gnss* gnss) : mGnss(gnss)
+{
+}
+
+/*
+ * This methods requests position, time and satellite ephemeris debug information
+ * from the HAL.
+ *
+ * @return void
+*/
+Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ V1_0::IGnssDebug::DebugData data = { };
+
+ if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
+ LOC_LOGE("GnssDebug - Null GNSS interface");
+ _hidl_cb(data);
+ return Void();
+ }
+
+ // get debug report snapshot via hal interface
+ GnssDebugReport reports = { };
+ mGnss->getGnssInterface()->getDebugReport(reports);
+
+ // location block
+ if (reports.mLocation.mValid) {
+ data.position.valid = true;
+ data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
+ data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
+ data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
+
+ data.position.speedMetersPerSec =
+ (double)(reports.mLocation.mLocation.speed);
+ data.position.bearingDegrees =
+ (double)(reports.mLocation.mLocation.bearing);
+ data.position.horizontalAccuracyMeters =
+ (double)(reports.mLocation.mLocation.accuracy);
+ data.position.verticalAccuracyMeters =
+ reports.mLocation.verticalAccuracyMeters;
+ data.position.speedAccuracyMetersPerSecond =
+ reports.mLocation.speedAccuracyMetersPerSecond;
+ data.position.bearingAccuracyDegrees =
+ reports.mLocation.bearingAccuracyDegrees;
+
+ timeval tv_now, tv_report;
+ tv_report.tv_sec = reports.mLocation.mUtcReported.tv_sec;
+ tv_report.tv_usec = reports.mLocation.mUtcReported.tv_nsec / 1000ULL;
+ gettimeofday(&tv_now, NULL);
+ data.position.ageSeconds =
+ (tv_now.tv_sec - tv_report.tv_sec) +
+ (float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
+ }
+ else {
+ data.position.valid = false;
+ }
+
+ if (data.position.horizontalAccuracyMeters <= 0 ||
+ data.position.horizontalAccuracyMeters > GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS) {
+ data.position.horizontalAccuracyMeters = GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS;
+ }
+ if (data.position.verticalAccuracyMeters <= 0 ||
+ data.position.verticalAccuracyMeters > GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS) {
+ data.position.verticalAccuracyMeters = GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS;
+ }
+ if (data.position.speedAccuracyMetersPerSecond <= 0 ||
+ data.position.speedAccuracyMetersPerSecond > GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC) {
+ data.position.speedAccuracyMetersPerSecond = GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC;
+ }
+ if (data.position.bearingAccuracyDegrees <= 0 ||
+ data.position.bearingAccuracyDegrees > GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG) {
+ data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG;
+ }
+
+ // time block
+ if (reports.mTime.mValid) {
+ data.time.timeEstimate = reports.mTime.timeEstimate;
+ data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
+ data.time.frequencyUncertaintyNsPerSec =
+ reports.mTime.frequencyUncertaintyNsPerSec;
+ }
+
+ if (data.time.timeEstimate < GNSS_DEBUG_UNKNOWN_UTC_TIME) {
+ data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME;
+ }
+ if (data.time.timeUncertaintyNs <= 0) {
+ data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MIN;
+ } else if (data.time.timeUncertaintyNs > GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX) {
+ data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX;
+ }
+ if (data.time.frequencyUncertaintyNsPerSec <= 0 ||
+ data.time.frequencyUncertaintyNsPerSec > (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC) {
+ data.time.frequencyUncertaintyNsPerSec = (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC;
+ }
+
+ // satellite data block
+ V1_0::IGnssDebug::SatelliteData s = { };
+ std::vector<V1_0::IGnssDebug::SatelliteData> s_array;
+
+ for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
+ memset(&s, 0, sizeof(s));
+ s.svid = reports.mSatelliteInfo[i].svid;
+ convertGnssConstellationType(
+ reports.mSatelliteInfo[i].constellation, s.constellation);
+ convertGnssEphemerisType(
+ reports.mSatelliteInfo[i].mEphemerisType, s.ephemerisType);
+ convertGnssEphemerisSource(
+ reports.mSatelliteInfo[i].mEphemerisSource, s.ephemerisSource);
+ convertGnssEphemerisHealth(
+ reports.mSatelliteInfo[i].mEphemerisHealth, s.ephemerisHealth);
+
+ s.ephemerisAgeSeconds =
+ reports.mSatelliteInfo[i].ephemerisAgeSeconds;
+ s.serverPredictionIsAvailable =
+ reports.mSatelliteInfo[i].serverPredictionIsAvailable;
+ s.serverPredictionAgeSeconds =
+ reports.mSatelliteInfo[i].serverPredictionAgeSeconds;
+
+ s_array.push_back(s);
+ }
+ data.satelliteDataArray = s_array;
+
+ // callback HIDL with collected debug data
+ _hidl_cb(data);
+ return Void();
+}
+
+Return<void> GnssDebug::getDebugData_2_0(getDebugData_2_0_cb _hidl_cb)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ V2_0::IGnssDebug::DebugData data = { };
+
+ if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
+ LOC_LOGE("GnssDebug - Null GNSS interface");
+ _hidl_cb(data);
+ return Void();
+ }
+
+ // get debug report snapshot via hal interface
+ GnssDebugReport reports = { };
+ mGnss->getGnssInterface()->getDebugReport(reports);
+
+ // location block
+ if (reports.mLocation.mValid) {
+ data.position.valid = true;
+ data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
+ data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
+ data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
+
+ data.position.speedMetersPerSec =
+ (double)(reports.mLocation.mLocation.speed);
+ data.position.bearingDegrees =
+ (double)(reports.mLocation.mLocation.bearing);
+ data.position.horizontalAccuracyMeters =
+ (double)(reports.mLocation.mLocation.accuracy);
+ data.position.verticalAccuracyMeters =
+ reports.mLocation.verticalAccuracyMeters;
+ data.position.speedAccuracyMetersPerSecond =
+ reports.mLocation.speedAccuracyMetersPerSecond;
+ data.position.bearingAccuracyDegrees =
+ reports.mLocation.bearingAccuracyDegrees;
+
+ timeval tv_now, tv_report;
+ tv_report.tv_sec = reports.mLocation.mUtcReported.tv_sec;
+ tv_report.tv_usec = reports.mLocation.mUtcReported.tv_nsec / 1000ULL;
+ gettimeofday(&tv_now, NULL);
+ data.position.ageSeconds =
+ (tv_now.tv_sec - tv_report.tv_sec) +
+ (float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
+ }
+ else {
+ data.position.valid = false;
+ }
+
+ if (data.position.horizontalAccuracyMeters <= 0 ||
+ data.position.horizontalAccuracyMeters > GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS) {
+ data.position.horizontalAccuracyMeters = GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS;
+ }
+ if (data.position.verticalAccuracyMeters <= 0 ||
+ data.position.verticalAccuracyMeters > GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS) {
+ data.position.verticalAccuracyMeters = GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS;
+ }
+ if (data.position.speedAccuracyMetersPerSecond <= 0 ||
+ data.position.speedAccuracyMetersPerSecond > GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC) {
+ data.position.speedAccuracyMetersPerSecond = GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC;
+ }
+ if (data.position.bearingAccuracyDegrees <= 0 ||
+ data.position.bearingAccuracyDegrees > GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG) {
+ data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG;
+ }
+
+ // time block
+ if (reports.mTime.mValid) {
+ data.time.timeEstimate = reports.mTime.timeEstimate;
+ data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
+ data.time.frequencyUncertaintyNsPerSec =
+ reports.mTime.frequencyUncertaintyNsPerSec;
+ }
+
+ if (data.time.timeEstimate < GNSS_DEBUG_UNKNOWN_UTC_TIME) {
+ data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME;
+ }
+ if (data.time.timeUncertaintyNs <= 0) {
+ data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MIN;
+ }
+ else if (data.time.timeUncertaintyNs > GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX) {
+ data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC_MAX;
+ }
+ if (data.time.frequencyUncertaintyNsPerSec <= 0 ||
+ data.time.frequencyUncertaintyNsPerSec > (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC) {
+ data.time.frequencyUncertaintyNsPerSec = (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC;
+ }
+
+ // satellite data block
+ V2_0::IGnssDebug::SatelliteData s = { };
+ std::vector<V2_0::IGnssDebug::SatelliteData> s_array;
+
+ for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
+ memset(&s, 0, sizeof(s));
+ s.v1_0.svid = reports.mSatelliteInfo[i].svid;
+ convertGnssConstellationType(
+ reports.mSatelliteInfo[i].constellation, s.constellation);
+ convertGnssEphemerisType(
+ reports.mSatelliteInfo[i].mEphemerisType, s.v1_0.ephemerisType);
+ convertGnssEphemerisSource(
+ reports.mSatelliteInfo[i].mEphemerisSource, s.v1_0.ephemerisSource);
+ convertGnssEphemerisHealth(
+ reports.mSatelliteInfo[i].mEphemerisHealth, s.v1_0.ephemerisHealth);
+
+ s.v1_0.ephemerisAgeSeconds =
+ reports.mSatelliteInfo[i].ephemerisAgeSeconds;
+ s.v1_0.serverPredictionIsAvailable =
+ reports.mSatelliteInfo[i].serverPredictionIsAvailable;
+ s.v1_0.serverPredictionAgeSeconds =
+ reports.mSatelliteInfo[i].serverPredictionAgeSeconds;
+
+ s_array.push_back(s);
+ }
+ data.satelliteDataArray = s_array;
+
+ // callback HIDL with collected debug data
+ _hidl_cb(data);
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/GnssDebug.h b/gps/android/2.0/GnssDebug.h
new file mode 100644
index 0000000..8d75bea
--- /dev/null
+++ b/gps/android/2.0/GnssDebug.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
+
+
+#include <android/hardware/gnss/2.0/IGnssDebug.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_0::IGnssDebug;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/* Interface for GNSS Debug support. */
+struct Gnss;
+struct GnssDebug : public IGnssDebug {
+ GnssDebug(Gnss* gnss);
+ ~GnssDebug() {};
+
+ // Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow
+ Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
+ // Methods from ::android::hardware::gnss::V2_0::IGnssDebug follow.
+ Return<void> getDebugData_2_0(getDebugData_2_0_cb _hidl_cb) override;
+
+private:
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
diff --git a/gps/android/2.0/GnssGeofencing.cpp b/gps/android/2.0/GnssGeofencing.cpp
new file mode 100644
index 0000000..b72d835
--- /dev/null
+++ b/gps/android/2.0/GnssGeofencing.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHal_GnssGeofencing"
+
+#include <log_util.h>
+#include <GeofenceAPIClient.h>
+#include "GnssGeofencing.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied(
+ uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnssGeofencing != nullptr) {
+ mGnssGeofencing->removeAllGeofences();
+ }
+}
+
+GnssGeofencing::GnssGeofencing() : mApi(nullptr) {
+ mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this);
+}
+
+GnssGeofencing::~GnssGeofencing() {
+ if (mApi != nullptr) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) {
+ if (mApi != nullptr) {
+ LOC_LOGd("mApi is NOT nullptr");
+ return Void();
+ }
+
+ mApi = new GeofenceAPIClient(callback);
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+ }
+
+ if (mGnssGeofencingCbIface != nullptr) {
+ mGnssGeofencingCbIface->unlinkToDeath(mGnssGeofencingDeathRecipient);
+ }
+ mGnssGeofencingCbIface = callback;
+ if (mGnssGeofencingCbIface != nullptr) {
+ mGnssGeofencingCbIface->linkToDeath(mGnssGeofencingDeathRecipient, 0 /*cookie*/);
+ }
+
+ return Void();
+}
+
+Return<void> GnssGeofencing::addGeofence(
+ int32_t geofenceId,
+ double latitudeDegrees,
+ double longitudeDegrees,
+ double radiusMeters,
+ IGnssGeofenceCallback::GeofenceTransition lastTransition,
+ int32_t monitorTransitions,
+ uint32_t notificationResponsivenessMs,
+ uint32_t unknownTimerMs) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofenceAdd(
+ geofenceId,
+ latitudeDegrees,
+ longitudeDegrees,
+ radiusMeters,
+ static_cast<int32_t>(lastTransition),
+ monitorTransitions,
+ notificationResponsivenessMs,
+ unknownTimerMs);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofencePause(geofenceId);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofenceResume(geofenceId, monitorTransitions);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId) {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ } else {
+ mApi->geofenceRemove(geofenceId);
+ }
+ return Void();
+}
+
+Return<void> GnssGeofencing::removeAllGeofences() {
+ if (mApi == nullptr) {
+ LOC_LOGD("%s]: mApi is nullptr, do nothing", __FUNCTION__);
+ } else {
+ mApi->geofenceRemoveAll();
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/GnssGeofencing.h b/gps/android/2.0/GnssGeofencing.h
new file mode 100644
index 0000000..caa56d0
--- /dev/null
+++ b/gps/android/2.0/GnssGeofencing.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
+
+#include <android/hardware/gnss/1.0/IGnssGeofencing.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using ::android::hardware::gnss::V1_0::IGnssGeofencing;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class GeofenceAPIClient;
+struct GnssGeofencing : public IGnssGeofencing {
+ GnssGeofencing();
+ ~GnssGeofencing();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+ * These declarations were generated from IGnssGeofencing.hal.
+ */
+ Return<void> setCallback(const sp<IGnssGeofenceCallback>& callback) override;
+ Return<void> addGeofence(int32_t geofenceId,
+ double latitudeDegrees,
+ double longitudeDegrees,
+ double radiusMeters,
+ IGnssGeofenceCallback::GeofenceTransition lastTransition,
+ int32_t monitorTransitions,
+ uint32_t notificationResponsivenessMs,
+ uint32_t unknownTimerMs) override;
+
+ Return<void> pauseGeofence(int32_t geofenceId) override;
+ Return<void> resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) override;
+ Return<void> removeGeofence(int32_t geofenceId) override;
+
+ private:
+ // This method is not part of the IGnss base class.
+ // It is called by GnssGeofencingDeathRecipient to remove all geofences added so far.
+ Return<void> removeAllGeofences();
+
+ private:
+ struct GnssGeofencingDeathRecipient : hidl_death_recipient {
+ GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) :
+ mGnssGeofencing(gnssGeofencing) {
+ }
+ ~GnssGeofencingDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssGeofencing> mGnssGeofencing;
+ };
+
+ private:
+ sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr;
+ sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr;
+ GeofenceAPIClient* mApi = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
diff --git a/gps/android/2.0/GnssMeasurement.cpp b/gps/android/2.0/GnssMeasurement.cpp
new file mode 100644
index 0000000..721a48c
--- /dev/null
+++ b/gps/android/2.0/GnssMeasurement.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssMeasurementInterface"
+
+#include <log_util.h>
+#include "GnssMeasurement.h"
+#include "MeasurementAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied(
+ uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ if (mGnssMeasurement != nullptr) {
+ mGnssMeasurement->close();
+ }
+}
+
+GnssMeasurement::GnssMeasurement() {
+ mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this);
+ mApi = new MeasurementAPIClient();
+}
+
+GnssMeasurement::~GnssMeasurement() {
+ if (mApi) {
+ delete mApi;
+ mApi = nullptr;
+ }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback) {
+
+ Return<GnssMeasurement::GnssMeasurementStatus> ret =
+ IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+ if (mGnssMeasurementCbIface != nullptr) {
+ LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+ return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+ }
+
+ if (callback == nullptr) {
+ LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+ return ret;
+ }
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return ret;
+ }
+
+ mGnssMeasurementCbIface = callback;
+ mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ return mApi->measurementSetCallback(callback);
+}
+
+Return<void> GnssMeasurement::close() {
+ if (mApi == nullptr) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ if (mGnssMeasurementCbIface != nullptr) {
+ mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
+ mGnssMeasurementCbIface = nullptr;
+ }
+ if (mGnssMeasurementCbIface_1_1 != nullptr) {
+ mGnssMeasurementCbIface_1_1->unlinkToDeath(mGnssMeasurementDeathRecipient);
+ mGnssMeasurementCbIface_1_1 = nullptr;
+ }
+ if (mGnssMeasurementCbIface_2_0 != nullptr) {
+ mGnssMeasurementCbIface_2_0->unlinkToDeath(mGnssMeasurementDeathRecipient);
+ mGnssMeasurementCbIface_2_0 = nullptr;
+ }
+ mApi->measurementClose();
+
+ return Void();
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) {
+
+ Return<GnssMeasurement::GnssMeasurementStatus> ret =
+ IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+ if (mGnssMeasurementCbIface_1_1 != nullptr) {
+ LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+ return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+ }
+
+ if (callback == nullptr) {
+ LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+ return ret;
+ }
+ if (nullptr == mApi) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return ret;
+ }
+
+ mGnssMeasurementCbIface_1_1 = callback;
+ mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ GnssPowerMode powerMode = enableFullTracking?
+ GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
+
+ return mApi->measurementSetCallback_1_1(callback, powerMode);
+}
+// Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) {
+
+ Return<GnssMeasurement::GnssMeasurementStatus> ret =
+ IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+ if (mGnssMeasurementCbIface_2_0 != nullptr) {
+ LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+ return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+ }
+
+ if (callback == nullptr) {
+ LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+ return ret;
+ }
+ if (nullptr == mApi) {
+ LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+ return ret;
+ }
+
+ mGnssMeasurementCbIface_2_0 = callback;
+ mGnssMeasurementCbIface_2_0->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+ GnssPowerMode powerMode = enableFullTracking ?
+ GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
+
+ return mApi->measurementSetCallback_2_0(callback, powerMode);
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/GnssMeasurement.h b/gps/android/2.0/GnssMeasurement.h
new file mode 100644
index 0000000..000b00f
--- /dev/null
+++ b/gps/android/2.0/GnssMeasurement.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
+
+#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class MeasurementAPIClient;
+struct GnssMeasurement : public V2_0::IGnssMeasurement {
+ GnssMeasurement();
+ ~GnssMeasurement();
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+ * These declarations were generated from IGnssMeasurement.hal.
+ */
+ Return<GnssMeasurement::GnssMeasurementStatus> setCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback) override;
+ Return<void> close() override;
+
+ // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+ Return<GnssMeasurement::GnssMeasurementStatus> setCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) override;
+
+ // Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow.
+ Return<GnssMeasurement::GnssMeasurementStatus> setCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback,
+ bool enableFullTracking) override;
+ private:
+ struct GnssMeasurementDeathRecipient : hidl_death_recipient {
+ GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) :
+ mGnssMeasurement(gnssMeasurement) {
+ }
+ ~GnssMeasurementDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssMeasurement> mGnssMeasurement;
+ };
+
+ private:
+ sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
+ sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
+ sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr;
+ sp<V2_0::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_0 = nullptr;
+ MeasurementAPIClient* mApi;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
diff --git a/gps/android/2.0/GnssNi.cpp b/gps/android/2.0/GnssNi.cpp
new file mode 100644
index 0000000..d65a488
--- /dev/null
+++ b/gps/android/2.0/GnssNi.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssNiInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssNi.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
+ LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+ __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+ // we do nothing here
+ // Gnss::GnssDeathRecipient will stop the session
+}
+
+GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) {
+ mGnssNiDeathRecipient = new GnssNiDeathRecipient(this);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ mGnss->setGnssNiCb(callback);
+
+ if (mGnssNiCbIface != nullptr) {
+ mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient);
+ }
+ mGnssNiCbIface = callback;
+ if (mGnssNiCbIface != nullptr) {
+ mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/);
+ }
+
+ return Void();
+}
+
+Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse) {
+ if (mGnss == nullptr) {
+ LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ GnssAPIClient* api = mGnss->getApi();
+ if (api == nullptr) {
+ LOC_LOGE("%s]: api is nullptr", __FUNCTION__);
+ return Void();
+ }
+
+ api->gnssNiRespond(notifId, userResponse);
+
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/GnssNi.h b/gps/android/2.0/GnssNi.h
new file mode 100644
index 0000000..26e281f
--- /dev/null
+++ b/gps/android/2.0/GnssNi.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
+
+#include <android/hardware/gnss/1.0/IGnssNi.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssNi;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+struct GnssNi : public IGnssNi {
+ GnssNi(Gnss* gnss);
+ ~GnssNi() = default;
+
+ /*
+ * Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+ * These declarations were generated from IGnssNi.hal.
+ */
+ Return<void> setCallback(const sp<IGnssNiCallback>& callback) override;
+ Return<void> respond(int32_t notifId,
+ IGnssNiCallback::GnssUserResponseType userResponse) override;
+
+ private:
+ struct GnssNiDeathRecipient : hidl_death_recipient {
+ GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) {
+ }
+ ~GnssNiDeathRecipient() = default;
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+ sp<GnssNi> mGnssNi;
+ };
+
+ private:
+ sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr;
+ sp<IGnssNiCallback> mGnssNiCbIface = nullptr;
+ Gnss* mGnss = nullptr;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
diff --git a/gps/android/2.0/android.hardware.gnss@2.0-service-qti.rc b/gps/android/2.0/android.hardware.gnss@2.0-service-qti.rc
new file mode 100644
index 0000000..ad46d5d
--- /dev/null
+++ b/gps/android/2.0/android.hardware.gnss@2.0-service-qti.rc
@@ -0,0 +1,4 @@
+service gnss_service /vendor/bin/hw/android.hardware.gnss@2.0-service-qti
+ class hal
+ user gps
+ group system gps radio vendor_qti_diag
diff --git a/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml b/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml
new file mode 100644
index 0000000..ff9fb2c
--- /dev/null
+++ b/gps/android/2.0/android.hardware.gnss@2.0-service-qti.xml
@@ -0,0 +1,36 @@
+<!-- Copyright (c) 2019, 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.
+-->
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.gnss</name>
+ <transport>hwbinder</transport>
+ <fqname>@1.1::IGnss/default</fqname>
+ <fqname>@2.0::IGnss/default</fqname>
+ </hal>
+</manifest>
+
diff --git a/gps/android/2.0/location_api/BatchingAPIClient.cpp b/gps/android/2.0/location_api/BatchingAPIClient.cpp
new file mode 100644
index 0000000..49cd18a
--- /dev/null
+++ b/gps/android/2.0/location_api/BatchingAPIClient.cpp
@@ -0,0 +1,250 @@
+/* Copyright (c) 2017-2019, 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_BatchingAPIClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "BatchingAPIClient.h"
+
+#include "limits.h"
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_0::IGnssBatching;
+using ::android::hardware::gnss::V2_0::IGnssBatchingCallback;
+using ::android::hardware::gnss::V2_0::GnssLocation;
+
+static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
+ LocationCapabilitiesMask mask);
+
+BatchingAPIClient::BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback) :
+ LocationAPIClientBase(),
+ mGnssBatchingCbIface(nullptr),
+ mDefaultId(UINT_MAX),
+ mLocationCapabilitiesMask(0),
+ mGnssBatchingCbIface_2_0(nullptr)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ gnssUpdateCallbacks(callback);
+}
+
+BatchingAPIClient::BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback) :
+ LocationAPIClientBase(),
+ mGnssBatchingCbIface(nullptr),
+ mDefaultId(UINT_MAX),
+ mLocationCapabilitiesMask(0),
+ mGnssBatchingCbIface_2_0(nullptr)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ gnssUpdateCallbacks_2_0(callback);
+}
+
+BatchingAPIClient::~BatchingAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+int BatchingAPIClient::getBatchSize()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ return locAPIGetBatchSize();
+}
+
+void BatchingAPIClient::setCallbacks()
+{
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = nullptr;
+ locationCallbacks.batchingCb = [this](size_t count, Location* location,
+ BatchingOptions batchOptions) {
+ onBatchingCb(count, location, batchOptions);
+ };
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssNmeaCb = nullptr;
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback)
+{
+ mMutex.lock();
+ mGnssBatchingCbIface = callback;
+ mMutex.unlock();
+
+ if (mGnssBatchingCbIface != nullptr) {
+ setCallbacks();
+ }
+}
+
+void BatchingAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback)
+{
+ mMutex.lock();
+ mGnssBatchingCbIface_2_0 = callback;
+ mMutex.unlock();
+
+ if (mGnssBatchingCbIface_2_0 != nullptr) {
+ setCallbacks();
+ }
+}
+
+int BatchingAPIClient::startSession(const IGnssBatching::Options& opts)
+{
+ LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
+ static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
+ int retVal = -1;
+ LocationOptions options;
+ convertBatchOption(opts, options, mLocationCapabilitiesMask);
+ uint32_t mode = 0;
+ if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
+ mode = SESSION_MODE_ON_FULL;
+ }
+ if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
+ retVal = 1;
+ }
+ return retVal;
+}
+
+int BatchingAPIClient::updateSessionOptions(const IGnssBatching::Options& opts)
+{
+ LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
+ static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
+ int retVal = -1;
+ LocationOptions options;
+ convertBatchOption(opts, options, mLocationCapabilitiesMask);
+
+ uint32_t mode = 0;
+ if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
+ mode = SESSION_MODE_ON_FULL;
+ }
+ if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
+ retVal = 1;
+ }
+ return retVal;
+}
+
+int BatchingAPIClient::stopSession()
+{
+ LOC_LOGD("%s]: ", __FUNCTION__);
+ int retVal = -1;
+ if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
+ retVal = 1;
+ }
+ return retVal;
+}
+
+void BatchingAPIClient::getBatchedLocation(int last_n_locations)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
+ locAPIGetBatchedLocations(mDefaultId, last_n_locations);
+}
+
+void BatchingAPIClient::flushBatchedLocations()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
+}
+
+void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
+{
+ LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ mLocationCapabilitiesMask = capabilitiesMask;
+}
+
+void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
+ BatchingOptions /*batchOptions*/)
+{
+ mMutex.lock();
+ auto gnssBatchingCbIface(mGnssBatchingCbIface);
+ auto gnssBatchingCbIface_2_0(mGnssBatchingCbIface_2_0);
+ mMutex.unlock();
+
+ LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
+ if (gnssBatchingCbIface_2_0 != nullptr && count > 0) {
+ hidl_vec<V2_0::GnssLocation> locationVec;
+ locationVec.resize(count);
+ for (size_t i = 0; i < count; i++) {
+ convertGnssLocation(location[i], locationVec[i]);
+ }
+ auto r = gnssBatchingCbIface_2_0->gnssLocationBatchCb(locationVec);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationBatchCb 2.0 description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssBatchingCbIface != nullptr && count > 0) {
+ hidl_vec<V1_0::GnssLocation> locationVec;
+ locationVec.resize(count);
+ for (size_t i = 0; i < count; i++) {
+ convertGnssLocation(location[i], locationVec[i]);
+ }
+ auto r = gnssBatchingCbIface->gnssLocationBatchCb(locationVec);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationBatchCb 1.0 description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
+ LocationCapabilitiesMask mask)
+{
+ memset(&out, 0, sizeof(LocationOptions));
+ out.size = sizeof(LocationOptions);
+ out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
+ out.minDistance = 0;
+ out.mode = GNSS_SUPL_MODE_STANDALONE;
+ if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
+ out.mode = GNSS_SUPL_MODE_MSA;
+ if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
+ out.mode = GNSS_SUPL_MODE_MSB;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/location_api/BatchingAPIClient.h b/gps/android/2.0/location_api/BatchingAPIClient.h
new file mode 100644
index 0000000..7198341
--- /dev/null
+++ b/gps/android/2.0/location_api/BatchingAPIClient.h
@@ -0,0 +1,81 @@
+/* Copyright (c) 2017-2019, 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 BATCHING_API_CLINET_H
+#define BATCHING_API_CLINET_H
+
+#include <mutex>
+#include <android/hardware/gnss/2.0/IGnssBatching.h>
+#include <android/hardware/gnss/2.0/IGnssBatchingCallback.h>
+#include <pthread.h>
+
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+class BatchingAPIClient : public LocationAPIClientBase
+{
+public:
+ BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback);
+ BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback);
+ void gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback);
+ void gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback);
+ ~BatchingAPIClient();
+ int getBatchSize();
+ int startSession(const V1_0::IGnssBatching::Options& options);
+ int updateSessionOptions(const V1_0::IGnssBatching::Options& options);
+ int stopSession();
+ void getBatchedLocation(int last_n_locations);
+ void flushBatchedLocations();
+
+ inline LocationCapabilitiesMask getCapabilities() { return mLocationCapabilitiesMask; }
+
+ // callbacks
+ void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
+ void onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions) final;
+
+private:
+ void setCallbacks();
+ std::mutex mMutex;
+ sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
+ uint32_t mDefaultId;
+ LocationCapabilitiesMask mLocationCapabilitiesMask;
+ sp<V2_0::IGnssBatchingCallback> mGnssBatchingCbIface_2_0;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // BATCHING_API_CLINET_H
diff --git a/gps/android/2.0/location_api/GeofenceAPIClient.cpp b/gps/android/2.0/location_api/GeofenceAPIClient.cpp
new file mode 100644
index 0000000..a93c988
--- /dev/null
+++ b/gps/android/2.0/location_api/GeofenceAPIClient.cpp
@@ -0,0 +1,275 @@
+/* Copyright (c) 2017-2019, 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_GeofenceApiClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "GeofenceAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) :
+ LocationAPIClientBase(),
+ mGnssGeofencingCbIface(callback)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = nullptr;
+
+ locationCallbacks.geofenceBreachCb = nullptr;
+ if (mGnssGeofencingCbIface != nullptr) {
+ locationCallbacks.geofenceBreachCb =
+ [this](GeofenceBreachNotification geofenceBreachNotification) {
+ onGeofenceBreachCb(geofenceBreachNotification);
+ };
+
+ locationCallbacks.geofenceStatusCb =
+ [this](GeofenceStatusNotification geofenceStatusNotification) {
+ onGeofenceStatusCb(geofenceStatusNotification);
+ };
+ }
+
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssNmeaCb = nullptr;
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
+ double radius_meters, int32_t last_transition, int32_t monitor_transitions,
+ uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms)
+{
+ LOC_LOGD("%s]: (%d %f %f %f %d %d %d %d)", __FUNCTION__,
+ geofence_id, latitude, longitude, radius_meters,
+ last_transition, monitor_transitions, notification_responsiveness_ms, unknown_timer_ms);
+
+ GeofenceOption options;
+ memset(&options, 0, sizeof(GeofenceOption));
+ options.size = sizeof(GeofenceOption);
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
+ options.breachTypeMask |= GEOFENCE_BREACH_ENTER_BIT;
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
+ options.breachTypeMask |= GEOFENCE_BREACH_EXIT_BIT;
+ options.responsiveness = notification_responsiveness_ms;
+
+ GeofenceInfo data;
+ data.size = sizeof(GeofenceInfo);
+ data.latitude = latitude;
+ data.longitude = longitude;
+ data.radius = radius_meters;
+
+ LocationError err = (LocationError)locAPIAddGeofences(1, &geofence_id, &options, &data);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ onAddGeofencesCb(1, &err, &geofence_id);
+ }
+}
+
+void GeofenceAPIClient::geofencePause(uint32_t geofence_id)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
+ locAPIPauseGeofences(1, &geofence_id);
+}
+
+void GeofenceAPIClient::geofenceResume(uint32_t geofence_id, int32_t monitor_transitions)
+{
+ LOC_LOGD("%s]: (%d %d)", __FUNCTION__, geofence_id, monitor_transitions);
+ GeofenceBreachTypeMask mask = 0;
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
+ mask |= GEOFENCE_BREACH_ENTER_BIT;
+ if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
+ mask |= GEOFENCE_BREACH_EXIT_BIT;
+ locAPIResumeGeofences(1, &geofence_id, &mask);
+}
+
+void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
+ locAPIRemoveGeofences(1, &geofence_id);
+}
+
+void GeofenceAPIClient::geofenceRemoveAll()
+{
+ LOC_LOGD("%s]", __FUNCTION__);
+ // TODO locAPIRemoveAllGeofences();
+}
+
+// callbacks
+void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceBreachNotification.count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < geofenceBreachNotification.count; i++) {
+ GnssLocation gnssLocation;
+ convertGnssLocation(geofenceBreachNotification.location, gnssLocation);
+
+ IGnssGeofenceCallback::GeofenceTransition transition;
+ if (geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER)
+ transition = IGnssGeofenceCallback::GeofenceTransition::ENTERED;
+ else if (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT)
+ transition = IGnssGeofenceCallback::GeofenceTransition::EXITED;
+ else {
+ // continue with other breach if transition is
+ // nether GPS_GEOFENCE_ENTERED nor GPS_GEOFENCE_EXITED
+ continue;
+ }
+
+ auto r = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
+ geofenceBreachNotification.ids[i], gnssLocation, transition,
+ static_cast<V1_0::GnssUtcTime>(geofenceBreachNotification.timestamp));
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceTransitionCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available);
+ if (mGnssGeofencingCbIface != nullptr) {
+ IGnssGeofenceCallback::GeofenceAvailability status =
+ IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE;
+ if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) {
+ status = IGnssGeofenceCallback::GeofenceAvailability::AVAILABLE;
+ }
+ GnssLocation gnssLocation;
+ memset(&gnssLocation, 0, sizeof(GnssLocation));
+ auto r = mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_EXISTS)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS;
+ auto r = mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+ auto r = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+ auto r = mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+ LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+ if (mGnssGeofencingCbIface != nullptr) {
+ for (size_t i = 0; i < count; i++) {
+ IGnssGeofenceCallback::GeofenceStatus status =
+ IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+ if (errors[i] == LOCATION_ERROR_SUCCESS)
+ status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+ else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+ status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+ auto r = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/location_api/GeofenceAPIClient.h b/gps/android/2.0/location_api/GeofenceAPIClient.h
new file mode 100644
index 0000000..71049de
--- /dev/null
+++ b/gps/android/2.0/location_api/GeofenceAPIClient.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2017-2019, 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 GEOFENCE_API_CLINET_H
+#define GEOFENCE_API_CLINET_H
+
+
+#include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h>
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+
+class GeofenceAPIClient : public LocationAPIClientBase
+{
+public:
+ GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback);
+ virtual ~GeofenceAPIClient() = default;
+
+ void geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
+ double radius_meters, int32_t last_transition, int32_t monitor_transitions,
+ uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms);
+ void geofencePause(uint32_t geofence_id);
+ void geofenceResume(uint32_t geofence_id, int32_t monitor_transitions);
+ void geofenceRemove(uint32_t geofence_id);
+ void geofenceRemoveAll();
+
+ // callbacks
+ void onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) final;
+ void onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) final;
+ void onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+ void onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+ void onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+ void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+
+private:
+ sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // GEOFENCE_API_CLINET_H
diff --git a/gps/android/2.0/location_api/GnssAPIClient.cpp b/gps/android/2.0/location_api/GnssAPIClient.cpp
new file mode 100644
index 0000000..a3cdd27
--- /dev/null
+++ b/gps/android/2.0/location_api/GnssAPIClient.cpp
@@ -0,0 +1,728 @@
+/* Copyright (c) 2017-2019, 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_GnssAPIClient"
+#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "GnssAPIClient.h"
+#include <LocContext.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_0::IGnss;
+using ::android::hardware::gnss::V2_0::IGnssCallback;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::gnss::V2_0::GnssLocation;
+
+static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out);
+static void convertGnssSvStatus(GnssSvNotification& in,
+ hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out);
+
+GnssAPIClient::GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<V1_0::IGnssNiCallback>& niCb) :
+ LocationAPIClientBase(),
+ mGnssCbIface(nullptr),
+ mGnssNiCbIface(nullptr),
+ mControlClient(new LocationAPIControlClient()),
+ mLocationCapabilitiesMask(0),
+ mLocationCapabilitiesCached(false),
+ mTracking(false),
+ mGnssCbIface_2_0(nullptr)
+{
+ LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
+
+ initLocationOptions();
+ gnssUpdateCallbacks(gpsCb, niCb);
+}
+
+GnssAPIClient::GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb) :
+ LocationAPIClientBase(),
+ mGnssCbIface(nullptr),
+ mGnssNiCbIface(nullptr),
+ mControlClient(new LocationAPIControlClient()),
+ mLocationCapabilitiesMask(0),
+ mLocationCapabilitiesCached(false),
+ mTracking(false),
+ mGnssCbIface_2_0(nullptr)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
+
+ initLocationOptions();
+ gnssUpdateCallbacks_2_0(gpsCb);
+}
+
+GnssAPIClient::~GnssAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ if (mControlClient) {
+ delete mControlClient;
+ mControlClient = nullptr;
+ }
+}
+
+void GnssAPIClient::initLocationOptions()
+{
+ // set default LocationOptions.
+ memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+ mTrackingOptions.size = sizeof(TrackingOptions);
+ mTrackingOptions.minInterval = 1000;
+ mTrackingOptions.minDistance = 0;
+ mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+}
+
+void GnssAPIClient::setCallbacks()
+{
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.trackingCb = [this](Location location) {
+ onTrackingCb(location);
+ };
+
+ locationCallbacks.batchingCb = nullptr;
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ if (mGnssNiCbIface != nullptr) {
+ loc_core::ContextBase* context =
+ loc_core::LocContext::getLocContext(
+ NULL, NULL,
+ loc_core::LocContext::mLocationHalName, false);
+ if (!context->hasAgpsExtendedCapabilities()) {
+ LOC_LOGD("Registering NI CB");
+ locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotify) {
+ onGnssNiCb(id, gnssNiNotify);
+ };
+ }
+ }
+
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
+ onGnssSvCb(gnssSvNotification);
+ };
+
+ locationCallbacks.gnssNmeaCb = nullptr;
+ locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
+ onGnssNmeaCb(gnssNmeaNotification);
+ };
+
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+
+ locAPISetCallbacks(locationCallbacks);
+}
+
+// for GpsInterface
+void GnssAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<IGnssNiCallback>& niCb)
+{
+ LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
+
+ mMutex.lock();
+ mGnssCbIface = gpsCb;
+ mGnssNiCbIface = niCb;
+ mMutex.unlock();
+
+ if (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr) {
+ setCallbacks();
+ }
+}
+
+void GnssAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
+
+ mMutex.lock();
+ mGnssCbIface_2_0 = gpsCb;
+ mMutex.unlock();
+
+ if (mGnssCbIface_2_0 != nullptr) {
+ setCallbacks();
+ }
+}
+
+bool GnssAPIClient::gnssStart()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+
+ mMutex.lock();
+ mTracking = true;
+ mMutex.unlock();
+
+ bool retVal = true;
+ locAPIStartTracking(mTrackingOptions);
+ return retVal;
+}
+
+bool GnssAPIClient::gnssStop()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+
+ mMutex.lock();
+ mTracking = false;
+ mMutex.unlock();
+
+ bool retVal = true;
+ locAPIStopTracking();
+ return retVal;
+}
+
+bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
+ IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LOC_LOGD("%s]: (%d %d %d %d %d %d %d)", __FUNCTION__,
+ (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters,
+ preferredTimeMs, (int)powerMode, timeBetweenMeasurement);
+ bool retVal = true;
+ memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+ mTrackingOptions.size = sizeof(TrackingOptions);
+ mTrackingOptions.minInterval = minIntervalMs;
+ if (IGnss::GnssPositionMode::MS_ASSISTED == mode ||
+ IGnss::GnssPositionRecurrence::RECURRENCE_SINGLE == recurrence) {
+ // We set a very large interval to simulate SINGLE mode. Once we report a fix,
+ // the caller should take the responsibility to stop the session.
+ // For MSA, we always treat it as SINGLE mode.
+ mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC;
+ }
+ mTrackingOptions.minDistance = preferredAccuracyMeters;
+ if (mode == IGnss::GnssPositionMode::STANDALONE)
+ mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+ else if (mode == IGnss::GnssPositionMode::MS_BASED)
+ mTrackingOptions.mode = GNSS_SUPL_MODE_MSB;
+ else if (mode == IGnss::GnssPositionMode::MS_ASSISTED)
+ mTrackingOptions.mode = GNSS_SUPL_MODE_MSA;
+ else {
+ LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
+ retVal = false;
+ }
+ if (GNSS_POWER_MODE_INVALID != powerMode) {
+ mTrackingOptions.powerMode = powerMode;
+ mTrackingOptions.tbm = timeBetweenMeasurement;
+ }
+ locAPIUpdateTrackingOptions(mTrackingOptions);
+ return retVal;
+}
+
+// for GpsNiInterface
+void GnssAPIClient::gnssNiRespond(int32_t notifId,
+ IGnssNiCallback::GnssUserResponseType userResponse)
+{
+ LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
+ GnssNiResponse data;
+ switch (userResponse) {
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT:
+ data = GNSS_NI_RESPONSE_ACCEPT;
+ break;
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY:
+ data = GNSS_NI_RESPONSE_DENY;
+ break;
+ case IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP:
+ data = GNSS_NI_RESPONSE_NO_RESPONSE;
+ break;
+ default:
+ data = GNSS_NI_RESPONSE_IGNORE;
+ break;
+ }
+
+ locAPIGnssNiResponse(notifId, data);
+}
+
+// these apis using LocationAPIControlClient
+void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
+{
+ LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ GnssAidingData data;
+ memset(&data, 0, sizeof (GnssAidingData));
+ data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT |
+ GNSS_AIDING_DATA_SV_TYPE_NAVIC_BIT;
+ data.posEngineMask = STANDARD_POSITIONING_ENGINE;
+
+ if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
+ data.deleteAll = true;
+ else {
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
+ data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
+ if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
+ data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
+ }
+ mControlClient->locAPIGnssDeleteAidingData(data);
+}
+
+void GnssAPIClient::gnssEnable(LocationTechnologyType techType)
+{
+ LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ mControlClient->locAPIEnable(techType);
+}
+
+void GnssAPIClient::gnssDisable()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ mControlClient->locAPIDisable();
+}
+
+void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
+{
+ LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
+ if (mControlClient == nullptr) {
+ return;
+ }
+ mControlClient->locAPIGnssUpdateConfig(gnssConfig);
+}
+
+void GnssAPIClient::requestCapabilities() {
+ // only send capablities if it's already cached, otherwise the first time LocationAPI
+ // is initialized, capabilities will be sent by LocationAPI
+ if (mLocationCapabilitiesCached) {
+ onCapabilitiesCb(mLocationCapabilitiesMask);
+ }
+}
+
+// callbacks
+void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
+{
+ LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+ mLocationCapabilitiesMask = capabilitiesMask;
+ mLocationCapabilitiesCached = true;
+
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ mMutex.unlock();
+
+ if (gnssCbIface_2_0 != nullptr || gnssCbIface != nullptr) {
+ uint32_t data = 0;
+ if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
+ (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
+ (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
+ (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
+ data |= IGnssCallback::Capabilities::SCHEDULING;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
+ data |= V1_0::IGnssCallback::Capabilities::GEOFENCING;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
+ data |= V1_0::IGnssCallback::Capabilities::MEASUREMENTS;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
+ data |= IGnssCallback::Capabilities::MSB;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
+ data |= IGnssCallback::Capabilities::MSA;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT)
+ data |= IGnssCallback::Capabilities::LOW_POWER_MODE;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT)
+ data |= IGnssCallback::Capabilities::SATELLITE_BLACKLIST;
+
+ IGnssCallback::GnssSystemInfo gnssInfo;
+ if (capabilitiesMask & LOCATION_CAPABILITIES_PRIVACY_BIT) {
+ gnssInfo.yearOfHw = 2019;
+ } else if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
+ capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
+ gnssInfo.yearOfHw = 2018;
+ } else if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
+ gnssInfo.yearOfHw = 2017;
+ } else if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
+ gnssInfo.yearOfHw = 2016;
+ } else {
+ gnssInfo.yearOfHw = 2015;
+ }
+ LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
+
+ if (gnssCbIface_2_0 != nullptr) {
+ auto r = gnssCbIface_2_0->gnssSetCapabilitiesCb_2_0(data);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_0 description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface_2_0->gnssSetSystemInfoCb(gnssInfo);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssSetCapabilitesCb(data);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+
+ }
+
+}
+
+void GnssAPIClient::onTrackingCb(Location location)
+{
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ bool isTracking = mTracking;
+ mMutex.unlock();
+
+ LOC_LOGD("%s]: (flags: %02x isTracking: %d)", __FUNCTION__, location.flags, isTracking);
+
+ if (!isTracking) {
+ return;
+ }
+
+ if (gnssCbIface_2_0 != nullptr) {
+ V2_0::GnssLocation gnssLocation;
+ convertGnssLocation(location, gnssLocation);
+ auto r = gnssCbIface_2_0->gnssLocationCb_2_0(gnssLocation);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface != nullptr) {
+ V1_0::GnssLocation gnssLocation;
+ convertGnssLocation(location, gnssLocation);
+ auto r = gnssCbIface->gnssLocationCb(gnssLocation);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssLocationCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else {
+ LOC_LOGW("%s] No GNSS Interface ready for gnssLocationCb ", __FUNCTION__);
+ }
+
+}
+
+void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
+{
+ LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
+ mMutex.lock();
+ auto gnssNiCbIface(mGnssNiCbIface);
+ mMutex.unlock();
+
+ if (gnssNiCbIface == nullptr) {
+ LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
+ return;
+ }
+
+ IGnssNiCallback::GnssNiNotification notificationGnss = {};
+
+ notificationGnss.notificationId = id;
+
+ if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
+ else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
+ else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
+ else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
+ notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
+
+ if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
+ notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
+ if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
+ notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
+ if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
+ notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
+
+ notificationGnss.timeoutSec = gnssNiNotification.timeout;
+
+ if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
+ notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
+ else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
+ notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
+ else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
+ gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
+ notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
+
+ notificationGnss.requestorId = gnssNiNotification.requestor;
+
+ notificationGnss.notificationMessage = gnssNiNotification.message;
+
+ if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
+ else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
+ else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
+ else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
+ notificationGnss.requestorIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
+
+ if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
+ else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
+ else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
+ else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
+ notificationGnss.notificationIdEncoding =
+ IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
+
+ gnssNiCbIface->niNotifyCb(notificationGnss);
+}
+
+void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
+{
+ LOC_LOGD("%s]: (count: %u)", __FUNCTION__, gnssSvNotification.count);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ mMutex.unlock();
+
+ if (gnssCbIface_2_0 != nullptr) {
+ hidl_vec<V2_0::IGnssCallback::GnssSvInfo> svInfoList;
+ convertGnssSvStatus(gnssSvNotification, svInfoList);
+ auto r = gnssCbIface_2_0->gnssSvStatusCb_2_0(svInfoList);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSvStatusCb_2_0 description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface != nullptr) {
+ V1_0::IGnssCallback::GnssSvStatus svStatus;
+ convertGnssSvStatus(gnssSvNotification, svStatus);
+ auto r = gnssCbIface->gnssSvStatusCb(svStatus);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+}
+
+void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
+{
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ mMutex.unlock();
+
+ if (gnssCbIface != nullptr || gnssCbIface_2_0 != nullptr) {
+ const std::string s(gnssNmeaNotification.nmea);
+ std::stringstream ss(s);
+ std::string each;
+ while(std::getline(ss, each, '\n')) {
+ each += '\n';
+ android::hardware::hidl_string nmeaString;
+ nmeaString.setToExternal(each.c_str(), each.length());
+ if (gnssCbIface_2_0 != nullptr) {
+ auto r = gnssCbIface_2_0->gnssNmeaCb(
+ static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssCbIface_2_0 nmea=%s length=%u description=%s",
+ __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
+ r.description().c_str());
+ }
+ } else if (gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssNmeaCb(
+ static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%u description=%s",
+ __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
+ r.description().c_str());
+ }
+ }
+ }
+ }
+}
+
+void GnssAPIClient::onStartTrackingCb(LocationError error)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ mMutex.unlock();
+
+ if (error == LOCATION_ERROR_SUCCESS) {
+ if (gnssCbIface_2_0 != nullptr) {
+ auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2.0 ENGINE_ON description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2.0 SESSION_BEGIN description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+void GnssAPIClient::onStopTrackingCb(LocationError error)
+{
+ LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
+ mMutex.lock();
+ auto gnssCbIface(mGnssCbIface);
+ auto gnssCbIface_2_0(mGnssCbIface_2_0);
+ mMutex.unlock();
+
+ if (error == LOCATION_ERROR_SUCCESS) {
+ if (gnssCbIface_2_0 != nullptr) {
+ auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2.0 SESSION_END description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb 2.0 ENGINE_OFF description=%s",
+ __func__, r.description().c_str());
+ }
+
+ } else if (gnssCbIface != nullptr) {
+ auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
+ __func__, r.description().c_str());
+ }
+ r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out)
+{
+ memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
+ out.numSvs = in.count;
+ if (out.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+ LOC_LOGW("%s]: Too many satellites %u. Clamps to %d.",
+ __FUNCTION__, out.numSvs, V1_0::GnssMax::SVS_COUNT);
+ out.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
+ }
+ for (size_t i = 0; i < out.numSvs; i++) {
+ out.gnssSvList[i].svid = in.gnssSvs[i].svId;
+ convertGnssConstellationType(in.gnssSvs[i].type, out.gnssSvList[i].constellation);
+ out.gnssSvList[i].cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
+ out.gnssSvList[i].elevationDegrees = in.gnssSvs[i].elevation;
+ out.gnssSvList[i].azimuthDegrees = in.gnssSvs[i].azimuth;
+ out.gnssSvList[i].carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
+ out.gnssSvList[i].svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
+ out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
+ out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
+ out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+ out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+ }
+}
+
+static void convertGnssSvStatus(GnssSvNotification& in,
+ hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out)
+{
+ out.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ out[i].v1_0.svid = in.gnssSvs[i].svId;
+ out[i].v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
+ out[i].v1_0.elevationDegrees = in.gnssSvs[i].elevation;
+ out[i].v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
+ out[i].v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
+ out[i].v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
+ out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
+ out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
+ out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+ if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+ out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+
+ convertGnssConstellationType(in.gnssSvs[i].type, out[i].constellation);
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/location_api/GnssAPIClient.h b/gps/android/2.0/location_api/GnssAPIClient.h
new file mode 100644
index 0000000..63b4561
--- /dev/null
+++ b/gps/android/2.0/location_api/GnssAPIClient.h
@@ -0,0 +1,114 @@
+/* Copyright (c) 2017-2019, 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 GNSS_API_CLINET_H
+#define GNSS_API_CLINET_H
+
+
+#include <mutex>
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <android/hardware/gnss/2.0/IGnssCallback.h>
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+
+class GnssAPIClient : public LocationAPIClientBase
+{
+public:
+ GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<V1_0::IGnssNiCallback>& niCb);
+ GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb);
+ virtual ~GnssAPIClient();
+ GnssAPIClient(const GnssAPIClient&) = delete;
+ GnssAPIClient& operator=(const GnssAPIClient&) = delete;
+
+ // for GpsInterface
+ void gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
+ const sp<V1_0::IGnssNiCallback>& niCb);
+ void gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb);
+ bool gnssStart();
+ bool gnssStop();
+ bool gnssSetPositionMode(V1_0::IGnss::GnssPositionMode mode,
+ V1_0::IGnss::GnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs,
+ uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs,
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = 0);
+
+ // for GpsNiInterface
+ void gnssNiRespond(int32_t notifId, V1_0::IGnssNiCallback::GnssUserResponseType userResponse);
+
+ // these apis using LocationAPIControlClient
+ void gnssDeleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags);
+ void gnssEnable(LocationTechnologyType techType);
+ void gnssDisable();
+ void gnssConfigurationUpdate(const GnssConfig& gnssConfig);
+
+ inline LocationCapabilitiesMask gnssGetCapabilities() const {
+ return mLocationCapabilitiesMask;
+ }
+ void requestCapabilities();
+
+ // callbacks we are interested in
+ void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
+ void onTrackingCb(Location location) final;
+ void onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) final;
+ void onGnssSvCb(GnssSvNotification gnssSvNotification) final;
+ void onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) final;
+
+ void onStartTrackingCb(LocationError error) final;
+ void onStopTrackingCb(LocationError error) final;
+
+private:
+ void setCallbacks();
+ void initLocationOptions();
+ sp<V1_0::IGnssCallback> mGnssCbIface;
+ sp<V1_0::IGnssNiCallback> mGnssNiCbIface;
+ std::mutex mMutex;
+ LocationAPIControlClient* mControlClient;
+ LocationCapabilitiesMask mLocationCapabilitiesMask;
+ bool mLocationCapabilitiesCached;
+ TrackingOptions mTrackingOptions;
+ bool mTracking;
+ sp<V2_0::IGnssCallback> mGnssCbIface_2_0;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // GNSS_API_CLINET_H
diff --git a/gps/android/2.0/location_api/LocationUtil.cpp b/gps/android/2.0/location_api/LocationUtil.cpp
new file mode 100644
index 0000000..8a30066
--- /dev/null
+++ b/gps/android/2.0/location_api/LocationUtil.cpp
@@ -0,0 +1,311 @@
+/* Copyright (c) 2017-2019, 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.
+ *
+ */
+
+#include <LocationUtil.h>
+#include <log_util.h>
+#include <inttypes.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V2_0::GnssLocation;
+using ::android::hardware::gnss::V2_0::GnssConstellationType;
+using ::android::hardware::gnss::V1_0::GnssLocationFlags;
+
+void convertGnssLocation(Location& in, V1_0::GnssLocation& out)
+{
+ memset(&out, 0, sizeof(V1_0::GnssLocation));
+ if (in.flags & LOCATION_HAS_LAT_LONG_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
+ out.latitudeDegrees = in.latitude;
+ out.longitudeDegrees = in.longitude;
+ }
+ if (in.flags & LOCATION_HAS_ALTITUDE_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
+ out.altitudeMeters = in.altitude;
+ }
+ if (in.flags & LOCATION_HAS_SPEED_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
+ out.speedMetersPerSec = in.speed;
+ }
+ if (in.flags & LOCATION_HAS_BEARING_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
+ out.bearingDegrees = in.bearing;
+ }
+ if (in.flags & LOCATION_HAS_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
+ out.horizontalAccuracyMeters = in.accuracy;
+ }
+ if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
+ out.verticalAccuracyMeters = in.verticalAccuracy;
+ }
+ if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
+ out.speedAccuracyMetersPerSecond = in.speedAccuracy;
+ }
+ if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) {
+ out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
+ out.bearingAccuracyDegrees = in.bearingAccuracy;
+ }
+
+ out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
+}
+
+void convertGnssLocation(Location& in, V2_0::GnssLocation& out)
+{
+ memset(&out, 0, sizeof(V2_0::GnssLocation));
+ convertGnssLocation(in, out.v1_0);
+
+ struct timespec sinceBootTime;
+ struct timespec currentTime;
+ struct timespec sinceBootTimeTest;
+ int64_t sinceBootTimeNanos = 0;
+ bool clockGetTimeSuccess = false;
+ const uint32_t MAX_TIME_DELTA_VALUE_NANOS = 10000;
+ const uint32_t MAX_GET_TIME_COUNT = 20;
+ /* Attempt to get CLOCK_REALTIME and CLOCK_BOOTIME in succession without an interruption
+ or context switch (for up to MAX_GET_TIME_COUNT times) to avoid errors in the calculation */
+ for (uint32_t i=0; i < MAX_GET_TIME_COUNT; i++) {
+ if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTime) != 0) {
+ break;
+ };
+ if (clock_gettime(CLOCK_REALTIME, &currentTime) != 0) {
+ break;
+ }
+ if (clock_gettime(CLOCK_BOOTTIME, &sinceBootTimeTest) != 0) {
+ break;
+ };
+ sinceBootTimeNanos = sinceBootTime.tv_sec*1000000000 + sinceBootTime.tv_nsec;
+ int64_t sinceBootTimeTestNanos =
+ sinceBootTimeTest.tv_sec*1000000000 + sinceBootTimeTest.tv_nsec;
+ int64_t sinceBootTimeDeltaNanos = sinceBootTimeTestNanos - sinceBootTimeNanos;
+
+ /* sinceBootTime and sinceBootTimeTest should have a close value if there was no
+ interruption or context switch between clock_gettime for CLOCK_BOOTIME and
+ clock_gettime for CLOCK_REALTIME */
+ if (sinceBootTimeDeltaNanos < MAX_TIME_DELTA_VALUE_NANOS) {
+ clockGetTimeSuccess = true;
+ break;
+ } else {
+ LOC_LOGD("%s]: Delta:%" PRIi64 "ns time too large, retry number #%u...",
+ __FUNCTION__, sinceBootTimeDeltaNanos, i+1);
+ }
+ }
+
+ if (clockGetTimeSuccess) {
+ int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec;
+ int64_t locationTimeNanos = in.timestamp*1000000;
+ LOC_LOGD("%s]: sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
+ " locationTimeNanos:%" PRIi64 "",
+ __FUNCTION__, sinceBootTimeNanos, currentTimeNanos, locationTimeNanos);
+ if (currentTimeNanos >= locationTimeNanos) {
+ int64_t ageTimeNanos = currentTimeNanos - locationTimeNanos;
+ LOC_LOGD("%s]: ageTimeNanos:%" PRIi64 ")", __FUNCTION__, ageTimeNanos);
+ if (ageTimeNanos >= 0 && ageTimeNanos <= sinceBootTimeNanos) {
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+ out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos;
+ out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+ // time uncertainty is 1 ms since it is calculated from utc time that is in ms
+ out.elapsedRealtime.timeUncertaintyNs = 1000000;
+ LOC_LOGD("%s]: timestampNs:%" PRIi64 ")",
+ __FUNCTION__, out.elapsedRealtime.timestampNs);
+ }
+ }
+ } else {
+ LOC_LOGE("%s]: Failed to calculate elapsedRealtimeNanos timestamp after %u tries",
+ __FUNCTION__, MAX_GET_TIME_COUNT);
+ }
+}
+
+void convertGnssLocation(const V1_0::GnssLocation& in, Location& out)
+{
+ memset(&out, 0, sizeof(out));
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) {
+ out.flags |= LOCATION_HAS_LAT_LONG_BIT;
+ out.latitude = in.latitudeDegrees;
+ out.longitude = in.longitudeDegrees;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE) {
+ out.flags |= LOCATION_HAS_ALTITUDE_BIT;
+ out.altitude = in.altitudeMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED) {
+ out.flags |= LOCATION_HAS_SPEED_BIT;
+ out.speed = in.speedMetersPerSec;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+ out.flags |= LOCATION_HAS_BEARING_BIT;
+ out.bearing = in.bearingDegrees;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
+ out.flags |= LOCATION_HAS_ACCURACY_BIT;
+ out.accuracy = in.horizontalAccuracyMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+ out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
+ out.verticalAccuracy = in.verticalAccuracyMeters;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
+ out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
+ out.speedAccuracy = in.speedAccuracyMetersPerSecond;
+ }
+ if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
+ out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
+ out.bearingAccuracy = in.bearingAccuracyDegrees;
+ }
+
+ out.timestamp = static_cast<uint64_t>(in.timestamp);
+}
+
+void convertGnssLocation(const V2_0::GnssLocation& in, Location& out)
+{
+ memset(&out, 0, sizeof(out));
+ convertGnssLocation(in.v1_0, out);
+}
+
+void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out)
+{
+ switch(in) {
+ case GNSS_SV_TYPE_GPS:
+ out = V1_0::GnssConstellationType::GPS;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = V1_0::GnssConstellationType::SBAS;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ out = V1_0::GnssConstellationType::GLONASS;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = V1_0::GnssConstellationType::QZSS;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = V1_0::GnssConstellationType::BEIDOU;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = V1_0::GnssConstellationType::GALILEO;
+ break;
+ case GNSS_SV_TYPE_UNKNOWN:
+ default:
+ out = V1_0::GnssConstellationType::UNKNOWN;
+ break;
+ }
+}
+
+void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out)
+{
+ switch(in) {
+ case GNSS_SV_TYPE_GPS:
+ out = V2_0::GnssConstellationType::GPS;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ out = V2_0::GnssConstellationType::SBAS;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ out = V2_0::GnssConstellationType::GLONASS;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ out = V2_0::GnssConstellationType::QZSS;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ out = V2_0::GnssConstellationType::BEIDOU;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ out = V2_0::GnssConstellationType::GALILEO;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ out = V2_0::GnssConstellationType::IRNSS;
+ break;
+ case GNSS_SV_TYPE_UNKNOWN:
+ default:
+ out = V2_0::GnssConstellationType::UNKNOWN;
+ break;
+ }
+}
+
+void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
+{
+ switch(in) {
+ case GNSS_EPH_TYPE_EPHEMERIS:
+ out = GnssDebug::SatelliteEphemerisType::EPHEMERIS;
+ break;
+ case GNSS_EPH_TYPE_ALMANAC:
+ out = GnssDebug::SatelliteEphemerisType::ALMANAC_ONLY;
+ break;
+ case GNSS_EPH_TYPE_UNKNOWN:
+ default:
+ out = GnssDebug::SatelliteEphemerisType::NOT_AVAILABLE;
+ break;
+ }
+}
+
+void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out)
+{
+ switch(in) {
+ case GNSS_EPH_SOURCE_DEMODULATED:
+ out = GnssDebug::SatelliteEphemerisSource::DEMODULATED;
+ break;
+ case GNSS_EPH_SOURCE_SUPL_PROVIDED:
+ out = GnssDebug::SatelliteEphemerisSource::SUPL_PROVIDED;
+ break;
+ case GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED:
+ out = GnssDebug::SatelliteEphemerisSource::OTHER_SERVER_PROVIDED;
+ break;
+ case GNSS_EPH_SOURCE_LOCAL:
+ case GNSS_EPH_SOURCE_UNKNOWN:
+ default:
+ out = GnssDebug::SatelliteEphemerisSource::OTHER;
+ break;
+ }
+}
+
+void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out)
+{
+ switch(in) {
+ case GNSS_EPH_HEALTH_GOOD:
+ out = GnssDebug::SatelliteEphemerisHealth::GOOD;
+ break;
+ case GNSS_EPH_HEALTH_BAD:
+ out = GnssDebug::SatelliteEphemerisHealth::BAD;
+ break;
+ case GNSS_EPH_HEALTH_UNKNOWN:
+ default:
+ out = GnssDebug::SatelliteEphemerisHealth::UNKNOWN;
+ break;
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/location_api/LocationUtil.h b/gps/android/2.0/location_api/LocationUtil.h
new file mode 100644
index 0000000..8426de7
--- /dev/null
+++ b/gps/android/2.0/location_api/LocationUtil.h
@@ -0,0 +1,58 @@
+/* Copyright (c) 2017-2019, 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 LOCATION_UTIL_H
+#define LOCATION_UTIL_H
+
+#include <android/hardware/gnss/2.0/types.h>
+#include <LocationAPI.h>
+#include <GnssDebug.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void convertGnssLocation(Location& in, V1_0::GnssLocation& out);
+void convertGnssLocation(Location& in, V2_0::GnssLocation& out);
+void convertGnssLocation(const V1_0::GnssLocation& in, Location& out);
+void convertGnssLocation(const V2_0::GnssLocation& in, Location& out);
+void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out);
+void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out);
+void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
+void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
+void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // LOCATION_UTIL_H
diff --git a/gps/android/2.0/location_api/MeasurementAPIClient.cpp b/gps/android/2.0/location_api/MeasurementAPIClient.cpp
new file mode 100644
index 0000000..dc972ec
--- /dev/null
+++ b/gps/android/2.0/location_api/MeasurementAPIClient.cpp
@@ -0,0 +1,474 @@
+/* Copyright (c) 2017-2019, 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_MeasurementAPIClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "MeasurementAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssMeasurement;
+using ::android::hardware::gnss::V2_0::IGnssMeasurementCallback;
+
+static void convertGnssData(GnssMeasurementsNotification& in,
+ V1_0::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssData_1_1(GnssMeasurementsNotification& in,
+ V1_1::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssData_2_0(GnssMeasurementsNotification& in,
+ V2_0::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssMeasurement(GnssMeasurementsData& in,
+ V1_0::IGnssMeasurementCallback::GnssMeasurement& out);
+static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out);
+static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& in,
+ ::android::hardware::hidl_string& out);
+
+MeasurementAPIClient::MeasurementAPIClient() :
+ mGnssMeasurementCbIface(nullptr),
+ mGnssMeasurementCbIface_1_1(nullptr),
+ mGnssMeasurementCbIface_2_0(nullptr),
+ mTracking(false)
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+MeasurementAPIClient::~MeasurementAPIClient()
+{
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+// for GpsInterface
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
+{
+ LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+ mMutex.lock();
+ mGnssMeasurementCbIface = callback;
+ mMutex.unlock();
+
+ return startTracking();
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
+ __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
+
+ mMutex.lock();
+ mGnssMeasurementCbIface_1_1 = callback;
+ mMutex.unlock();
+
+ return startTracking(powerMode, timeBetweenMeasurement);
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
+ __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
+
+ mMutex.lock();
+ mGnssMeasurementCbIface_2_0 = callback;
+ mMutex.unlock();
+
+ return startTracking(powerMode, timeBetweenMeasurement);
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::startTracking(
+ GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+ LocationCallbacks locationCallbacks;
+ memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+ locationCallbacks.size = sizeof(LocationCallbacks);
+
+ locationCallbacks.trackingCb = nullptr;
+ locationCallbacks.batchingCb = nullptr;
+ locationCallbacks.geofenceBreachCb = nullptr;
+ locationCallbacks.geofenceStatusCb = nullptr;
+ locationCallbacks.gnssLocationInfoCb = nullptr;
+ locationCallbacks.gnssNiCb = nullptr;
+ locationCallbacks.gnssSvCb = nullptr;
+ locationCallbacks.gnssNmeaCb = nullptr;
+
+ locationCallbacks.gnssMeasurementsCb = nullptr;
+ if (mGnssMeasurementCbIface_2_0 != nullptr ||
+ mGnssMeasurementCbIface_1_1 != nullptr ||
+ mGnssMeasurementCbIface != nullptr) {
+ locationCallbacks.gnssMeasurementsCb =
+ [this](GnssMeasurementsNotification gnssMeasurementsNotification) {
+ onGnssMeasurementsCb(gnssMeasurementsNotification);
+ };
+ }
+
+ locAPISetCallbacks(locationCallbacks);
+
+ TrackingOptions options = {};
+ memset(&options, 0, sizeof(TrackingOptions));
+ options.size = sizeof(TrackingOptions);
+ options.minInterval = 1000;
+ options.mode = GNSS_SUPL_MODE_STANDALONE;
+ if (GNSS_POWER_MODE_INVALID != powerMode) {
+ options.powerMode = powerMode;
+ options.tbm = timeBetweenMeasurement;
+ }
+
+ mTracking = true;
+ LOC_LOGD("%s]: start tracking session", __FUNCTION__);
+ locAPIStartTracking(options);
+ return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
+}
+
+// for GpsMeasurementInterface
+void MeasurementAPIClient::measurementClose() {
+ LOC_LOGD("%s]: ()", __FUNCTION__);
+ mTracking = false;
+ locAPIStopTracking();
+}
+
+// callbacks
+void MeasurementAPIClient::onGnssMeasurementsCb(
+ GnssMeasurementsNotification gnssMeasurementsNotification)
+{
+ LOC_LOGD("%s]: (count: %u active: %d)",
+ __FUNCTION__, gnssMeasurementsNotification.count, mTracking);
+ if (mTracking) {
+ mMutex.lock();
+ sp<V1_0::IGnssMeasurementCallback> gnssMeasurementCbIface = nullptr;
+ sp<V1_1::IGnssMeasurementCallback> gnssMeasurementCbIface_1_1 = nullptr;
+ sp<V2_0::IGnssMeasurementCallback> gnssMeasurementCbIface_2_0 = nullptr;
+ if (mGnssMeasurementCbIface_2_0 != nullptr) {
+ gnssMeasurementCbIface_2_0 = mGnssMeasurementCbIface_2_0;
+ } else if (mGnssMeasurementCbIface_1_1 != nullptr) {
+ gnssMeasurementCbIface_1_1 = mGnssMeasurementCbIface_1_1;
+ } else if (mGnssMeasurementCbIface != nullptr) {
+ gnssMeasurementCbIface = mGnssMeasurementCbIface;
+ }
+ mMutex.unlock();
+
+ if (gnssMeasurementCbIface_2_0 != nullptr) {
+ V2_0::IGnssMeasurementCallback::GnssData gnssData;
+ convertGnssData_2_0(gnssMeasurementsNotification, gnssData);
+ auto r = gnssMeasurementCbIface_2_0->gnssMeasurementCb_2_0(gnssData);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssMeasurementCbIface_1_1 != nullptr) {
+ V1_1::IGnssMeasurementCallback::GnssData gnssData;
+ convertGnssData_1_1(gnssMeasurementsNotification, gnssData);
+ auto r = gnssMeasurementCbIface_1_1->gnssMeasurementCb(gnssData);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
+ __func__, r.description().c_str());
+ }
+ } else if (gnssMeasurementCbIface != nullptr) {
+ V1_0::IGnssMeasurementCallback::GnssData gnssData;
+ convertGnssData(gnssMeasurementsNotification, gnssData);
+ auto r = gnssMeasurementCbIface->GnssMeasurementCb(gnssData);
+ if (!r.isOk()) {
+ LOC_LOGE("%s] Error from GnssMeasurementCb description=%s",
+ __func__, r.description().c_str());
+ }
+ }
+ }
+}
+
+static void convertGnssMeasurement(GnssMeasurementsData& in,
+ V1_0::IGnssMeasurementCallback::GnssMeasurement& out)
+{
+ memset(&out, 0, sizeof(out));
+ if (in.flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SNR;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_FREQUENCY;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_CYCLES;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY;
+ if (in.flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT)
+ out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL;
+ out.svid = in.svId;
+ convertGnssConstellationType(in.svType, out.constellation);
+ out.timeOffsetNs = in.timeOffsetNs;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC;
+ if (in.stateMask & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT)
+ out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC;
+ out.receivedSvTimeInNs = in.receivedSvTimeNs;
+ out.receivedSvTimeUncertaintyInNs = in.receivedSvTimeUncertaintyNs;
+ out.cN0DbHz = in.carrierToNoiseDbHz;
+ out.pseudorangeRateMps = in.pseudorangeRateMps;
+ out.pseudorangeRateUncertaintyMps = in.pseudorangeRateUncertaintyMps;
+ if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ out.accumulatedDeltaRangeM = in.adrMeters;
+ out.accumulatedDeltaRangeUncertaintyM = in.adrUncertaintyMeters;
+ out.carrierFrequencyHz = in.carrierFrequencyHz;
+ out.carrierCycles = in.carrierCycles;
+ out.carrierPhase = in.carrierPhase;
+ out.carrierPhaseUncertainty = in.carrierPhaseUncertainty;
+ uint8_t indicator =
+ static_cast<uint8_t>(IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN);
+ if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT)
+ indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_PRESENT;
+ if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT)
+ indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATIOR_NOT_PRESENT;
+ out.multipathIndicator =
+ static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(indicator);
+ out.snrDb = in.signalToNoiseRatioDb;
+ out.agcLevelDb = in.agcLevelDb;
+}
+
+static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out)
+{
+ memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssClock));
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_LEAP_SECOND;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_TIME_UNCERTAINTY;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_FULL_BIAS;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS_UNCERTAINTY;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT;
+ if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT)
+ out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT_UNCERTAINTY;
+ out.leapSecond = in.leapSecond;
+ out.timeNs = in.timeNs;
+ out.timeUncertaintyNs = in.timeUncertaintyNs;
+ out.fullBiasNs = in.fullBiasNs;
+ out.biasNs = in.biasNs;
+ out.biasUncertaintyNs = in.biasUncertaintyNs;
+ out.driftNsps = in.driftNsps;
+ out.driftUncertaintyNsps = in.driftUncertaintyNsps;
+ out.hwClockDiscontinuityCount = in.hwClockDiscontinuityCount;
+}
+
+static void convertGnssData(GnssMeasurementsNotification& in,
+ V1_0::IGnssMeasurementCallback::GnssData& out)
+{
+ out.measurementCount = in.count;
+ if (out.measurementCount > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+ LOC_LOGW("%s]: Too many measurement %u. Clamps to %d.",
+ __FUNCTION__, out.measurementCount, V1_0::GnssMax::SVS_COUNT);
+ out.measurementCount = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
+ }
+ for (size_t i = 0; i < out.measurementCount; i++) {
+ convertGnssMeasurement(in.measurements[i], out.measurements[i]);
+ }
+ convertGnssClock(in.clock, out.clock);
+}
+
+static void convertGnssData_1_1(GnssMeasurementsNotification& in,
+ V1_1::IGnssMeasurementCallback::GnssData& out)
+{
+ out.measurements.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_0);
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT)
+ out.measurements[i].accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_HALF_CYCLE_RESOLVED;
+ }
+ convertGnssClock(in.clock, out.clock);
+}
+
+static void convertGnssData_2_0(GnssMeasurementsNotification& in,
+ V2_0::IGnssMeasurementCallback::GnssData& out)
+{
+ out.measurements.resize(in.count);
+ for (size_t i = 0; i < in.count; i++) {
+ convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_1.v1_0);
+ convertGnssConstellationType(in.measurements[i].svType, out.measurements[i].constellation);
+ convertGnssMeasurementsCodeType(in.measurements[i].codeType, out.measurements[i].codeType);
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+ out.measurements[i].v1_1.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+ out.measurements[i].v1_1.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+ out.measurements[i].v1_1.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+ if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT)
+ out.measurements[i].v1_1.accumulatedDeltaRangeState |=
+ IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_HALF_CYCLE_RESOLVED;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_TOW_KNOWN_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_KNOWN;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_KNOWN_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_KNOWN;
+ if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_2ND_CODE_LOCK_BIT)
+ out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_2ND_CODE_LOCK;
+ }
+ convertGnssClock(in.clock, out.clock);
+}
+
+static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& in,
+ ::android::hardware::hidl_string& out)
+{
+ switch(in) {
+ case GNSS_MEASUREMENTS_CODE_TYPE_A:
+ out = "A";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_B:
+ out = "B";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_C:
+ out = "C";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_I:
+ out = "I";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_L:
+ out = "L";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_M:
+ out = "M";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_P:
+ out = "P";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_Q:
+ out = "Q";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_S:
+ out = "S";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_W:
+ out = "W";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_X:
+ out = "X";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_Y:
+ out = "Y";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_Z:
+ out = "Z";
+ break;
+ case GNSS_MEASUREMENTS_CODE_TYPE_N:
+ out = "N";
+ break;
+ default:
+ out = "UNKNOWN";
+ }
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/2.0/location_api/MeasurementAPIClient.h b/gps/android/2.0/location_api/MeasurementAPIClient.h
new file mode 100644
index 0000000..4146a13
--- /dev/null
+++ b/gps/android/2.0/location_api/MeasurementAPIClient.h
@@ -0,0 +1,89 @@
+/* Copyright (c) 2017-2019, 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 MEASUREMENT_API_CLINET_H
+#define MEASUREMENT_API_CLINET_H
+
+#include <mutex>
+#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
+//#include <android/hardware/gnss/1.1/IGnssMeasurementCallback.h>
+#include <LocationAPIClientBase.h>
+#include <hidl/Status.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+
+class MeasurementAPIClient : public LocationAPIClientBase
+{
+public:
+ MeasurementAPIClient();
+ virtual ~MeasurementAPIClient();
+ MeasurementAPIClient(const MeasurementAPIClient&) = delete;
+ MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
+
+ // for GpsMeasurementInterface
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
+ const sp<V1_0::IGnssMeasurementCallback>& callback);
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_1_1(
+ const sp<V1_1::IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_2_0(
+ const sp<V2_0::IGnssMeasurementCallback>& callback,
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+ void measurementClose();
+ Return<IGnssMeasurement::GnssMeasurementStatus> startTracking(
+ GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+ uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+
+ // callbacks we are interested in
+ void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
+
+private:
+ std::mutex mMutex;
+ sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface;
+ sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1;
+ sp<V2_0::IGnssMeasurementCallback> mGnssMeasurementCbIface_2_0;
+
+ bool mTracking;
+};
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+#endif // MEASUREMENT_API_CLINET_H
diff --git a/gps/android/2.0/service.cpp b/gps/android/2.0/service.cpp
new file mode 100644
index 0000000..664c661
--- /dev/null
+++ b/gps/android/2.0/service.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.gnss@2.0-service-qti"
+
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <hidl/LegacySupport.h>
+#include "loc_cfg.h"
+#include "loc_misc_utils.h"
+
+extern "C" {
+#include "vndfwk-detect.h"
+}
+
+#ifdef ARCH_ARM_32
+#define DEFAULT_HW_BINDER_MEM_SIZE 65536
+#endif
+
+using android::hardware::gnss::V2_0::IGnss;
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+
+using android::status_t;
+using android::OK;
+
+typedef int vendorEnhancedServiceMain(int /* argc */, char* /* argv */ []);
+
+int main() {
+
+ ALOGI("%s", __FUNCTION__);
+
+ int vendorInfo = getVendorEnhancedInfo();
+ bool vendorEnhanced = ( 1 == vendorInfo || 3 == vendorInfo );
+ setVendorEnhanced(vendorEnhanced);
+
+#ifdef ARCH_ARM_32
+ android::hardware::ProcessState::initWithMmapSize((size_t)(DEFAULT_HW_BINDER_MEM_SIZE));
+#endif
+ configureRpcThreadpool(1, true);
+ status_t status;
+
+ status = registerPassthroughServiceImplementation<IGnss>();
+ if (status == OK) {
+ if (vendorEnhanced) {
+ #ifdef LOC_HIDL_VERSION
+ #define VENDOR_ENHANCED_LIB "vendor.qti.gnss@" LOC_HIDL_VERSION "-service.so"
+
+ void* libHandle = NULL;
+ vendorEnhancedServiceMain* vendorEnhancedMainMethod = (vendorEnhancedServiceMain*)
+ dlGetSymFromLib(libHandle, VENDOR_ENHANCED_LIB, "main");
+ if (NULL != vendorEnhancedMainMethod) {
+ (*vendorEnhancedMainMethod)(0, NULL);
+ }
+ #else
+ ALOGE("LOC_HIDL_VERSION not defined.");
+ #endif
+ }
+
+ joinRpcThreadpool();
+
+ } else {
+ ALOGE("Error while registering IGnss 2.0 service: %d", status);
+ }
+
+ return 0;
+}
diff --git a/gps/android/Android.mk b/gps/android/Android.mk
index 8ec95bf..3b5c01f 100644
--- a/gps/android/Android.mk
+++ b/gps/android/Android.mk
@@ -1,87 +1,15 @@
LOCAL_PATH := $(call my-dir)
-
+ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gnss@1.0-impl-qti
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
- AGnss.cpp \
- Gnss.cpp \
- GnssBatching.cpp \
- GnssGeofencing.cpp \
- GnssMeasurement.cpp \
- GnssNi.cpp \
- GnssConfiguration.cpp \
- GnssDebug.cpp \
- AGnssRil.cpp
-
-LOCAL_SRC_FILES += \
- location_api/LocationUtil.cpp \
- location_api/GnssAPIClient.cpp \
- location_api/GeofenceAPIClient.cpp \
- location_api/BatchingAPIClient.cpp \
- location_api/MeasurementAPIClient.cpp \
-
-LOCAL_C_INCLUDES:= \
- $(LOCAL_PATH)/location_api
-LOCAL_HEADER_LIBRARIES := \
- libgps.utils_headers \
- libloc_core_headers \
- libloc_pla_headers \
- liblocation_api_headers
-
-LOCAL_SHARED_LIBRARIES := \
- liblog \
- libhidlbase \
- libcutils \
- libutils \
- android.hardware.gnss@1.0 \
-
-LOCAL_SHARED_LIBRARIES += \
- libloc_core \
- libgps.utils \
- libdl \
- liblocation_api \
-
-LOCAL_CFLAGS += $(GNSS_CFLAGS)
-include $(BUILD_SHARED_LIBRARY)
-
-BUILD_GNSS_HIDL_SERVICE := true
-ifneq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET), true)
-ifneq ($(LW_FEATURE_SET),true)
-BUILD_GNSS_HIDL_SERVICE := false
-endif # LW_FEATURE_SET
-endif # BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET
-
-ifeq ($(BUILD_GNSS_HIDL_SERVICE), true)
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gnss@1.0-service-qti
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_INIT_RC := android.hardware.gnss@1.0-service-qti.rc
-LOCAL_SRC_FILES := \
- service.cpp \
-
-LOCAL_C_INCLUDES:= \
- $(LOCAL_PATH)/location_api
-LOCAL_HEADER_LIBRARIES := \
- libgps.utils_headers \
- libloc_core_headers \
- libloc_pla_headers \
- liblocation_api_headers
-
-
-LOCAL_SHARED_LIBRARIES := \
- liblog \
- libcutils \
- libdl \
- libbase \
- libutils \
-
-LOCAL_SHARED_LIBRARIES += \
- libhidlbase \
- android.hardware.gnss@1.0 \
-
-LOCAL_CFLAGS += $(GNSS_CFLAGS)
-include $(BUILD_EXECUTABLE)
-endif # BUILD_GNSS_HIDL_SERVICE
+DIR_LIST := $(LOCAL_PATH)
+include $(DIR_LIST)/utils/Android.mk
+ifeq ($(GNSS_HIDL_VERSION),2.0)
+include $(DIR_LIST)/2.0/Android.mk
+else
+ifeq ($(GNSS_HIDL_VERSION),1.1)
+include $(DIR_LIST)/1.1/Android.mk
+else
+include $(DIR_LIST)/1.0/Android.mk
+endif #GNSS HIDL 1.1
+endif #GNSS HIDL 2.0
+endif #BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/gps/android/measurement_corrections/1.0/MeasurementCorrections.cpp b/gps/android/measurement_corrections/1.0/MeasurementCorrections.cpp
new file mode 100644
index 0000000..2c93cb3
--- /dev/null
+++ b/gps/android/measurement_corrections/1.0/MeasurementCorrections.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019, 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_TAG "LocSvc_MeasurementCorrectionsInterface"
+
+#include <log_util.h>
+#include "MeasurementCorrections.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace measurement_corrections {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+MeasurementCorrections::MeasurementCorrections() {
+}
+
+MeasurementCorrections::~MeasurementCorrections() {
+}
+
+Return<bool> MeasurementCorrections::setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& /*corrections*/) {
+ return true;
+}
+
+Return<bool> MeasurementCorrections::setCallback(
+ const sp<V1_0::IMeasurementCorrectionsCallback>& /*callback*/) {
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace measurement_corrections
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/measurement_corrections/1.0/MeasurementCorrections.h b/gps/android/measurement_corrections/1.0/MeasurementCorrections.h
new file mode 100644
index 0000000..ad534dc
--- /dev/null
+++ b/gps/android/measurement_corrections/1.0/MeasurementCorrections.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2019, 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 ANDROID_HARDWARE_GNSS_V1_0_MeasurementCorrections_H
+#define ANDROID_HARDWARE_GNSS_V1_0_MeasurementCorrections_H
+
+#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
+#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrectionsCallback.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace measurement_corrections {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
+
+struct MeasurementCorrections : public IMeasurementCorrections {
+ MeasurementCorrections();
+ ~MeasurementCorrections();
+
+// Methods from ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections follow.
+Return<bool> setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& corrections) override;
+
+Return<bool> setCallback(const sp<IMeasurementCorrectionsCallback>& callback) override;
+
+};
+
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace measurement_corrections
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_0_MeasurementCorrections_H
diff --git a/gps/android/utils/Android.mk b/gps/android/utils/Android.mk
new file mode 100644
index 0000000..bbcf512
--- /dev/null
+++ b/gps/android/utils/Android.mk
@@ -0,0 +1,38 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := liblocbatterylistener
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VENDOR_MODULE := true
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH) \
+
+LOCAL_SRC_FILES:= \
+ battery_listener.cpp
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libhidlbase \
+ libcutils \
+ libutils \
+ android.hardware.health@1.0 \
+ android.hardware.health@2.0 \
+ android.hardware.power@1.2 \
+ libbase
+
+LOCAL_STATIC_LIBRARIES := libhealthhalutils
+LOCAL_CFLAGS += -DBATTERY_LISTENER_ENABLED
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := liblocbatterylistener_headers
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+include $(BUILD_HEADER_LIBRARY)
+
+
diff --git a/gps/android/utils/battery_listener.cpp b/gps/android/utils/battery_listener.cpp
new file mode 100644
index 0000000..f96dc70
--- /dev/null
+++ b/gps/android/utils/battery_listener.cpp
@@ -0,0 +1,273 @@
+/*
+* Copyright (c) 2019-2020, 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.
+*/
+#include "battery_listener.h"
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "LocSvc_BatteryListener"
+
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <android/hardware/health/2.0/IHealth.h>
+#include <healthhalutils/HealthHalUtils.h>
+#include <hidl/HidlTransportSupport.h>
+#include <thread>
+using android::hardware::interfacesEqual;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::health::V1_0::BatteryStatus;
+using android::hardware::health::V1_0::toString;
+using android::hardware::health::V2_0::get_health_service;
+using android::hardware::health::V2_0::HealthInfo;
+using android::hardware::health::V2_0::IHealth;
+using android::hardware::health::V2_0::Result;
+using android::hidl::manager::V1_0::IServiceManager;
+using namespace std::literals::chrono_literals;
+
+static bool sIsBatteryListened = false;
+namespace android {
+
+#define GET_HEALTH_SVC_RETRY_CNT 5
+#define GET_HEALTH_SVC_WAIT_TIME_MS 500
+
+struct BatteryListenerImpl : public hardware::health::V2_0::IHealthInfoCallback,
+ public hardware::hidl_death_recipient {
+ typedef std::function<void(bool)> cb_fn_t;
+ BatteryListenerImpl(cb_fn_t cb);
+ virtual ~BatteryListenerImpl ();
+ virtual hardware::Return<void> healthInfoChanged(
+ const hardware::health::V2_0::HealthInfo& info);
+ virtual void serviceDied(uint64_t cookie,
+ const wp<hidl::base::V1_0::IBase>& who);
+ bool isCharging() {
+ std::lock_guard<std::mutex> _l(mLock);
+ return statusToBool(mStatus);
+ }
+ private:
+ sp<hardware::health::V2_0::IHealth> mHealth;
+ status_t init();
+ BatteryStatus mStatus;
+ cb_fn_t mCb;
+ std::mutex mLock;
+ std::condition_variable mCond;
+ std::unique_ptr<std::thread> mThread;
+ bool mDone;
+ bool statusToBool(const BatteryStatus &s) const {
+ return (s == BatteryStatus::CHARGING) ||
+ (s == BatteryStatus::FULL);
+ }
+};
+
+status_t BatteryListenerImpl::init()
+{
+ int tries = 0;
+
+ if (mHealth != NULL)
+ return INVALID_OPERATION;
+
+ do {
+ mHealth = hardware::health::V2_0::get_health_service();
+ if (mHealth != NULL)
+ break;
+ usleep(GET_HEALTH_SVC_WAIT_TIME_MS * 1000);
+ tries++;
+ } while(tries < GET_HEALTH_SVC_RETRY_CNT);
+
+ if (mHealth == NULL) {
+ ALOGE("no health service found, retries %d", tries);
+ return NO_INIT;
+ } else {
+ ALOGI("Get health service in %d tries", tries);
+ }
+ mStatus = BatteryStatus::UNKNOWN;
+ auto ret = mHealth->getChargeStatus([&](Result r, BatteryStatus status) {
+ if (r != Result::SUCCESS) {
+ ALOGE("batterylistener: cannot get battery status");
+ return;
+ }
+ mStatus = status;
+ });
+ if (!ret.isOk())
+ ALOGE("batterylistener: get charge status transaction error");
+
+ if (mStatus == BatteryStatus::UNKNOWN)
+ ALOGW("batterylistener: init: invalid battery status");
+ mDone = false;
+ mThread = std::make_unique<std::thread>([this]() {
+ std::unique_lock<std::mutex> l(mLock);
+ BatteryStatus local_status = mStatus;
+ while (!mDone) {
+ if (local_status == mStatus) {
+ mCond.wait(l);
+ continue;
+ }
+ local_status = mStatus;
+ switch (local_status) {
+ // NOT_CHARGING is a special event that indicates, a battery is connected,
+ // but not charging. This is seen for approx a second
+ // after charger is plugged in. A charging event is eventually received.
+ // We must try to avoid an unnecessary cb to HAL
+ // only to call it again shortly.
+ // An option to deal with this transient event would be to ignore this.
+ // Or process this event with a slight delay (i.e cancel this event
+ // if a different event comes in within a timeout
+ case BatteryStatus::NOT_CHARGING : {
+ auto mStatusnot_ncharging =
+ [this, local_status]() { return mStatus != local_status; };
+ mCond.wait_for(l, 3s, mStatusnot_ncharging);
+ if (mStatusnot_ncharging()) // i.e event changed
+ break;
+ [[clang::fallthrough]]; //explicit fall-through between switch labels
+ }
+ default:
+ bool c = statusToBool(local_status);
+ ALOGI("healthInfo cb thread: cb %s", c ? "CHARGING" : "NOT CHARGING");
+ l.unlock();
+ mCb(c);
+ l.lock();
+ break;
+ }
+ }
+ });
+ auto reg = mHealth->registerCallback(this);
+ if (!reg.isOk()) {
+ ALOGE("Transaction error in registeringCb to HealthHAL death: %s",
+ reg.description().c_str());
+ }
+
+ auto linked = mHealth->linkToDeath(this, 0 /* cookie */);
+ if (!linked.isOk() || linked == false) {
+ ALOGE("Transaction error in linking to HealthHAL death: %s", linked.description().c_str());
+ }
+ return NO_ERROR;
+}
+
+BatteryListenerImpl::BatteryListenerImpl(cb_fn_t cb) :
+ mCb(cb)
+{
+ init();
+}
+
+BatteryListenerImpl::~BatteryListenerImpl()
+{
+ {
+ std::lock_guard<std::mutex> _l(mLock);
+ if (mHealth != NULL) {
+ mHealth->unregisterCallback(this);
+ auto r = mHealth->unlinkToDeath(this);
+ if (!r.isOk() || r == false) {
+ ALOGE("Transaction error in unregister to HealthHAL death: %s",
+ r.description().c_str());
+ }
+ }
+ }
+ mDone = true;
+ if (NULL != mThread) {
+ mThread->join();
+ }
+}
+
+void BatteryListenerImpl::serviceDied(uint64_t cookie __unused,
+ const wp<hidl::base::V1_0::IBase>& who)
+{
+ {
+ std::lock_guard<std::mutex> _l(mLock);
+ if (mHealth == NULL || !interfacesEqual(mHealth, who.promote())) {
+ ALOGE("health not initialized or unknown interface died");
+ return;
+ }
+ ALOGI("health service died, reinit");
+ mDone = true;
+ }
+ mHealth = NULL;
+ mCond.notify_one();
+ if (NULL != mThread) {
+ mThread->join();
+ }
+ std::lock_guard<std::mutex> _l(mLock);
+ init();
+}
+
+// this callback seems to be a SYNC callback and so
+// waits for return before next event is issued.
+// therefore we need not have a queue to process
+// NOT_CHARGING and CHARGING concurrencies.
+// Replace single var by a list if this assumption is broken
+Return<void> BatteryListenerImpl::healthInfoChanged(
+ const hardware::health::V2_0::HealthInfo& info)
+{
+ ALOGV("healthInfoChanged: %d", info.legacy.batteryStatus);
+ std::unique_lock<std::mutex> l(mLock);
+ if (info.legacy.batteryStatus != mStatus) {
+ mStatus = info.legacy.batteryStatus;
+ mCond.notify_one();
+ }
+ return Void();
+}
+
+static sp<BatteryListenerImpl> batteryListener;
+status_t batteryPropertiesListenerInit(BatteryListenerImpl::cb_fn_t cb)
+{
+ ALOGV("batteryPropertiesListenerInit entry");
+ batteryListener = new BatteryListenerImpl(cb);
+ return NO_ERROR;
+}
+
+status_t batteryPropertiesListenerDeinit()
+{
+ batteryListener.clear();
+ return OK;
+}
+
+bool batteryPropertiesListenerIsCharging()
+{
+ return batteryListener->isCharging();
+}
+
+} // namespace android
+
+void loc_extn_battery_properties_listener_init(battery_status_change_fn_t fn)
+{
+ ALOGV("loc_extn_battery_properties_listener_init entry");
+ if (!sIsBatteryListened) {
+ std::thread t1(android::batteryPropertiesListenerInit,
+ [=](bool charging) { fn(charging); });
+ t1.detach();
+ sIsBatteryListened = true;
+ }
+}
+
+void loc_extn_battery_properties_listener_deinit()
+{
+ android::batteryPropertiesListenerDeinit();
+}
+
+bool loc_extn_battery_properties_is_charging()
+{
+ return android::batteryPropertiesListenerIsCharging();
+}
diff --git a/gps/android/utils/battery_listener.h b/gps/android/utils/battery_listener.h
new file mode 100644
index 0000000..bb6b715
--- /dev/null
+++ b/gps/android/utils/battery_listener.h
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 2019, 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.
+*/
+typedef void (* battery_status_change_fn_t)(bool);
+void loc_extn_battery_properties_listener_init(battery_status_change_fn_t fn);
+void loc_extn_battery_properties_listener_deinit();
+bool loc_extn_battery_properties_is_charging();
diff --git a/gps/android/visibility_control/1.0/GnssVisibilityControl.cpp b/gps/android/visibility_control/1.0/GnssVisibilityControl.cpp
new file mode 100644
index 0000000..5a8c697
--- /dev/null
+++ b/gps/android/visibility_control/1.0/GnssVisibilityControl.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "GnssVisibilityControl.h"
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace visibility_control {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+static GnssVisibilityControl* spGnssVisibilityControl = nullptr;
+
+static void convertGnssNfwNotification(GnssNfwNotification& in,
+ IGnssVisibilityControlCallback::NfwNotification& out);
+
+GnssVisibilityControl::GnssVisibilityControl(Gnss* gnss) : mGnss(gnss) {
+ spGnssVisibilityControl = this;
+}
+GnssVisibilityControl::~GnssVisibilityControl() {
+ spGnssVisibilityControl = nullptr;
+}
+
+void GnssVisibilityControl::nfwStatusCb(GnssNfwNotification notification) {
+ if (nullptr != spGnssVisibilityControl) {
+ spGnssVisibilityControl->statusCb(notification);
+ }
+}
+
+bool GnssVisibilityControl::isInEmergencySession() {
+ if (nullptr != spGnssVisibilityControl) {
+ return spGnssVisibilityControl->isE911Session();
+ }
+ return false;
+}
+
+static void convertGnssNfwNotification(GnssNfwNotification& in,
+ IGnssVisibilityControlCallback::NfwNotification& out)
+{
+ memset(&out, 0, sizeof(IGnssVisibilityControlCallback::NfwNotification));
+ out.proxyAppPackageName = in.proxyAppPackageName;
+ out.protocolStack = (IGnssVisibilityControlCallback::NfwProtocolStack)in.protocolStack;
+ out.otherProtocolStackName = in.otherProtocolStackName;
+ out.requestor = (IGnssVisibilityControlCallback::NfwRequestor)in.requestor;
+ out.requestorId = in.requestorId;
+ out.responseType = (IGnssVisibilityControlCallback::NfwResponseType)in.responseType;
+ out.inEmergencyMode = in.inEmergencyMode;
+ out.isCachedLocation = in.isCachedLocation;
+}
+
+void GnssVisibilityControl::statusCb(GnssNfwNotification notification) {
+
+ if (mGnssVisibilityControlCbIface != nullptr) {
+ IGnssVisibilityControlCallback::NfwNotification nfwNotification;
+
+ // Convert from one structure to another
+ convertGnssNfwNotification(notification, nfwNotification);
+
+ auto r = mGnssVisibilityControlCbIface->nfwNotifyCb(nfwNotification);
+ if (!r.isOk()) {
+ LOC_LOGw("Error invoking NFW status cb %s", r.description().c_str());
+ }
+ } else {
+ LOC_LOGw("setCallback has not been called yet");
+ }
+}
+
+bool GnssVisibilityControl::isE911Session() {
+
+ if (mGnssVisibilityControlCbIface != nullptr) {
+ auto r = mGnssVisibilityControlCbIface->isInEmergencySession();
+ if (!r.isOk()) {
+ LOC_LOGw("Error invoking NFW status cb %s", r.description().c_str());
+ return false;
+ } else {
+ return (r);
+ }
+ } else {
+ LOC_LOGw("setCallback has not been called yet");
+ return false;
+ }
+}
+
+// Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow.
+Return<bool> GnssVisibilityControl::enableNfwLocationAccess(const hidl_vec<::android::hardware::hidl_string>& proxyApps) {
+
+ if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) {
+ LOC_LOGe("Null GNSS interface");
+ return false;
+ }
+
+ /* If the vector is empty we need to disable all NFW clients
+ If there is at least one app in the vector we need to enable
+ all NFW clients */
+ if (0 == proxyApps.size()) {
+ mGnss->getGnssInterface()->enableNfwLocationAccess(false);
+ } else {
+ mGnss->getGnssInterface()->enableNfwLocationAccess(true);
+ }
+
+ return true;
+}
+/**
+ * Registers the callback for HAL implementation to use.
+ *
+ * @param callback Handle to IGnssVisibilityControlCallback interface.
+ */
+Return<bool> GnssVisibilityControl::setCallback(const ::android::sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback>& callback) {
+
+ if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) {
+ LOC_LOGe("Null GNSS interface");
+ return false;
+ }
+ mGnssVisibilityControlCbIface = callback;
+
+ NfwCbInfo cbInfo = {};
+ cbInfo.visibilityControlCb = (void*)nfwStatusCb;
+ cbInfo.isInEmergencySession = (void*)isInEmergencySession;
+
+ mGnss->getGnssInterface()->nfwInit(cbInfo);
+
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace visibility_control
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/visibility_control/1.0/GnssVisibilityControl.h b/gps/android/visibility_control/1.0/GnssVisibilityControl.h
new file mode 100644
index 0000000..9c26e38
--- /dev/null
+++ b/gps/android/visibility_control/1.0/GnssVisibilityControl.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2019, 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 ANDROID_HARDWARE_GNSS_V1_0_GnssVisibilityControl_H
+#define ANDROID_HARDWARE_GNSS_V1_0_GnssVisibilityControl_H
+
+#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <gps_extended_c.h>
+#include <location_interface.h>
+#include "Gnss.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace visibility_control {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V2_0::implementation::Gnss;
+
+struct GnssVisibilityControl : public IGnssVisibilityControl {
+ GnssVisibilityControl(Gnss* gnss);
+ ~GnssVisibilityControl();
+
+ // Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow.
+ Return<bool> enableNfwLocationAccess(const hidl_vec<::android::hardware::hidl_string>& proxyApps) override;
+ /**
+ * Registers the callback for HAL implementation to use.
+ *
+ * @param callback Handle to IGnssVisibilityControlCallback interface.
+ */
+ Return<bool> setCallback(const ::android::sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback>& callback) override;
+
+ void statusCb(GnssNfwNotification notification);
+ bool isE911Session();
+
+ /* Data call setup callback passed down to GNSS HAL implementation */
+ static void nfwStatusCb(GnssNfwNotification notification);
+ static bool isInEmergencySession();
+
+private:
+ Gnss* mGnss = nullptr;
+ sp<IGnssVisibilityControlCallback> mGnssVisibilityControlCbIface = nullptr;
+};
+
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace visibility_control
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_V1_0_GnssVisibilityControl_H
diff --git a/gps/batching/Android.mk b/gps/batching/Android.mk
new file mode 100644
index 0000000..f3e8fe4
--- /dev/null
+++ b/gps/batching/Android.mk
@@ -0,0 +1,39 @@
+ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libbatching
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ liblog \
+ libloc_core \
+ libgps.utils \
+ libdl
+
+LOCAL_SRC_FILES += \
+ location_batching.cpp \
+ BatchingAdapter.cpp
+
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+include $(BUILD_SHARED_LIBRARY)
+
+endif # not BUILD_TINY_ANDROID
+endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/gps/batching/BatchingAdapter.cpp b/gps/batching/BatchingAdapter.cpp
new file mode 100644
index 0000000..135f0ed
--- /dev/null
+++ b/gps/batching/BatchingAdapter.cpp
@@ -0,0 +1,1050 @@
+/* Copyright (c) 2017-2019, 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_BatchingAdapter"
+
+#include <loc_pla.h>
+#include <log_util.h>
+#include <LocContext.h>
+#include <BatchingAdapter.h>
+
+using namespace loc_core;
+
+BatchingAdapter::BatchingAdapter() :
+ LocAdapterBase(0,
+ LocContext::getLocContext(
+ NULL,
+ NULL,
+ LocContext::mLocationHalName,
+ false)),
+ mOngoingTripDistance(0),
+ mOngoingTripTBFInterval(0),
+ mTripWithOngoingTBFDropped(false),
+ mTripWithOngoingTripDistanceDropped(false),
+ mBatchingTimeout(0),
+ mBatchingAccuracy(1),
+ mBatchSize(0),
+ mTripBatchSize(0)
+{
+ LOC_LOGD("%s]: Constructor", __func__);
+ readConfigCommand();
+ setConfigCommand();
+}
+
+void
+BatchingAdapter::readConfigCommand()
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgReadConfig : public LocMsg {
+ BatchingAdapter& mAdapter;
+ inline MsgReadConfig(BatchingAdapter& adapter) :
+ LocMsg(),
+ mAdapter(adapter) {}
+ inline virtual void proc() const {
+ uint32_t batchingTimeout = 0;
+ uint32_t batchingAccuracy = 0;
+ uint32_t batchSize = 0;
+ uint32_t tripBatchSize = 0;
+ static const loc_param_s_type flp_conf_param_table[] =
+ {
+ {"BATCH_SIZE", &batchSize, NULL, 'n'},
+ {"OUTDOOR_TRIP_BATCH_SIZE", &tripBatchSize, NULL, 'n'},
+ {"BATCH_SESSION_TIMEOUT", &batchingTimeout, NULL, 'n'},
+ {"ACCURACY", &batchingAccuracy, NULL, 'n'},
+ };
+ UTIL_READ_CONF(LOC_PATH_FLP_CONF, flp_conf_param_table);
+
+ LOC_LOGD("%s]: batchSize %u tripBatchSize %u batchingAccuracy %u batchingTimeout %u ",
+ __func__, batchSize, tripBatchSize, batchingAccuracy, batchingTimeout);
+
+ mAdapter.setBatchSize(batchSize);
+ mAdapter.setTripBatchSize(tripBatchSize);
+ mAdapter.setBatchingTimeout(batchingTimeout);
+ mAdapter.setBatchingAccuracy(batchingAccuracy);
+ }
+ };
+
+ sendMsg(new MsgReadConfig(*this));
+
+}
+
+void
+BatchingAdapter::setConfigCommand()
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgSetConfig : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ inline MsgSetConfig(BatchingAdapter& adapter,
+ LocApiBase& api) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api) {}
+ inline virtual void proc() const {
+ mApi.setBatchSize(mAdapter.getBatchSize());
+ mApi.setTripBatchSize(mAdapter.getTripBatchSize());
+ }
+ };
+
+ sendMsg(new MsgSetConfig(*this, *mLocApi));
+}
+
+void
+BatchingAdapter::stopClientSessions(LocationAPI* client)
+{
+ LOC_LOGD("%s]: client %p", __func__, client);
+
+ typedef struct pairKeyBatchMode {
+ LocationAPI* client;
+ uint32_t id;
+ BatchingMode batchingMode;
+ inline pairKeyBatchMode(LocationAPI* _client, uint32_t _id, BatchingMode _bMode) :
+ client(_client), id(_id), batchingMode(_bMode) {}
+ } pairKeyBatchMode;
+ std::vector<pairKeyBatchMode> vBatchingClient;
+ for (auto it : mBatchingSessions) {
+ if (client == it.first.client) {
+ vBatchingClient.emplace_back(it.first.client, it.first.id, it.second.batchingMode);
+ }
+ }
+ for (auto keyBatchingMode : vBatchingClient) {
+ if (keyBatchingMode.batchingMode != BATCHING_MODE_TRIP) {
+ stopBatching(keyBatchingMode.client, keyBatchingMode.id);
+ } else {
+ stopTripBatchingMultiplex(keyBatchingMode.client, keyBatchingMode.id);
+ }
+ }
+}
+
+void
+BatchingAdapter::updateClientsEventMask()
+{
+ LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ // we don't register LOC_API_ADAPTER_BIT_BATCH_FULL until we
+ // start batching with ROUTINE or TRIP option
+ if (it->second.batchingCb != nullptr) {
+ mask |= LOC_API_ADAPTER_BIT_BATCH_STATUS;
+ }
+ }
+ if (autoReportBatchingSessionsCount() > 0) {
+ mask |= LOC_API_ADAPTER_BIT_BATCH_FULL;
+ }
+ updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
+}
+
+void
+BatchingAdapter::handleEngineUpEvent()
+{
+ struct MsgSSREvent : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ inline MsgSSREvent(BatchingAdapter& adapter,
+ LocApiBase& api) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api) {}
+ virtual void proc() const {
+ mAdapter.setEngineCapabilitiesKnown(true);
+ mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
+ mApi.setBatchSize(mAdapter.getBatchSize());
+ mApi.setTripBatchSize(mAdapter.getTripBatchSize());
+ mAdapter.restartSessions();
+ for (auto msg: mAdapter.mPendingMsgs) {
+ mAdapter.sendMsg(msg);
+ }
+ mAdapter.mPendingMsgs.clear();
+ }
+ };
+
+ sendMsg(new MsgSSREvent(*this, *mLocApi));
+}
+
+void
+BatchingAdapter::restartSessions()
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ if (autoReportBatchingSessionsCount() > 0) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_ENABLED);
+ }
+ for (auto it = mBatchingSessions.begin();
+ it != mBatchingSessions.end(); ++it) {
+ if (it->second.batchingMode != BATCHING_MODE_TRIP) {
+ mLocApi->startBatching(it->first.id, it->second,
+ getBatchingAccuracy(), getBatchingTimeout(),
+ new LocApiResponse(*getContext(),
+ [] (LocationError /*err*/) {}));
+ }
+ }
+
+ if (mTripSessions.size() > 0) {
+ // restart outdoor trip batching session if any.
+ mOngoingTripDistance = 0;
+ mOngoingTripTBFInterval = 0;
+
+ // record the min trip distance and min tbf interval of all ongoing sessions
+ for (auto tripSession : mTripSessions) {
+
+ TripSessionStatus &tripSessStatus = tripSession.second;
+
+ if ((0 == mOngoingTripDistance) ||
+ (mOngoingTripDistance >
+ (tripSessStatus.tripDistance - tripSessStatus.accumulatedDistanceThisTrip))) {
+ mOngoingTripDistance = tripSessStatus.tripDistance -
+ tripSessStatus.accumulatedDistanceThisTrip;
+ }
+
+ if ((0 == mOngoingTripTBFInterval) ||
+ (mOngoingTripTBFInterval > tripSessStatus.tripTBFInterval)) {
+ mOngoingTripTBFInterval = tripSessStatus.tripTBFInterval;
+ }
+
+ // reset the accumulatedDistanceOngoingBatch for each session
+ tripSessStatus.accumulatedDistanceOngoingBatch = 0;
+
+ }
+
+ mLocApi->startOutdoorTripBatching(mOngoingTripDistance, mOngoingTripTBFInterval,
+ getBatchingTimeout(), new LocApiResponse(*getContext(), [this] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ mOngoingTripDistance = 0;
+ mOngoingTripTBFInterval = 0;
+ }
+ printTripReport();
+ }));
+ }
+}
+
+bool
+BatchingAdapter::hasBatchingCallback(LocationAPI* client)
+{
+ auto it = mClientData.find(client);
+ return (it != mClientData.end() && it->second.batchingCb);
+}
+
+bool
+BatchingAdapter::isBatchingSession(LocationAPI* client, uint32_t sessionId)
+{
+ LocationSessionKey key(client, sessionId);
+ return (mBatchingSessions.find(key) != mBatchingSessions.end());
+}
+
+bool
+BatchingAdapter::isTripSession(uint32_t sessionId) {
+ return (mTripSessions.find(sessionId) != mTripSessions.end());
+}
+
+void
+BatchingAdapter::saveBatchingSession(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions)
+{
+ LocationSessionKey key(client, sessionId);
+ mBatchingSessions[key] = batchingOptions;
+}
+
+void
+BatchingAdapter::eraseBatchingSession(LocationAPI* client, uint32_t sessionId)
+{
+ LocationSessionKey key(client, sessionId);
+ auto it = mBatchingSessions.find(key);
+ if (it != mBatchingSessions.end()) {
+ mBatchingSessions.erase(it);
+ }
+}
+
+void
+BatchingAdapter::reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId)
+{
+ LOC_LOGD("%s]: client %p id %u err %u", __func__, client, sessionId, err);
+
+ auto it = mClientData.find(client);
+ if (it != mClientData.end() &&
+ it->second.responseCb != nullptr) {
+ it->second.responseCb(err, sessionId);
+ } else {
+ LOC_LOGE("%s]: client %p id %u not found in data", __func__, client, sessionId);
+ }
+}
+
+uint32_t
+BatchingAdapter::autoReportBatchingSessionsCount()
+{
+ uint32_t count = 0;
+ for (auto batchingSession: mBatchingSessions) {
+ if (batchingSession.second.batchingMode != BATCHING_MODE_NO_AUTO_REPORT) {
+ count++;
+ }
+ }
+ count += mTripSessions.size();
+ return count;
+}
+
+uint32_t
+BatchingAdapter::startBatchingCommand(
+ LocationAPI* client, BatchingOptions& batchOptions)
+{
+ uint32_t sessionId = generateSessionId();
+ LOC_LOGD("%s]: client %p id %u minInterval %u minDistance %u mode %u Batching Mode %d",
+ __func__, client, sessionId, batchOptions.minInterval, batchOptions.minDistance,
+ batchOptions.mode,batchOptions.batchingMode);
+
+ struct MsgStartBatching : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ uint32_t mSessionId;
+ BatchingOptions mBatchingOptions;
+ inline MsgStartBatching(BatchingAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ uint32_t sessionId,
+ BatchingOptions batchOptions) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mSessionId(sessionId),
+ mBatchingOptions(batchOptions) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgStartBatching(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+
+ if (!mAdapter.hasBatchingCallback(mClient)) {
+ err = LOCATION_ERROR_CALLBACK_MISSING;
+ } else if (0 == mBatchingOptions.size) {
+ err = LOCATION_ERROR_INVALID_PARAMETER;
+ } else if (!ContextBase::isMessageSupported(
+ LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)) {
+ err = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (mBatchingOptions.batchingMode == BATCHING_MODE_ROUTINE ||
+ mBatchingOptions.batchingMode == BATCHING_MODE_NO_AUTO_REPORT) {
+ mAdapter.startBatching(mClient, mSessionId, mBatchingOptions);
+ } else if (mBatchingOptions.batchingMode == BATCHING_MODE_TRIP) {
+ mAdapter.startTripBatchingMultiplex(mClient, mSessionId, mBatchingOptions);
+ } else {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_INVALID_PARAMETER, mSessionId);
+ }
+ }
+ }
+ };
+
+ sendMsg(new MsgStartBatching(*this, *mLocApi, client, sessionId, batchOptions));
+
+ return sessionId;
+}
+
+void
+BatchingAdapter::startBatching(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions)
+{
+ if (batchingOptions.batchingMode != BATCHING_MODE_NO_AUTO_REPORT &&
+ 0 == autoReportBatchingSessionsCount()) {
+ // if there is currenty no batching sessions interested in batch full event, then this
+ // new session will need to register for batch full event
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_ENABLED);
+ }
+
+ // Assume start will be OK, remove session if not
+ saveBatchingSession(client, sessionId, batchingOptions);
+ mLocApi->startBatching(sessionId, batchingOptions, getBatchingAccuracy(), getBatchingTimeout(),
+ new LocApiResponse(*getContext(),
+ [this, client, sessionId, batchingOptions] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ eraseBatchingSession(client, sessionId);
+ }
+
+ if (LOCATION_ERROR_SUCCESS != err &&
+ batchingOptions.batchingMode != BATCHING_MODE_NO_AUTO_REPORT &&
+ 0 == autoReportBatchingSessionsCount()) {
+ // if we fail to start batching and we have already registered batch full event
+ // we need to undo that since no sessions are now interested in batch full event
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+
+ reportResponse(client, err, sessionId);
+ }));
+}
+
+void
+BatchingAdapter::updateBatchingOptionsCommand(LocationAPI* client, uint32_t id,
+ BatchingOptions& batchOptions)
+{
+ LOC_LOGD("%s]: client %p id %u minInterval %u minDistance %u mode %u batchMode %u",
+ __func__, client, id, batchOptions.minInterval,
+ batchOptions.minDistance, batchOptions.mode,
+ batchOptions.batchingMode);
+
+ struct MsgUpdateBatching : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ uint32_t mSessionId;
+ BatchingOptions mBatchOptions;
+ inline MsgUpdateBatching(BatchingAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ uint32_t sessionId,
+ BatchingOptions batchOptions) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mSessionId(sessionId),
+ mBatchOptions(batchOptions) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgUpdateBatching(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ if (!mAdapter.isBatchingSession(mClient, mSessionId)) {
+ err = LOCATION_ERROR_ID_UNKNOWN;
+ } else if ((0 == mBatchOptions.size) ||
+ (mBatchOptions.batchingMode > BATCHING_MODE_NO_AUTO_REPORT)) {
+ err = LOCATION_ERROR_INVALID_PARAMETER;
+ }
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (!mAdapter.isTripSession(mSessionId)) {
+ mAdapter.stopBatching(mClient, mSessionId, true, mBatchOptions);
+ } else {
+ mAdapter.stopTripBatchingMultiplex(mClient, mSessionId, true, mBatchOptions);
+ }
+ }
+ }
+ };
+
+ sendMsg(new MsgUpdateBatching(*this, *mLocApi, client, id, batchOptions));
+}
+
+void
+BatchingAdapter::stopBatchingCommand(LocationAPI* client, uint32_t id)
+{
+ LOC_LOGD("%s]: client %p id %u", __func__, client, id);
+
+ struct MsgStopBatching : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ uint32_t mSessionId;
+ inline MsgStopBatching(BatchingAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ uint32_t sessionId) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mSessionId(sessionId) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgStopBatching(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ if (!mAdapter.isBatchingSession(mClient, mSessionId)) {
+ err = LOCATION_ERROR_ID_UNKNOWN;
+ }
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (mAdapter.isTripSession(mSessionId)) {
+ mAdapter.stopTripBatchingMultiplex(mClient, mSessionId);
+ } else {
+ mAdapter.stopBatching(mClient, mSessionId);
+ }
+ }
+ }
+ };
+
+ sendMsg(new MsgStopBatching(*this, *mLocApi, client, id));
+}
+
+void
+BatchingAdapter::stopBatching(LocationAPI* client, uint32_t sessionId, bool restartNeeded,
+ const BatchingOptions& batchOptions)
+{
+ LocationSessionKey key(client, sessionId);
+ auto it = mBatchingSessions.find(key);
+ if (it != mBatchingSessions.end()) {
+ auto flpOptions = it->second;
+ // Assume stop will be OK, restore session if not
+ eraseBatchingSession(client, sessionId);
+ mLocApi->stopBatching(sessionId,
+ new LocApiResponse(*getContext(),
+ [this, client, sessionId, flpOptions, restartNeeded, batchOptions]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ saveBatchingSession(client, sessionId, batchOptions);
+ } else {
+ // if stopBatching is success, unregister for batch full event if this was the last
+ // batching session that is interested in batch full event
+ if (0 == autoReportBatchingSessionsCount() &&
+ flpOptions.batchingMode != BATCHING_MODE_NO_AUTO_REPORT) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+
+ if (restartNeeded) {
+ if (batchOptions.batchingMode == BATCHING_MODE_ROUTINE ||
+ batchOptions.batchingMode == BATCHING_MODE_NO_AUTO_REPORT) {
+ startBatching(client, sessionId, batchOptions);
+ } else if (batchOptions.batchingMode == BATCHING_MODE_TRIP) {
+ startTripBatchingMultiplex(client, sessionId, batchOptions);
+ }
+ }
+ }
+ reportResponse(client, err, sessionId);
+ }));
+ }
+}
+
+void
+BatchingAdapter::getBatchedLocationsCommand(LocationAPI* client, uint32_t id, size_t count)
+{
+ LOC_LOGD("%s]: client %p id %u count %zu", __func__, client, id, count);
+
+ struct MsgGetBatchedLocations : public LocMsg {
+ BatchingAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ uint32_t mSessionId;
+ size_t mCount;
+ inline MsgGetBatchedLocations(BatchingAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ uint32_t sessionId,
+ size_t count) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mSessionId(sessionId),
+ mCount(count) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgGetBatchedLocations(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ if (!mAdapter.hasBatchingCallback(mClient)) {
+ err = LOCATION_ERROR_CALLBACK_MISSING;
+ } else if (!mAdapter.isBatchingSession(mClient, mSessionId)) {
+ err = LOCATION_ERROR_ID_UNKNOWN;
+ }
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (mAdapter.isTripSession(mSessionId)) {
+ mApi.getBatchedTripLocations(mCount, 0,
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId,
+ mClient = mClient] (LocationError err) {
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ } else {
+ mApi.getBatchedLocations(mCount, new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId,
+ mClient = mClient] (LocationError err) {
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ }
+ } else {
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }
+ }
+ };
+
+ sendMsg(new MsgGetBatchedLocations(*this, *mLocApi, client, id, count));
+}
+
+void
+BatchingAdapter::reportLocationsEvent(const Location* locations, size_t count,
+ BatchingMode batchingMode)
+{
+ LOC_LOGD("%s]: count %zu batchMode %d", __func__, count, batchingMode);
+
+ struct MsgReportLocations : public LocMsg {
+ BatchingAdapter& mAdapter;
+ Location* mLocations;
+ size_t mCount;
+ BatchingMode mBatchingMode;
+ inline MsgReportLocations(BatchingAdapter& adapter,
+ const Location* locations,
+ size_t count,
+ BatchingMode batchingMode) :
+ LocMsg(),
+ mAdapter(adapter),
+ mLocations(new Location[count]),
+ mCount(count),
+ mBatchingMode(batchingMode)
+ {
+ if (nullptr == mLocations) {
+ LOC_LOGE("%s]: new failed to allocate mLocations", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ mLocations[i] = locations[i];
+ }
+ }
+ inline virtual ~MsgReportLocations() {
+ if (nullptr != mLocations)
+ delete[] mLocations;
+ }
+ inline virtual void proc() const {
+ mAdapter.reportLocations(mLocations, mCount, mBatchingMode);
+ }
+ };
+
+ sendMsg(new MsgReportLocations(*this, locations, count, batchingMode));
+}
+
+void
+BatchingAdapter::reportLocations(Location* locations, size_t count, BatchingMode batchingMode)
+{
+ BatchingOptions batchOptions = {sizeof(BatchingOptions), batchingMode};
+
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if (nullptr != it->second.batchingCb) {
+ it->second.batchingCb(count, locations, batchOptions);
+ }
+ }
+}
+
+void
+BatchingAdapter::reportCompletedTripsEvent(uint32_t accumulated_distance)
+{
+ struct MsgReportCompletedTrips : public LocMsg {
+ BatchingAdapter& mAdapter;
+ uint32_t mAccumulatedDistance;
+ inline MsgReportCompletedTrips(BatchingAdapter& adapter,
+ uint32_t accumulated_distance) :
+ LocMsg(),
+ mAdapter(adapter),
+ mAccumulatedDistance(accumulated_distance)
+ {
+ }
+ inline virtual ~MsgReportCompletedTrips() {
+ }
+ inline virtual void proc() const {
+
+ // Check if any trips are completed
+ std::list<uint32_t> completedTripsList;
+ completedTripsList.clear();
+
+ for(auto itt = mAdapter.mTripSessions.begin(); itt != mAdapter.mTripSessions.end();)
+ {
+ TripSessionStatus &tripSession = itt->second;
+
+ tripSession.accumulatedDistanceThisTrip =
+ tripSession.accumulatedDistanceOnTripRestart
+ + (mAccumulatedDistance - tripSession.accumulatedDistanceOngoingBatch);
+ if (tripSession.tripDistance <= tripSession.accumulatedDistanceThisTrip) {
+ // trip is completed
+ completedTripsList.push_back(itt->first);
+ itt = mAdapter.mTripSessions.erase(itt);
+
+ if (tripSession.tripTBFInterval == mAdapter.mOngoingTripTBFInterval) {
+ // trip with ongoing TBF interval is completed
+ mAdapter.mTripWithOngoingTBFDropped = true;
+ }
+
+ if (tripSession.tripDistance == mAdapter.mOngoingTripDistance) {
+ // trip with ongoing trip distance is completed
+ mAdapter.mTripWithOngoingTripDistanceDropped = true;
+ }
+ } else {
+ itt++;
+ }
+ }
+
+ if (completedTripsList.size() > 0) {
+ mAdapter.reportBatchStatusChange(BATCHING_STATUS_TRIP_COMPLETED,
+ completedTripsList);
+ mAdapter.restartTripBatching(false, mAccumulatedDistance, 0);
+ } else {
+ mAdapter.printTripReport();
+ }
+ }
+ };
+
+ LOC_LOGD("%s]: Accumulated Distance so far: %u",
+ __func__, accumulated_distance);
+
+ sendMsg(new MsgReportCompletedTrips(*this, accumulated_distance));
+}
+
+void
+BatchingAdapter::reportBatchStatusChange(BatchingStatus batchStatus,
+ std::list<uint32_t> & completedTripsList)
+{
+ BatchingStatusInfo batchStatusInfo =
+ {sizeof(BatchingStatusInfo), batchStatus};
+
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if (nullptr != it->second.batchingStatusCb) {
+ it->second.batchingStatusCb(batchStatusInfo, completedTripsList);
+ }
+ }
+}
+
+void
+BatchingAdapter::reportBatchStatusChangeEvent(BatchingStatus batchStatus)
+{
+ struct MsgReportBatchStatus : public LocMsg {
+ BatchingAdapter& mAdapter;
+ BatchingStatus mBatchStatus;
+ inline MsgReportBatchStatus(BatchingAdapter& adapter,
+ BatchingStatus batchStatus) :
+ LocMsg(),
+ mAdapter(adapter),
+ mBatchStatus(batchStatus)
+ {
+ }
+ inline virtual ~MsgReportBatchStatus() {
+ }
+ inline virtual void proc() const {
+ std::list<uint32_t> tempList;
+ tempList.clear();
+ mAdapter.reportBatchStatusChange(mBatchStatus, tempList);
+ }
+ };
+
+ sendMsg(new MsgReportBatchStatus(*this, batchStatus));
+}
+
+void
+BatchingAdapter::startTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions)
+{
+ if (mTripSessions.size() == 0) {
+ // if there is currenty no batching sessions interested in batch full event, then this
+ // new session will need to register for batch full event
+ if (0 == autoReportBatchingSessionsCount()) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_ENABLED);
+ }
+
+ // Assume start will be OK, remove session if not
+ saveBatchingSession(client, sessionId, batchingOptions);
+
+ mTripSessions[sessionId] = { 0, 0, 0, batchingOptions.minDistance,
+ batchingOptions.minInterval};
+ mLocApi->startOutdoorTripBatching(batchingOptions.minDistance,
+ batchingOptions.minInterval, getBatchingTimeout(), new LocApiResponse(*getContext(),
+ [this, client, sessionId, batchingOptions] (LocationError err) {
+ if (err == LOCATION_ERROR_SUCCESS) {
+ mOngoingTripDistance = batchingOptions.minDistance;
+ mOngoingTripTBFInterval = batchingOptions.minInterval;
+ LOC_LOGD("%s] New Trip started ...", __func__);
+ printTripReport();
+ } else {
+ eraseBatchingSession(client, sessionId);
+ mTripSessions.erase(sessionId);
+ // if we fail to start batching and we have already registered batch full event
+ // we need to undo that since no sessions are now interested in batch full event
+ if (0 == autoReportBatchingSessionsCount()) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+ }
+ reportResponse(client, err, sessionId);
+ }));
+ } else {
+ // query accumulated distance
+ mLocApi->queryAccumulatedTripDistance(
+ new LocApiResponseData<LocApiBatchData>(*getContext(),
+ [this, batchingOptions, sessionId, client]
+ (LocationError err, LocApiBatchData data) {
+ uint32_t accumulatedDistanceOngoingBatch = 0;
+ uint32_t numOfBatchedPositions = 0;
+ uint32_t ongoingTripDistance = mOngoingTripDistance;
+ uint32_t ongoingTripInterval = mOngoingTripTBFInterval;
+ bool needsRestart = false;
+
+ // check if TBF of new session is lesser than ongoing TBF interval
+ if (ongoingTripInterval > batchingOptions.minInterval) {
+ ongoingTripInterval = batchingOptions.minInterval;
+ needsRestart = true;
+ }
+ accumulatedDistanceOngoingBatch = data.accumulatedDistance;
+ numOfBatchedPositions = data.numOfBatchedPositions;
+ TripSessionStatus newTripSession = { accumulatedDistanceOngoingBatch, 0, 0,
+ batchingOptions.minDistance,
+ batchingOptions.minInterval};
+ if (err != LOCATION_ERROR_SUCCESS) {
+ // unable to query accumulated distance, assume remaining distance in
+ // ongoing batch is mongoingTripDistance.
+ if (batchingOptions.minDistance < ongoingTripDistance) {
+ ongoingTripDistance = batchingOptions.minDistance;
+ needsRestart = true;
+ }
+ } else {
+ // compute the remaining distance
+ uint32_t ongoing_trip_remaining_distance = ongoingTripDistance -
+ accumulatedDistanceOngoingBatch;
+
+ // check if new trip distance is lesser than the ongoing batch remaining distance
+ if (batchingOptions.minDistance < ongoing_trip_remaining_distance) {
+ ongoingTripDistance = batchingOptions.minDistance;
+ needsRestart = true;
+ } else if (needsRestart == true) {
+ // needsRestart is anyways true , may be because of lesser TBF of new session.
+ ongoingTripDistance = ongoing_trip_remaining_distance;
+ }
+ mTripSessions[sessionId] = newTripSession;
+ LOC_LOGD("%s] New Trip started ...", __func__);
+ printTripReport();
+ }
+
+ if (needsRestart) {
+ mOngoingTripDistance = ongoingTripDistance;
+ mOngoingTripTBFInterval = ongoingTripInterval;
+
+ // reset the accumulatedDistanceOngoingBatch for each session,
+ // and record the total accumulated distance so far for the session.
+ for (auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
+ TripSessionStatus &tripSessStatus = itt->second;
+ tripSessStatus.accumulatedDistanceOngoingBatch = 0;
+ tripSessStatus.accumulatedDistanceOnTripRestart =
+ tripSessStatus.accumulatedDistanceThisTrip;
+ }
+ mLocApi->reStartOutdoorTripBatching(ongoingTripDistance, ongoingTripInterval,
+ getBatchingTimeout(), new LocApiResponse(*getContext(),
+ [this, client, sessionId] (LocationError err) {
+ if (err != LOCATION_ERROR_SUCCESS) {
+ LOC_LOGE("%s] New Trip restart failed!", __func__);
+ }
+ reportResponse(client, err, sessionId);
+ }));
+ } else {
+ reportResponse(client, LOCATION_ERROR_SUCCESS, sessionId);
+ }
+ }));
+ }
+}
+
+void
+BatchingAdapter::stopTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
+ bool restartNeeded, const BatchingOptions& batchOptions)
+{
+ LocationError err = LOCATION_ERROR_SUCCESS;
+
+ if (mTripSessions.size() == 1) {
+ mLocApi->stopOutdoorTripBatching(true, new LocApiResponse(*getContext(),
+ [this, restartNeeded, client, sessionId, batchOptions]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ // if stopOutdoorTripBatching is success, unregister for batch full event if this
+ // was the last batching session that is interested in batch full event
+ if (1 == autoReportBatchingSessionsCount()) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+ }
+ stopTripBatchingMultiplexCommon(err, client, sessionId, restartNeeded, batchOptions);
+ }));
+ return;
+ }
+
+ stopTripBatchingMultiplexCommon(err, client, sessionId, restartNeeded, batchOptions);
+}
+
+void
+BatchingAdapter::stopTripBatchingMultiplexCommon(LocationError err, LocationAPI* client,
+ uint32_t sessionId, bool restartNeeded, const BatchingOptions& batchOptions)
+{
+ auto itt = mTripSessions.find(sessionId);
+ TripSessionStatus tripSess = itt->second;
+ if (tripSess.tripTBFInterval == mOngoingTripTBFInterval) {
+ // trip with ongoing trip interval is stopped
+ mTripWithOngoingTBFDropped = true;
+ }
+
+ if (tripSess.tripDistance == mOngoingTripDistance) {
+ // trip with ongoing trip distance is stopped
+ mTripWithOngoingTripDistanceDropped = true;
+ }
+
+ mTripSessions.erase(sessionId);
+
+ if (mTripSessions.size() == 0) {
+ mOngoingTripDistance = 0;
+ mOngoingTripTBFInterval = 0;
+ } else {
+ restartTripBatching(true);
+ }
+
+ if (restartNeeded) {
+ eraseBatchingSession(client, sessionId);
+ if (batchOptions.batchingMode == BATCHING_MODE_ROUTINE ||
+ batchOptions.batchingMode == BATCHING_MODE_NO_AUTO_REPORT) {
+ startBatching(client, sessionId, batchOptions);
+ } else if (batchOptions.batchingMode == BATCHING_MODE_TRIP) {
+ startTripBatchingMultiplex(client, sessionId, batchOptions);
+ }
+ }
+ reportResponse(client, err, sessionId);
+}
+
+
+void
+BatchingAdapter::restartTripBatching(bool queryAccumulatedDistance, uint32_t accDist,
+ uint32_t numbatchedPos)
+{
+ // does batch need restart with new trip distance / TBF interval
+ uint32_t minRemainingDistance = 0;
+ uint32_t minTBFInterval = 0;
+
+ // if no more trips left, stop the ongoing trip
+ if (mTripSessions.size() == 0) {
+ mLocApi->stopOutdoorTripBatching(true, new LocApiResponse(*getContext(),
+ [] (LocationError /*err*/) {}));
+ mOngoingTripDistance = 0;
+ mOngoingTripTBFInterval = 0;
+ // unregister for batch full event if there are no more
+ // batching session that is interested in batch full event
+ if (0 == autoReportBatchingSessionsCount()) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_BATCH_FULL,
+ LOC_REGISTRATION_MASK_DISABLED);
+ }
+ return;
+ }
+
+ // record the min trip distance and min tbf interval of all ongoing sessions
+ for (auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
+
+ TripSessionStatus tripSessStatus = itt->second;
+
+ if ((minRemainingDistance == 0) ||
+ (minRemainingDistance > (tripSessStatus.tripDistance
+ - tripSessStatus.accumulatedDistanceThisTrip))) {
+ minRemainingDistance = tripSessStatus.tripDistance -
+ tripSessStatus.accumulatedDistanceThisTrip;
+ }
+
+ if ((minTBFInterval == 0) ||
+ (minTBFInterval > tripSessStatus.tripTBFInterval)) {
+ minTBFInterval = tripSessStatus.tripTBFInterval;
+ }
+ }
+
+ mLocApi->queryAccumulatedTripDistance(
+ new LocApiResponseData<LocApiBatchData>(*getContext(),
+ [this, queryAccumulatedDistance, minRemainingDistance, minTBFInterval, accDist,
+ numbatchedPos] (LocationError /*err*/, LocApiBatchData data) {
+ bool needsRestart = false;
+
+ uint32_t ongoingTripDistance = mOngoingTripDistance;
+ uint32_t ongoingTripInterval = mOngoingTripTBFInterval;
+ uint32_t accumulatedDistance = accDist;
+ uint32_t numOfBatchedPositions = numbatchedPos;
+
+ if (queryAccumulatedDistance) {
+ accumulatedDistance = data.accumulatedDistance;
+ numOfBatchedPositions = data.numOfBatchedPositions;
+ }
+
+ if ((!mTripWithOngoingTripDistanceDropped) &&
+ (ongoingTripDistance - accumulatedDistance != 0)) {
+ // if ongoing trip is already not completed still,
+ // check the min distance against the remaining distance
+ if (minRemainingDistance <
+ (ongoingTripDistance - accumulatedDistance)) {
+ ongoingTripDistance = minRemainingDistance;
+ needsRestart = true;
+ }
+ } else if (minRemainingDistance != 0) {
+ // else if ongoing trip is already completed / dropped,
+ // use the minRemainingDistance of ongoing sessions
+ ongoingTripDistance = minRemainingDistance;
+ needsRestart = true;
+ }
+
+ if ((minTBFInterval < ongoingTripInterval) ||
+ ((minTBFInterval != ongoingTripInterval) &&
+ (mTripWithOngoingTBFDropped))) {
+ ongoingTripInterval = minTBFInterval;
+ needsRestart = true;
+ }
+
+ if (needsRestart) {
+ mLocApi->reStartOutdoorTripBatching(ongoingTripDistance, ongoingTripInterval,
+ getBatchingTimeout(), new LocApiResponse(*getContext(),
+ [this, accumulatedDistance, ongoingTripDistance, ongoingTripInterval]
+ (LocationError err) {
+
+ if (err == LOCATION_ERROR_SUCCESS) {
+ for(auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
+ TripSessionStatus &tripSessStatus = itt->second;
+ tripSessStatus.accumulatedDistanceThisTrip =
+ tripSessStatus.accumulatedDistanceOnTripRestart +
+ (accumulatedDistance -
+ tripSessStatus.accumulatedDistanceOngoingBatch);
+
+ tripSessStatus.accumulatedDistanceOngoingBatch = 0;
+ tripSessStatus.accumulatedDistanceOnTripRestart =
+ tripSessStatus.accumulatedDistanceThisTrip;
+ }
+
+ mOngoingTripDistance = ongoingTripDistance;
+ mOngoingTripTBFInterval = ongoingTripInterval;
+ }
+ }));
+ }
+ }));
+}
+
+void
+BatchingAdapter::printTripReport()
+{
+ IF_LOC_LOGD {
+ LOC_LOGD("Ongoing Trip Distance = %u, Ongoing Trip TBF Interval = %u",
+ mOngoingTripDistance, mOngoingTripTBFInterval);
+
+ for (auto itt = mTripSessions.begin(); itt != mTripSessions.end(); itt++) {
+ TripSessionStatus tripSessStatus = itt->second;
+
+ LOC_LOGD("tripDistance:%u tripTBFInterval:%u"
+ " trip accumulated Distance:%u"
+ " trip accumualted distance ongoing batch:%u"
+ " trip accumulated distance on trip restart %u \r\n",
+ tripSessStatus.tripDistance, tripSessStatus.tripTBFInterval,
+ tripSessStatus.accumulatedDistanceThisTrip,
+ tripSessStatus.accumulatedDistanceOngoingBatch,
+ tripSessStatus.accumulatedDistanceOnTripRestart);
+ }
+ }
+}
diff --git a/gps/batching/BatchingAdapter.h b/gps/batching/BatchingAdapter.h
new file mode 100644
index 0000000..66f7c5f
--- /dev/null
+++ b/gps/batching/BatchingAdapter.h
@@ -0,0 +1,152 @@
+/* Copyright (c) 2017-2019, 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 BATCHING_ADAPTER_H
+#define BATCHING_ADAPTER_H
+
+#include <LocAdapterBase.h>
+#include <LocContext.h>
+#include <LocationAPI.h>
+#include <map>
+
+using namespace loc_core;
+
+class BatchingAdapter : public LocAdapterBase {
+
+ /* ==== BATCHING ======================================================================= */
+ typedef struct {
+ uint32_t accumulatedDistanceOngoingBatch;
+ uint32_t accumulatedDistanceThisTrip;
+ uint32_t accumulatedDistanceOnTripRestart;
+ uint32_t tripDistance;
+ uint32_t tripTBFInterval;
+ } TripSessionStatus;
+ typedef std::map<uint32_t, TripSessionStatus> TripSessionStatusMap;
+ typedef std::map<LocationSessionKey, BatchingOptions> BatchingSessionMap;
+
+ BatchingSessionMap mBatchingSessions;
+ TripSessionStatusMap mTripSessions;
+ uint32_t mOngoingTripDistance;
+ uint32_t mOngoingTripTBFInterval;
+ bool mTripWithOngoingTBFDropped;
+ bool mTripWithOngoingTripDistanceDropped;
+
+ void startTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions);
+ void stopTripBatchingMultiplex(LocationAPI* client, uint32_t sessionId,
+ bool restartNeeded,
+ const BatchingOptions& batchOptions);
+ inline void stopTripBatchingMultiplex(LocationAPI* client, uint32_t id) {
+ BatchingOptions batchOptions;
+ stopTripBatchingMultiplex(client, id, false, batchOptions);
+ };
+ void stopTripBatchingMultiplexCommon(LocationError err,
+ LocationAPI* client,
+ uint32_t sessionId,
+ bool restartNeeded,
+ const BatchingOptions& batchOptions);
+ void restartTripBatching(bool queryAccumulatedDistance, uint32_t accDist = 0,
+ uint32_t numbatchedPos = 0);
+ void printTripReport();
+
+ /* ==== CONFIGURATION ================================================================== */
+ uint32_t mBatchingTimeout;
+ uint32_t mBatchingAccuracy;
+ size_t mBatchSize;
+ size_t mTripBatchSize;
+
+protected:
+
+ /* ==== CLIENT ========================================================================= */
+ virtual void updateClientsEventMask();
+ virtual void stopClientSessions(LocationAPI* client);
+
+public:
+ BatchingAdapter();
+ virtual ~BatchingAdapter() {}
+
+ /* ==== SSR ============================================================================ */
+ /* ======== EVENTS ====(Called from QMI Thread)========================================= */
+ virtual void handleEngineUpEvent();
+ /* ======== UTILITIES ================================================================== */
+ void restartSessions();
+
+ /* ==== BATCHING ======================================================================= */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ uint32_t startBatchingCommand(LocationAPI* client, BatchingOptions &batchOptions);
+ void updateBatchingOptionsCommand(
+ LocationAPI* client, uint32_t id, BatchingOptions& batchOptions);
+ void stopBatchingCommand(LocationAPI* client, uint32_t id);
+ void getBatchedLocationsCommand(LocationAPI* client, uint32_t id, size_t count);
+ /* ======== RESPONSES ================================================================== */
+ void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
+ /* ======== UTILITIES ================================================================== */
+ bool hasBatchingCallback(LocationAPI* client);
+ bool isBatchingSession(LocationAPI* client, uint32_t sessionId);
+ bool isTripSession(uint32_t sessionId);
+ void saveBatchingSession(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions);
+ void eraseBatchingSession(LocationAPI* client, uint32_t sessionId);
+ uint32_t autoReportBatchingSessionsCount();
+ void startBatching(LocationAPI* client, uint32_t sessionId,
+ const BatchingOptions& batchingOptions);
+ void stopBatching(LocationAPI* client, uint32_t sessionId, bool restartNeeded,
+ const BatchingOptions& batchOptions);
+ void stopBatching(LocationAPI* client, uint32_t sessionId) {
+ BatchingOptions batchOptions;
+ stopBatching(client, sessionId, false, batchOptions);
+ };
+
+ /* ==== REPORTS ======================================================================== */
+ /* ======== EVENTS ====(Called from QMI Thread)========================================= */
+ void reportLocationsEvent(const Location* locations, size_t count,
+ BatchingMode batchingMode);
+ void reportCompletedTripsEvent(uint32_t accumulatedDistance);
+ void reportBatchStatusChangeEvent(BatchingStatus batchStatus);
+ /* ======== UTILITIES ================================================================== */
+ void reportLocations(Location* locations, size_t count, BatchingMode batchingMode);
+ void reportBatchStatusChange(BatchingStatus batchStatus,
+ std::list<uint32_t> & completedTripsList);
+
+ /* ==== CONFIGURATION ================================================================== */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ void readConfigCommand();
+ void setConfigCommand();
+ /* ======== UTILITIES ================================================================== */
+ void setBatchSize(size_t batchSize) { mBatchSize = batchSize; }
+ size_t getBatchSize() { return mBatchSize; }
+ void setTripBatchSize(size_t batchSize) { mTripBatchSize = batchSize; }
+ size_t getTripBatchSize() { return mTripBatchSize; }
+ void setBatchingTimeout(uint32_t batchingTimeout) { mBatchingTimeout = batchingTimeout; }
+ uint32_t getBatchingTimeout() { return mBatchingTimeout; }
+ void setBatchingAccuracy(uint32_t accuracy) { mBatchingAccuracy = accuracy; }
+ uint32_t getBatchingAccuracy() { return mBatchingAccuracy; }
+
+};
+
+#endif /* BATCHING_ADAPTER_H */
diff --git a/gps/batching/location_batching.cpp b/gps/batching/location_batching.cpp
new file mode 100644
index 0000000..571da72
--- /dev/null
+++ b/gps/batching/location_batching.cpp
@@ -0,0 +1,134 @@
+/* Copyright (c) 2017-2019, 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.
+ *
+ */
+#include "BatchingAdapter.h"
+#include "location_interface.h"
+
+static BatchingAdapter* gBatchingAdapter = NULL;
+
+static void initialize();
+static void deinitialize();
+
+static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb);
+static void requestCapabilities(LocationAPI* client);
+
+static uint32_t startBatching(LocationAPI* client, BatchingOptions&);
+static void stopBatching(LocationAPI* client, uint32_t id);
+static void updateBatchingOptions(LocationAPI* client, uint32_t id, BatchingOptions&);
+static void getBatchedLocations(LocationAPI* client, uint32_t id, size_t count);
+
+static const BatchingInterface gBatchingInterface = {
+ sizeof(BatchingInterface),
+ initialize,
+ deinitialize,
+ addClient,
+ removeClient,
+ requestCapabilities,
+ startBatching,
+ stopBatching,
+ updateBatchingOptions,
+ getBatchedLocations
+};
+
+#ifndef DEBUG_X86
+extern "C" const BatchingInterface* getBatchingInterface()
+#else
+const BatchingInterface* getBatchingInterface()
+#endif // DEBUG_X86
+{
+ return &gBatchingInterface;
+}
+
+static void initialize()
+{
+ if (NULL == gBatchingAdapter) {
+ gBatchingAdapter = new BatchingAdapter();
+ }
+}
+
+static void deinitialize()
+{
+ if (NULL != gBatchingAdapter) {
+ delete gBatchingAdapter;
+ gBatchingAdapter = NULL;
+ }
+}
+
+static void addClient(LocationAPI* client, const LocationCallbacks& callbacks)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->addClientCommand(client, callbacks);
+ }
+}
+
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->removeClientCommand(client, rmClientCb);
+ }
+}
+
+static void requestCapabilities(LocationAPI* client)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->requestCapabilitiesCommand(client);
+ }
+}
+
+static uint32_t startBatching(LocationAPI* client, BatchingOptions &batchOptions)
+{
+ if (NULL != gBatchingAdapter) {
+ return gBatchingAdapter->startBatchingCommand(client, batchOptions);
+ } else {
+ return 0;
+ }
+}
+
+static void stopBatching(LocationAPI* client, uint32_t id)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->stopBatchingCommand(client, id);
+ }
+}
+
+static void updateBatchingOptions(
+ LocationAPI* client, uint32_t id, BatchingOptions& batchOptions)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->updateBatchingOptionsCommand(client, id, batchOptions);
+ }
+}
+
+static void getBatchedLocations(LocationAPI* client, uint32_t id, size_t count)
+{
+ if (NULL != gBatchingAdapter) {
+ gBatchingAdapter->getBatchedLocationsCommand(client, id, count);
+ }
+}
+
diff --git a/gps/build/target_specific_features.mk b/gps/build/target_specific_features.mk
index 1a00ef1..155431a 100644
--- a/gps/build/target_specific_features.mk
+++ b/gps/build/target_specific_features.mk
@@ -1,3 +1,73 @@
GNSS_CFLAGS := \
-Werror \
- -Wno-undefined-bool-conversion
+ -Wno-error=unused-parameter \
+ -Wno-error=macro-redefined \
+ -Wno-error=reorder \
+ -Wno-error=missing-braces \
+ -Wno-error=self-assign \
+ -Wno-error=enum-conversion \
+ -Wno-error=logical-op-parentheses \
+ -Wno-error=null-arithmetic \
+ -Wno-error=null-conversion \
+ -Wno-error=parentheses-equality \
+ -Wno-error=undefined-bool-conversion \
+ -Wno-error=tautological-compare \
+ -Wno-error=switch \
+ -Wno-error=date-time
+
+# GPS-HIDL
+GNSS_HIDL_1_0_TARGET_LIST := msm8960
+GNSS_HIDL_1_0_TARGET_LIST += msm8974
+GNSS_HIDL_1_0_TARGET_LIST += msm8226
+GNSS_HIDL_1_0_TARGET_LIST += msm8610
+GNSS_HIDL_1_0_TARGET_LIST += apq8084
+GNSS_HIDL_1_0_TARGET_LIST += msm8916
+GNSS_HIDL_1_0_TARGET_LIST += msm8994
+GNSS_HIDL_1_0_TARGET_LIST += msm8909
+GNSS_HIDL_1_0_TARGET_LIST += msm8952
+GNSS_HIDL_1_0_TARGET_LIST += msm8992
+GNSS_HIDL_2_0_TARGET_LIST := msm8996
+GNSS_HIDL_2_0_TARGET_LIST += msm8937
+GNSS_HIDL_2_0_TARGET_LIST += msm8953
+GNSS_HIDL_2_0_TARGET_LIST += msm8998
+GNSS_HIDL_2_0_TARGET_LIST += apq8098_latv
+GNSS_HIDL_2_0_TARGET_LIST += sdm710
+GNSS_HIDL_2_0_TARGET_LIST += qcs605
+GNSS_HIDL_2_0_TARGET_LIST += sdm845
+GNSS_HIDL_2_0_TARGET_LIST += sdm660
+GNSS_HIDL_2_0_TARGET_LIST += msmnile
+GNSS_HIDL_2_0_TARGET_LIST += sdmshrike
+GNSS_HIDL_2_0_TARGET_LIST += $(MSMSTEPPE)
+GNSS_HIDL_2_0_TARGET_LIST += $(TRINKET)
+GNSS_HIDL_2_0_TARGET_LIST += kona
+GNSS_HIDL_2_0_TARGET_LIST += atoll
+GNSS_HIDL_2_0_TARGET_LIST += lito
+GNSS_HIDL_2_0_TARGET_LIST += bengal
+
+ifneq (,$(filter $(GNSS_HIDL_2_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
+GNSS_HIDL_VERSION = 2.0
+endif
+ifneq (,$(filter $(GNSS_HIDL_1_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
+GNSS_HIDL_VERSION = 1.0
+endif
+ifneq (,$(filter $(GNSS_HIDL_1_1_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
+GNSS_HIDL_VERSION = 1.1
+endif
+
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST := msm8937
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += msm8953
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += msm8996
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += msm8998
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += apq8098_latv
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += sdm710
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += qcs605
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += sdm845
+GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST += sdm660
+
+ifneq (,$(filter $(GNSS_HIDL_LEGACY_MEASURMENTS_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
+GNSS_HIDL_LEGACY_MEASURMENTS = true
+endif
+
+# Activate the following two lines for regression testing
+#GNSS_SANITIZE := address cfi alignment bounds null unreachable integer
+#GNSS_SANITIZE_DIAG := address cfi alignment bounds null unreachable integer
diff --git a/gps/configure.ac b/gps/configure.ac
deleted file mode 100644
index 0ab8e68..0000000
--- a/gps/configure.ac
+++ /dev/null
@@ -1,87 +0,0 @@
-# configure.ac -- Autoconf script for gps loc_hal
-#
-# Process this file with autoconf to produce a configure script
-
-# Requires autoconf tool later than 2.61
-AC_PREREQ(2.61)
-# Initialize the gps loc-hal package version 1.0.0
-AC_INIT([loc-hal],1.0.0)
-# Does not strictly follow GNU Coding standards
-AM_INIT_AUTOMAKE([foreign])
-# Disables auto rebuilding of configure, Makefile.ins
-AM_MAINTAINER_MODE
-# Verifies the --srcdir is correct by checking for the path
-AC_CONFIG_SRCDIR([Makefile.am])
-# defines some macros variable to be included by source
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_MACRO_DIR([m4])
-
-# Checks for programs.
-AC_PROG_LIBTOOL
-AC_PROG_CXX
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_AWK
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-PKG_PROG_PKG_CONFIG
-
-# Checks for libraries.
-PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
-AC_SUBST([GPSUTILS_CFLAGS])
-AC_SUBST([GPSUTILS_LIBS])
-
-PKG_CHECK_MODULES([LOCCORE], [loc-core])
-AC_SUBST([LOCCORE_CFLAGS])
-AC_SUBST([LOCCORE_LIBS])
-
-AC_ARG_WITH([core_includes],
- AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
- [Specify the location of the core headers]),
- [core_incdir=$withval],
- with_core_includes=no)
-
-if test "x$with_core_includes" != "xno"; then
- CPPFLAGS="${CPPFLAGS} -I${core_incdir}"
-fi
-
-AC_ARG_WITH([locpla_includes],
- AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@],
- [specify the path to locpla-includes in loc-pla_git.bb]),
- [locpla_incdir=$withval],
- with_locpla_includes=no)
-
-if test "x$with_locpla_includes" != "xno"; then
- AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}")
-fi
-
-AC_SUBST([CPPFLAGS])
-
-AC_ARG_WITH([glib],
- AC_HELP_STRING([--with-glib],
- [enable glib, building HLOS systems which use glib]))
-
-if (test "x${with_glib}" = "xyes"); then
- AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
- PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GThread >= 2.16 is required))
- PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GLib >= 2.16 is required))
- GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
- GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
-
- AC_SUBST(GLIB_CFLAGS)
- AC_SUBST(GLIB_LIBS)
-fi
-
-AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
-
-AC_CONFIG_FILES([ \
- Makefile \
- gnss/Makefile \
- loc-hal.pc \
- ])
-
-AC_OUTPUT
diff --git a/gps/core/Android.mk b/gps/core/Android.mk
index 1a4f51a..ce5d6a8 100644
--- a/gps/core/Android.mk
+++ b/gps/core/Android.mk
@@ -6,15 +6,12 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libloc_core
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
-ifeq ($(TARGET_DEVICE),apq8026_lw)
-LOCAL_CFLAGS += -DPDK_FEATURE_SET
-else ifeq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET),true)
-LOCAL_CFLAGS += -DPDK_FEATURE_SET
-endif
-
LOCAL_SHARED_LIBRARIES := \
liblog \
libutils \
@@ -27,7 +24,7 @@ LOCAL_SRC_FILES += \
LocApiBase.cpp \
LocAdapterBase.cpp \
ContextBase.cpp \
- LocDualContext.cpp \
+ LocContext.cpp \
loc_core_log.cpp \
data-items/DataItemsFactoryProxy.cpp \
SystemStatusOsObserver.cpp \
diff --git a/gps/core/ContextBase.cpp b/gps/core/ContextBase.cpp
index 35e6585..7434590 100644
--- a/gps/core/ContextBase.cpp
+++ b/gps/core/ContextBase.cpp
@@ -40,8 +40,16 @@
namespace loc_core {
+#define SLL_LOC_API_LIB_NAME "libsynergy_loc_api.so"
+#define LOC_APIV2_0_LIB_NAME "libloc_api_v02.so"
+#define IS_SS5_HW_ENABLED 1
+
loc_gps_cfg_s_type ContextBase::mGps_conf {};
loc_sap_cfg_s_type ContextBase::mSap_conf {};
+bool ContextBase::sIsEngineCapabilitiesKnown = false;
+uint64_t ContextBase::sSupportedMsgMask = 0;
+bool ContextBase::sGnssMeasurementSupported = false;
+uint8_t ContextBase::sFeaturesSupported[MAX_FEATURE_LENGTH];
const loc_param_s_type ContextBase::mGps_conf_table[] =
{
@@ -62,11 +70,28 @@ const loc_param_s_type ContextBase::mGps_conf_table[] =
{"XTRA_SERVER_1", &mGps_conf.XTRA_SERVER_1, NULL, 's'},
{"XTRA_SERVER_2", &mGps_conf.XTRA_SERVER_2, NULL, 's'},
{"XTRA_SERVER_3", &mGps_conf.XTRA_SERVER_3, NULL, 's'},
- {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", &mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL, NULL, 'n'},
+ {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL",
+ &mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL, NULL, 'n'},
{"AGPS_CONFIG_INJECT", &mGps_conf.AGPS_CONFIG_INJECT, NULL, 'n'},
{"EXTERNAL_DR_ENABLED", &mGps_conf.EXTERNAL_DR_ENABLED, NULL, 'n'},
{"SUPL_HOST", &mGps_conf.SUPL_HOST, NULL, 's'},
{"SUPL_PORT", &mGps_conf.SUPL_PORT, NULL, 'n'},
+ {"MODEM_TYPE", &mGps_conf.MODEM_TYPE, NULL, 'n' },
+ {"MO_SUPL_HOST", &mGps_conf.MO_SUPL_HOST, NULL, 's' },
+ {"MO_SUPL_PORT", &mGps_conf.MO_SUPL_PORT, NULL, 'n' },
+ {"CONSTRAINED_TIME_UNCERTAINTY_ENABLED",
+ &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED, NULL, 'n'},
+ {"CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD",
+ &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD, NULL, 'f'},
+ {"CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET",
+ &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET, NULL, 'n'},
+ {"POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED",
+ &mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED, NULL, 'n'},
+ {"PROXY_APP_PACKAGE_NAME", &mGps_conf.PROXY_APP_PACKAGE_NAME, NULL, 's' },
+ {"CP_MTLR_ES", &mGps_conf.CP_MTLR_ES, NULL, 'n' },
+ {"GNSS_DEPLOYMENT", &mGps_conf.GNSS_DEPLOYMENT, NULL, 'n'},
+ {"CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED",
+ &mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED, NULL, 'n'},
};
const loc_param_s_type ContextBase::mSap_conf_table[] =
@@ -85,72 +110,105 @@ const loc_param_s_type ContextBase::mSap_conf_table[] =
{"SENSOR_GYRO_BATCHES_PER_SEC_HIGH", &mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH, NULL, 'n'},
{"SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH", &mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH, NULL, 'n'},
{"SENSOR_CONTROL_MODE", &mSap_conf.SENSOR_CONTROL_MODE, NULL, 'n'},
- {"SENSOR_USAGE", &mSap_conf.SENSOR_USAGE, NULL, 'n'},
- {"SENSOR_ALGORITHM_CONFIG_MASK", &mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK, NULL, 'n'},
- {"SENSOR_PROVIDER", &mSap_conf.SENSOR_PROVIDER, NULL, 'n'}
+ {"SENSOR_ALGORITHM_CONFIG_MASK", &mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK, NULL, 'n'}
};
void ContextBase::readConfig()
{
- /*Defaults for gps.conf*/
- mGps_conf.INTERMEDIATE_POS = 0;
- mGps_conf.ACCURACY_THRES = 0;
- mGps_conf.NMEA_PROVIDER = 0;
- mGps_conf.GPS_LOCK = 0;
- mGps_conf.SUPL_VER = 0x10000;
- mGps_conf.SUPL_MODE = 0x1;
- mGps_conf.SUPL_ES = 0;
- mGps_conf.SUPL_HOST[0] = 0;
- mGps_conf.SUPL_PORT = 0;
- mGps_conf.CAPABILITIES = 0x7;
- /* LTE Positioning Profile configuration is disable by default*/
- mGps_conf.LPP_PROFILE = 0;
- /*By default no positioning protocol is selected on A-GLONASS system*/
- mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0;
- /*XTRA version check is disabled by default*/
- mGps_conf.XTRA_VERSION_CHECK=0;
- /*Use emergency PDN by default*/
- mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = 1;
- /* By default no LPPe CP technology is enabled*/
- mGps_conf.LPPE_CP_TECHNOLOGY = 0;
- /* By default no LPPe UP technology is enabled*/
- mGps_conf.LPPE_UP_TECHNOLOGY = 0;
-
- /*Defaults for sap.conf*/
- mSap_conf.GYRO_BIAS_RANDOM_WALK = 0;
- mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
- mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
- mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
- mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
- mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4;
- mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25;
- mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4;
- mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25;
- mSap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
- mSap_conf.SENSOR_USAGE = 0; /* Enabled */
- mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK = 0; /* INS Disabled = FALSE*/
- /* Values MUST be set by OEMs in configuration for sensor-assisted
- navigation to work. There are NO default values */
- mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0;
- mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
- mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
- mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0;
- mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
- mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
- mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
- mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
- mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
- /* default provider is SSC */
- mSap_conf.SENSOR_PROVIDER = 1;
-
- /* None of the 10 slots for agps certificates are writable by default */
- mGps_conf.AGPS_CERT_WRITABLE_MASK = 0;
-
- /* inject supl config to modem with config values from config.xml or gps.conf, default 1 */
- mGps_conf.AGPS_CONFIG_INJECT = 1;
-
- UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table);
- UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table);
+ static bool confReadDone = false;
+ if (!confReadDone) {
+ confReadDone = true;
+ /*Defaults for gps.conf*/
+ mGps_conf.INTERMEDIATE_POS = 0;
+ mGps_conf.ACCURACY_THRES = 0;
+ mGps_conf.NMEA_PROVIDER = 0;
+ mGps_conf.GPS_LOCK = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
+ mGps_conf.SUPL_VER = 0x10000;
+ mGps_conf.SUPL_MODE = 0x1;
+ mGps_conf.SUPL_ES = 0;
+ mGps_conf.CP_MTLR_ES = 0;
+ mGps_conf.SUPL_HOST[0] = 0;
+ mGps_conf.SUPL_PORT = 0;
+ mGps_conf.CAPABILITIES = 0x7;
+ /* LTE Positioning Profile configuration is disable by default*/
+ mGps_conf.LPP_PROFILE = 0;
+ /*By default no positioning protocol is selected on A-GLONASS system*/
+ mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT = 0;
+ /*XTRA version check is disabled by default*/
+ mGps_conf.XTRA_VERSION_CHECK=0;
+ /*Use emergency PDN by default*/
+ mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = 1;
+ /* By default no LPPe CP technology is enabled*/
+ mGps_conf.LPPE_CP_TECHNOLOGY = 0;
+ /* By default no LPPe UP technology is enabled*/
+ mGps_conf.LPPE_UP_TECHNOLOGY = 0;
+ /* By default we use unknown modem type*/
+ mGps_conf.MODEM_TYPE = 2;
+
+ /*Defaults for sap.conf*/
+ mSap_conf.GYRO_BIAS_RANDOM_WALK = 0;
+ mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC = 2;
+ mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH = 5;
+ mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC = 2;
+ mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH = 5;
+ mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH = 4;
+ mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH = 25;
+ mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH = 4;
+ mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH = 25;
+ mSap_conf.SENSOR_CONTROL_MODE = 0; /* AUTO */
+ mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK = 0; /* INS Disabled = FALSE*/
+ /* Values MUST be set by OEMs in configuration for sensor-assisted
+ navigation to work. There are NO default values */
+ mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY = 0;
+ mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID = 0;
+ mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+ mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID = 0;
+
+ /* None of the 10 slots for agps certificates are writable by default */
+ mGps_conf.AGPS_CERT_WRITABLE_MASK = 0;
+
+ /* inject supl config to modem with config values from config.xml or gps.conf, default 1 */
+ mGps_conf.AGPS_CONFIG_INJECT = 1;
+
+ /* default configuration value of constrained time uncertainty mode:
+ feature disabled, time uncertainty threshold defined by modem,
+ and unlimited power budget */
+#ifdef FEATURE_AUTOMOTIVE
+ mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED = 1;
+#else
+ mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED = 0;
+#endif
+ mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD = 0.0;
+ mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET = 0;
+
+ /* default configuration value of position assisted clock estimator mode */
+ mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED = 0;
+ /* default configuration QTI GNSS H/W */
+ mGps_conf.GNSS_DEPLOYMENT = 0;
+ mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0;
+
+ UTIL_READ_CONF(LOC_PATH_GPS_CONF, mGps_conf_table);
+ UTIL_READ_CONF(LOC_PATH_SAP_CONF, mSap_conf_table);
+
+ LOC_LOGI("%s] GNSS Deployment: %s", __FUNCTION__,
+ ((mGps_conf.GNSS_DEPLOYMENT == 1) ? "SS5" :
+ ((mGps_conf.GNSS_DEPLOYMENT == 2) ? "QFUSION" : "QGNSS")));
+
+ switch (getTargetGnssType(loc_get_target())) {
+ case GNSS_GSS:
+ case GNSS_AUTO:
+ // For APQ targets, MSA/MSB capabilities should be reset
+ mGps_conf.CAPABILITIES &= ~(LOC_GPS_CAPABILITY_MSA | LOC_GPS_CAPABILITY_MSB);
+ break;
+ default:
+ break;
+ }
+ }
}
uint32_t ContextBase::getCarrierCapabilities() {
@@ -197,20 +255,25 @@ LBSProxyBase* ContextBase::getLBSProxy(const char* libName)
LocApiBase* ContextBase::createLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask)
{
LocApiBase* locApi = NULL;
+ const char* libname = LOC_APIV2_0_LIB_NAME;
// Check the target
if (TARGET_NO_GNSS != loc_get_target()){
- if (NULL == (locApi = mLBSProxy->getLocApi(mMsgTask, exMask, this))) {
+ if (NULL == (locApi = mLBSProxy->getLocApi(exMask, this))) {
void *handle = NULL;
- //try to see if LocApiV02 is present
- if ((handle = dlopen("libloc_api_v02.so", RTLD_NOW)) != NULL) {
- LOC_LOGD("%s:%d]: libloc_api_v02.so is present", __func__, __LINE__);
+
+ if (IS_SS5_HW_ENABLED == mGps_conf.GNSS_DEPLOYMENT) {
+ libname = SLL_LOC_API_LIB_NAME;
+ }
+
+ if ((handle = dlopen(libname, RTLD_NOW)) != NULL) {
+ LOC_LOGD("%s:%d]: %s is present", __func__, __LINE__, libname);
getLocApi_t* getter = (getLocApi_t*) dlsym(handle, "getLocApi");
if (getter != NULL) {
- LOC_LOGD("%s:%d]: getter is not NULL for LocApiV02", __func__,
- __LINE__);
- locApi = (*getter)(mMsgTask, exMask, this);
+ LOC_LOGD("%s:%d]: getter is not NULL of %s", __func__,
+ __LINE__, libname);
+ locApi = (*getter)(exMask, this);
}
}
// only RPC is the option now
@@ -223,7 +286,7 @@ LocApiBase* ContextBase::createLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask)
if (NULL != getter) {
LOC_LOGD("%s:%d]: getter is not NULL in RPC", __func__,
__LINE__);
- locApi = (*getter)(mMsgTask, exMask, this);
+ locApi = (*getter)(exMask, this);
}
}
}
@@ -233,7 +296,7 @@ LocApiBase* ContextBase::createLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask)
// locApi could still be NULL at this time
// we would then create a dummy one
if (NULL == locApi) {
- locApi = new LocApiBase(mMsgTask, exMask, this);
+ locApi = new LocApiBase(exMask, this);
}
return locApi;
@@ -249,4 +312,33 @@ ContextBase::ContextBase(const MsgTask* msgTask,
{
}
+void ContextBase::setEngineCapabilities(uint64_t supportedMsgMask,
+ uint8_t *featureList, bool gnssMeasurementSupported) {
+
+ if (ContextBase::sIsEngineCapabilitiesKnown == false) {
+ ContextBase::sSupportedMsgMask = supportedMsgMask;
+ ContextBase::sGnssMeasurementSupported = gnssMeasurementSupported;
+ if (featureList != NULL) {
+ memcpy((void *)ContextBase::sFeaturesSupported,
+ (void *)featureList, sizeof(ContextBase::sFeaturesSupported));
+ }
+
+ ContextBase::sIsEngineCapabilitiesKnown = true;
+ }
+}
+
+
+bool ContextBase::isFeatureSupported(uint8_t featureVal)
+{
+ uint8_t arrayIndex = featureVal >> 3;
+ uint8_t bitPos = featureVal & 7;
+
+ if (arrayIndex >= MAX_FEATURE_LENGTH) return false;
+ return ((ContextBase::sFeaturesSupported[arrayIndex] >> bitPos ) & 0x1);
+}
+
+bool ContextBase::gnssConstellationConfig() {
+ return sGnssMeasurementSupported;
+}
+
}
diff --git a/gps/core/ContextBase.h b/gps/core/ContextBase.h
index dc64b6a..6701600 100644
--- a/gps/core/ContextBase.h
+++ b/gps/core/ContextBase.h
@@ -36,9 +36,6 @@
#include <LBSProxyBase.h>
#include <loc_cfg.h>
-#define MAX_XTRA_SERVER_URL_LENGTH (256)
-#define MAX_SUPL_SERVER_URL_LENGTH (256)
-
/* GPS.conf support */
/* NOTE: the implementaiton of the parser casts number
fields to 32 bit. To ensure all 'n' fields working,
@@ -53,20 +50,31 @@ typedef struct loc_gps_cfg_s
uint32_t CAPABILITIES;
uint32_t LPP_PROFILE;
uint32_t XTRA_VERSION_CHECK;
- char XTRA_SERVER_1[MAX_XTRA_SERVER_URL_LENGTH];
- char XTRA_SERVER_2[MAX_XTRA_SERVER_URL_LENGTH];
- char XTRA_SERVER_3[MAX_XTRA_SERVER_URL_LENGTH];
+ char XTRA_SERVER_1[LOC_MAX_PARAM_STRING];
+ char XTRA_SERVER_2[LOC_MAX_PARAM_STRING];
+ char XTRA_SERVER_3[LOC_MAX_PARAM_STRING];
uint32_t USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL;
uint32_t NMEA_PROVIDER;
- uint32_t GPS_LOCK;
+ GnssConfigGpsLock GPS_LOCK;
uint32_t A_GLONASS_POS_PROTOCOL_SELECT;
uint32_t AGPS_CERT_WRITABLE_MASK;
uint32_t AGPS_CONFIG_INJECT;
uint32_t LPPE_CP_TECHNOLOGY;
uint32_t LPPE_UP_TECHNOLOGY;
uint32_t EXTERNAL_DR_ENABLED;
- char SUPL_HOST[MAX_SUPL_SERVER_URL_LENGTH];
+ char SUPL_HOST[LOC_MAX_PARAM_STRING];
uint32_t SUPL_PORT;
+ uint32_t MODEM_TYPE;
+ char MO_SUPL_HOST[LOC_MAX_PARAM_STRING];
+ uint32_t MO_SUPL_PORT;
+ uint32_t CONSTRAINED_TIME_UNCERTAINTY_ENABLED;
+ double CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD;
+ uint32_t CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET;
+ uint32_t POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED;
+ char PROXY_APP_PACKAGE_NAME[LOC_MAX_PARAM_STRING];
+ uint32_t CP_MTLR_ES;
+ uint32_t GNSS_DEPLOYMENT;
+ uint32_t CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED;
} loc_gps_cfg_s_type;
/* NOTE: the implementaiton of the parser casts number
@@ -89,7 +97,6 @@ typedef struct
uint32_t SENSOR_GYRO_BATCHES_PER_SEC_HIGH;
uint32_t SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH;
uint32_t SENSOR_CONTROL_MODE;
- uint32_t SENSOR_USAGE;
uint32_t SENSOR_ALGORITHM_CONFIG_MASK;
uint8_t ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
double ACCEL_RANDOM_WALK_SPECTRAL_DENSITY;
@@ -99,7 +106,6 @@ typedef struct
double RATE_RANDOM_WALK_SPECTRAL_DENSITY;
uint8_t VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID;
double VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY;
- uint32_t SENSOR_PROVIDER;
} loc_sap_cfg_s_type;
namespace loc_core {
@@ -116,23 +122,28 @@ protected:
const MsgTask* mMsgTask;
LocApiBase* mLocApi;
LocApiProxyBase *mLocApiProxy;
+
public:
ContextBase(const MsgTask* msgTask,
LOC_API_ADAPTER_EVENT_MASK_T exMask,
const char* libName);
- inline virtual ~ContextBase() { delete mLocApi; delete mLBSProxy; }
+ inline virtual ~ContextBase() {
+ if (nullptr != mLocApi) {
+ mLocApi->destroy();
+ mLocApi = nullptr;
+ }
+ if (nullptr != mLBSProxy) {
+ delete mLBSProxy;
+ mLBSProxy = nullptr;
+ }
+ }
inline const MsgTask* getMsgTask() { return mMsgTask; }
inline LocApiBase* getLocApi() { return mLocApi; }
inline LocApiProxyBase* getLocApiProxy() { return mLocApiProxy; }
inline bool hasAgpsExtendedCapabilities() { return mLBSProxy->hasAgpsExtendedCapabilities(); }
- inline bool hasCPIExtendedCapabilities() { return mLBSProxy->hasCPIExtendedCapabilities(); }
inline bool hasNativeXtraClient() { return mLBSProxy->hasNativeXtraClient(); }
inline void modemPowerVote(bool power) const { return mLBSProxy->modemPowerVote(power); }
- inline void requestUlp(LocAdapterBase* adapter,
- unsigned long capabilities) {
- mLBSProxy->requestUlp(adapter, capabilities);
- }
inline IzatDevId_t getIzatDevId() const {
return mLBSProxy->getIzatDevId();
}
@@ -140,12 +151,111 @@ public:
static loc_gps_cfg_s_type mGps_conf;
static loc_sap_cfg_s_type mSap_conf;
+ static bool sIsEngineCapabilitiesKnown;
+ static uint64_t sSupportedMsgMask;
+ static uint8_t sFeaturesSupported[MAX_FEATURE_LENGTH];
+ static bool sGnssMeasurementSupported;
void readConfig();
static uint32_t getCarrierCapabilities();
+ void setEngineCapabilities(uint64_t supportedMsgMask,
+ uint8_t *featureList, bool gnssMeasurementSupported);
+
+ static inline bool isEngineCapabilitiesKnown() {
+ return sIsEngineCapabilitiesKnown;
+ }
+
+ static inline bool isMessageSupported(LocCheckingMessagesID msgID) {
+
+ // confirm if msgID is not larger than the number of bits in
+ // mSupportedMsg
+ if ((uint64_t)msgID > (sizeof(sSupportedMsgMask) << 3)) {
+ return false;
+ } else {
+ uint32_t messageChecker = 1 << msgID;
+ return (messageChecker & sSupportedMsgMask) == messageChecker;
+ }
+ }
+
+ /*
+ Check if a feature is supported
+ */
+ static bool isFeatureSupported(uint8_t featureVal);
+
+ /*
+ Check if gnss measurement is supported
+ */
+ static bool gnssConstellationConfig();
};
+struct LocApiResponse: LocMsg {
+ private:
+ ContextBase& mContext;
+ std::function<void (LocationError err)> mProcImpl;
+ inline virtual void proc() const {
+ mProcImpl(mLocationError);
+ }
+ protected:
+ LocationError mLocationError;
+ public:
+ inline LocApiResponse(ContextBase& context,
+ std::function<void (LocationError err)> procImpl ) :
+ mContext(context), mProcImpl(procImpl) {}
+
+ void returnToSender(const LocationError err) {
+ mLocationError = err;
+ mContext.sendMsg(this);
+ }
+};
+
+struct LocApiCollectiveResponse: LocMsg {
+ private:
+ ContextBase& mContext;
+ std::function<void (std::vector<LocationError> errs)> mProcImpl;
+ inline virtual void proc() const {
+ mProcImpl(mLocationErrors);
+ }
+ protected:
+ std::vector<LocationError> mLocationErrors;
+ public:
+ inline LocApiCollectiveResponse(ContextBase& context,
+ std::function<void (std::vector<LocationError> errs)> procImpl ) :
+ mContext(context), mProcImpl(procImpl) {}
+ inline virtual ~LocApiCollectiveResponse() {
+ }
+
+ void returnToSender(std::vector<LocationError>& errs) {
+ mLocationErrors = errs;
+ mContext.sendMsg(this);
+ }
+};
+
+
+template <typename DATA>
+struct LocApiResponseData: LocMsg {
+ private:
+ ContextBase& mContext;
+ std::function<void (LocationError err, DATA data)> mProcImpl;
+ inline virtual void proc() const {
+ mProcImpl(mLocationError, mData);
+ }
+ protected:
+ LocationError mLocationError;
+ DATA mData;
+ public:
+ inline LocApiResponseData(ContextBase& context,
+ std::function<void (LocationError err, DATA data)> procImpl ) :
+ mContext(context), mProcImpl(procImpl) {}
+
+ void returnToSender(const LocationError err, const DATA data) {
+ mLocationError = err;
+ mData = data;
+ mContext.sendMsg(this);
+ }
+};
+
+
} // namespace loc_core
#endif //__LOC_CONTEXT_BASE__
diff --git a/gps/core/EngineHubProxyBase.h b/gps/core/EngineHubProxyBase.h
new file mode 100644
index 0000000..ec881f6
--- /dev/null
+++ b/gps/core/EngineHubProxyBase.h
@@ -0,0 +1,127 @@
+/* Copyright (c) 2018, 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 ENGINE_HUB_PROXY_BASE_H
+#define ENGINE_HUB_PROXY_BASE_H
+
+namespace loc_core {
+
+class EngineHubProxyBase {
+public:
+ inline EngineHubProxyBase() {
+ }
+ inline virtual ~EngineHubProxyBase() {}
+
+ // gnss session related functions
+ inline virtual bool gnssStartFix() {
+ return false;
+ }
+
+ inline virtual bool gnssStopFix() {
+ return false;
+ }
+
+ inline virtual bool gnssSetFixMode(const LocPosMode &params) {
+ (void) params;
+ return false;
+ }
+
+ inline virtual bool gnssDeleteAidingData(const GnssAidingData &aidingData) {
+ (void) aidingData;
+ return false;
+ }
+
+ // GNSS reports
+ inline virtual bool gnssReportPosition(const UlpLocation &location,
+ const GpsLocationExtended &locationExtended,
+ enum loc_sess_status status) {
+ (void) location;
+ (void) locationExtended;
+ (void) status;
+ return false;
+ }
+
+ inline virtual bool gnssReportSv(const GnssSvNotification& svNotify) {
+ (void) svNotify;
+ return false;
+ }
+
+ inline virtual bool gnssReportSvMeasurement(const GnssSvMeasurementSet& svMeasurementSet) {
+ (void) svMeasurementSet;
+ return false;
+ }
+
+ inline virtual bool gnssReportSvPolynomial(const GnssSvPolynomial& svPolynomial) {
+ (void) svPolynomial;
+ return false;
+ }
+
+ inline virtual bool gnssReportSvEphemeris(const GnssSvEphemerisReport& svEphemeris) {
+ (void) svEphemeris;
+ return false;
+ }
+
+ inline virtual bool gnssReportSystemInfo(const LocationSystemInfo& systemInfo) {
+ (void) systemInfo;
+ return false;
+ }
+
+ inline virtual bool gnssReportKlobucharIonoModel(const GnssKlobucharIonoModel& ionoModel) {
+ (void) ionoModel;
+ return false;
+ }
+
+ inline virtual bool gnssReportAdditionalSystemInfo(
+ const GnssAdditionalSystemInfo& additionalSystemInfo) {
+ (void) additionalSystemInfo;
+ return false;
+ }
+};
+
+typedef std::function<void(int count, EngineLocationInfo* locationArr)>
+ GnssAdapterReportEnginePositionsEventCb;
+
+typedef std::function<void(const GnssSvNotification& svNotify,
+ bool fromEngineHub)>
+ GnssAdapterReportSvEventCb;
+
+typedef std::function<void(const GnssAidingDataSvMask& svDataMask)>
+ GnssAdapterReqAidingDataCb;
+
+// potential parameters: message queue: MsgTask * msgTask;
+// callback function to report back dr and ppe position and sv report
+typedef EngineHubProxyBase* (getEngHubProxyFn)(
+ const MsgTask * msgTask,
+ IOsObserver* osObserver,
+ GnssAdapterReportEnginePositionsEventCb positionEventCb,
+ GnssAdapterReportSvEventCb svEventCb,
+ GnssAdapterReqAidingDataCb reqAidingDataCb);
+
+} // namespace loc_core
+
+#endif // ENGINE_HUB_PROXY_BASE_H
diff --git a/gps/core/LBSProxyBase.h b/gps/core/LBSProxyBase.h
index 94ddd0f..564c60b 100644
--- a/gps/core/LBSProxyBase.h
+++ b/gps/core/LBSProxyBase.h
@@ -29,7 +29,6 @@
#ifndef IZAT_PROXY_BASE_H
#define IZAT_PROXY_BASE_H
#include <gps_extended.h>
-#include <MsgTask.h>
namespace loc_core {
@@ -40,11 +39,9 @@ class ContextBase;
class LBSProxyBase {
friend class ContextBase;
inline virtual LocApiBase*
- getLocApi(const MsgTask* msgTask,
- LOC_API_ADAPTER_EVENT_MASK_T exMask,
+ getLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask,
ContextBase* context) const {
- (void)msgTask;
(void)exMask;
(void)context;
return NULL;
@@ -53,14 +50,7 @@ protected:
inline LBSProxyBase() {}
public:
inline virtual ~LBSProxyBase() {}
- inline virtual void requestUlp(LocAdapterBase* adapter,
- unsigned long capabilities) const {
-
- (void)adapter;
- (void)capabilities;
- }
inline virtual bool hasAgpsExtendedCapabilities() const { return false; }
- inline virtual bool hasCPIExtendedCapabilities() const { return false; }
inline virtual void modemPowerVote(bool power) const {
(void)power;
diff --git a/gps/core/LocAdapterBase.cpp b/gps/core/LocAdapterBase.cpp
index d0da3da..1b844e5 100644
--- a/gps/core/LocAdapterBase.cpp
+++ b/gps/core/LocAdapterBase.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2017The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2019 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
@@ -42,10 +42,12 @@ namespace loc_core {
// But if getLocApi(targetEnumType target) is overriden,
// the right locApi should get created.
LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
- ContextBase* context, LocAdapterProxyBase *adapterProxyBase) :
- mEvtMask(mask), mContext(context),
+ ContextBase* context, bool isMaster,
+ LocAdapterProxyBase *adapterProxyBase) :
+ mIsMaster(isMaster), mEvtMask(mask), mContext(context),
mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase),
- mMsgTask(context->getMsgTask())
+ mMsgTask(context->getMsgTask()),
+ mIsEngineCapabilitiesKnown(ContextBase::sIsEngineCapabilitiesKnown)
{
mLocApi->addAdapter(this);
}
@@ -79,7 +81,9 @@ void LocAdapterBase::
const GpsLocationExtended& locationExtended,
enum loc_sess_status status,
LocPosTechMask loc_technology_mask,
- bool /*fromUlp*/) {
+ GnssDataNotification* pDataNotify,
+ int msInWeek)
+{
if (mLocAdapterProxyBase != NULL) {
mLocAdapterProxyBase->reportPositionEvent((UlpLocation&)location,
(GpsLocationExtended&)locationExtended,
@@ -91,24 +95,31 @@ void LocAdapterBase::
}
void LocAdapterBase::
- reportSvEvent(const GnssSvNotification& /*svNotify*/, bool /*fromUlp*/)
+ reportSvEvent(const GnssSvNotification& /*svNotify*/,
+ bool /*fromEngineHub*/)
DEFAULT_IMPL()
void LocAdapterBase::
- reportSvMeasurementEvent(GnssSvMeasurementSet &/*svMeasurementSet*/)
+ reportSvPolynomialEvent(GnssSvPolynomial &/*svPolynomial*/)
DEFAULT_IMPL()
void LocAdapterBase::
- reportSvPolynomialEvent(GnssSvPolynomial &/*svPolynomial*/)
+ reportSvEphemerisEvent(GnssSvEphemerisReport &/*svEphemeris*/)
DEFAULT_IMPL()
+
void LocAdapterBase::
reportStatus(LocGpsStatusValue /*status*/)
DEFAULT_IMPL()
void LocAdapterBase::
- reportNmeaEvent(const char* /*nmea*/, size_t /*length*/, bool /*fromUlp*/)
+ reportNmeaEvent(const char* /*nmea*/, size_t /*length*/)
+DEFAULT_IMPL()
+
+void LocAdapterBase::
+ reportDataEvent(const GnssDataNotification& /*dataNotify*/,
+ int /*msInWeek*/)
DEFAULT_IMPL()
bool LocAdapterBase::
@@ -116,6 +127,10 @@ bool LocAdapterBase::
const char* /*url3*/, const int /*maxlength*/)
DEFAULT_IMPL(false)
+void LocAdapterBase::
+ reportLocationSystemInfoEvent(const LocationSystemInfo& /*locationSystemInfo*/)
+DEFAULT_IMPL()
+
bool LocAdapterBase::
requestXtraData()
DEFAULT_IMPL(false)
@@ -129,7 +144,8 @@ bool LocAdapterBase::
DEFAULT_IMPL(false)
bool LocAdapterBase::
- requestATL(int /*connHandle*/, LocAGpsType /*agps_type*/)
+ requestATL(int /*connHandle*/, LocAGpsType /*agps_type*/,
+ LocApnTypeMask /*apn_type_mask*/)
DEFAULT_IMPL(false)
bool LocAdapterBase::
@@ -137,32 +153,259 @@ bool LocAdapterBase::
DEFAULT_IMPL(false)
bool LocAdapterBase::
- requestSuplES(int /*connHandle*/)
+ requestNiNotifyEvent(const GnssNiNotification &/*notify*/,
+ const void* /*data*/,
+ const LocInEmergency emergencyState)
DEFAULT_IMPL(false)
+void LocAdapterBase::
+reportGnssMeasurementsEvent(const GnssMeasurements& /*gnssMeasurements*/,
+ int /*msInWeek*/)
+DEFAULT_IMPL()
+
bool LocAdapterBase::
- reportDataCallOpened()
+ reportWwanZppFix(LocGpsLocation &/*zppLoc*/)
DEFAULT_IMPL(false)
bool LocAdapterBase::
- reportDataCallClosed()
+ reportZppBestAvailableFix(LocGpsLocation& /*zppLoc*/,
+ GpsLocationExtended& /*location_extended*/, LocPosTechMask /*tech_mask*/)
DEFAULT_IMPL(false)
+void LocAdapterBase::reportGnssSvIdConfigEvent(const GnssSvIdConfig& /*config*/)
+DEFAULT_IMPL()
+
+void LocAdapterBase::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& /*config*/)
+DEFAULT_IMPL()
+
bool LocAdapterBase::
- requestNiNotifyEvent(const GnssNiNotification &/*notify*/, const void* /*data*/)
+ requestOdcpiEvent(OdcpiRequestInfo& /*request*/)
DEFAULT_IMPL(false)
-void LocAdapterBase::
- reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& /*measurements*/,
- int /*msInWeek*/)
-DEFAULT_IMPL()
+bool LocAdapterBase::
+ reportGnssEngEnergyConsumedEvent(uint64_t /*energyConsumedSinceFirstBoot*/)
+DEFAULT_IMPL(false)
bool LocAdapterBase::
- reportWwanZppFix(LocGpsLocation &/*zppLoc*/)
+ reportDeleteAidingDataEvent(GnssAidingData & /*aidingData*/)
DEFAULT_IMPL(false)
bool LocAdapterBase::
- reportOdcpiRequestEvent(OdcpiRequestInfo& /*request*/)
+ reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& /*ionoModel*/)
DEFAULT_IMPL(false)
+bool LocAdapterBase::
+ reportGnssAdditionalSystemInfoEvent(GnssAdditionalSystemInfo& /*additionalSystemInfo*/)
+DEFAULT_IMPL(false)
+
+void LocAdapterBase::
+ reportNfwNotificationEvent(GnssNfwNotification& /*notification*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::geofenceBreachEvent(size_t /*count*/, uint32_t* /*hwIds*/, Location& /*location*/,
+ GeofenceBreachType /*breachType*/, uint64_t /*timestamp*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::geofenceStatusEvent(GeofenceStatusAvailable /*available*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::reportLocationsEvent(const Location* /*locations*/, size_t /*count*/,
+ BatchingMode /*batchingMode*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::reportCompletedTripsEvent(uint32_t /*accumulated_distance*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::reportBatchStatusChangeEvent(BatchingStatus /*batchStatus*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::reportPositionEvent(UlpLocation& /*location*/,
+ GpsLocationExtended& /*locationExtended*/,
+ enum loc_sess_status /*status*/,
+ LocPosTechMask /*loc_technology_mask*/)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::saveClient(LocationAPI* client, const LocationCallbacks& callbacks)
+{
+ mClientData[client] = callbacks;
+ updateClientsEventMask();
+}
+
+void
+LocAdapterBase::eraseClient(LocationAPI* client)
+{
+ auto it = mClientData.find(client);
+ if (it != mClientData.end()) {
+ mClientData.erase(it);
+ }
+ updateClientsEventMask();
+}
+
+LocationCallbacks
+LocAdapterBase::getClientCallbacks(LocationAPI* client)
+{
+ LocationCallbacks callbacks = {};
+ auto it = mClientData.find(client);
+ if (it != mClientData.end()) {
+ callbacks = it->second;
+ }
+ return callbacks;
+}
+
+LocationCapabilitiesMask
+LocAdapterBase::getCapabilities()
+{
+ LocationCapabilitiesMask mask = 0;
+
+ if (isEngineCapabilitiesKnown()) {
+ // time based tracking always supported
+ mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT;
+ if (ContextBase::isMessageSupported(
+ LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)){
+ mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT |
+ LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT;
+ }
+ if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
+ mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT;
+ }
+ if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) {
+ mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT;
+ }
+ // geofence always supported
+ mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT;
+ if (ContextBase::gnssConstellationConfig()) {
+ mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT;
+ }
+ uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities();
+ if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) {
+ mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT;
+ }
+ if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) {
+ mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
+ mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ mask |= LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) {
+ mask |= LOCATION_CAPABILITIES_AGPM_BIT;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_LOCATION_PRIVACY)) {
+ mask |= LOCATION_CAPABILITIES_PRIVACY_BIT;
+ }
+ } else {
+ LOC_LOGE("%s]: attempt to get capabilities before they are known.", __func__);
+ }
+
+ return mask;
+}
+
+void
+LocAdapterBase::broadcastCapabilities(LocationCapabilitiesMask mask)
+{
+ for (auto clientData : mClientData) {
+ if (nullptr != clientData.second.capabilitiesCb) {
+ clientData.second.capabilitiesCb(mask);
+ }
+ }
+}
+
+void
+LocAdapterBase::updateClientsEventMask()
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::stopClientSessions(LocationAPI* client)
+DEFAULT_IMPL()
+
+void
+LocAdapterBase::addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks)
+{
+ LOC_LOGD("%s]: client %p", __func__, client);
+
+ struct MsgAddClient : public LocMsg {
+ LocAdapterBase& mAdapter;
+ LocationAPI* mClient;
+ const LocationCallbacks mCallbacks;
+ inline MsgAddClient(LocAdapterBase& adapter,
+ LocationAPI* client,
+ const LocationCallbacks& callbacks) :
+ LocMsg(),
+ mAdapter(adapter),
+ mClient(client),
+ mCallbacks(callbacks) {}
+ inline virtual void proc() const {
+ mAdapter.saveClient(mClient, mCallbacks);
+ }
+ };
+
+ sendMsg(new MsgAddClient(*this, client, callbacks));
+}
+
+void
+LocAdapterBase::removeClientCommand(LocationAPI* client,
+ removeClientCompleteCallback rmClientCb)
+{
+ LOC_LOGD("%s]: client %p", __func__, client);
+
+ struct MsgRemoveClient : public LocMsg {
+ LocAdapterBase& mAdapter;
+ LocationAPI* mClient;
+ removeClientCompleteCallback mRmClientCb;
+ inline MsgRemoveClient(LocAdapterBase& adapter,
+ LocationAPI* client,
+ removeClientCompleteCallback rmCb) :
+ LocMsg(),
+ mAdapter(adapter),
+ mClient(client),
+ mRmClientCb(rmCb){}
+ inline virtual void proc() const {
+ mAdapter.stopClientSessions(mClient);
+ mAdapter.eraseClient(mClient);
+ if (nullptr != mRmClientCb) {
+ (mRmClientCb)(mClient);
+ }
+ }
+ };
+
+ sendMsg(new MsgRemoveClient(*this, client, rmClientCb));
+}
+
+void
+LocAdapterBase::requestCapabilitiesCommand(LocationAPI* client)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgRequestCapabilities : public LocMsg {
+ LocAdapterBase& mAdapter;
+ LocationAPI* mClient;
+ inline MsgRequestCapabilities(LocAdapterBase& adapter,
+ LocationAPI* client) :
+ LocMsg(),
+ mAdapter(adapter),
+ mClient(client) {}
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgRequestCapabilities(*this));
+ return;
+ }
+ LocationCallbacks callbacks = mAdapter.getClientCallbacks(mClient);
+ if (callbacks.capabilitiesCb != nullptr) {
+ callbacks.capabilitiesCb(mAdapter.getCapabilities());
+ }
+ }
+ };
+
+ sendMsg(new MsgRequestCapabilities(*this, client));
+}
+
} // namespace loc_core
diff --git a/gps/core/LocAdapterBase.h b/gps/core/LocAdapterBase.h
index 35fc48e..909b6fe 100644
--- a/gps/core/LocAdapterBase.h
+++ b/gps/core/LocAdapterBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2019 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
@@ -30,11 +30,12 @@
#define LOC_API_ADAPTER_BASE_H
#include <gps_extended.h>
-#include <UlpProxyBase.h>
#include <ContextBase.h>
#include <LocationAPI.h>
#include <map>
+#define MIN_TRACKING_INTERVAL (100) // 100 msec
+
typedef struct LocationSessionKey {
LocationAPI* client;
uint32_t id;
@@ -50,7 +51,8 @@ inline bool operator ==(LocationSessionKey const& left, LocationSessionKey const
inline bool operator !=(LocationSessionKey const& left, LocationSessionKey const& right) {
return left.id != right.id || left.client != right.client;
}
-typedef std::map<LocationSessionKey, LocationOptions> LocationSessionMap;
+
+typedef void (*removeClientCompleteCallback)(LocationAPI* client);
namespace loc_core {
@@ -59,6 +61,9 @@ class LocAdapterProxyBase;
class LocAdapterBase {
private:
static uint32_t mSessionIdCounter;
+ const bool mIsMaster;
+ bool mIsEngineCapabilitiesKnown = false;
+
protected:
LOC_API_ADAPTER_EVENT_MASK_T mEvtMask;
ContextBase* mContext;
@@ -66,12 +71,28 @@ protected:
LocAdapterProxyBase* mLocAdapterProxyBase;
const MsgTask* mMsgTask;
inline LocAdapterBase(const MsgTask* msgTask) :
- mEvtMask(0), mContext(NULL), mLocApi(NULL),
+ mIsMaster(false), mEvtMask(0), mContext(NULL), mLocApi(NULL),
mLocAdapterProxyBase(NULL), mMsgTask(msgTask) {}
+
+ /* ==== CLIENT ========================================================================= */
+ typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
+ ClientDataMap mClientData;
+ std::vector<LocMsg*> mPendingMsgs; // For temporal storage of msgs before Open is completed
+ /* ======== UTILITIES ================================================================== */
+ void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
+ void eraseClient(LocationAPI* client);
+ LocationCallbacks getClientCallbacks(LocationAPI* client);
+ LocationCapabilitiesMask getCapabilities();
+ void broadcastCapabilities(LocationCapabilitiesMask mask);
+ virtual void updateClientsEventMask();
+ virtual void stopClientSessions(LocationAPI* client);
+
public:
inline virtual ~LocAdapterBase() { mLocApi->removeAdapter(this); }
LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
- ContextBase* context, LocAdapterProxyBase *adapterProxyBase = NULL);
+ ContextBase* context, bool isMaster = false,
+ LocAdapterProxyBase *adapterProxyBase = NULL);
+
inline LOC_API_ADAPTER_EVENT_MASK_T
checkMask(LOC_API_ADAPTER_EVENT_MASK_T mask) const {
return mEvtMask & mask;
@@ -106,54 +127,94 @@ public:
mLocApi->updateEvtMask();
}
+ inline void updateNmeaMask(uint32_t mask)
+ {
+ mLocApi->updateNmeaMask(mask);
+ }
+
inline bool isFeatureSupported(uint8_t featureVal) {
- return mLocApi->isFeatureSupported(featureVal);
+ return ContextBase::isFeatureSupported(featureVal);
}
uint32_t generateSessionId();
- // This will be overridden by the individual adapters
- // if necessary.
- inline virtual void setUlpProxyCommand(UlpProxyBase* ulp) {
-
- (void)ulp;
+ inline bool isAdapterMaster() {
+ return mIsMaster;
}
+
+ inline bool isEngineCapabilitiesKnown() { return mIsEngineCapabilitiesKnown;}
+ inline void setEngineCapabilitiesKnown(bool value) { mIsEngineCapabilitiesKnown = value;}
+
virtual void handleEngineUpEvent();
virtual void handleEngineDownEvent();
- inline virtual void setPositionModeCommand(LocPosMode& posMode) {
-
- (void)posMode;
- }
- virtual void startTrackingCommand() {}
- virtual void stopTrackingCommand() {}
- virtual void getZppCommand() {}
virtual void reportPositionEvent(const UlpLocation& location,
const GpsLocationExtended& locationExtended,
enum loc_sess_status status,
LocPosTechMask loc_technology_mask,
- bool fromUlp=false);
- virtual void reportSvEvent(const GnssSvNotification& svNotify, bool fromUlp=false);
- virtual void reportNmeaEvent(const char* nmea, size_t length, bool fromUlp=false);
- virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
+ GnssDataNotification* pDataNotify = nullptr,
+ int msInWeek = -1);
+ virtual void reportEnginePositionsEvent(unsigned int count,
+ EngineLocationInfo* locationArr) {
+ (void)count;
+ (void)locationArr;
+ }
+ virtual void reportSvEvent(const GnssSvNotification& svNotify,
+ bool fromEngineHub=false);
+ virtual void reportDataEvent(const GnssDataNotification& dataNotify, int msInWeek);
+ virtual void reportNmeaEvent(const char* nmea, size_t length);
virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
+ virtual void reportSvEphemerisEvent(GnssSvEphemerisReport &svEphemeris);
virtual void reportStatus(LocGpsStatusValue status);
virtual bool reportXtraServer(const char* url1, const char* url2,
const char* url3, const int maxlength);
+ virtual void reportLocationSystemInfoEvent(const LocationSystemInfo& locationSystemInfo);
+
virtual bool requestXtraData();
virtual bool requestTime();
virtual bool requestLocation();
- virtual bool requestATL(int connHandle, LocAGpsType agps_type);
+ virtual bool requestATL(int connHandle, LocAGpsType agps_type,
+ LocApnTypeMask apn_type_mask);
virtual bool releaseATL(int connHandle);
- virtual bool requestSuplES(int connHandle);
- virtual bool reportDataCallOpened();
- virtual bool reportDataCallClosed();
- virtual bool requestNiNotifyEvent(const GnssNiNotification &notify, const void* data);
+ virtual bool requestNiNotifyEvent(const GnssNiNotification &notify, const void* data,
+ const LocInEmergency emergencyState);
inline virtual bool isInSession() { return false; }
ContextBase* getContext() const { return mContext; }
- virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
+ virtual void reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements,
int msInWeek);
virtual bool reportWwanZppFix(LocGpsLocation &zppLoc);
- virtual bool reportOdcpiRequestEvent(OdcpiRequestInfo& request);
+ virtual bool reportZppBestAvailableFix(LocGpsLocation &zppLoc,
+ GpsLocationExtended &location_extended, LocPosTechMask tech_mask);
+ virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
+ virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config);
+ virtual bool requestOdcpiEvent(OdcpiRequestInfo& request);
+ virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot);
+ virtual bool reportDeleteAidingDataEvent(GnssAidingData &aidingData);
+ virtual bool reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& ionoModel);
+ virtual bool reportGnssAdditionalSystemInfoEvent(
+ GnssAdditionalSystemInfo& additionalSystemInfo);
+ virtual void reportNfwNotificationEvent(GnssNfwNotification& notification);
+
+ virtual void geofenceBreachEvent(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp);
+ virtual void geofenceStatusEvent(GeofenceStatusAvailable available);
+
+ virtual void reportPositionEvent(UlpLocation &location,
+ GpsLocationExtended &locationExtended,
+ enum loc_sess_status status,
+ LocPosTechMask loc_technology_mask);
+
+ virtual void reportLocationsEvent(const Location* locations, size_t count,
+ BatchingMode batchingMode);
+ virtual void reportCompletedTripsEvent(uint32_t accumulated_distance);
+ virtual void reportBatchStatusChangeEvent(BatchingStatus batchStatus);
+
+ /* ==== CLIENT ========================================================================= */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
+ void removeClientCommand(LocationAPI* client,
+ removeClientCompleteCallback rmClientCb);
+ void requestCapabilitiesCommand(LocationAPI* client);
+
};
} // namespace loc_core
diff --git a/gps/core/LocAdapterProxyBase.h b/gps/core/LocAdapterProxyBase.h
index 044f59b..727d424 100644
--- a/gps/core/LocAdapterProxyBase.h
+++ b/gps/core/LocAdapterProxyBase.h
@@ -40,8 +40,8 @@ private:
LocAdapterBase *mLocAdapterBase;
protected:
inline LocAdapterProxyBase(const LOC_API_ADAPTER_EVENT_MASK_T mask,
- ContextBase* context):
- mLocAdapterBase(new LocAdapterBase(mask, context, this)) {
+ ContextBase* context, bool isMaster = false):
+ mLocAdapterBase(new LocAdapterBase(mask, context, isMaster, this)) {
}
inline virtual ~LocAdapterProxyBase() {
delete mLocAdapterBase;
@@ -65,7 +65,6 @@ public:
GpsLocationExtended &locationExtended,
enum loc_sess_status status,
LocPosTechMask loc_technology_mask) {
-
(void)location;
(void)locationExtended;
(void)status;
diff --git a/gps/core/LocApiBase.cpp b/gps/core/LocApiBase.cpp
index 426335d..8c79cf7 100644
--- a/gps/core/LocApiBase.cpp
+++ b/gps/core/LocApiBase.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2019 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
@@ -31,10 +31,11 @@
#include <dlfcn.h>
#include <inttypes.h>
+#include <gps_extended_c.h>
#include <LocApiBase.h>
#include <LocAdapterBase.h>
#include <log_util.h>
-#include <LocDualContext.h>
+#include <LocContext.h>
namespace loc_core {
@@ -95,7 +96,10 @@ struct LocSsrMsg : public LocMsg {
}
inline virtual void proc() const {
mLocApi->close();
- mLocApi->open(mLocApi->getEvtMask());
+ if (LOC_API_ADAPTER_ERR_SUCCESS == mLocApi->open(mLocApi->getEvtMask())) {
+ // Notify adapters that engine up after SSR
+ mLocApi->handleEngineUpEvent();
+ }
}
inline void locallog() const {
LOC_LOGV("LocSsrMsg");
@@ -107,13 +111,17 @@ struct LocSsrMsg : public LocMsg {
struct LocOpenMsg : public LocMsg {
LocApiBase* mLocApi;
- inline LocOpenMsg(LocApiBase* locApi) :
- LocMsg(), mLocApi(locApi)
+ LocAdapterBase* mAdapter;
+ inline LocOpenMsg(LocApiBase* locApi, LocAdapterBase* adapter = nullptr) :
+ LocMsg(), mLocApi(locApi), mAdapter(adapter)
{
locallog();
}
inline virtual void proc() const {
- mLocApi->open(mLocApi->getEvtMask());
+ if (LOC_API_ADAPTER_ERR_SUCCESS == mLocApi->open(mLocApi->getEvtMask()) &&
+ nullptr != mAdapter) {
+ mAdapter->handleEngineUpEvent();
+ }
}
inline void locallog() const {
LOC_LOGv("LocOpen Mask: %" PRIx64 "\n", mLocApi->getEvtMask());
@@ -123,14 +131,37 @@ struct LocOpenMsg : public LocMsg {
}
};
-LocApiBase::LocApiBase(const MsgTask* msgTask,
- LOC_API_ADAPTER_EVENT_MASK_T excludedMask,
+struct LocCloseMsg : public LocMsg {
+ LocApiBase* mLocApi;
+ inline LocCloseMsg(LocApiBase* locApi) :
+ LocMsg(), mLocApi(locApi)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mLocApi->close();
+ }
+ inline void locallog() const {
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+};
+
+MsgTask* LocApiBase::mMsgTask = nullptr;
+volatile int32_t LocApiBase::mMsgTaskRefCount = 0;
+
+LocApiBase::LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask,
ContextBase* context) :
- mMsgTask(msgTask), mContext(context), mSupportedMsg(0),
+ mContext(context),
mMask(0), mExcludedMask(excludedMask)
{
memset(mLocAdapters, 0, sizeof(mLocAdapters));
- memset(mFeaturesSupported, 0, sizeof(mFeaturesSupported));
+
+ android_atomic_inc(&mMsgTaskRefCount);
+ if (nullptr == mMsgTask) {
+ mMsgTask = new MsgTask("LocApiMsgTask", false);
+ }
}
LOC_API_ADAPTER_EVENT_MASK_T LocApiBase::getEvtMask()
@@ -142,6 +173,18 @@ LOC_API_ADAPTER_EVENT_MASK_T LocApiBase::getEvtMask()
return mask & ~mExcludedMask;
}
+bool LocApiBase::isMaster()
+{
+ bool isMaster = false;
+
+ for (int i = 0;
+ !isMaster && i < MAX_ADAPTERS && NULL != mLocAdapters[i];
+ i++) {
+ isMaster |= mLocAdapters[i]->isAdapterMaster();
+ }
+ return isMaster;
+}
+
bool LocApiBase::isInSession()
{
bool inSession = false;
@@ -155,12 +198,41 @@ bool LocApiBase::isInSession()
return inSession;
}
+bool LocApiBase::needReport(const UlpLocation& ulpLocation,
+ enum loc_sess_status status,
+ LocPosTechMask techMask)
+{
+ bool reported = false;
+
+ if (LOC_SESS_SUCCESS == status) {
+ // this is a final fix
+ LocPosTechMask mask =
+ LOC_POS_TECH_MASK_SATELLITE | LOC_POS_TECH_MASK_SENSORS | LOC_POS_TECH_MASK_HYBRID;
+ // it is a Satellite fix or a sensor fix
+ reported = (mask & techMask);
+ }
+ else if (LOC_SESS_INTERMEDIATE == status &&
+ LOC_SESS_INTERMEDIATE == ContextBase::mGps_conf.INTERMEDIATE_POS) {
+ // this is a intermediate fix and we accept intermediate
+
+ // it is NOT the case that
+ // there is inaccuracy; and
+ // we care about inaccuracy; and
+ // the inaccuracy exceeds our tolerance
+ reported = !((ulpLocation.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ACCURACY) &&
+ (ContextBase::mGps_conf.ACCURACY_THRES != 0) &&
+ (ulpLocation.gpsLocation.accuracy > ContextBase::mGps_conf.ACCURACY_THRES));
+ }
+
+ return reported;
+}
+
void LocApiBase::addAdapter(LocAdapterBase* adapter)
{
for (int i = 0; i < MAX_ADAPTERS && mLocAdapters[i] != adapter; i++) {
if (mLocAdapters[i] == NULL) {
mLocAdapters[i] = adapter;
- mMsgTask->sendMsg(new LocOpenMsg(this));
+ sendMsg(new LocOpenMsg(this, adapter));
break;
}
}
@@ -193,10 +265,10 @@ void LocApiBase::removeAdapter(LocAdapterBase* adapter)
// if we have an empty list of adapters
if (0 == i) {
- close();
+ sendMsg(new LocCloseMsg(this));
} else {
// else we need to remove the bit
- mMsgTask->sendMsg(new LocOpenMsg(this));
+ sendMsg(new LocOpenMsg(this));
}
}
}
@@ -204,22 +276,43 @@ void LocApiBase::removeAdapter(LocAdapterBase* adapter)
void LocApiBase::updateEvtMask()
{
- open(getEvtMask());
+ sendMsg(new LocOpenMsg(this));
}
-void LocApiBase::handleEngineUpEvent()
+void LocApiBase::updateNmeaMask(uint32_t mask)
{
- // This will take care of renegotiating the loc handle
- mMsgTask->sendMsg(new LocSsrMsg(this));
+ struct LocSetNmeaMsg : public LocMsg {
+ LocApiBase* mLocApi;
+ uint32_t mMask;
+ inline LocSetNmeaMsg(LocApiBase* locApi, uint32_t mask) :
+ LocMsg(), mLocApi(locApi), mMask(mask)
+ {
+ locallog();
+ }
+ inline virtual void proc() const {
+ mLocApi->setNMEATypesSync(mMask);
+ }
+ inline void locallog() const {
+ LOC_LOGv("LocSyncNmea NmeaMask: %" PRIx32 "\n", mMask);
+ }
+ inline virtual void log() const {
+ locallog();
+ }
+ };
- LocDualContext::injectFeatureConfig(mContext);
+ sendMsg(new LocSetNmeaMsg(this, mask));
+}
+void LocApiBase::handleEngineUpEvent()
+{
// loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(mLocAdapters[i]->handleEngineUpEvent());
}
void LocApiBase::handleEngineDownEvent()
-{
+{ // This will take care of renegotiating the loc handle
+ sendMsg(new LocSsrMsg(this));
+
// loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(mLocAdapters[i]->handleEngineDownEvent());
}
@@ -227,21 +320,22 @@ void LocApiBase::handleEngineDownEvent()
void LocApiBase::reportPosition(UlpLocation& location,
GpsLocationExtended& locationExtended,
enum loc_sess_status status,
- LocPosTechMask loc_technology_mask)
+ LocPosTechMask loc_technology_mask,
+ GnssDataNotification* pDataNotify,
+ int msInWeek)
{
// print the location info before delivering
LOC_LOGD("flags: %d\n source: %d\n latitude: %f\n longitude: %f\n "
"altitude: %f\n speed: %f\n bearing: %f\n accuracy: %f\n "
- "timestamp: %" PRId64 "\n rawDataSize: %d\n rawData: %p\n "
+ "timestamp: %" PRId64 "\n"
"Session status: %d\n Technology mask: %u\n "
"SV used in fix (gps/glo/bds/gal/qzss) : \
- (%" PRIx64 "/%" PRIx64 "/%" PRIx64 "/%" PRIx64 "/%" PRIx64 ")",
+ (0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 "/0x%" PRIx64 ")",
location.gpsLocation.flags, location.position_source,
location.gpsLocation.latitude, location.gpsLocation.longitude,
location.gpsLocation.altitude, location.gpsLocation.speed,
location.gpsLocation.bearing, location.gpsLocation.accuracy,
- location.gpsLocation.timestamp, location.rawDataSize,
- location.rawData, status, loc_technology_mask,
+ location.gpsLocation.timestamp, status, loc_technology_mask,
locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask,
locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask,
locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask,
@@ -250,7 +344,8 @@ void LocApiBase::reportPosition(UlpLocation& location,
// loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(
mLocAdapters[i]->reportPositionEvent(location, locationExtended,
- status, loc_technology_mask)
+ status, loc_technology_mask,
+ pDataNotify, msInWeek)
);
}
@@ -260,19 +355,57 @@ void LocApiBase::reportWwanZppFix(LocGpsLocation &zppLoc)
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportWwanZppFix(zppLoc));
}
-void LocApiBase::reportOdcpiRequest(OdcpiRequestInfo& request)
+void LocApiBase::reportZppBestAvailableFix(LocGpsLocation &zppLoc,
+ GpsLocationExtended &location_extended, LocPosTechMask tech_mask)
+{
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportZppBestAvailableFix(zppLoc,
+ location_extended, tech_mask));
+}
+
+void LocApiBase::requestOdcpi(OdcpiRequestInfo& request)
+{
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestOdcpiEvent(request));
+}
+
+void LocApiBase::reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot)
+{
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssEngEnergyConsumedEvent(
+ energyConsumedSinceFirstBoot));
+}
+
+void LocApiBase::reportDeleteAidingDataEvent(GnssAidingData& aidingData) {
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportDeleteAidingDataEvent(aidingData));
+}
+
+void LocApiBase::reportKlobucharIonoModel(GnssKlobucharIonoModel & ionoModel) {
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportKlobucharIonoModelEvent(ionoModel));
+}
+
+void LocApiBase::reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo) {
+ // loop through adapters, and deliver to the first handling adapter.
+ TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportGnssAdditionalSystemInfoEvent(
+ additionalSystemInfo));
+}
+
+void LocApiBase::sendNfwNotification(GnssNfwNotification& notification)
{
// loop through adapters, and deliver to the first handling adapter.
- TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportOdcpiRequestEvent(request));
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportNfwNotificationEvent(notification));
+
}
void LocApiBase::reportSv(GnssSvNotification& svNotify)
{
const char* constellationString[] = { "Unknown", "GPS", "SBAS", "GLONASS",
- "QZSS", "BEIDOU", "GALILEO" };
+ "QZSS", "BEIDOU", "GALILEO", "NAVIC" };
// print the SV info before delivering
- LOC_LOGV("num sv: %zu\n"
+ LOC_LOGV("num sv: %u\n"
" sv: constellation svid cN0"
" elevation azimuth flags",
svNotify.count);
@@ -281,14 +414,19 @@ void LocApiBase::reportSv(GnssSvNotification& svNotify)
sizeof(constellationString) / sizeof(constellationString[0]) - 1) {
svNotify.gnssSvs[i].type = GNSS_SV_TYPE_UNKNOWN;
}
- LOC_LOGV(" %03zu: %*s %02d %f %f %f 0x%02X",
+ // Display what we report to clients
+ uint16_t displaySvId = GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[i].type ?
+ svNotify.gnssSvs[i].svId + QZSS_SV_PRN_MIN - 1 :
+ svNotify.gnssSvs[i].svId;
+ LOC_LOGV(" %03zu: %*s %02d %f %f %f %f 0x%02X",
i,
13,
constellationString[svNotify.gnssSvs[i].type],
- svNotify.gnssSvs[i].svId,
+ displaySvId,
svNotify.gnssSvs[i].cN0Dbhz,
svNotify.gnssSvs[i].elevation,
svNotify.gnssSvs[i].azimuth,
+ svNotify.gnssSvs[i].carrierFrequencyHz,
svNotify.gnssSvs[i].gnssSvOptionsMask);
}
// loop through adapters, and deliver to all adapters.
@@ -297,19 +435,19 @@ void LocApiBase::reportSv(GnssSvNotification& svNotify)
);
}
-void LocApiBase::reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet)
+void LocApiBase::reportSvPolynomial(GnssSvPolynomial &svPolynomial)
{
// loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(
- mLocAdapters[i]->reportSvMeasurementEvent(svMeasurementSet)
+ mLocAdapters[i]->reportSvPolynomialEvent(svPolynomial)
);
}
-void LocApiBase::reportSvPolynomial(GnssSvPolynomial &svPolynomial)
+void LocApiBase::reportSvEphemeris(GnssSvEphemerisReport & svEphemeris)
{
// loop through adapters, and deliver to all adapters.
TO_ALL_LOCADAPTERS(
- mLocAdapters[i]->reportSvPolynomialEvent(svPolynomial)
+ mLocAdapters[i]->reportSvEphemerisEvent(svEphemeris)
);
}
@@ -319,6 +457,12 @@ void LocApiBase::reportStatus(LocGpsStatusValue status)
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportStatus(status));
}
+void LocApiBase::reportData(GnssDataNotification& dataNotify, int msInWeek)
+{
+ // loop through adapters, and deliver to all adapters.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportDataEvent(dataNotify, msInWeek));
+}
+
void LocApiBase::reportNmea(const char* nmea, int length)
{
// loop through adapters, and deliver to all adapters.
@@ -333,6 +477,12 @@ void LocApiBase::reportXtraServer(const char* url1, const char* url2,
}
+void LocApiBase::reportLocationSystemInfo(const LocationSystemInfo& locationSystemInfo)
+{
+ // loop through adapters, and deliver to all adapters.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLocationSystemInfoEvent(locationSystemInfo));
+}
+
void LocApiBase::requestXtraData()
{
// loop through adapters, and deliver to the first handling adapter.
@@ -351,10 +501,12 @@ void LocApiBase::requestLocation()
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestLocation());
}
-void LocApiBase::requestATL(int connHandle, LocAGpsType agps_type)
+void LocApiBase::requestATL(int connHandle, LocAGpsType agps_type,
+ LocApnTypeMask apn_type_mask)
{
// loop through adapters, and deliver to the first handling adapter.
- TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestATL(connHandle, agps_type));
+ TO_1ST_HANDLING_LOCADAPTERS(
+ mLocAdapters[i]->requestATL(connHandle, agps_type, apn_type_mask));
}
void LocApiBase::releaseATL(int connHandle)
@@ -363,145 +515,160 @@ void LocApiBase::releaseATL(int connHandle)
TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->releaseATL(connHandle));
}
-void LocApiBase::requestSuplES(int connHandle)
+void LocApiBase::requestNiNotify(GnssNiNotification &notify, const void* data,
+ const LocInEmergency emergencyState)
{
// loop through adapters, and deliver to the first handling adapter.
- TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestSuplES(connHandle));
+ TO_1ST_HANDLING_LOCADAPTERS(
+ mLocAdapters[i]->requestNiNotifyEvent(notify,
+ data,
+ emergencyState));
}
-void LocApiBase::reportDataCallOpened()
+void* LocApiBase :: getSibling()
+ DEFAULT_IMPL(NULL)
+
+LocApiProxyBase* LocApiBase :: getLocApiProxy()
+ DEFAULT_IMPL(NULL)
+
+void LocApiBase::reportGnssMeasurements(GnssMeasurements& gnssMeasurements, int msInWeek)
{
- // loop through adapters, and deliver to the first handling adapter.
- TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportDataCallOpened());
+ // loop through adapters, and deliver to all adapters.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssMeasurementsEvent(gnssMeasurements, msInWeek));
}
-void LocApiBase::reportDataCallClosed()
+void LocApiBase::reportGnssSvIdConfig(const GnssSvIdConfig& config)
{
- // loop through adapters, and deliver to the first handling adapter.
- TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->reportDataCallClosed());
+ // Print the config
+ LOC_LOGv("gloBlacklistSvMask: %" PRIu64 ", bdsBlacklistSvMask: %" PRIu64 ",\n"
+ "qzssBlacklistSvMask: %" PRIu64 ", galBlacklistSvMask: %" PRIu64,
+ config.gloBlacklistSvMask, config.bdsBlacklistSvMask,
+ config.qzssBlacklistSvMask, config.galBlacklistSvMask);
+
+ // Loop through adapters, and deliver to all adapters.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssSvIdConfigEvent(config));
}
-void LocApiBase::requestNiNotify(GnssNiNotification &notify, const void* data)
+void LocApiBase::reportGnssSvTypeConfig(const GnssSvTypeConfig& config)
{
- // loop through adapters, and deliver to the first handling adapter.
- TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestNiNotifyEvent(notify, data));
+ // Print the config
+ LOC_LOGv("blacklistedMask: %" PRIu64 ", enabledMask: %" PRIu64,
+ config.blacklistedSvTypesMask, config.enabledSvTypesMask);
+
+ // Loop through adapters, and deliver to all adapters.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssSvTypeConfigEvent(config));
}
-void LocApiBase::saveSupportedMsgList(uint64_t supportedMsgList)
+void LocApiBase::geofenceBreach(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp)
{
- mSupportedMsg = supportedMsgList;
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->geofenceBreachEvent(count, hwIds, location, breachType,
+ timestamp));
}
-void LocApiBase::saveSupportedFeatureList(uint8_t *featureList)
+void LocApiBase::geofenceStatus(GeofenceStatusAvailable available)
{
- memcpy((void *)mFeaturesSupported, (void *)featureList, sizeof(mFeaturesSupported));
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->geofenceStatusEvent(available));
}
-void* LocApiBase :: getSibling()
- DEFAULT_IMPL(NULL)
+void LocApiBase::reportDBTPosition(UlpLocation &location, GpsLocationExtended &locationExtended,
+ enum loc_sess_status status, LocPosTechMask loc_technology_mask)
+{
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportPositionEvent(location, locationExtended, status,
+ loc_technology_mask));
+}
-LocApiProxyBase* LocApiBase :: getLocApiProxy()
- DEFAULT_IMPL(NULL)
+void LocApiBase::reportLocations(Location* locations, size_t count, BatchingMode batchingMode)
+{
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportLocationsEvent(locations, count, batchingMode));
+}
-void LocApiBase::reportGnssMeasurementData(GnssMeasurementsNotification& measurements,
- int msInWeek)
+void LocApiBase::reportCompletedTrips(uint32_t accumulated_distance)
{
- // loop through adapters, and deliver to all adapters.
- TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssMeasurementDataEvent(measurements, msInWeek));
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportCompletedTripsEvent(accumulated_distance));
}
-enum loc_api_adapter_err LocApiBase::
- open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
+void LocApiBase::handleBatchStatusEvent(BatchingStatus batchStatus)
+{
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportBatchStatusChangeEvent(batchStatus));
+}
-enum loc_api_adapter_err LocApiBase::
- close()
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
enum loc_api_adapter_err LocApiBase::
- startFix(const LocPosMode& /*posMode*/)
+ open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/)
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
enum loc_api_adapter_err LocApiBase::
- stopFix()
+ close()
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
-LocationError LocApiBase::
- deleteAidingData(const GnssAidingData& /*data*/)
-DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+void LocApiBase::startFix(const LocPosMode& /*posMode*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
-enum loc_api_adapter_err LocApiBase::
- enableData(int /*enable*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
+void LocApiBase::stopFix(LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
-enum loc_api_adapter_err LocApiBase::
- setAPN(char* /*apn*/, int /*len*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
+void LocApiBase::
+ deleteAidingData(const GnssAidingData& /*data*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
-enum loc_api_adapter_err LocApiBase::
+void LocApiBase::
injectPosition(double /*latitude*/, double /*longitude*/, float /*accuracy*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
+DEFAULT_IMPL()
-enum loc_api_adapter_err LocApiBase::
- injectPosition(const Location& /*location*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
+void LocApiBase::
+ injectPosition(const Location& /*location*/, bool /*onDemandCpi*/)
+DEFAULT_IMPL()
-enum loc_api_adapter_err LocApiBase::
+void LocApiBase::
+ injectPosition(const GnssLocationInfoNotification & /*locationInfo*/, bool /*onDemandCpi*/)
+DEFAULT_IMPL()
+
+void LocApiBase::
setTime(LocGpsUtcTime /*time*/, int64_t /*timeReference*/, int /*uncertainty*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
+DEFAULT_IMPL()
enum loc_api_adapter_err LocApiBase::
setXtraData(char* /*data*/, int /*length*/)
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
-enum loc_api_adapter_err LocApiBase::
- requestXtraServer()
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
-
-enum loc_api_adapter_err LocApiBase::
- atlOpenStatus(int /*handle*/, int /*is_succ*/, char* /*apn*/,
- AGpsBearerType /*bear*/, LocAGpsType /*agpsType*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
+void LocApiBase::
+ atlOpenStatus(int /*handle*/, int /*is_succ*/, char* /*apn*/, uint32_t /*apnLen*/,
+ AGpsBearerType /*bear*/, LocAGpsType /*agpsType*/,
+ LocApnTypeMask /*mask*/)
+DEFAULT_IMPL()
-enum loc_api_adapter_err LocApiBase::
+void LocApiBase::
atlCloseStatus(int /*handle*/, int /*is_succ*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
-
-enum loc_api_adapter_err LocApiBase::
- setPositionMode(const LocPosMode& /*posMode*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
+DEFAULT_IMPL()
LocationError LocApiBase::
- setServer(const char* /*url*/, int /*len*/)
+ setServerSync(const char* /*url*/, int /*len*/, LocServerType /*type*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
LocationError LocApiBase::
- setServer(unsigned int /*ip*/, int /*port*/, LocServerType /*type*/)
+ setServerSync(unsigned int /*ip*/, int /*port*/, LocServerType /*type*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
-LocationError LocApiBase::
+void LocApiBase::
informNiResponse(GnssNiResponse /*userResponse*/, const void* /*passThroughData*/)
-DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+DEFAULT_IMPL()
LocationError LocApiBase::
- setSUPLVersion(GnssConfigSuplVersion /*version*/)
+ setSUPLVersionSync(GnssConfigSuplVersion /*version*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
enum loc_api_adapter_err LocApiBase::
- setNMEATypes (uint32_t /*typesMask*/)
+ setNMEATypesSync (uint32_t /*typesMask*/)
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
LocationError LocApiBase::
- setLPPConfig(GnssConfigLppProfile /*profile*/)
+ setLPPConfigSync(GnssConfigLppProfile /*profile*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
-enum loc_api_adapter_err LocApiBase::
- setSensorControlConfig(int /*sensorUsage*/,
- int /*sensorProvider*/)
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
enum loc_api_adapter_err LocApiBase::
- setSensorProperties(bool /*gyroBiasVarianceRandomWalk_valid*/,
+ setSensorPropertiesSync(bool /*gyroBiasVarianceRandomWalk_valid*/,
float /*gyroBiasVarianceRandomWalk*/,
bool /*accelBiasVarianceRandomWalk_valid*/,
float /*accelBiasVarianceRandomWalk*/,
@@ -514,7 +681,7 @@ enum loc_api_adapter_err LocApiBase::
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
enum loc_api_adapter_err LocApiBase::
- setSensorPerfControlConfig(int /*controlMode*/,
+ setSensorPerfControlConfigSync(int /*controlMode*/,
int /*accelSamplesPerBatch*/,
int /*accelBatchesPerSec*/,
int /*gyroSamplesPerBatch*/,
@@ -527,88 +694,184 @@ enum loc_api_adapter_err LocApiBase::
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
LocationError LocApiBase::
- setAGLONASSProtocol(GnssConfigAGlonassPositionProtocolMask /*aGlonassProtocol*/)
+ setAGLONASSProtocolSync(GnssConfigAGlonassPositionProtocolMask /*aGlonassProtocol*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
LocationError LocApiBase::
- setLPPeProtocolCp(GnssConfigLppeControlPlaneMask /*lppeCP*/)
+ setLPPeProtocolCpSync(GnssConfigLppeControlPlaneMask /*lppeCP*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
LocationError LocApiBase::
- setLPPeProtocolUp(GnssConfigLppeUserPlaneMask /*lppeUP*/)
+ setLPPeProtocolUpSync(GnssConfigLppeUserPlaneMask /*lppeUP*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
-enum loc_api_adapter_err LocApiBase::
- getWwanZppFix()
-DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
+GnssConfigSuplVersion LocApiBase::convertSuplVersion(const uint32_t /*suplVersion*/)
+DEFAULT_IMPL(GNSS_CONFIG_SUPL_VERSION_1_0_0)
-enum loc_api_adapter_err LocApiBase::
- getBestAvailableZppFix(LocGpsLocation& zppLoc)
-{
- memset(&zppLoc, 0, sizeof(zppLoc));
- DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
-}
+GnssConfigLppProfile LocApiBase::convertLppProfile(const uint32_t /*lppProfile*/)
+DEFAULT_IMPL(GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE)
-enum loc_api_adapter_err LocApiBase::
- getBestAvailableZppFix(LocGpsLocation & zppLoc, GpsLocationExtended & locationExtended,
- LocPosTechMask & tech_mask)
-{
- memset(&zppLoc, 0, sizeof(zppLoc));
- memset(&tech_mask, 0, sizeof(tech_mask));
- memset(&locationExtended, 0, sizeof (locationExtended));
- DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
-}
+GnssConfigLppeControlPlaneMask LocApiBase::convertLppeCp(const uint32_t /*lppeControlPlaneMask*/)
+DEFAULT_IMPL(0)
-int LocApiBase::
- initDataServiceClient(bool /*isDueToSsr*/)
-DEFAULT_IMPL(-1)
+GnssConfigLppeUserPlaneMask LocApiBase::convertLppeUp(const uint32_t /*lppeUserPlaneMask*/)
+DEFAULT_IMPL(0)
-int LocApiBase::
- openAndStartDataCall()
-DEFAULT_IMPL(-1)
-
-void LocApiBase::
- stopDataCall()
-DEFAULT_IMPL()
+LocationError LocApiBase::setEmergencyExtensionWindowSync(
+ const uint32_t /*emergencyExtensionSeconds*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
void LocApiBase::
- closeDataCall()
+ getWwanZppFix()
DEFAULT_IMPL()
void LocApiBase::
- releaseDataServiceClient()
+ getBestAvailableZppFix()
DEFAULT_IMPL()
LocationError LocApiBase::
- setGpsLock(GnssConfigGpsLock /*lock*/)
+ setGpsLockSync(GnssConfigGpsLock /*lock*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
void LocApiBase::
+ requestForAidingData(GnssAidingDataSvMask /*svDataMask*/)
+DEFAULT_IMPL()
+
+void LocApiBase::
installAGpsCert(const LocDerEncodedCertificate* /*pData*/,
size_t /*length*/,
uint32_t /*slotBitMask*/)
DEFAULT_IMPL()
-int LocApiBase::
- getGpsLock()
-DEFAULT_IMPL(-1)
+LocationError LocApiBase::
+ setXtraVersionCheckSync(uint32_t /*check*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+LocationError LocApiBase::setBlacklistSvSync(const GnssSvIdConfig& /*config*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::setBlacklistSv(const GnssSvIdConfig& /*config*/)
+DEFAULT_IMPL()
+
+void LocApiBase::getBlacklistSv()
+DEFAULT_IMPL()
+
+void LocApiBase::setConstellationControl(const GnssSvTypeConfig& /*config*/)
+DEFAULT_IMPL()
+
+void LocApiBase::getConstellationControl()
+DEFAULT_IMPL()
+
+void LocApiBase::resetConstellationControl()
+DEFAULT_IMPL()
LocationError LocApiBase::
- setXtraVersionCheck(uint32_t /*check*/)
+ setConstrainedTuncMode(bool /*enabled*/,
+ float /*tuncConstraint*/,
+ uint32_t /*energyBudget*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
-bool LocApiBase::
- gnssConstellationConfig()
-DEFAULT_IMPL(false)
+LocationError LocApiBase::
+ setPositionAssistedClockEstimatorMode(bool /*enabled*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
-bool LocApiBase::
- isFeatureSupported(uint8_t featureVal)
-{
- uint8_t arrayIndex = featureVal >> 3;
- uint8_t bitPos = featureVal & 7;
+LocationError LocApiBase::getGnssEnergyConsumed()
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+
+void LocApiBase::addGeofence(uint32_t /*clientId*/, const GeofenceOption& /*options*/,
+ const GeofenceInfo& /*info*/,
+ LocApiResponseData<LocApiGeofenceData>* /*adapterResponseData*/)
+DEFAULT_IMPL()
+
+void LocApiBase::removeGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::pauseGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::resumeGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::modifyGeofence(uint32_t /*hwId*/, uint32_t /*clientId*/,
+ const GeofenceOption& /*options*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::startTimeBasedTracking(const TrackingOptions& /*options*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::stopTimeBasedTracking(LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::startDistanceBasedTracking(uint32_t /*sessionId*/,
+ const LocationOptions& /*options*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::stopDistanceBasedTracking(uint32_t /*sessionId*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::startBatching(uint32_t /*sessionId*/, const LocationOptions& /*options*/,
+ uint32_t /*accuracy*/, uint32_t /*timeout*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::stopBatching(uint32_t /*sessionId*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::startOutdoorTripBatchingSync(uint32_t /*tripDistance*/,
+ uint32_t /*tripTbf*/, uint32_t /*timeout*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::startOutdoorTripBatching(uint32_t /*tripDistance*/, uint32_t /*tripTbf*/,
+ uint32_t /*timeout*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+void LocApiBase::reStartOutdoorTripBatching(uint32_t /*ongoingTripDistance*/,
+ uint32_t /*ongoingTripInterval*/, uint32_t /*batchingTimeout,*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::stopOutdoorTripBatchingSync(bool /*deallocBatchBuffer*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::stopOutdoorTripBatching(bool /*deallocBatchBuffer*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::getBatchedLocationsSync(size_t /*count*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::getBatchedLocations(size_t /*count*/, LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::getBatchedTripLocationsSync(size_t /*count*/,
+ uint32_t /*accumulatedDistance*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::getBatchedTripLocations(size_t /*count*/, uint32_t /*accumulatedDistance*/,
+ LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
+
+LocationError LocApiBase::queryAccumulatedTripDistanceSync(uint32_t& /*accumulated_trip_distance*/,
+ uint32_t& /*numOfBatchedPositions*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+void LocApiBase::queryAccumulatedTripDistance(
+ LocApiResponseData<LocApiBatchData>* /*adapterResponseData*/)
+DEFAULT_IMPL()
+
+void LocApiBase::setBatchSize(size_t /*size*/)
+DEFAULT_IMPL()
+
+void LocApiBase::setTripBatchSize(size_t /*size*/)
+DEFAULT_IMPL()
+
+void LocApiBase::addToCallQueue(LocApiResponse* /*adapterResponse*/)
+DEFAULT_IMPL()
- if (arrayIndex >= MAX_FEATURE_LENGTH) return false;
- return ((mFeaturesSupported[arrayIndex] >> bitPos ) & 0x1);
-}
} // namespace loc_core
diff --git a/gps/core/LocApiBase.h b/gps/core/LocApiBase.h
index 6563dea..6dac585 100644
--- a/gps/core/LocApiBase.h
+++ b/gps/core/LocApiBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016-2019 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
@@ -34,10 +34,14 @@
#include <gps_extended.h>
#include <LocationAPI.h>
#include <MsgTask.h>
+#include <LocSharedLock.h>
#include <log_util.h>
namespace loc_core {
+
class ContextBase;
+struct LocApiResponse;
+template <typename> struct LocApiResponseData;
int hexcode(char *hexstring, int string_size,
const char *data, int data_size);
@@ -66,6 +70,28 @@ class LocAdapterBase;
struct LocSsrMsg;
struct LocOpenMsg;
+typedef struct
+{
+ uint32_t accumulatedDistance;
+ uint32_t numOfBatchedPositions;
+} LocApiBatchData;
+
+typedef struct
+{
+ uint32_t hwId;
+} LocApiGeofenceData;
+
+struct LocApiMsg: LocMsg {
+ private:
+ std::function<void ()> mProcImpl;
+ inline virtual void proc() const {
+ mProcImpl();
+ }
+ public:
+ inline LocApiMsg(std::function<void ()> procImpl ) :
+ mProcImpl(procImpl) {}
+};
+
class LocApiProxyBase {
public:
inline LocApiProxyBase() {}
@@ -78,31 +104,57 @@ class LocApiBase {
//LocOpenMsg calls open() which makes it necessary to declare
//it as a friend
friend struct LocOpenMsg;
+ friend struct LocCloseMsg;
+ friend struct LocKillMsg;
friend class ContextBase;
- const MsgTask* mMsgTask;
- ContextBase *mContext;
+ static MsgTask* mMsgTask;
+ static volatile int32_t mMsgTaskRefCount;
LocAdapterBase* mLocAdapters[MAX_ADAPTERS];
- uint64_t mSupportedMsg;
- uint8_t mFeaturesSupported[MAX_FEATURE_LENGTH];
protected:
+ ContextBase *mContext;
virtual enum loc_api_adapter_err
open(LOC_API_ADAPTER_EVENT_MASK_T mask);
virtual enum loc_api_adapter_err
close();
LOC_API_ADAPTER_EVENT_MASK_T getEvtMask();
LOC_API_ADAPTER_EVENT_MASK_T mMask;
- LocApiBase(const MsgTask* msgTask,
- LOC_API_ADAPTER_EVENT_MASK_T excludedMask,
+ uint32_t mNmeaMask;
+ LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask,
ContextBase* context = NULL);
- inline virtual ~LocApiBase() { close(); }
+ inline virtual ~LocApiBase() {
+ android_atomic_dec(&mMsgTaskRefCount);
+ if (nullptr != mMsgTask && 0 == mMsgTaskRefCount) {
+ mMsgTask->destroy();
+ mMsgTask = nullptr;
+ }
+ }
bool isInSession();
const LOC_API_ADAPTER_EVENT_MASK_T mExcludedMask;
+ bool isMaster();
public:
inline void sendMsg(const LocMsg* msg) const {
- mMsgTask->sendMsg(msg);
+ if (nullptr != mMsgTask) {
+ mMsgTask->sendMsg(msg);
+ }
}
+ inline void destroy() {
+ close();
+ struct LocKillMsg : public LocMsg {
+ LocApiBase* mLocApi;
+ inline LocKillMsg(LocApiBase* locApi) : LocMsg(), mLocApi(locApi) {}
+ inline virtual void proc() const {
+ delete mLocApi;
+ }
+ };
+ sendMsg(new LocKillMsg(this));
+ }
+
+ static bool needReport(const UlpLocation& ulpLocation,
+ enum loc_sess_status status,
+ LocPosTechMask techMask);
+
void addAdapter(LocAdapterBase* adapter);
void removeAdapter(LocAdapterBase* adapter);
@@ -113,155 +165,156 @@ public:
GpsLocationExtended& locationExtended,
enum loc_sess_status status,
LocPosTechMask loc_technology_mask =
- LOC_POS_TECH_MASK_DEFAULT);
+ LOC_POS_TECH_MASK_DEFAULT,
+ GnssDataNotification* pDataNotify = nullptr,
+ int msInWeek = -1);
void reportSv(GnssSvNotification& svNotify);
- void reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet);
void reportSvPolynomial(GnssSvPolynomial &svPolynomial);
+ void reportSvEphemeris(GnssSvEphemerisReport &svEphemeris);
void reportStatus(LocGpsStatusValue status);
void reportNmea(const char* nmea, int length);
+ void reportData(GnssDataNotification& dataNotify, int msInWeek);
void reportXtraServer(const char* url1, const char* url2,
const char* url3, const int maxlength);
+ void reportLocationSystemInfo(const LocationSystemInfo& locationSystemInfo);
void requestXtraData();
void requestTime();
void requestLocation();
- void requestATL(int connHandle, LocAGpsType agps_type);
+ void requestATL(int connHandle, LocAGpsType agps_type, LocApnTypeMask apn_type_mask);
void releaseATL(int connHandle);
- void requestSuplES(int connHandle);
- void reportDataCallOpened();
- void reportDataCallClosed();
- void requestNiNotify(GnssNiNotification &notify, const void* data);
- void saveSupportedMsgList(uint64_t supportedMsgList);
- void reportGnssMeasurementData(GnssMeasurementsNotification& measurements, int msInWeek);
- void saveSupportedFeatureList(uint8_t *featureList);
+ void requestNiNotify(GnssNiNotification &notify, const void* data,
+ const LocInEmergency emergencyState);
+ void reportGnssMeasurements(GnssMeasurements& gnssMeasurements, int msInWeek);
void reportWwanZppFix(LocGpsLocation &zppLoc);
- void reportOdcpiRequest(OdcpiRequestInfo& request);
+ void reportZppBestAvailableFix(LocGpsLocation &zppLoc, GpsLocationExtended &location_extended,
+ LocPosTechMask tech_mask);
+ void reportGnssSvIdConfig(const GnssSvIdConfig& config);
+ void reportGnssSvTypeConfig(const GnssSvTypeConfig& config);
+ void requestOdcpi(OdcpiRequestInfo& request);
+ void reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot);
+ void reportDeleteAidingDataEvent(GnssAidingData& aidingData);
+ void reportKlobucharIonoModel(GnssKlobucharIonoModel& ionoModel);
+ void reportGnssAdditionalSystemInfo(GnssAdditionalSystemInfo& additionalSystemInfo);
+ void sendNfwNotification(GnssNfwNotification& notification);
- // downward calls
- // All below functions are to be defined by adapter specific modules:
- // RPC, QMI, etc. The default implementation is empty.
+ void geofenceBreach(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp);
+ void geofenceStatus(GeofenceStatusAvailable available);
+ void reportDBTPosition(UlpLocation &location,
+ GpsLocationExtended &locationExtended,
+ enum loc_sess_status status,
+ LocPosTechMask loc_technology_mask);
+ void reportLocations(Location* locations, size_t count, BatchingMode batchingMode);
+ void reportCompletedTrips(uint32_t accumulated_distance);
+ void handleBatchStatusEvent(BatchingStatus batchStatus);
+ // downward calls
virtual void* getSibling();
virtual LocApiProxyBase* getLocApiProxy();
- virtual enum loc_api_adapter_err
- startFix(const LocPosMode& posMode);
- virtual enum loc_api_adapter_err
- stopFix();
- virtual LocationError
- deleteAidingData(const GnssAidingData& data);
- virtual enum loc_api_adapter_err
- enableData(int enable);
- virtual enum loc_api_adapter_err
- setAPN(char* apn, int len);
- virtual enum loc_api_adapter_err
- injectPosition(double latitude, double longitude, float accuracy);
- virtual enum loc_api_adapter_err
- injectPosition(const Location& location);
- virtual enum loc_api_adapter_err
- setTime(LocGpsUtcTime time, int64_t timeReference, int uncertainty);
- virtual enum loc_api_adapter_err
- setXtraData(char* data, int length);
- virtual enum loc_api_adapter_err
- requestXtraServer();
- virtual enum loc_api_adapter_err
- atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bear, LocAGpsType agpsType);
- virtual enum loc_api_adapter_err
- atlCloseStatus(int handle, int is_succ);
- virtual enum loc_api_adapter_err
- setPositionMode(const LocPosMode& posMode);
- virtual LocationError
- setServer(const char* url, int len);
- virtual LocationError
- setServer(unsigned int ip, int port,
- LocServerType type);
+ virtual void startFix(const LocPosMode& fixCriteria, LocApiResponse* adapterResponse);
+ virtual void stopFix(LocApiResponse* adapterResponse);
+ virtual void deleteAidingData(const GnssAidingData& data, LocApiResponse* adapterResponse);
+ virtual void injectPosition(double latitude, double longitude, float accuracy);
+ virtual void injectPosition(const GnssLocationInfoNotification &locationInfo,
+ bool onDemandCpi=false);
+ virtual void injectPosition(const Location& location, bool onDemandCpi);
+ virtual void setTime(LocGpsUtcTime time, int64_t timeReference, int uncertainty);
+ virtual enum loc_api_adapter_err setXtraData(char* data, int length);
+ virtual void atlOpenStatus(int handle, int is_succ, char* apn, uint32_t apnLen,
+ AGpsBearerType bear, LocAGpsType agpsType, LocApnTypeMask mask);
+ virtual void atlCloseStatus(int handle, int is_succ);
+ virtual LocationError setServerSync(const char* url, int len, LocServerType type);
+ virtual LocationError setServerSync(unsigned int ip, int port, LocServerType type);
+ virtual void informNiResponse(GnssNiResponse userResponse, const void* passThroughData);
+ virtual LocationError setSUPLVersionSync(GnssConfigSuplVersion version);
+ virtual enum loc_api_adapter_err setNMEATypesSync(uint32_t typesMask);
+ virtual LocationError setLPPConfigSync(GnssConfigLppProfile profile);
+ virtual enum loc_api_adapter_err setSensorPropertiesSync(
+ bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk,
+ bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk,
+ bool angleBiasVarianceRandomWalk_valid, float angleBiasVarianceRandomWalk,
+ bool rateBiasVarianceRandomWalk_valid, float rateBiasVarianceRandomWalk,
+ bool velocityBiasVarianceRandomWalk_valid, float velocityBiasVarianceRandomWalk);
+ virtual enum loc_api_adapter_err setSensorPerfControlConfigSync(int controlMode,
+ int accelSamplesPerBatch, int accelBatchesPerSec, int gyroSamplesPerBatch,
+ int gyroBatchesPerSec, int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh,
+ int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh, int algorithmConfig);
virtual LocationError
- informNiResponse(GnssNiResponse userResponse, const void* passThroughData);
- virtual LocationError setSUPLVersion(GnssConfigSuplVersion version);
- virtual enum loc_api_adapter_err
- setNMEATypes (uint32_t typesMask);
- virtual LocationError setLPPConfig(GnssConfigLppProfile profile);
- virtual enum loc_api_adapter_err
- setSensorControlConfig(int sensorUsage, int sensorProvider);
- virtual enum loc_api_adapter_err
- setSensorProperties(bool gyroBiasVarianceRandomWalk_valid,
- float gyroBiasVarianceRandomWalk,
- bool accelBiasVarianceRandomWalk_valid,
- float accelBiasVarianceRandomWalk,
- bool angleBiasVarianceRandomWalk_valid,
- float angleBiasVarianceRandomWalk,
- bool rateBiasVarianceRandomWalk_valid,
- float rateBiasVarianceRandomWalk,
- bool velocityBiasVarianceRandomWalk_valid,
- float velocityBiasVarianceRandomWalk);
- virtual enum loc_api_adapter_err
- setSensorPerfControlConfig(int controlMode,
- int accelSamplesPerBatch,
- int accelBatchesPerSec,
- int gyroSamplesPerBatch,
- int gyroBatchesPerSec,
- int accelSamplesPerBatchHigh,
- int accelBatchesPerSecHigh,
- int gyroSamplesPerBatchHigh,
- int gyroBatchesPerSecHigh,
- int algorithmConfig);
- virtual LocationError
- setAGLONASSProtocol(GnssConfigAGlonassPositionProtocolMask aGlonassProtocol);
- virtual LocationError setLPPeProtocolCp(GnssConfigLppeControlPlaneMask lppeCP);
- virtual LocationError setLPPeProtocolUp(GnssConfigLppeUserPlaneMask lppeUP);
- virtual enum loc_api_adapter_err
- getWwanZppFix();
- virtual enum loc_api_adapter_err
- getBestAvailableZppFix(LocGpsLocation & zppLoc);
- virtual enum loc_api_adapter_err
- getBestAvailableZppFix(LocGpsLocation & zppLoc, GpsLocationExtended & locationExtended,
- LocPosTechMask & tech_mask);
- virtual int initDataServiceClient(bool isDueToSsr);
- virtual int openAndStartDataCall();
- virtual void stopDataCall();
- virtual void closeDataCall();
- virtual void releaseDataServiceClient();
- virtual void installAGpsCert(const LocDerEncodedCertificate* pData,
- size_t length,
- uint32_t slotBitMask);
- inline virtual void setInSession(bool inSession) {
+ setAGLONASSProtocolSync(GnssConfigAGlonassPositionProtocolMask aGlonassProtocol);
+ virtual LocationError setLPPeProtocolCpSync(GnssConfigLppeControlPlaneMask lppeCP);
+ virtual LocationError setLPPeProtocolUpSync(GnssConfigLppeUserPlaneMask lppeUP);
+ virtual GnssConfigSuplVersion convertSuplVersion(const uint32_t suplVersion);
+ virtual GnssConfigLppProfile convertLppProfile(const uint32_t lppProfile);
+ virtual GnssConfigLppeControlPlaneMask convertLppeCp(const uint32_t lppeControlPlaneMask);
+ virtual GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask);
+ virtual LocationError setEmergencyExtensionWindowSync(const uint32_t emergencyExtensionSeconds);
- (void)inSession;
- }
- inline bool isMessageSupported (LocCheckingMessagesID msgID) const {
+ virtual void getWwanZppFix();
+ virtual void getBestAvailableZppFix();
+ virtual void installAGpsCert(const LocDerEncodedCertificate* pData, size_t length,
+ uint32_t slotBitMask);
+ virtual LocationError setGpsLockSync(GnssConfigGpsLock lock);
+ virtual void requestForAidingData(GnssAidingDataSvMask svDataMask);
+ virtual LocationError setXtraVersionCheckSync(uint32_t check);
+ /* Requests for SV/Constellation Control */
+ virtual LocationError setBlacklistSvSync(const GnssSvIdConfig& config);
+ virtual void setBlacklistSv(const GnssSvIdConfig& config);
+ virtual void getBlacklistSv();
+ virtual void setConstellationControl(const GnssSvTypeConfig& config);
+ virtual void getConstellationControl();
+ virtual void resetConstellationControl();
+ virtual LocationError setConstrainedTuncMode(bool enabled, float tuncConstraint,
+ uint32_t energyBudget);
+ virtual LocationError setPositionAssistedClockEstimatorMode(bool enabled);
+ virtual LocationError getGnssEnergyConsumed();
- // confirm if msgID is not larger than the number of bits in
- // mSupportedMsg
- if ((uint64_t)msgID > (sizeof(mSupportedMsg) << 3)) {
- return false;
- } else {
- uint32_t messageChecker = 1 << msgID;
- return (messageChecker & mSupportedMsg) == messageChecker;
- }
- }
+ virtual void addGeofence(uint32_t clientId, const GeofenceOption& options,
+ const GeofenceInfo& info, LocApiResponseData<LocApiGeofenceData>* adapterResponseData);
+ virtual void removeGeofence(uint32_t hwId, uint32_t clientId, LocApiResponse* adapterResponse);
+ virtual void pauseGeofence(uint32_t hwId, uint32_t clientId, LocApiResponse* adapterResponse);
+ virtual void resumeGeofence(uint32_t hwId, uint32_t clientId, LocApiResponse* adapterResponse);
+ virtual void modifyGeofence(uint32_t hwId, uint32_t clientId, const GeofenceOption& options,
+ LocApiResponse* adapterResponse);
- void updateEvtMask();
+ virtual void startTimeBasedTracking(const TrackingOptions& options,
+ LocApiResponse* adapterResponse);
+ virtual void stopTimeBasedTracking(LocApiResponse* adapterResponse);
+ virtual void startDistanceBasedTracking(uint32_t sessionId, const LocationOptions& options,
+ LocApiResponse* adapterResponse);
+ virtual void stopDistanceBasedTracking(uint32_t sessionId,
+ LocApiResponse* adapterResponse = nullptr);
+ virtual void startBatching(uint32_t sessionId, const LocationOptions& options,
+ uint32_t accuracy, uint32_t timeout, LocApiResponse* adapterResponse);
+ virtual void stopBatching(uint32_t sessionId, LocApiResponse* adapterResponse);
+ virtual LocationError startOutdoorTripBatchingSync(uint32_t tripDistance,
+ uint32_t tripTbf, uint32_t timeout);
+ virtual void startOutdoorTripBatching(uint32_t tripDistance,
+ uint32_t tripTbf, uint32_t timeout, LocApiResponse* adapterResponse);
+ virtual void reStartOutdoorTripBatching(uint32_t ongoingTripDistance,
+ uint32_t ongoingTripInterval, uint32_t batchingTimeout,
+ LocApiResponse* adapterResponse);
+ virtual LocationError stopOutdoorTripBatchingSync(bool deallocBatchBuffer = true);
+ virtual void stopOutdoorTripBatching(bool deallocBatchBuffer = true,
+ LocApiResponse* adapterResponse = nullptr);
+ virtual LocationError getBatchedLocationsSync(size_t count);
+ virtual void getBatchedLocations(size_t count, LocApiResponse* adapterResponse);
+ virtual LocationError getBatchedTripLocationsSync(size_t count, uint32_t accumulatedDistance);
+ virtual void getBatchedTripLocations(size_t count, uint32_t accumulatedDistance,
+ LocApiResponse* adapterResponse);
+ virtual LocationError queryAccumulatedTripDistanceSync(uint32_t &accumulated_trip_distance,
+ uint32_t &numOfBatchedPositions);
+ virtual void queryAccumulatedTripDistance(
+ LocApiResponseData<LocApiBatchData>* adapterResponseData);
+ virtual void setBatchSize(size_t size);
+ virtual void setTripBatchSize(size_t size);
+ virtual void addToCallQueue(LocApiResponse* adapterResponse);
- virtual LocationError setGpsLock(GnssConfigGpsLock lock);
- /*
- Returns
- Current value of GPS Lock on success
- -1 on failure
- */
- virtual int getGpsLock(void);
-
- virtual LocationError setXtraVersionCheck(uint32_t check);
- /*
- Check if the modem support the service
- */
- virtual bool gnssConstellationConfig();
+ void updateEvtMask();
+ void updateNmeaMask(uint32_t mask);
- /*
- Check if a feature is supported
- */
- bool isFeatureSupported(uint8_t featureVal);
};
-typedef LocApiBase* (getLocApi_t)(const MsgTask* msgTask,
- LOC_API_ADAPTER_EVENT_MASK_T exMask,
+typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask,
ContextBase *context);
} // namespace loc_core
diff --git a/gps/core/LocContext.cpp b/gps/core/LocContext.cpp
new file mode 100644
index 0000000..18d3f2d
--- /dev/null
+++ b/gps/core/LocContext.cpp
@@ -0,0 +1,98 @@
+/* Copyright (c) 2011-2014, 2016-2019 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_Ctx"
+
+#include <cutils/sched_policy.h>
+#include <unistd.h>
+#include <LocContext.h>
+#include <msg_q.h>
+#include <log_util.h>
+#include <loc_log.h>
+
+namespace loc_core {
+
+const MsgTask* LocContext::mMsgTask = NULL;
+ContextBase* LocContext::mContext = NULL;
+// the name must be shorter than 15 chars
+const char* LocContext::mLocationHalName = "Loc_hal_worker";
+#ifndef USE_GLIB
+const char* LocContext::mLBSLibName = "liblbs_core.so";
+#else
+const char* LocContext::mLBSLibName = "liblbs_core.so.1";
+#endif
+
+pthread_mutex_t LocContext::mGetLocContextMutex = PTHREAD_MUTEX_INITIALIZER;
+
+const MsgTask* LocContext::getMsgTask(LocThread::tCreate tCreator,
+ const char* name, bool joinable)
+{
+ if (NULL == mMsgTask) {
+ mMsgTask = new MsgTask(tCreator, name, joinable);
+ }
+ return mMsgTask;
+}
+
+inline
+const MsgTask* LocContext::getMsgTask(const char* name, bool joinable) {
+ return getMsgTask((LocThread::tCreate)NULL, name, joinable);
+}
+
+ContextBase* LocContext::getLocContext(LocThread::tCreate tCreator,
+ LocMsg* firstMsg, const char* name, bool joinable)
+{
+ pthread_mutex_lock(&LocContext::mGetLocContextMutex);
+ LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
+ if (NULL == mContext) {
+ LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
+ const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
+ mContext = new LocContext(msgTask);
+ }
+ pthread_mutex_unlock(&LocContext::mGetLocContextMutex);
+
+ if (firstMsg) {
+ mContext->sendMsg(firstMsg);
+ }
+
+ return mContext;
+}
+
+void LocContext :: injectFeatureConfig(ContextBase *curContext)
+{
+ LOC_LOGD("%s:%d]: Calling LBSProxy (%p) to inject feature config",
+ __func__, __LINE__, ((LocContext *)curContext)->mLBSProxy);
+ ((LocContext *)curContext)->mLBSProxy->injectFeatureConfig(curContext);
+}
+
+LocContext::LocContext(const MsgTask* msgTask) :
+ ContextBase(msgTask, 0, mLBSLibName)
+{
+}
+
+}
diff --git a/gps/core/LocDualContext.h b/gps/core/LocContext.h
index 3b3ce2c..fb7d009 100644
--- a/gps/core/LocDualContext.h
+++ b/gps/core/LocContext.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2017-2019 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
@@ -26,8 +26,8 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-#ifndef __LOC_ENG_CONTEXT__
-#define __LOC_ENG_CONTEXT__
+#ifndef __LOC_CONTEXT__
+#define __LOC_CONTEXT__
#include <stdbool.h>
#include <ctype.h>
@@ -36,36 +36,26 @@
namespace loc_core {
-class LocDualContext : public ContextBase {
+class LocContext : public ContextBase {
static const MsgTask* mMsgTask;
- static ContextBase* mFgContext;
- static ContextBase* mBgContext;
- static ContextBase* mInjectContext;
+ static ContextBase* mContext;
static const MsgTask* getMsgTask(LocThread::tCreate tCreator,
const char* name, bool joinable = true);
static const MsgTask* getMsgTask(const char* name, bool joinable = true);
static pthread_mutex_t mGetLocContextMutex;
protected:
- LocDualContext(const MsgTask* msgTask,
- LOC_API_ADAPTER_EVENT_MASK_T exMask);
- inline virtual ~LocDualContext() {}
+ LocContext(const MsgTask* msgTask);
+ inline virtual ~LocContext() {}
public:
static const char* mLBSLibName;
- static const LOC_API_ADAPTER_EVENT_MASK_T mFgExclMask;
- static const LOC_API_ADAPTER_EVENT_MASK_T mBgExclMask;
static const char* mLocationHalName;
- static ContextBase* getLocFgContext(LocThread::tCreate tCreator, LocMsg* firstMsg,
+ static ContextBase* getLocContext(LocThread::tCreate tCreator, LocMsg* firstMsg,
const char* name, bool joinable = true);
- inline static ContextBase* getLocFgContext(const char* name, bool joinable = true) {
- return getLocFgContext(NULL, NULL, name, joinable);
- }
- static ContextBase* getLocBgContext(LocThread::tCreate tCreator, LocMsg* firstMsg,
- const char* name, bool joinable = true);
- inline static ContextBase* getLocBgContext(const char* name, bool joinable = true) {
- return getLocBgContext(NULL, NULL, name, joinable);
+ inline static ContextBase* getLocContext(const char* name, bool joinable = true) {
+ return getLocContext(NULL, NULL, name, joinable);
}
static void injectFeatureConfig(ContextBase *context);
@@ -73,4 +63,4 @@ public:
}
-#endif //__LOC_ENG_CONTEXT__
+#endif //__LOC_CONTEXT__
diff --git a/gps/core/LocDualContext.cpp b/gps/core/LocDualContext.cpp
deleted file mode 100644
index 180d9dc..0000000
--- a/gps/core/LocDualContext.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Copyright (c) 2011-2014, 2016-2017 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_DualCtx"
-
-#include <cutils/sched_policy.h>
-#include <unistd.h>
-#include <LocDualContext.h>
-#include <msg_q.h>
-#include <log_util.h>
-#include <loc_log.h>
-
-namespace loc_core {
-
-// nothing exclude for foreground
-const LOC_API_ADAPTER_EVENT_MASK_T
-LocDualContext::mFgExclMask = 0;
-// excluded events for background clients
-const LOC_API_ADAPTER_EVENT_MASK_T
-LocDualContext::mBgExclMask =
- (LOC_API_ADAPTER_BIT_SATELLITE_REPORT |
- LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT |
- LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT |
- LOC_API_ADAPTER_BIT_IOCTL_REPORT |
- LOC_API_ADAPTER_BIT_STATUS_REPORT |
- LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT |
- LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT);
-
-const MsgTask* LocDualContext::mMsgTask = NULL;
-ContextBase* LocDualContext::mFgContext = NULL;
-ContextBase* LocDualContext::mBgContext = NULL;
-ContextBase* LocDualContext::mInjectContext = NULL;
-// the name must be shorter than 15 chars
-const char* LocDualContext::mLocationHalName = "Loc_hal_worker";
-#ifndef USE_GLIB
-const char* LocDualContext::mLBSLibName = "liblbs_core.so";
-#else
-const char* LocDualContext::mLBSLibName = "liblbs_core.so.1";
-#endif
-
-pthread_mutex_t LocDualContext::mGetLocContextMutex = PTHREAD_MUTEX_INITIALIZER;
-
-const MsgTask* LocDualContext::getMsgTask(LocThread::tCreate tCreator,
- const char* name, bool joinable)
-{
- if (NULL == mMsgTask) {
- mMsgTask = new MsgTask(tCreator, name, joinable);
- }
- return mMsgTask;
-}
-
-inline
-const MsgTask* LocDualContext::getMsgTask(const char* name, bool joinable) {
- return getMsgTask((LocThread::tCreate)NULL, name, joinable);
-}
-
-ContextBase* LocDualContext::getLocFgContext(LocThread::tCreate tCreator,
- LocMsg* firstMsg, const char* name, bool joinable)
-{
- pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
- LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
- if (NULL == mFgContext) {
- LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
- const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
- mFgContext = new LocDualContext(msgTask,
- mFgExclMask);
- }
- if(NULL == mInjectContext) {
- LOC_LOGD("%s:%d]: mInjectContext is FgContext", __func__, __LINE__);
- mInjectContext = mFgContext;
- injectFeatureConfig(mInjectContext);
- }
- pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
-
- if (firstMsg) {
- mFgContext->sendMsg(firstMsg);
- }
-
- return mFgContext;
-}
-
-ContextBase* LocDualContext::getLocBgContext(LocThread::tCreate tCreator,
- LocMsg* firstMsg, const char* name, bool joinable)
-{
- pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
- LOC_LOGD("%s:%d]: querying ContextBase with tCreator", __func__, __LINE__);
- if (NULL == mBgContext) {
- LOC_LOGD("%s:%d]: creating msgTask with tCreator", __func__, __LINE__);
- const MsgTask* msgTask = getMsgTask(tCreator, name, joinable);
- mBgContext = new LocDualContext(msgTask,
- mBgExclMask);
- }
- if(NULL == mInjectContext) {
- LOC_LOGD("%s:%d]: mInjectContext is BgContext", __func__, __LINE__);
- mInjectContext = mBgContext;
- injectFeatureConfig(mInjectContext);
- }
- pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
-
- if (firstMsg) {
- mBgContext->sendMsg(firstMsg);
- }
-
- return mBgContext;
-}
-
-void LocDualContext :: injectFeatureConfig(ContextBase *curContext)
-{
- LOC_LOGD("%s:%d]: Enter", __func__, __LINE__);
- if(curContext == mInjectContext) {
- LOC_LOGD("%s:%d]: Calling LBSProxy (%p) to inject feature config",
- __func__, __LINE__, ((LocDualContext *)mInjectContext)->mLBSProxy);
- ((LocDualContext *)mInjectContext)->mLBSProxy->injectFeatureConfig(curContext);
- }
- LOC_LOGD("%s:%d]: Exit", __func__, __LINE__);
-}
-
-LocDualContext::LocDualContext(const MsgTask* msgTask,
- LOC_API_ADAPTER_EVENT_MASK_T exMask) :
- ContextBase(msgTask, exMask, mLBSLibName)
-{
-}
-
-}
diff --git a/gps/core/Makefile.am b/gps/core/Makefile.am
deleted file mode 100644
index 77bc610..0000000
--- a/gps/core/Makefile.am
+++ /dev/null
@@ -1,66 +0,0 @@
-ACLOCAL_AMFLAGS = -I m4
-
-AM_CFLAGS = -I./ \
- $(LOCPLA_CFLAGS) \
- $(GPSUTILS_CFLAGS) \
- -I./data-items/ \
- -I./data-items/common \
- -I./observer \
- -I$(WORKSPACE)/gps-noship/flp \
- -D__func__=__PRETTY_FUNCTION__ \
- -fno-short-enums \
- -std=c++11
-
-libloc_core_la_h_sources = \
- LocApiBase.h \
- LocAdapterBase.h \
- ContextBase.h \
- LocDualContext.h \
- LBSProxyBase.h \
- UlpProxyBase.h \
- loc_core_log.h \
- LocAdapterProxyBase.h \
- data-items/DataItemId.h \
- data-items/IDataItemCore.h \
- data-items/DataItemConcreteTypesBase.h \
- observer/IDataItemObserver.h \
- observer/IDataItemSubscription.h \
- observer/IFrameworkActionReq.h \
- observer/IOsObserver.h \
- SystemStatusOsObserver.h \
- SystemStatus.h
-
-libloc_core_la_c_sources = \
- LocApiBase.cpp \
- LocAdapterBase.cpp \
- ContextBase.cpp \
- LocDualContext.cpp \
- loc_core_log.cpp \
- data-items/DataItemsFactoryProxy.cpp \
- SystemStatusOsObserver.cpp \
- SystemStatus.cpp
-
-library_includedir = $(pkgincludedir)
-
-library_include_HEADERS = $(libloc_core_la_h_sources)
-
-libloc_core_la_SOURCES = $(libloc_core_la_c_sources)
-
-if USE_GLIB
-libloc_core_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
-libloc_core_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
-libloc_core_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
-else
-libloc_core_la_CFLAGS = $(AM_CFLAGS)
-libloc_core_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
-libloc_core_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
-endif
-
-libloc_core_la_LIBADD = -ldl $(GPSUTILS_LIBS)
-
-#Create and Install libraries
-lib_LTLIBRARIES = libloc_core.la
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = loc-core.pc
-EXTRA_DIST = $(pkgconfig_DATA)
diff --git a/gps/core/SystemStatus.cpp b/gps/core/SystemStatus.cpp
index f4316ca..0624580 100644
--- a/gps/core/SystemStatus.cpp
+++ b/gps/core/SystemStatus.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 2019, 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
@@ -126,6 +126,7 @@ public:
uint32_t mBdsBpAmpQ; // x1C
uint32_t mGalBpAmpI; // x1D
uint32_t mGalBpAmpQ; // x1E
+ uint64_t mTimeUncNs; // x1F
};
// parser
@@ -166,6 +167,7 @@ private:
eBdsBpAmpQ = 28,
eGalBpAmpI = 29,
eGalBpAmpQ = 30,
+ eTimeUncNs = 31,
eMax
};
SystemStatusPQWM1 mM1;
@@ -201,6 +203,7 @@ public:
inline uint32_t getBdsBpAmpQ() { return mM1.mBdsBpAmpQ; }
inline uint32_t getGalBpAmpI() { return mM1.mGalBpAmpI; }
inline uint32_t getGalBpAmpQ() { return mM1.mGalBpAmpQ; }
+ inline uint64_t getTimeUncNs() { return mM1.mTimeUncNs; }
SystemStatusPQWM1parser(const char *str_in, uint32_t len_in)
: SystemStatusNmeaBase(str_in, len_in)
@@ -245,6 +248,9 @@ public:
mM1.mGalBpAmpI = atoi(mField[eGalBpAmpI].c_str());
mM1.mGalBpAmpQ = atoi(mField[eGalBpAmpQ].c_str());
}
+ if (mField.size() > eTimeUncNs) {
+ mM1.mTimeUncNs = strtoull(mField[eTimeUncNs].c_str(), nullptr, 10);
+ }
}
inline SystemStatusPQWM1& get() { return mM1;} //getparser
@@ -376,16 +382,19 @@ public:
uint32_t mBdsXtraAge;
uint32_t mGalXtraAge;
uint32_t mQzssXtraAge;
+ uint32_t mNavicXtraAge;
uint32_t mGpsXtraValid;
uint32_t mGloXtraValid;
uint64_t mBdsXtraValid;
uint64_t mGalXtraValid;
uint8_t mQzssXtraValid;
+ uint32_t mNavicXtraValid;
};
class SystemStatusPQWP3parser : public SystemStatusNmeaBase
{
private:
+ // todo: update for navic once available
enum
{
eTalker = 0,
@@ -412,11 +421,13 @@ public:
inline uint32_t getBdsXtraAge() { return mP3.mBdsXtraAge; }
inline uint32_t getGalXtraAge() { return mP3.mGalXtraAge; }
inline uint32_t getQzssXtraAge() { return mP3.mQzssXtraAge; }
+ inline uint32_t getNavicXtraAge() { return mP3.mNavicXtraAge; }
inline uint32_t getGpsXtraValid() { return mP3.mGpsXtraValid; }
inline uint32_t getGloXtraValid() { return mP3.mGloXtraValid; }
inline uint64_t getBdsXtraValid() { return mP3.mBdsXtraValid; }
inline uint64_t getGalXtraValid() { return mP3.mGalXtraValid; }
inline uint8_t getQzssXtraValid() { return mP3.mQzssXtraValid; }
+ inline uint32_t getNavicXtraValid() { return mP3.mNavicXtraValid; }
SystemStatusPQWP3parser(const char *str_in, uint32_t len_in)
: SystemStatusNmeaBase(str_in, len_in)
@@ -425,6 +436,7 @@ public:
return;
}
memset(&mP3, 0, sizeof(mP3));
+ // todo: update for navic once available
mP3.mXtraValidMask = strtol(mField[eXtraValidMask].c_str(), NULL, 16);
mP3.mGpsXtraAge = atoi(mField[eGpsXtraAge].c_str());
mP3.mGloXtraAge = atoi(mField[eGloXtraAge].c_str());
@@ -505,21 +517,25 @@ public:
uint64_t mBdsUnknownMask;
uint64_t mGalUnknownMask;
uint8_t mQzssUnknownMask;
+ uint32_t mNavicUnknownMask;
uint32_t mGpsGoodMask;
uint32_t mGloGoodMask;
uint64_t mBdsGoodMask;
uint64_t mGalGoodMask;
uint8_t mQzssGoodMask;
+ uint32_t mNavicGoodMask;
uint32_t mGpsBadMask;
uint32_t mGloBadMask;
uint64_t mBdsBadMask;
uint64_t mGalBadMask;
uint8_t mQzssBadMask;
+ uint32_t mNavicBadMask;
};
class SystemStatusPQWP5parser : public SystemStatusNmeaBase
{
private:
+ // todo: update for navic once available
enum
{
eTalker = 0,
@@ -549,16 +565,19 @@ public:
inline uint64_t getBdsUnknownMask() { return mP5.mBdsUnknownMask; }
inline uint64_t getGalUnknownMask() { return mP5.mGalUnknownMask; }
inline uint8_t getQzssUnknownMask() { return mP5.mQzssUnknownMask; }
+ inline uint32_t getNavicUnknownMask() { return mP5.mNavicUnknownMask; }
inline uint32_t getGpsGoodMask() { return mP5.mGpsGoodMask; }
inline uint32_t getGloGoodMask() { return mP5.mGloGoodMask; }
inline uint64_t getBdsGoodMask() { return mP5.mBdsGoodMask; }
inline uint64_t getGalGoodMask() { return mP5.mGalGoodMask; }
inline uint8_t getQzssGoodMask() { return mP5.mQzssGoodMask; }
+ inline uint32_t getNavicGoodMask() { return mP5.mNavicGoodMask; }
inline uint32_t getGpsBadMask() { return mP5.mGpsBadMask; }
inline uint32_t getGloBadMask() { return mP5.mGloBadMask; }
inline uint64_t getBdsBadMask() { return mP5.mBdsBadMask; }
inline uint64_t getGalBadMask() { return mP5.mGalBadMask; }
inline uint8_t getQzssBadMask() { return mP5.mQzssBadMask; }
+ inline uint32_t getNavicBadMask() { return mP5.mNavicBadMask; }
SystemStatusPQWP5parser(const char *str_in, uint32_t len_in)
: SystemStatusNmeaBase(str_in, len_in)
@@ -567,6 +586,7 @@ public:
return;
}
memset(&mP5, 0, sizeof(mP5));
+ // todo: update for navic once available
mP5.mGpsUnknownMask = strtol(mField[eGpsUnknownMask].c_str(), NULL, 16);
mP5.mGloUnknownMask = strtol(mField[eGloUnknownMask].c_str(), NULL, 16);
mP5.mBdsUnknownMask = strtol(mField[eBdsUnknownMask].c_str(), NULL, 16);
@@ -640,6 +660,7 @@ private:
{
eTalker = 0,
eUtcTime = 1,
+ eMin = 2 + SV_ALL_NUM_MIN*3,
eMax = 2 + SV_ALL_NUM*3
};
SystemStatusPQWP7 mP7;
@@ -648,11 +669,18 @@ public:
SystemStatusPQWP7parser(const char *str_in, uint32_t len_in)
: SystemStatusNmeaBase(str_in, len_in)
{
- if (mField.size() < eMax) {
+ uint32_t svLimit = SV_ALL_NUM;
+ if (mField.size() < eMin) {
LOC_LOGE("PQWP7parser - invalid size=%zu", mField.size());
return;
}
- for (uint32_t i=0; i<SV_ALL_NUM; i++) {
+ if (mField.size() < eMax) {
+ // Try reducing limit, accounting for possibly missing NAVIC support
+ svLimit = SV_ALL_NUM_MIN;
+ }
+
+ memset(mP7.mNav, 0, sizeof(mP7.mNav));
+ for (uint32_t i=0; i<svLimit; i++) {
mP7.mNav[i].mType = GnssEphemerisType(atoi(mField[i*3+2].c_str()));
mP7.mNav[i].mSource = GnssEphemerisSource(atoi(mField[i*3+3].c_str()));
mP7.mNav[i].mAgeSec = atoi(mField[i*3+4].c_str());
@@ -715,7 +743,8 @@ SystemStatusTimeAndClock::SystemStatusTimeAndClock(const SystemStatusPQWM1& nmea
mClockFreqBias(nmea.mClockFreqBias),
mClockFreqBiasUnc(nmea.mClockFreqBiasUnc),
mLeapSeconds(nmea.mLeapSeconds),
- mLeapSecUnc(nmea.mLeapSecUnc)
+ mLeapSecUnc(nmea.mLeapSecUnc),
+ mTimeUncNs(nmea.mTimeUncNs)
{
}
@@ -729,7 +758,8 @@ bool SystemStatusTimeAndClock::equals(const SystemStatusTimeAndClock& peer)
(mClockFreqBias != peer.mClockFreqBias) ||
(mClockFreqBiasUnc != peer.mClockFreqBiasUnc) ||
(mLeapSeconds != peer.mLeapSeconds) ||
- (mLeapSecUnc != peer.mLeapSecUnc)) {
+ (mLeapSecUnc != peer.mLeapSecUnc) ||
+ (mTimeUncNs != peer.mTimeUncNs)) {
return false;
}
return true;
@@ -737,7 +767,7 @@ bool SystemStatusTimeAndClock::equals(const SystemStatusTimeAndClock& peer)
void SystemStatusTimeAndClock::dump()
{
- LOC_LOGV("TimeAndClock: u=%ld:%ld g=%d:%d v=%d ts=%d tu=%d b=%d bu=%d ls=%d lu=%d",
+ LOC_LOGV("TimeAndClock: u=%ld:%ld g=%d:%d v=%d ts=%d tu=%d b=%d bu=%d ls=%d lu=%d un=%" PRIu64,
mUtcTime.tv_sec, mUtcTime.tv_nsec,
mGpsWeek,
mGpsTowMs,
@@ -747,7 +777,8 @@ void SystemStatusTimeAndClock::dump()
mClockFreqBias,
mClockFreqBiasUnc,
mLeapSeconds,
- mLeapSecUnc);
+ mLeapSecUnc,
+ mTimeUncNs);
return;
}
@@ -962,11 +993,13 @@ SystemStatusXtra::SystemStatusXtra(const SystemStatusPQWP3& nmea) :
mBdsXtraAge(nmea.mBdsXtraAge),
mGalXtraAge(nmea.mGalXtraAge),
mQzssXtraAge(nmea.mQzssXtraAge),
+ mNavicXtraAge(nmea.mNavicXtraAge),
mGpsXtraValid(nmea.mGpsXtraValid),
mGloXtraValid(nmea.mGloXtraValid),
mBdsXtraValid(nmea.mBdsXtraValid),
mGalXtraValid(nmea.mGalXtraValid),
- mQzssXtraValid(nmea.mQzssXtraValid)
+ mQzssXtraValid(nmea.mQzssXtraValid),
+ mNavicXtraValid(nmea.mNavicXtraValid)
{
}
@@ -978,11 +1011,13 @@ bool SystemStatusXtra::equals(const SystemStatusXtra& peer)
(mBdsXtraAge != peer.mBdsXtraAge) ||
(mGalXtraAge != peer.mGalXtraAge) ||
(mQzssXtraAge != peer.mQzssXtraAge) ||
+ (mNavicXtraAge != peer.mNavicXtraAge) ||
(mGpsXtraValid != peer.mGpsXtraValid) ||
(mGloXtraValid != peer.mGloXtraValid) ||
(mBdsXtraValid != peer.mBdsXtraValid) ||
(mGalXtraValid != peer.mGalXtraValid) ||
- (mQzssXtraValid != peer.mQzssXtraValid)) {
+ (mQzssXtraValid != peer.mQzssXtraValid) ||
+ (mNavicXtraValid != peer.mNavicXtraValid)) {
return false;
}
return true;
@@ -1051,16 +1086,19 @@ SystemStatusSvHealth::SystemStatusSvHealth(const SystemStatusPQWP5& nmea) :
mBdsUnknownMask(nmea.mBdsUnknownMask),
mGalUnknownMask(nmea.mGalUnknownMask),
mQzssUnknownMask(nmea.mQzssUnknownMask),
+ mNavicUnknownMask(nmea.mNavicUnknownMask),
mGpsGoodMask(nmea.mGpsGoodMask),
mGloGoodMask(nmea.mGloGoodMask),
mBdsGoodMask(nmea.mBdsGoodMask),
mGalGoodMask(nmea.mGalGoodMask),
mQzssGoodMask(nmea.mQzssGoodMask),
+ mNavicGoodMask(nmea.mNavicGoodMask),
mGpsBadMask(nmea.mGpsBadMask),
mGloBadMask(nmea.mGloBadMask),
mBdsBadMask(nmea.mBdsBadMask),
mGalBadMask(nmea.mGalBadMask),
- mQzssBadMask(nmea.mQzssBadMask)
+ mQzssBadMask(nmea.mQzssBadMask),
+ mNavicBadMask(nmea.mNavicBadMask)
{
}
@@ -1682,14 +1720,29 @@ bool SystemStatus::setDefaultGnssEngineStates(void)
@return true when successfully done
******************************************************************************/
-bool SystemStatus::eventConnectionStatus(bool connected, int8_t type)
+bool SystemStatus::eventConnectionStatus(bool connected, int8_t type,
+ bool roaming, NetworkHandle networkHandle)
{
// send networkinof dataitem to systemstatus observer clients
- SystemStatusNetworkInfo s(type, "", "", connected);
+ SystemStatusNetworkInfo s(type, "", "", connected, roaming,
+ (uint64_t) networkHandle);
mSysStatusObsvr.notify({&s});
return true;
}
+/******************************************************************************
+@brief API to update power connect state
+
+@param[In] power connect status
+
+@return true when successfully done
+******************************************************************************/
+bool SystemStatus::updatePowerConnectState(bool charging)
+{
+ SystemStatusPowerConnectState s(charging);
+ mSysStatusObsvr.notify({&s});
+ return true;
+}
} // namespace loc_core
diff --git a/gps/core/SystemStatus.h b/gps/core/SystemStatus.h
index b2f4fb6..2cfb25d 100644
--- a/gps/core/SystemStatus.h
+++ b/gps/core/SystemStatus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -32,6 +32,8 @@
#include <stdint.h>
#include <sys/time.h>
#include <vector>
+#include <algorithm>
+#include <iterator>
#include <loc_pla.h>
#include <log_util.h>
#include <MsgTask.h>
@@ -42,20 +44,23 @@
#include <gps_extended_c.h>
-#define GPS_MIN (1) //1-32
-#define SBAS_MIN (33)
-#define GLO_MIN (65) //65-88
-#define QZSS_MIN (193) //193-197
-#define BDS_MIN (201) //201-237
-#define GAL_MIN (301) //301-336
-
-#define GPS_NUM (32)
-#define SBAS_NUM (32)
-#define GLO_NUM (24)
-#define QZSS_NUM (5)
-#define BDS_NUM (37)
-#define GAL_NUM (36)
-#define SV_ALL_NUM (GPS_NUM+GLO_NUM+QZSS_NUM+BDS_NUM+GAL_NUM) //=134
+#define GPS_MIN (1) //1-32
+#define SBAS_MIN (33)
+#define GLO_MIN (65) //65-88
+#define QZSS_MIN (193) //193-197
+#define BDS_MIN (201) //201-237
+#define GAL_MIN (301) //301-336
+#define NAVIC_MIN (401) //401-414
+
+#define GPS_NUM (32)
+#define SBAS_NUM (32)
+#define GLO_NUM (24)
+#define QZSS_NUM (5)
+#define BDS_NUM (37)
+#define GAL_NUM (36)
+#define NAVIC_NUM (14)
+#define SV_ALL_NUM_MIN (GPS_NUM + GLO_NUM + QZSS_NUM + BDS_NUM + GAL_NUM) //=134
+#define SV_ALL_NUM (SV_ALL_NUM_MIN + NAVIC_NUM) //=148
namespace loc_core
{
@@ -66,15 +71,15 @@ namespace loc_core
class SystemStatusItemBase
{
public:
- timespec mUtcTime; // UTC timestamp when this info was last updated
- timespec mUtcReported; // UTC timestamp when this info was reported
+ timespec mUtcTime;
+ timespec mUtcReported;
static const uint32_t maxItem = 5;
SystemStatusItemBase() {
- struct timespec tv;
- clock_gettime(CLOCK_MONOTONIC, &tv);
+ timeval tv;
+ gettimeofday(&tv, NULL);
mUtcTime.tv_sec = tv.tv_sec;
- mUtcTime.tv_nsec = tv.tv_nsec;
+ mUtcTime.tv_nsec = tv.tv_usec*1000ULL;
mUtcReported = mUtcTime;
};
virtual ~SystemStatusItemBase() {};
@@ -114,6 +119,7 @@ public:
int32_t mClockFreqBiasUnc;
int32_t mLeapSeconds;
int32_t mLeapSecUnc;
+ uint64_t mTimeUncNs;
inline SystemStatusTimeAndClock() :
mGpsWeek(0),
mGpsTowMs(0),
@@ -123,7 +129,8 @@ public:
mClockFreqBias(0),
mClockFreqBiasUnc(0),
mLeapSeconds(0),
- mLeapSecUnc(0) {}
+ mLeapSecUnc(0),
+ mTimeUncNs(0ULL) {}
inline SystemStatusTimeAndClock(const SystemStatusPQWM1& nmea);
bool equals(const SystemStatusTimeAndClock& peer);
void dump(void);
@@ -254,11 +261,13 @@ public:
uint32_t mBdsXtraAge;
uint32_t mGalXtraAge;
uint32_t mQzssXtraAge;
+ uint32_t mNavicXtraAge;
uint32_t mGpsXtraValid;
uint32_t mGloXtraValid;
uint64_t mBdsXtraValid;
uint64_t mGalXtraValid;
uint8_t mQzssXtraValid;
+ uint32_t mNavicXtraValid;
inline SystemStatusXtra() :
mXtraValidMask(0),
mGpsXtraAge(0),
@@ -266,11 +275,13 @@ public:
mBdsXtraAge(0),
mGalXtraAge(0),
mQzssXtraAge(0),
+ mNavicXtraAge(0),
mGpsXtraValid(0),
mGloXtraValid(0),
mBdsXtraValid(0ULL),
mGalXtraValid(0ULL),
- mQzssXtraValid(0) {}
+ mQzssXtraValid(0),
+ mNavicXtraValid(0) {}
inline SystemStatusXtra(const SystemStatusPQWP3& nmea);
bool equals(const SystemStatusXtra& peer);
void dump(void);
@@ -305,32 +316,38 @@ public:
uint64_t mBdsUnknownMask;
uint64_t mGalUnknownMask;
uint8_t mQzssUnknownMask;
+ uint32_t mNavicUnknownMask;
uint32_t mGpsGoodMask;
uint32_t mGloGoodMask;
uint64_t mBdsGoodMask;
uint64_t mGalGoodMask;
uint8_t mQzssGoodMask;
+ uint32_t mNavicGoodMask;
uint32_t mGpsBadMask;
uint32_t mGloBadMask;
uint64_t mBdsBadMask;
uint64_t mGalBadMask;
uint8_t mQzssBadMask;
+ uint32_t mNavicBadMask;
inline SystemStatusSvHealth() :
mGpsUnknownMask(0),
mGloUnknownMask(0),
mBdsUnknownMask(0ULL),
mGalUnknownMask(0ULL),
mQzssUnknownMask(0),
+ mNavicUnknownMask(0),
mGpsGoodMask(0),
mGloGoodMask(0),
mBdsGoodMask(0ULL),
mGalGoodMask(0ULL),
mQzssGoodMask(0),
+ mNavicGoodMask(0),
mGpsBadMask(0),
mGloBadMask(0),
mBdsBadMask(0ULL),
mGalBadMask(0ULL),
- mQzssBadMask(0) {}
+ mQzssBadMask(0),
+ mNavicBadMask(0) {}
inline SystemStatusSvHealth(const SystemStatusPQWP5& nmea);
bool equals(const SystemStatusSvHealth& peer);
void dump(void);
@@ -467,7 +484,8 @@ public:
std::string typeName="",
string subTypeName="",
bool connected=false,
- bool roaming=false) :
+ bool roaming=false,
+ uint64_t networkHandle=NETWORK_HANDLE_UNKNOWN) :
NetworkInfoDataItemBase(
(NetworkType)type,
type,
@@ -475,7 +493,8 @@ public:
subTypeName,
connected && (!roaming),
connected,
- roaming),
+ roaming,
+ networkHandle),
mSrcObjPtr(nullptr) {}
inline SystemStatusNetworkInfo(const NetworkInfoDataItemBase& itemBase) :
NetworkInfoDataItemBase(itemBase),
@@ -483,20 +502,76 @@ public:
mType = itemBase.getType();
}
inline bool equals(const SystemStatusNetworkInfo& peer) {
- return (mAllTypes == peer.mAllTypes);
+ for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
+ if (!(mAllNetworkHandles[i] == peer.mAllNetworkHandles[i])) {
+ return false;
+ }
+ }
+ return true;
}
inline virtual SystemStatusItemBase& collate(SystemStatusItemBase& curInfo) {
uint64_t allTypes = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mAllTypes;
+ uint64_t networkHandle =
+ (static_cast<SystemStatusNetworkInfo&>(curInfo)).mNetworkHandle;
+ int32_t type = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mType;
+ // Replace current with cached table for now and then update
+ memcpy(mAllNetworkHandles,
+ (static_cast<SystemStatusNetworkInfo&>(curInfo)).getNetworkHandle(),
+ sizeof(mAllNetworkHandles));
if (mConnected) {
mAllTypes |= allTypes;
+ for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
+ if (mNetworkHandle == mAllNetworkHandles[i].networkHandle) {
+ LOC_LOGD("collate duplicate detected, not updating");
+ break;
+ }
+ if (NETWORK_HANDLE_UNKNOWN == mAllNetworkHandles[i].networkHandle) {
+ mAllNetworkHandles[i].networkHandle = mNetworkHandle;
+ mAllNetworkHandles[i].networkType = (loc_core::NetworkType) mType;
+ break;
+ }
+ }
} else if (0 != mAllTypes) {
- mAllTypes = (allTypes & (~mAllTypes));
+ uint8_t deletedIndex = MAX_NETWORK_HANDLES;
+ uint8_t lastValidIndex = 0;
+ uint8_t typeCount = 0;
+ for (; lastValidIndex < MAX_NETWORK_HANDLES &&
+ NETWORK_HANDLE_UNKNOWN != mAllNetworkHandles[lastValidIndex].networkHandle;
+ ++lastValidIndex) {
+ // Maintain count for number of network handles still
+ // connected for given type
+ if (mType == mAllNetworkHandles[lastValidIndex].networkType) {
+ typeCount++;
+ }
+
+ if (mNetworkHandle == mAllNetworkHandles[lastValidIndex].networkHandle) {
+ deletedIndex = lastValidIndex;
+ typeCount--;
+ }
+ }
+
+ if (MAX_NETWORK_HANDLES != deletedIndex) {
+ LOC_LOGD("deletedIndex:%u, lastValidIndex:%u, typeCount:%u",
+ deletedIndex, lastValidIndex, typeCount);
+ mAllNetworkHandles[deletedIndex] = mAllNetworkHandles[lastValidIndex];
+ mAllNetworkHandles[lastValidIndex].networkHandle = NETWORK_HANDLE_UNKNOWN;
+ mAllNetworkHandles[lastValidIndex].networkType = TYPE_UNKNOWN;
+ }
+
+ // If no more handles of given type, set bitmask
+ if (0 == typeCount) {
+ mAllTypes = (allTypes & (~mAllTypes));
+ LOC_LOGD("mAllTypes:%" PRIx64, mAllTypes);
+ }
} // else (mConnected == false && mAllTypes == 0)
// we keep mAllTypes as 0, which means no more connections.
if (nullptr != mSrcObjPtr) {
// this is critical, changing mAllTypes of the original obj
mSrcObjPtr->mAllTypes = mAllTypes;
+ memcpy(mSrcObjPtr->mAllNetworkHandles,
+ mAllNetworkHandles,
+ sizeof(mSrcObjPtr->mAllNetworkHandles));
}
return *this;
}
@@ -713,8 +788,12 @@ public:
BtDeviceScanDetailsDataItemBase() {}
inline SystemStatusBtDeviceScanDetail(const BtDeviceScanDetailsDataItemBase& itemBase) :
BtDeviceScanDetailsDataItemBase(itemBase) {}
- inline bool equals(const SystemStatusBtDeviceScanDetail& /*peer*/) {
- return true;
+ inline bool equals(const SystemStatusBtDeviceScanDetail& peer) {
+ return ((mApSrnRssi == peer.mApSrnRssi) &&
+ (0 == memcmp(mApSrnMacAddress, peer.mApSrnMacAddress, sizeof(mApSrnMacAddress))) &&
+ (mApSrnTimestamp == peer.mApSrnTimestamp) &&
+ (mRequestTimestamp == peer.mRequestTimestamp) &&
+ (mReceiveTimestamp == peer.mReceiveTimestamp));
}
};
@@ -726,8 +805,12 @@ public:
BtLeDeviceScanDetailsDataItemBase() {}
inline SystemStatusBtleDeviceScanDetail(const BtLeDeviceScanDetailsDataItemBase& itemBase) :
BtLeDeviceScanDetailsDataItemBase(itemBase) {}
- inline bool equals(const SystemStatusBtleDeviceScanDetail& /*peer*/) {
- return true;
+ inline bool equals(const SystemStatusBtleDeviceScanDetail& peer) {
+ return ((mApSrnRssi == peer.mApSrnRssi) &&
+ (0 == memcmp(mApSrnMacAddress, peer.mApSrnMacAddress, sizeof(mApSrnMacAddress))) &&
+ (mApSrnTimestamp == peer.mApSrnTimestamp) &&
+ (mRequestTimestamp == peer.mRequestTimestamp) &&
+ (mReceiveTimestamp == peer.mReceiveTimestamp));
}
};
@@ -822,7 +905,9 @@ public:
bool setNmeaString(const char *data, uint32_t len);
bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const;
bool setDefaultGnssEngineStates(void);
- bool eventConnectionStatus(bool connected, int8_t type);
+ bool eventConnectionStatus(bool connected, int8_t type,
+ bool roaming, NetworkHandle networkHandle);
+ bool updatePowerConnectState(bool charging);
};
} // namespace loc_core
diff --git a/gps/core/SystemStatusOsObserver.cpp b/gps/core/SystemStatusOsObserver.cpp
index 8127e86..0427380 100644
--- a/gps/core/SystemStatusOsObserver.cpp
+++ b/gps/core/SystemStatusOsObserver.cpp
@@ -97,6 +97,7 @@ void SystemStatusOsObserver::subscribe(const list<DataItemId>& l, IDataItemObser
list<DataItemId>& l, IDataItemObserver* client, bool requestData) :
mParent(parent), mClient(client),
mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)),
+ diItemlist(l),
mToRequestData(requestData) {}
void proc() const {
@@ -107,16 +108,13 @@ void SystemStatusOsObserver::subscribe(const list<DataItemId>& l, IDataItemObser
mParent->sendCachedDataItems(mDataItemSet, mClient);
// Send subscription set to framework
- if (nullptr != mParent->mContext.mSubscriptionObj && !dataItemsToSubscribe.empty()) {
- LOC_LOGD("Subscribe Request sent to framework for the following");
- mParent->logMe(dataItemsToSubscribe);
-
+ if (nullptr != mParent->mContext.mSubscriptionObj) {
if (mToRequestData) {
- mParent->mContext.mSubscriptionObj->requestData(
- containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
- std::move(dataItemsToSubscribe)),
- mParent);
- } else {
+ LOC_LOGD("Request Data sent to framework for the following");
+ mParent->mContext.mSubscriptionObj->requestData(diItemlist, mParent);
+ } else if (!dataItemsToSubscribe.empty()) {
+ LOC_LOGD("Subscribe Request sent to framework for the following");
+ mParent->logMe(dataItemsToSubscribe);
mParent->mContext.mSubscriptionObj->subscribe(
containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
std::move(dataItemsToSubscribe)),
@@ -127,6 +125,7 @@ void SystemStatusOsObserver::subscribe(const list<DataItemId>& l, IDataItemObser
mutable SystemStatusOsObserver* mParent;
IDataItemObserver* mClient;
const unordered_set<DataItemId> mDataItemSet;
+ const list<DataItemId> diItemlist;
bool mToRequestData;
};
@@ -405,7 +404,8 @@ void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut)
DataItemId mDataItemId;
int mTimeOut;
};
- mContext.mMsgTask->sendMsg(new (nothrow) HandleTurnOnMsg(this, dit, timeOut));
+ mContext.mMsgTask->sendMsg(
+ new (nothrow) HandleTurnOnMsg(mContext.mFrameworkActionReqObj, dit, timeOut));
}
else {
// Found in map, update reference count
diff --git a/gps/core/UlpProxyBase.h b/gps/core/UlpProxyBase.h
deleted file mode 100644
index 8863b66..0000000
--- a/gps/core/UlpProxyBase.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Copyright (c) 2013-2017, 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 ULP_PROXY_BASE_H
-#define ULP_PROXY_BASE_H
-
-#include <gps_extended.h>
-#include <LocationAPI.h>
-
-namespace loc_core {
-
-class LocAdapterBase;
-
-class UlpProxyBase {
-public:
- LocPosMode mPosMode;
- bool mFixSet;
- inline UlpProxyBase() {
- mPosMode.mode = LOC_POSITION_MODE_INVALID;
- mFixSet = false;
- }
- inline virtual ~UlpProxyBase() {}
- inline virtual bool sendStartFix() { mFixSet = true; return false; }
- inline virtual bool sendStopFix() { mFixSet = false; return false; }
- inline virtual bool sendFixMode(LocPosMode &params) {
- mPosMode = params;
- return false;
- }
-
- inline virtual bool reportPosition(const UlpLocation &location,
- const GpsLocationExtended &locationExtended,
- enum loc_sess_status status,
- LocPosTechMask loc_technology_mask) {
- (void)location;
- (void)locationExtended;
- (void)status;
- (void)loc_technology_mask;
- return false;
- }
- inline virtual bool reportSv(const GnssSvNotification& svNotify) {
- (void)svNotify;
- return false;
- }
- inline virtual bool reportSvMeasurement(GnssSvMeasurementSet &svMeasurementSet) {
- (void)svMeasurementSet;
- return false;
- }
-
- inline virtual bool reportSvPolynomial(GnssSvPolynomial &svPolynomial)
- {
- (void)svPolynomial;
- return false;
- }
- inline virtual bool reportStatus(LocGpsStatusValue status) {
-
- (void)status;
- return false;
- }
- inline virtual void setAdapter(LocAdapterBase* adapter) {
-
- (void)adapter;
- }
- inline virtual void setCapabilities(unsigned long capabilities) {
-
- (void)capabilities;
- }
- inline virtual bool reportBatchingSession(const LocationOptions& options, bool active)
- {
- (void)options;
- (void)active;
- return false;
- }
- inline virtual bool reportPositions(const UlpLocation* ulpLocations,
- const GpsLocationExtended* extendedLocations,
- const uint32_t* techMasks,
- const size_t count)
- {
- (void)ulpLocations;
- (void)extendedLocations;
- (void)techMasks;
- (void)count;
- return false;
- }
- inline virtual bool reportDeleteAidingData(LocGpsAidingData aidingData)
- {
- (void)aidingData;
- return false;
- }
- inline virtual bool reportNmea(const char* nmea, int length)
- {
- (void)nmea;
- (void)length;
- return false;
- }
-};
-
-} // namespace loc_core
-
-#endif // ULP_PROXY_BASE_H
diff --git a/gps/core/configure.ac b/gps/core/configure.ac
deleted file mode 100644
index ea0a128..0000000
--- a/gps/core/configure.ac
+++ /dev/null
@@ -1,82 +0,0 @@
-# configure.ac -- Autoconf script for gps loc-core
-#
-# Process this file with autoconf to produce a configure script
-
-# Requires autoconf tool later than 2.61
-AC_PREREQ(2.61)
-# Initialize the gps loc-hal package version 1.0.0
-AC_INIT([loc-core],1.0.0)
-# Does not strictly follow GNU Coding standards
-AM_INIT_AUTOMAKE([foreign])
-# Disables auto rebuilding of configure, Makefile.ins
-AM_MAINTAINER_MODE
-# Verifies the --srcdir is correct by checking for the path
-AC_CONFIG_SRCDIR([loc-core.pc.in])
-# defines some macros variable to be included by source
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_MACRO_DIR([m4])
-
-# Checks for programs.
-AC_PROG_LIBTOOL
-AC_PROG_CXX
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_AWK
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-PKG_PROG_PKG_CONFIG
-
-# Checks for libraries.
-PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
-AC_SUBST([GPSUTILS_CFLAGS])
-AC_SUBST([GPSUTILS_LIBS])
-
-AC_ARG_WITH([core_includes],
- AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
- [Specify the location of the core headers]),
- [core_incdir=$withval],
- with_core_includes=no)
-
-if test "x$with_core_includes" != "xno"; then
- CPPFLAGS="${CPPFLAGS} -I${core_incdir}"
-fi
-
-AC_ARG_WITH([locpla_includes],
- AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@],
- [specify the path to locpla-includes in loc-pla_git.bb]),
- [locpla_incdir=$withval],
- with_locpla_includes=no)
-
-if test "x$with_locpla_includes" != "xno"; then
- AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}")
-fi
-
-AC_SUBST([CPPFLAGS])
-
-AC_ARG_WITH([glib],
- AC_HELP_STRING([--with-glib],
- [enable glib, building HLOS systems which use glib]))
-
-if (test "x${with_glib}" = "xyes"); then
- AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
- PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GThread >= 2.16 is required))
- PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GLib >= 2.16 is required))
- GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
- GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
-
- AC_SUBST(GLIB_CFLAGS)
- AC_SUBST(GLIB_LIBS)
-fi
-
-AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
-
-AC_CONFIG_FILES([ \
- Makefile \
- loc-core.pc \
- ])
-
-AC_OUTPUT
diff --git a/gps/core/data-items/DataItemConcreteTypesBase.h b/gps/core/data-items/DataItemConcreteTypesBase.h
index bcb8d72..c32d65d 100644
--- a/gps/core/data-items/DataItemConcreteTypesBase.h
+++ b/gps/core/data-items/DataItemConcreteTypesBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 2019, 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
@@ -32,8 +32,11 @@
#include <string>
#include <cstring>
+#include <sstream>
#include <DataItemId.h>
#include <IDataItemCore.h>
+#include <gps_extended_c.h>
+#include <inttypes.h>
#define MAC_ADDRESS_LENGTH 6
// MAC address length in bytes
@@ -41,10 +44,68 @@
#define SRN_MAC_ADDRESS_LENGTH 6
#define WIFI_SUPPLICANT_DEFAULT_STATE 0
+static constexpr char sDelimit = ':';
+
namespace loc_core
{
using namespace std;
+enum NetworkType {
+ TYPE_MOBILE = 0,
+ TYPE_WIFI,
+ TYPE_ETHERNET,
+ TYPE_BLUETOOTH,
+ TYPE_MMS,
+ TYPE_SUPL,
+ TYPE_DUN,
+ TYPE_HIPRI,
+ TYPE_WIMAX,
+ TYPE_PROXY,
+ TYPE_UNKNOWN,
+};
+
+typedef struct NetworkInfoType
+{
+ // Unique network handle ID
+ uint64_t networkHandle;
+ // Type of network for corresponding network handle
+ NetworkType networkType;
+ NetworkInfoType() : networkHandle(NETWORK_HANDLE_UNKNOWN), networkType(TYPE_UNKNOWN) {}
+ NetworkInfoType(string strObj) {
+ size_t posDelimit = strObj.find(sDelimit);
+
+ if ( posDelimit != string::npos) {
+ int32_t type = TYPE_UNKNOWN;
+ string handleStr = strObj.substr(0, posDelimit);
+ string typeStr = strObj.substr(posDelimit + 1, strObj.length() - posDelimit - 1);
+ stringstream(handleStr) >> networkHandle;
+ stringstream(typeStr) >> type;
+ networkType = (NetworkType) type;
+ } else {
+ networkHandle = NETWORK_HANDLE_UNKNOWN;
+ networkType = TYPE_UNKNOWN;
+ }
+ }
+ bool operator== (const NetworkInfoType& other) {
+ return ((networkHandle == other.networkHandle) && (networkType == other.networkType));
+ }
+ string toString() {
+ string valueStr;
+ valueStr.clear ();
+ char nethandle [32];
+ memset (nethandle, 0, 32);
+ snprintf(nethandle, sizeof(nethandle), "%" PRIu64, networkHandle);
+ valueStr += string(nethandle);
+ valueStr += sDelimit;
+ char type [12];
+ memset (type, 0, 12);
+ snprintf (type, 12, "%u", networkType);
+ valueStr += string (type);
+ return valueStr;
+ }
+} NetworkInfoType;
+
+
class AirplaneModeDataItemBase : public IDataItemCore {
public:
AirplaneModeDataItemBase(bool mode):
@@ -221,21 +282,9 @@ protected:
class NetworkInfoDataItemBase : public IDataItemCore {
public:
- enum NetworkType {
- TYPE_MOBILE,
- TYPE_WIFI,
- TYPE_ETHERNET,
- TYPE_BLUETOOTH,
- TYPE_MMS,
- TYPE_SUPL,
- TYPE_DUN,
- TYPE_HIPRI,
- TYPE_WIMAX,
- TYPE_UNKNOWN,
- };
NetworkInfoDataItemBase(
NetworkType initialType, int32_t type, string typeName, string subTypeName,
- bool available, bool connected, bool roaming ):
+ bool available, bool connected, bool roaming, uint64_t networkHandle ):
mAllTypes(typeToAllTypes(initialType)),
mType(type),
mTypeName(typeName),
@@ -243,7 +292,11 @@ public:
mAvailable(available),
mConnected(connected),
mRoaming(roaming),
- mId(NETWORKINFO_DATA_ITEM_ID) {}
+ mNetworkHandle(networkHandle),
+ mId(NETWORKINFO_DATA_ITEM_ID) {
+ mAllNetworkHandles[0].networkHandle = networkHandle;
+ mAllNetworkHandles[0].networkType = initialType;
+ }
virtual ~NetworkInfoDataItemBase() {}
inline virtual DataItemId getId() { return mId; }
virtual void stringify(string& /*valueStr*/) {}
@@ -252,6 +305,9 @@ public:
return (NetworkType)mType;
}
inline uint64_t getAllTypes() { return mAllTypes; }
+ inline NetworkInfoType* getNetworkHandle() {
+ return &mAllNetworkHandles[0];
+ }
// Data members
uint64_t mAllTypes;
int32_t mType;
@@ -260,6 +316,8 @@ public:
bool mAvailable;
bool mConnected;
bool mRoaming;
+ NetworkInfoType mAllNetworkHandles[MAX_NETWORK_HANDLES];
+ uint64_t mNetworkHandle;
protected:
DataItemId mId;
inline uint64_t typeToAllTypes(NetworkType type) {
diff --git a/gps/core/loc-core.pc.in b/gps/core/loc-core.pc.in
deleted file mode 100644
index 76b514c..0000000
--- a/gps/core/loc-core.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: loc-core
-Description: QTI GPS Loc Core
-Version: @VERSION@
-Libs: -L${libdir} -lloc_core
-Cflags: -I${includedir}/loc-core
diff --git a/gps/core/loc_core_log.cpp b/gps/core/loc_core_log.cpp
index 67d68f0..ddf18ec 100644
--- a/gps/core/loc_core_log.cpp
+++ b/gps/core/loc_core_log.cpp
@@ -39,14 +39,17 @@ void LocPosMode::logv() const
{
LOC_LOGV ("Position mode: %s\n Position recurrence: %s\n "
"min interval: %d\n preferred accuracy: %d\n "
- "preferred time: %d\n credentials: %s provider: %s",
+ "preferred time: %d\n credentials: %s provider: %s \n "
+ "power mode: %d\n tbm %d",
loc_get_position_mode_name(mode),
loc_get_position_recurrence_name(recurrence),
min_interval,
preferred_accuracy,
preferred_time,
credentials,
- provider);
+ provider,
+ powerMode,
+ timeBetweenMeasurements);
}
/* GPS status names */
diff --git a/gps/core/observer/IOsObserver.h b/gps/core/observer/IOsObserver.h
index 40d7671..f661828 100644
--- a/gps/core/observer/IOsObserver.h
+++ b/gps/core/observer/IOsObserver.h
@@ -91,8 +91,8 @@ public:
inline virtual void turnOn (DataItemId /*dit*/, int /*timeOut*/){}
inline virtual void turnOff (DataItemId /*dit*/) {}
#ifdef USE_GLIB
- inline virtual bool connectBackhaul() {}
- inline virtual bool disconnectBackhaul() {}
+ inline virtual bool connectBackhaul() { return false; }
+ inline virtual bool disconnectBackhaul() { return false; }
#endif
/**
diff --git a/gps/etc/flp.conf b/gps/etc/flp.conf
new file mode 100644
index 0000000..65d54d3
--- /dev/null
+++ b/gps/etc/flp.conf
@@ -0,0 +1,60 @@
+###################################
+##### FLP settings #####
+###################################
+
+###################################
+# FLP BATCH SIZE
+###################################
+# The number of batched locations
+# requested to modem. The desired number
+# defined below may not be satisfied, as
+# the modem can only return the number
+# of batched locations that can be allocated,
+# which is limited by memory. The default
+# batch size defined as 20 as below.
+BATCH_SIZE=20
+
+###################################
+# FLP OUTDOOR TRIP BATCH SIZE
+###################################
+# The number of batched locations
+# requested to modem for outdoor
+# trip batching. The desired number
+# defined below may not be satisfied, as
+# the modem can only return the number
+# of batched locations that can be allocated,
+# which is limited by memory. The default
+# trip batch size defined as 600 as below.
+OUTDOOR_TRIP_BATCH_SIZE=600
+
+###################################
+# FLP BATCHING SESSION TIMEOUT
+###################################
+# Duration with which batch session timeout
+# happens in milliseconds. If not specified
+# or set to zero, batching session timeout
+# defaults to 20 seconds by the modem.
+# BATCH_SESSION_TIMEOUT=20000
+
+###################################
+# FLP BATCHING ACCURACY
+###################################
+# Set to one of the defined values below
+# to define the accuracy of batching.
+# If not specified, accuracy defaults
+# to LOW.
+# FLP BATCHING ACCURACY values:
+# Low accuracy = 0
+# Medium accuracy = 1
+# High accuracy = 2
+ACCURACY=1
+
+####################################
+# By default if network fixes are not sensor assisted
+# these fixes must be dropped. This parameter adds an exception
+# for targets where there is no PDR and we still want to
+# report out network fixes
+# 0: MUST NOT ALLOW NETWORK FIXES
+# 1: ALLOW NETWORK FIXES
+####################################
+ALLOW_NETWORK_FIXES = 0
diff --git a/gps/etc/gps.conf b/gps/etc/gps.conf
new file mode 100644
index 0000000..f1d2ece
--- /dev/null
+++ b/gps/etc/gps.conf
@@ -0,0 +1,306 @@
+#Version check for XTRA
+#DISABLE = 0
+#AUTO = 1
+#XTRA2 = 2
+#XTRA3 = 3
+XTRA_VERSION_CHECK=0
+
+# Error Estimate
+# _SET = 1
+# _CLEAR = 0
+ERR_ESTIMATE=0
+
+#NTP server
+NTP_SERVER=time.izatcloud.net
+#Asia
+# NTP_SERVER=asia.pool.ntp.org
+#Europe
+# NTP_SERVER=europe.pool.ntp.org
+#North America
+# NTP_SERVER=north-america.pool.ntp.org
+#XTRA CA path
+XTRA_CA_PATH=/usr/lib/ssl/certs
+
+# DEBUG LEVELS: 0 - none, 1 - Error, 2 - Warning, 3 - Info
+# 4 - Debug, 5 - Verbose
+# If DEBUG_LEVEL is commented, Android's logging levels will be used
+DEBUG_LEVEL = 2
+
+# Intermediate position report, 1=enable, 0=disable
+INTERMEDIATE_POS=1
+
+# supl version 1.0
+SUPL_VER=0x20000
+
+# Emergency SUPL, 1=enable, 0=disable
+#SUPL_ES=1
+
+#Choose PDN for Emergency SUPL
+#1 - Use emergency PDN
+#0 - Use regular SUPL PDN for Emergency SUPL
+#USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=0
+
+#SUPL_MODE is a bit mask set in config.xml per carrier by default.
+#If it is uncommented here, this value will overwrite the value from
+#config.xml.
+#MSA=0X2
+#MSB=0X1
+SUPL_MODE=3
+
+# GPS Capabilities bit mask
+# SCHEDULING = 0x01
+# MSB = 0x02
+# MSA = 0x04
+# ON_DEMAND_TIME = 0x10
+# default = ON_DEMAND_TIME | MSA | MSB | SCHEDULING
+CAPABILITIES=0x17
+
+# Accuracy threshold for intermediate positions
+# less accurate positions are ignored, 0 for passing all positions
+ACCURACY_THRES=70
+
+################################
+##### AGPS server settings #####
+################################
+
+# FOR SUPL SUPPORT, set the following
+# SUPL_HOST=supl.host.com or IP
+# SUPL_PORT=1234
+SUPL_HOST=supl.google.com
+SUPL_PORT=7275
+
+# FOR MO SUPL SUPPORT, set the following
+# MO_SUPL_HOST=supl.host.com or IP
+# MO_SUPL_PORT=1234
+
+# FOR C2K PDE SUPPORT, set the following
+# C2K_HOST=c2k.pde.com or IP
+# C2K_PORT=1234
+
+# Bitmask of slots that are available
+# for write/install to, where 1s indicate writable,
+# and the default value is 0 where no slots
+# are writable. For example, AGPS_CERT_WRITABLE_MASK
+# of b1000001010 makes 3 slots available
+# and the remaining 7 slots unwritable.
+#AGPS_CERT_WRITABLE_MASK=0
+
+####################################
+# LTE Positioning Profile Settings
+####################################
+# 0: Enable RRLP on LTE(Default)
+# 1: Enable LPP_User_Plane on LTE
+# 2: Enable LPP_Control_Plane
+# 3: Enable both LPP_User_Plane and LPP_Control_Plane
+LPP_PROFILE = 2
+
+####################################
+#Datum Type
+####################################
+# 0: WGS-84
+# 1: PZ-90
+DATUM_TYPE = 0
+
+################################
+# EXTRA SETTINGS
+################################
+# NMEA provider (1=Modem Processor, 0=Application Processor)
+NMEA_PROVIDER=0
+# Mark if it is a SGLTE target (1=SGLTE, 0=nonSGLTE)
+SGLTE_TARGET=0
+
+##################################################
+# Select Positioning Protocol on A-GLONASS system
+##################################################
+# 0x1: RRC CPlane
+# 0x2: RRLP UPlane
+# 0x4: LLP Uplane
+A_GLONASS_POS_PROTOCOL_SELECT = 0
+
+##################################################
+# Select technology for LPPe Control Plane
+##################################################
+# 0x1: DBH for LPPe CP
+# 0x2: WLAN AP Measurements for LPPe CP
+# 0x4: SRN AP measurement for CP
+# 0x8: Sensor Barometer Measurement LPPe CP
+#LPPE_CP_TECHNOLOGY = 0
+
+##################################################
+# Select technology for LPPe User Plane
+##################################################
+# 0x1: DBH for LPPe UP
+# 0x2: WLAN AP Measurements for LPPe UP
+# 0x4: SRN AP measurement for UP
+# 0x8: Sensor Barometer Measurement LPPe UP
+#LPPE_UP_TECHNOLOGY = 0
+
+##################################################
+# AGPS_CONFIG_INJECT
+##################################################
+# enable/disable injection of AGPS configurations:
+# SUPL_VER
+# SUPL_HOST
+# SUPL_PORT
+# MO_SUPL_HOST
+# MO_SUPL_PORT
+# C2K_HOST
+# C2K_PORT
+# LPP_PROFILE
+# A_GLONASS_POS_PROTOCOL_SELECT
+# 0: disable
+# 1: enable
+AGPS_CONFIG_INJECT = 1
+
+##################################################
+# GNSS settings for automotive use cases
+# Configurations in following section are
+# specific to automotive use cases, others
+# please do not change, keep the default values
+##################################################
+
+# AP Coarse Timestamp Uncertainty
+##################################################
+# default : 10
+# AP time stamp uncertainty, until GNSS receiver
+# is able to acquire better timing information
+AP_TIMESTAMP_UNCERTAINTY = 10
+
+##################################################
+# QDR engine availability status
+##################################################
+# 0 : NO QDR (default)
+# 1 : QDR enabled
+# This settings enables QDR Configuration for
+# automotive use case, if enabled then
+# DR_AP_Service needs to be enabled in izat.conf
+#EXTERNAL_DR_ENABLED = 0
+
+#####################################
+# DR_SYNC Pulse Availability
+#####################################
+# 0 : DR_SYNC pulse not available (default)
+# 1 : DR_SYNC pulse available
+# This configuration enables the driver to make use
+# of PPS events generated by DR_SYNC pulse
+# Standard Linux PPS driver needs to be enabled
+DR_SYNC_ENABLED = 0
+
+#####################################
+# PPS Device name
+#####################################
+PPS_DEVICENAME = /dev/pps0
+
+#####################################
+# Ignore PPS at Startup and after long outage
+#####################################
+IGNORE_PPS_PULSE_COUNT = 1
+
+#####################################
+# Long GNSS RF outage in seconds
+#####################################
+GNSS_OUTAGE_DURATION = 10
+
+#####################################
+# AP Clock Accuracy
+#####################################
+# Quality of APPS processor clock (in PPM).
+# Value specified is used for calculation of
+# APPS time stamp uncertainty
+AP_CLOCK_PPM = 100
+
+#####################################
+# MAX ms difference to detect missing pulse
+#####################################
+# Specifies time threshold in ms to validate any missing PPS pulses
+MISSING_PULSE_TIME_DELTA = 900
+
+#####################################
+# Propagation time uncertainty
+#####################################
+# This settings enables time uncertainty propagation
+# logic incase of missing PPS pulse
+PROPAGATION_TIME_UNCERTAINTY = 1
+
+#######################################
+# APN / IP Type Configuration
+# APN and IP Type to use for setting
+# up WWAN call.
+# Use below values for IP Type:
+# v4 = 4
+# v6 = 6
+# v4v6 = 10
+#######################################
+# INTERNET_APN = abc.xyz
+# INTERNET_IP_TYPE = 4
+# SUPL_APN = abc.xyz
+# SUPL_IP_TYPE = 4
+
+#####################################
+# Modem type
+#####################################
+# This setting configures modem type
+# (external=0 or internal=1)
+# comment out the next line to vote
+# for the first modem in the list
+MODEM_TYPE = 1
+
+##################################################
+# CONSTRAINED TIME UNCERTAINTY MODE
+##################################################
+# 0 : disabled (default)
+# 1 : enabled
+# This setting enables GPS engine to keep its time
+# uncertainty below the specified constraint
+#CONSTRAINED_TIME_UNCERTAINTY_ENABLED = 0
+
+# If constrained time uncertainty mode is enabled,
+# this setting specifies the time uncertainty
+# threshold that gps engine need to maintain.
+# In unit of milli-seconds.
+# Default is 0.0 meaning that modem default value
+# of time uncertainty threshold will be used.
+#CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD = 0.0
+
+# If constrained time uncertainty mode is enabled,
+# this setting specifies the power budget that
+# gps engine is allowed to spend to maintain the time
+# uncertainty.
+# Default is 0 meaning that GPS engine is not constained
+# by power budget and can spend as much power as needed.
+# In unit of 0.1 milli watt second.
+#CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET = 0
+
+##################################################
+# POSITION ASSISTED CLOCK ESTIMATOR
+##################################################
+# 0 : disabled (default)
+# 1 : enabled
+# This setting enables GPS engine to estimate clock
+# bias and drift when the signal from at least 1
+# SV is available and the UE’s position is known by
+# other position engines.
+#POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED = 0
+
+#####################################
+# proxyAppPackageName
+#####################################
+# This is a string that is sent to the framework
+# in nfwNotifyCb callback
+PROXY_APP_PACKAGE_NAME = com.google.android.carrierlocation
+
+#####################################
+# CP_MTLR_ES
+#####################################
+# CP MTLR ES, 1=enable, 0=disable
+CP_MTLR_ES=0
+
+##################################################
+# GNSS_DEPLOYMENT
+##################################################
+# 0 : Enable QTI GNSS (default)
+# 1 : Enable QCSR SS5
+# This setting use to select between QTI GNSS
+# and QCSR SS5 hardware receiver.
+# By default QTI GNSS receiver is enabled.
+# GNSS_DEPLOYMENT = 0
diff --git a/gps/etc/izat.conf b/gps/etc/izat.conf
new file mode 100644
index 0000000..27d3170
--- /dev/null
+++ b/gps/etc/izat.conf
@@ -0,0 +1,247 @@
+#########################################
+# Log verbosity control for izat modules
+#########################################
+# OFF = 0, ERROR = 1, WARNING = 2, INFO = 3, DEBUG = 4, VERBOSE = 5
+IZAT_DEBUG_LEVEL = 2
+
+##################################################
+# Select WIFI Wait Timeout value in seconds for SUPL
+##################################################
+WIFI_WAIT_TIMEOUT_SELECT = 0
+
+##################################################
+# Time interval of injecting SRN scan data to modem
+# time in seconds.
+# Note: recommended value is between 1-5 sec
+##################################################
+LPPE_SRN_DATA_SCAN_INJECT_TIME=2
+
+################################
+# NLP Settings
+################################
+# NLP_MODE 1: OSNLP Only, 2: QNP Only, 3: Combo, 4: QNP preferred
+# For Automotive products, please use NLP_MODE = 4 only.
+# NLP_TOLERANCE_TIME_FIRST: Time in ms used in Combo mode
+# to determine how much Tolerance for first position
+# NLP_TOLERANCE_TIME_AFTER: Time in ms used in Combo mode
+# to determine how much Tolerance for positions after first
+# NLP_THRESHOLD: Sets how many failures needed before
+# switching preferred NLP in Combo mode
+# NLP_ACCURACY_MULTIPLE: Determines how far off the accuracy
+# must be, in multiples, between two NLP location reports to
+# be considered much worse accuracy. Used in switching logic
+# NLP COMBO MODE USES QNP WITH NO EULA CONSENT: Determines
+# whether or not to still send network location requests to
+# QNP when the EULA is not consented to by the user. QNP can
+# still return ZPP locations or injected locations even
+# without EULA consent, but the uncertainty can be high.
+# QNP preferred mode prefers QNP when there is EULA consent,
+# otherwise OSNLP is used.
+NLP_MODE = 4
+NLP_MODE_EMERGENCY = 2
+NLP_TOLERANCE_TIME_FIRST = 5000
+NLP_TOLERANCE_TIME_AFTER = 20000
+NLP_THRESHOLD = 3
+NLP_ACCURACY_MULTIPLE = 2
+NLP_COMBO_MODE_USES_QNP_WITH_NO_EULA_CONSENT = 1
+
+#########################################
+# NLP PACKAGE SETTINGS
+#########################################
+# OSNLP_PACKAGE: name of default NLP package
+OSNLP_PACKAGE = com.google.android.gms
+# REGION_OSNLP_PACKAGE:
+# This value will be used as alternative
+# for particular region where default NLP is not functional.
+#REGION_OSNLP_PACKAGE =
+
+###################################
+# GEOFENCE SERVICES
+###################################
+# If set to one of the defined values below, it will override
+# the responsiveness for geofence services, which implements
+# the Proximity Alert API. If not set to a value defined below,
+# which is default, it will not override the responsivness.
+# The geofence HAL API is unaffected by this value.
+# GEOFENCE_SERVICES_RESPONSIVENESS_OVERRIDE Values:
+# 1: LOW responsiveness
+# 2: MEDIUM responsiveness
+# 3: HIGH responsiveness
+GEOFENCE_SERVICES_RESPONSIVENESS_OVERRIDE = 0
+
+#####################################
+#GTP Opt-In app
+#####################################
+
+#GTP privacy policy version url
+#https support is required
+GTP_PRIVACY_VERSION_URL = https://info.izatcloud.net/privacy/version.html
+
+#GTP privacy policy version download retry interval
+#unit is second. default is 86400
+GTP_PRIVACY_RETRY_INTERVAL = 86400
+
+#####################################
+# IZAT PREMIUM FEATURE SETTINGS
+#####################################
+#Possible states of a feature:
+#DISABLED
+#BASIC
+#PREMIUM
+
+#GTP_MODE valid modes:
+# DISABLED
+# LEGACY_WWAN
+# SDK (WWAN not available for Modems before LocTech 10.0)
+GTP_MODE=DISABLED
+
+#GTP_WAA valid modes:
+# DISABLED
+# BASIC
+GTP_WAA=DISABLED
+
+#SAP valid modes:
+# DISABLED
+# BASIC
+# PREMIUM
+# MODEM_DEFAULT
+SAP=MODEM_DEFAULT
+
+#FREE_WIFI_SCAN_INJECT valid modes:
+#DISABLED
+#BASIC
+FREE_WIFI_SCAN_INJECT=BASIC
+
+#SUPL_WIFI valid modes:
+#DISABLED
+#BASIC
+SUPL_WIFI=BASIC
+
+#WIFI_SUPPLICANT_INFO valid modes:
+#DISABLED
+#BASIC
+WIFI_SUPPLICANT_INFO=BASIC
+
+#####################################
+# Location process launcher settings
+#####################################
+
+# DO NOT MODIFY
+# Modifying below attributes without
+# caution can have serious implications.
+
+#Values for PROCESS_STATE:
+# ENABLED
+# DISABLED
+
+#PROCESS_NAME
+# Name of the executable file.
+
+#FEATURE MASKS:
+# GTP-WIFI 0X03
+# GTP-MP-CELL 0xc00
+# GTP-WAA 0x100
+# SAP 0Xc0
+# ODCPI 0x1000
+# FREE_WIFI_SCAN_INJECT 0x2000
+# SUPL_WIFI 0x4000
+# WIFI_SUPPLICANT_INFO 0x8000
+
+#Values for PLATFORMS can be:
+#1. Any valid values obtained from ro.board.platform separated by single space. For example: msm8960 msm8226
+#2. 'all' or 'all exclude' -> for All platforms
+#3. 'all exclude XXXX' -> All platforms exclude XXXX. For example: all exclude msm8937
+
+#Values for BASEBAND can be:
+#1. Any valid values obtained from ro.baseband separated by single space. For example: sglte sglte2
+#2. 'all' or 'all exclude' -> for all basebands
+#3. 'all exclude XXXX' -> All basebands exclude XXXX. For example: all exclude sglte
+PROCESS_NAME=lowi-server
+PROCESS_ARGUMENT=
+PROCESS_STATE=ENABLED
+PROCESS_GROUPS=gps wifi inet oem_2901
+PREMIUM_FEATURE=0
+IZAT_FEATURE_MASK=0xf303
+PLATFORMS=all
+BASEBAND=all
+HARDWARE_TYPE=all
+VENDOR_ENHANCED_PROCESS=0
+
+PROCESS_NAME=xtwifi-inet-agent
+PROCESS_ARGUMENT=
+PROCESS_STATE=ENABLED
+PROCESS_GROUPS=inet gps
+PREMIUM_FEATURE=1
+IZAT_FEATURE_MASK=0xc03
+PLATFORMS=all
+BASEBAND=all
+HARDWARE_TYPE=all
+VENDOR_ENHANCED_PROCESS=1
+
+PROCESS_NAME=xtwifi-client
+PROCESS_ARGUMENT=
+PROCESS_STATE=ENABLED
+PROCESS_GROUPS=wifi inet gps system oem_2904
+PREMIUM_FEATURE=1
+IZAT_FEATURE_MASK=0xd03
+PLATFORMS=all
+BASEBAND=all
+HARDWARE_TYPE=all
+VENDOR_ENHANCED_PROCESS=1
+
+PROCESS_NAME=slim_daemon
+PROCESS_ARGUMENT=
+PROCESS_STATE=ENABLED
+PROCESS_GROUPS=gps oem_2901 can plugdev diag sensors
+PREMIUM_FEATURE=1
+IZAT_FEATURE_MASK=0xf0
+PLATFORMS=all
+BASEBAND=all
+HARDWARE_TYPE=all
+VENDOR_ENHANCED_PROCESS=1
+
+PROCESS_NAME=xtra-daemon
+PROCESS_ARGUMENT=
+PROCESS_STATE=ENABLED
+PROCESS_GROUPS=inet gps system
+PREMIUM_FEATURE=0
+IZAT_FEATURE_MASK=0
+PLATFORMS=all
+BASEBAND=all
+HARDWARE_TYPE=all
+VENDOR_ENHANCED_PROCESS=0
+
+########################################
+# Engine Service which host DRE module #
+# To enable DRE engine service, change #
+# PROCESS_STATE=ENABLED #
+########################################
+PROCESS_NAME=engine-service
+PROCESS_ARGUMENT=DRE-INT libloc_epDr.so
+PROCESS_STATE=DISABLED
+PROCESS_GROUPS=gps diag inet qwes oem_2901 system
+PREMIUM_FEATURE=0
+IZAT_FEATURE_MASK=0
+PLATFORMS=all
+BASEBAND=all
+HARDWARE_TYPE=all
+VENDOR_ENHANCED_PROCESS=1
+
+########################################
+# Engine Service which host PPE module #
+# To enable PPE engine service, change #
+# PROCESS_STATE=ENABLED #
+# and update process arugements #
+# with PPE library name #
+#PROCESS_ARGUMENT=PPE libepsimulator.so#
+########################################
+PROCESS_NAME=engine-service
+PROCESS_ARGUMENT=PPE libepsimulator.so
+PROCESS_STATE=DISABLED
+PROCESS_GROUPS=gps diag inet oem_2901
+PREMIUM_FEATURE=0
+IZAT_FEATURE_MASK=0
+PLATFORMS=all
+BASEBAND=all
+HARDWARE_TYPE=all
+VENDOR_ENHANCED_PROCESS=1
diff --git a/gps/etc/lowi.conf b/gps/etc/lowi.conf
new file mode 100644
index 0000000..5006b59
--- /dev/null
+++ b/gps/etc/lowi.conf
@@ -0,0 +1,27 @@
+#*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
+#
+# LOWI Config file
+#
+# GENERAL DESCRIPTION
+# This file contains the config params for LOWI
+#
+# Copyright (c) 2019 Qualcomm Technologies, Inc.
+# All Rights Reserved.
+# Confidential and Proprietary - Qualcomm Technologies, Inc.
+#
+# 2012-2013 Qualcomm Atheros, Inc.
+# All Rights Reserved.
+# Qualcomm Atheros Confidential and Proprietary.
+#
+# Export of this technology or software is regulated by the U.S. Government.
+# Diversion contrary to U.S. law prohibited.
+#=============================================================================*/
+
+# X86 ONLY - UBUNTU:
+# Copy this file in the same directory where the executable is
+
+# Log level
+# EL_LOG_OFF = 0, EL_ERROR = 1, EL_WARNING = 2, EL_INFO = 3, EL_DEBUG = 4, EL_VERBOSE = 5, EL_LOG_ALL = 100
+LOWI_LOG_LEVEL = 3
+LOWI_USE_LOWI_LP = 0
+
diff --git a/gps/etc/sap.conf b/gps/etc/sap.conf
new file mode 100644
index 0000000..0f71794
--- /dev/null
+++ b/gps/etc/sap.conf
@@ -0,0 +1,161 @@
+################################
+# Sensor Settings
+################################
+#The following parameters are optional.
+#Internal defaults support MEMS sensors
+#native to most handset devices.
+#Device specific sensor characterization
+#for improved performance is possible as
+#described in SAP application notes.
+#GYRO_BIAS_RANDOM_WALK=
+#ACCEL_RANDOM_WALK_SPECTRAL_DENSITY=
+#ANGLE_RANDOM_WALK_SPECTRAL_DENSITY=
+#RATE_RANDOM_WALK_SPECTRAL_DENSITY=
+#VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY=
+
+# Sensor Sampling Rate Parameters for Low-Data Rate Filter (should be greater than 0)
+# used in loc_eng_reinit
+SENSOR_ACCEL_BATCHES_PER_SEC=2
+SENSOR_ACCEL_SAMPLES_PER_BATCH=5
+SENSOR_GYRO_BATCHES_PER_SEC=2
+SENSOR_GYRO_SAMPLES_PER_BATCH=5
+# Sensor Sampling Rate Parameters for High-Data Rate Filter (should be greater than 0)
+SENSOR_ACCEL_BATCHES_PER_SEC_HIGH=4
+SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH=25
+SENSOR_GYRO_BATCHES_PER_SEC_HIGH=4
+SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH=25
+
+# Sensor Control Mode (0=AUTO, 1=FORCE_ON, 2=MODEM_DEFAULT)
+# used in loc_eng_reinit
+SENSOR_CONTROL_MODE=2
+
+# Bit mask used to define which sensor algorithms are used.
+# Setting each bit has the following definition:
+# 0x1 - DISABLE_INS_POSITIONING_FILTER
+# 0x0 - ENABLE_INS_POSITIONING_FILTER
+SENSOR_ALGORITHM_CONFIG_MASK=0x0
+
+#Vehicle Network Provider configuration
+
+#Service configuration strings
+#The number before colon in VN_X items defines version of the format of the rest of the string
+#VN_ACCEL_CFG=0:5
+#VN_GYRO_CFG=0:5.5
+#VN_ODOMETRY_CFG=0:2,4.5
+
+################################################
+# QDR3 configurations #
+################################################
+VN_SPEED_CFG=1:131,5,8,1,2,3,1,1,9,2,14,2
+VN_GEAR_CFG=1:422,20,4,0,4,1,9,0,1,2,3,4,5,6,7,8
+
+################################################
+# QDR2-Gyro configurations #
+################################################
+#VN_GYRO_CFG=1:555,0,1,0,0,0,0,-6.5,6.6066,-6.5,-1.00,2,6.607,6.6068,0,0,16,0.0002,0,16,0.0002,0,16,0.0002
+#VN_SPEED_CFG=1:555,0,0,1,2,1,0.01,0,56,8,48,8
+#VN_GEAR_CFG=1:555,16,4,0,1,1,9,0,1,2,3,4,5,6,7,8
+
+################################################
+# QDR2-DWT configurations #
+################################################
+#VN_SPEED_CFG=1:555,22,1,2,1,1,1,0,8,8,23,1,2,0,1,0,8,8,23,1
+#VN_GEAR_CFG=1:555,12,4,16,14,16,8,1,2,3,4,5,6,7,8
+#VN_DWS_CFG=1:555,0,0,1,3,1,1,0,0,8,0,0,8,8,0,0,16,8,0,0,24,8,0,0
+#VN_GYRO_CFG=1:555,40,16,1.0,40,16,1.0,40,16,1.0
+
+#####################################################################################
+# VNW service batching configuration strings #
+# VNW provider will initialize default type as Time based batching #
+# Each service batch value is configured to be 100 #
+# VN_ACCEL_CFG_BATCH_VALUE will be treated as time in Ms if VN_CFG_BATCH_TYPE #
+# is set to time based batching #
+# VN_ACCEL_CFG_BATCH_VALUE will be treated as sample count if VN_CFG_BATCH_TYPE #
+# is set to count based batching #
+# Uncomment and update batch time /sample count as per selected batching type #
+#####################################################################################
+# Batching type
+# 1 - Time based (default)
+# 2 - Count based
+#VN_CFG_BATCH_TYPE=1
+
+#Vehicle Accel batching value, it can either accept time in milli seconds or sample count
+#VN_ACCEL_CFG_BATCH_VALUE=100
+
+#Vehicle Gyro batching value, it can either accept time in milli seconds or sample count
+#VN_GYRO_CFG_BATCH_VALUE=100
+
+#Vehicle Odo batching value, it can either accept time in milli seconds or sample count
+#VN_ODOMETRY_CFG_BATCH_VALUE=100
+
+#Vehicle Speed batching value, it can either accept time in milli seconds or sample count
+#VN_SPEED_CFG_BATCH_VALUE=100
+
+#Vehicle Gear batching value, it can either accept time in milli seconds or sample count
+#VN_GEAR_CFG_BATCH_VALUE=100
+
+#Vehicle DWS batching value, it can either accept time in milli seconds or sample count
+#VN_DWS_CFG_BATCH_VALUE=100
+####################################################################################
+
+#Procesors clock ratio: AP and CAN bus microcontroller
+################################################
+# QDR3 configurations #
+################################################
+VN_PROC_CLOCK_RATIO=1.0
+
+################################################
+# QDR2-DWT OR QDR2-Gyro configurations #
+################################################
+#VN_PROC_CLOCK_RATIO = 1.0
+
+# Time source used by Sensor HAL
+# Setting this value controls accuracy of location sensor services.
+# 0 - Unknown
+# 1 - CLOCK_BOOTTIME
+# 2 - CLOCK_MONOTONIC
+# 3 - CLOCK_REALTIME
+# 4 - CLOCK_BOOTTIME using Alarm timer interface
+NDK_PROVIDER_TIME_SOURCE=1
+
+# Sensor Batching Configuration
+# 0 - Time based
+# 1 - Fixed count based
+# 2 - Variable count based
+COUNT_BASED_BATCHING=1
+SYNC_ONCE=0
+
+#Sensor HAL Provider Configuration HAL Library name including path
+################################################
+# #
+# Configuration for BMI 160 Sensor #
+# #
+################################################
+SENSOR_TYPE=2
+SENSOR_HAL_LIB_PATH=/usr/lib/libbmi160sensors.so.1
+
+################################################
+# #
+# Configuration for ASM330 Sensor #
+# #
+################################################
+#SENSOR_TYPE=1
+#SENSOR_HAL_LIB_PATH=/usr/lib/libasm330sensors.so.1
+
+
+################################################
+# #
+# Configuration for IAM20680 Sensor #
+# #
+################################################
+#SENSOR_TYPE=3
+#SENSOR_HAL_LIB_PATH=/usr/lib/libiam20680sensors.so.1
+
+
+################################################
+# #
+# Configuration for SMI130 Sensor #
+# #
+################################################
+#SENSOR_TYPE=4
+#SENSOR_HAL_LIB_PATH=/usr/lib/libsmi130sensors.so.1
diff --git a/gps/etc/xtwifi.conf b/gps/etc/xtwifi.conf
new file mode 100644
index 0000000..5d7df9e
--- /dev/null
+++ b/gps/etc/xtwifi.conf
@@ -0,0 +1,78 @@
+#GTP AP Project client core config file
+#
+#GENERAL DESCRIPTION
+#This is used by client core
+#
+#Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
+#All Rights Reserved.
+#Qualcomm Atheros Confidential and Proprietary.
+#
+#Copyright (c) 2017 Qualcomm Technologies, Inc.
+#All Rights Reserved.
+#Confidential and Proprietary - Qualcomm Technologies, Inc.
+
+##############################################################################
+# non-IOT devices configuration items #
+# For non-IOT devices, configure below configuration items #
+# according to the app note: 80-NK218-1 and remove the configuration items #
+# in section of "IOT devices configuration items". #
+##############################################################################
+
+# ASN URI v2 to be used by some GTP AP modules that
+# need to run with ASN URI v2 protocol.
+XT_SERVER_ROOT_URL = https://gtp1.izatcloud.net:443/uds/v2
+
+# ASN URI v3 to be used by GTP AP modules that
+# can support ASN URI v3 protocol.
+XT_SERVER_ROOT_URL_V3 = https://gtp1.izatcloud.net:443/uds/v3
+
+# size, in bytes, of the cache on device
+SIZE_BYTE_TOTAL_CACHE = 5000000
+
+##############################################################################
+# IOT devices configuration items #
+# For IOT devices, configure below configuration items #
+# according to the app note and remove the configuration items in section of #
+# "non-IOT devices configuration items". #
+##############################################################################
+
+# ASN URI v3 to be used by GTP AP modules that
+# can support ASN URI v3 protocol.
+# XT_SERVER_ROOT_URL_V3 = https://gtpma1.izatcloud.net:443/uds/v3
+
+# 3: Wi-Fi APDB injection via Izat SDK. GTP server is not accessed
+# for any GTP requests, instead notification is sent to Izat SDK.
+# WiFi crowdsourcing module is disabled.
+# 4: Wi-Fi APDB injection via Izat SDK. GTP server is not accessed
+# for any GTP requests, instead notification is sent to Izat SDK.
+# WiFi crowdsourcing module is active, also accessed via Izat SDK.
+# GTP_AP_MODE = 4
+
+# 1: MP cell features relies on GTP AP for either download or upload
+# 0: MP cell features does not rely on GTP AP
+# GTP_AP_NEEDED_BY_MP_CELL = 1
+
+##############################################################################
+# Configuration items applicable to all devices #
+##############################################################################
+
+# Log verbosity control for most of the GTP WiFi system, including native and
+# Java componenets
+# OFF = 0, ERROR = 1, WARNING = 2, INFO = 3, DEBUG = 4, VERBOSE = 5, ALL = 100
+DEBUG_GLOBAL_LOG_LEVEL = 2
+
+# this is used at the server side to distinguish uploads from different maker/model
+# default "Qualcomm"
+OEM_ID_IN_REQUEST_TO_SERVER = "Qualcomm"
+
+# this is used at the server side to distinguish uploads from different maker/model
+# default "UNKNOWN"
+MODEL_ID_IN_REQUEST_TO_SERVER = "UNKNOWN"
+
+##############################################################################
+# Qualcomm Network Location Provider config #
+##############################################################################
+
+# Accuracy Threshold for NLP position. Position exceeds thsi threshold will be filtered out.
+# Default is 25000 meters.
+LARGE_ACCURACY_THRESHOLD_TO_FILTER_NLP_POSITION = 25000
diff --git a/gps/geofence/Android.mk b/gps/geofence/Android.mk
new file mode 100644
index 0000000..133d408
--- /dev/null
+++ b/gps/geofence/Android.mk
@@ -0,0 +1,38 @@
+ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libgeofencing
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES:= \
+ GeofenceAdapter.cpp \
+ location_geofence.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libcutils \
+ libgps.utils \
+ liblog \
+ libloc_core
+
+LOCAL_HEADER_LIBRARIES := \
+ libgps.utils_headers \
+ libloc_core_headers \
+ libloc_pla_headers \
+ liblocation_api_headers
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+include $(BUILD_SHARED_LIBRARY)
+
+endif # not BUILD_TINY_ANDROID
+endif # BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
+
diff --git a/gps/geofence/GeofenceAdapter.cpp b/gps/geofence/GeofenceAdapter.cpp
new file mode 100644
index 0000000..e299589
--- /dev/null
+++ b/gps/geofence/GeofenceAdapter.cpp
@@ -0,0 +1,870 @@
+/* Copyright (c) 2013-2019, 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_TAG "LocSvc_GeofenceAdapter"
+
+#include <GeofenceAdapter.h>
+#include "loc_log.h"
+#include <log_util.h>
+#include <string>
+
+using namespace loc_core;
+
+GeofenceAdapter::GeofenceAdapter() :
+ LocAdapterBase(0,
+ LocContext::getLocContext(
+ NULL,
+ NULL,
+ LocContext::mLocationHalName,
+ false),
+ true /*isMaster*/)
+{
+ LOC_LOGD("%s]: Constructor", __func__);
+}
+
+void
+GeofenceAdapter::stopClientSessions(LocationAPI* client)
+{
+ LOC_LOGD("%s]: client %p", __func__, client);
+
+
+ for (auto it = mGeofenceIds.begin(); it != mGeofenceIds.end();) {
+ uint32_t hwId = it->second;
+ GeofenceKey key(it->first);
+ if (client == key.client) {
+ it = mGeofenceIds.erase(it);
+ mLocApi->removeGeofence(hwId, key.id,
+ new LocApiResponse(*getContext(),
+ [this, hwId] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ auto it2 = mGeofences.find(hwId);
+ if (it2 != mGeofences.end()) {
+ mGeofences.erase(it2);
+ } else {
+ LOC_LOGE("%s]:geofence item to erase not found. hwId %u", __func__, hwId);
+ }
+ }
+ }));
+ continue;
+ }
+ ++it; // increment only when not erasing an iterator
+ }
+
+}
+
+void
+GeofenceAdapter::updateClientsEventMask()
+{
+ LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if (it->second.geofenceBreachCb != nullptr) {
+ mask |= LOC_API_ADAPTER_BIT_BATCHED_GENFENCE_BREACH_REPORT;
+ mask |= LOC_API_ADAPTER_BIT_REPORT_GENFENCE_DWELL;
+ }
+ if (it->second.geofenceStatusCb != nullptr) {
+ mask |= LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT;
+ }
+ }
+ updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
+}
+
+LocationError
+GeofenceAdapter::getHwIdFromClient(LocationAPI* client, uint32_t clientId, uint32_t& hwId)
+{
+ GeofenceKey key(client, clientId);
+ auto it = mGeofenceIds.find(key);
+ if (it != mGeofenceIds.end()) {
+ hwId = it->second;
+ return LOCATION_ERROR_SUCCESS;
+ }
+ return LOCATION_ERROR_ID_UNKNOWN;
+}
+
+LocationError
+GeofenceAdapter::getGeofenceKeyFromHwId(uint32_t hwId, GeofenceKey& key)
+{
+ auto it = mGeofences.find(hwId);
+ if (it != mGeofences.end()) {
+ key = it->second.key;
+ return LOCATION_ERROR_SUCCESS;
+ }
+ return LOCATION_ERROR_ID_UNKNOWN;
+}
+
+void
+GeofenceAdapter::handleEngineUpEvent()
+{
+ struct MsgSSREvent : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ inline MsgSSREvent(GeofenceAdapter& adapter) :
+ LocMsg(),
+ mAdapter(adapter) {}
+ virtual void proc() const {
+ mAdapter.setEngineCapabilitiesKnown(true);
+ mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
+ mAdapter.restartGeofences();
+ for (auto msg: mAdapter.mPendingMsgs) {
+ mAdapter.sendMsg(msg);
+ }
+ mAdapter.mPendingMsgs.clear();
+ }
+ };
+
+ sendMsg(new MsgSSREvent(*this));
+}
+
+void
+GeofenceAdapter::restartGeofences()
+{
+ if (mGeofences.empty()) {
+ return;
+ }
+
+ GeofencesMap oldGeofences(mGeofences);
+ mGeofences.clear();
+ mGeofenceIds.clear();
+
+ for (auto it = oldGeofences.begin(); it != oldGeofences.end(); it++) {
+ GeofenceObject object = it->second;
+ GeofenceOption options = {sizeof(GeofenceOption),
+ object.breachMask,
+ object.responsiveness,
+ object.dwellTime};
+ GeofenceInfo info = {sizeof(GeofenceInfo),
+ object.latitude,
+ object.longitude,
+ object.radius};
+ mLocApi->addGeofence(object.key.id,
+ options,
+ info,
+ new LocApiResponseData<LocApiGeofenceData>(*getContext(),
+ [this, object, options, info] (LocationError err, LocApiGeofenceData data) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (true == object.paused) {
+ mLocApi->pauseGeofence(data.hwId, object.key.id,
+ new LocApiResponse(*getContext(), [] (LocationError err ) {}));
+ }
+ saveGeofenceItem(object.key.client, object.key.id, data.hwId, options, info);
+ }
+ }));
+ }
+}
+
+void
+GeofenceAdapter::reportResponse(LocationAPI* client, size_t count, LocationError* errs,
+ uint32_t* ids)
+{
+ IF_LOC_LOGD {
+ std::string idsString = "[";
+ std::string errsString = "[";
+ if (NULL != ids && NULL != errs) {
+ for (size_t i=0; i < count; ++i) {
+ idsString += std::to_string(ids[i]) + " ";
+ errsString += std::to_string(errs[i]) + " ";
+ }
+ }
+ idsString += "]";
+ errsString += "]";
+
+ LOC_LOGD("%s]: client %p ids %s errs %s",
+ __func__, client, idsString.c_str(), errsString.c_str());
+ }
+
+ auto it = mClientData.find(client);
+ if (it != mClientData.end() && it->second.collectiveResponseCb != nullptr) {
+ it->second.collectiveResponseCb(count, errs, ids);
+ } else {
+ LOC_LOGE("%s]: client %p response not found in info", __func__, client);
+ }
+}
+
+uint32_t*
+GeofenceAdapter::addGeofencesCommand(LocationAPI* client, size_t count, GeofenceOption* options,
+ GeofenceInfo* infos)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgAddGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ GeofenceOption* mOptions;
+ GeofenceInfo* mInfos;
+ inline MsgAddGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids,
+ GeofenceOption* options,
+ GeofenceInfo* infos) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids),
+ mOptions(options),
+ mInfos(infos) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ if (NULL == mIds || NULL == mOptions || NULL == mInfos) {
+ errs[i] = LOCATION_ERROR_INVALID_PARAMETER;
+ } else {
+ mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient,
+ mOptions = mOptions, mInfos = mInfos, mIds = mIds, &mApi = mApi,
+ errs, i] (LocationError err ) {
+ mApi.addGeofence(mIds[i], mOptions[i], mInfos[i],
+ new LocApiResponseData<LocApiGeofenceData>(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mOptions = mOptions, mClient = mClient,
+ mCount = mCount, mIds = mIds, mInfos = mInfos, errs, i]
+ (LocationError err, LocApiGeofenceData data) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.saveGeofenceItem(mClient,
+ mIds[i],
+ data.hwId,
+ mOptions[i],
+ mInfos[i]);
+ }
+ errs[i] = err;
+
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ delete[] mOptions;
+ delete[] mInfos;
+ }
+ }));
+ }));
+ }
+ }
+ }
+ };
+
+ if (0 == count) {
+ return NULL;
+ }
+ uint32_t* ids = new uint32_t[count];
+ if (nullptr == ids) {
+ LOC_LOGE("%s]: new failed to allocate ids", __func__);
+ return NULL;
+ }
+ if (NULL != ids) {
+ for (size_t i=0; i < count; ++i) {
+ ids[i] = generateSessionId();
+ }
+ }
+ GeofenceOption* optionsCopy;
+ if (options == NULL) {
+ optionsCopy = NULL;
+ } else {
+ optionsCopy = new GeofenceOption[count];
+ if (nullptr == optionsCopy) {
+ LOC_LOGE("%s]: new failed to allocate optionsCopy", __func__);
+ return NULL;
+ }
+ COPY_IF_NOT_NULL(optionsCopy, options, count);
+ }
+ GeofenceInfo* infosCopy;
+ if (infos == NULL) {
+ infosCopy = NULL;
+ } else {
+ infosCopy = new GeofenceInfo[count];
+ if (nullptr == infosCopy) {
+ LOC_LOGE("%s]: new failed to allocate infosCopy", __func__);
+ return NULL;
+ }
+ COPY_IF_NOT_NULL(infosCopy, infos, count);
+ }
+
+ sendMsg(new MsgAddGeofences(*this, *mLocApi, client, count, ids, optionsCopy, infosCopy));
+ return ids;
+}
+
+void
+GeofenceAdapter::removeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgRemoveGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ inline MsgRemoveGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ &mApi = mApi, errs, i] (LocationError err ) {
+ uint32_t hwId = 0;
+ errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
+ if (LOCATION_ERROR_SUCCESS == errs[i]) {
+ mApi.removeGeofence(hwId, mIds[i],
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ hwId, errs, i] (LocationError err ) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.removeGeofenceItem(hwId);
+ }
+ errs[i] = err;
+
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }));
+ } else {
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }
+ }));
+ }
+ }
+ };
+
+ if (0 == count) {
+ return;
+ }
+ uint32_t* idsCopy = new uint32_t[count];
+ if (nullptr == idsCopy) {
+ LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(idsCopy, ids, count);
+ sendMsg(new MsgRemoveGeofences(*this, *mLocApi, client, count, idsCopy));
+}
+
+void
+GeofenceAdapter::pauseGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgPauseGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ inline MsgPauseGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ &mApi = mApi, errs, i] (LocationError err ) {
+ uint32_t hwId = 0;
+ errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
+ if (LOCATION_ERROR_SUCCESS == errs[i]) {
+ mApi.pauseGeofence(hwId, mIds[i], new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ hwId, errs, i] (LocationError err ) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.pauseGeofenceItem(hwId);
+ }
+ errs[i] = err;
+
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }));
+ } else {
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }
+ }));
+ }
+ }
+ };
+
+ if (0 == count) {
+ return;
+ }
+ uint32_t* idsCopy = new uint32_t[count];
+ if (nullptr == idsCopy) {
+ LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(idsCopy, ids, count);
+ sendMsg(new MsgPauseGeofences(*this, *mLocApi, client, count, idsCopy));
+}
+
+void
+GeofenceAdapter::resumeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgResumeGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ inline MsgResumeGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ &mApi = mApi, errs, i] (LocationError err ) {
+ uint32_t hwId = 0;
+ errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
+ if (LOCATION_ERROR_SUCCESS == errs[i]) {
+ mApi.resumeGeofence(hwId, mIds[i],
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, hwId,
+ errs, mIds = mIds, i] (LocationError err ) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ errs[i] = err;
+
+ mAdapter.resumeGeofenceItem(hwId);
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }
+ }));
+ } else {
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ }
+ }
+ }));
+ }
+ }
+ };
+
+ if (0 == count) {
+ return;
+ }
+ uint32_t* idsCopy = new uint32_t[count];
+ if (nullptr == idsCopy) {
+ LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(idsCopy, ids, count);
+ sendMsg(new MsgResumeGeofences(*this, *mLocApi, client, count, idsCopy));
+}
+
+void
+GeofenceAdapter::modifyGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids,
+ GeofenceOption* options)
+{
+ LOC_LOGD("%s]: client %p count %zu", __func__, client, count);
+
+ struct MsgModifyGeofences : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ LocApiBase& mApi;
+ LocationAPI* mClient;
+ size_t mCount;
+ uint32_t* mIds;
+ GeofenceOption* mOptions;
+ inline MsgModifyGeofences(GeofenceAdapter& adapter,
+ LocApiBase& api,
+ LocationAPI* client,
+ size_t count,
+ uint32_t* ids,
+ GeofenceOption* options) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mClient(client),
+ mCount(count),
+ mIds(ids),
+ mOptions(options) {}
+ inline virtual void proc() const {
+ LocationError* errs = new LocationError[mCount];
+ if (nullptr == errs) {
+ LOC_LOGE("%s]: new failed to allocate errs", __func__);
+ return;
+ }
+ for (size_t i=0; i < mCount; ++i) {
+ if (NULL == mIds || NULL == mOptions) {
+ errs[i] = LOCATION_ERROR_INVALID_PARAMETER;
+ } else {
+ mApi.addToCallQueue(new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient, mIds = mIds,
+ &mApi = mApi, mOptions = mOptions, errs, i] (LocationError err ) {
+ uint32_t hwId = 0;
+ errs[i] = mAdapter.getHwIdFromClient(mClient, mIds[i], hwId);
+ if (LOCATION_ERROR_SUCCESS == errs[i]) {
+ mApi.modifyGeofence(hwId, mIds[i], mOptions[i],
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mCount = mCount, mClient = mClient,
+ mIds = mIds, mOptions = mOptions, hwId, errs, i]
+ (LocationError err ) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ errs[i] = err;
+
+ mAdapter.modifyGeofenceItem(hwId, mOptions[i]);
+ }
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ delete[] mOptions;
+ }
+ }));
+ } else {
+ // Send aggregated response on last item and cleanup
+ if (i == mCount-1) {
+ mAdapter.reportResponse(mClient, mCount, errs, mIds);
+ delete[] errs;
+ delete[] mIds;
+ delete[] mOptions;
+ }
+ }
+ }));
+ }
+ }
+ }
+ };
+
+ if (0 == count) {
+ return;
+ }
+ uint32_t* idsCopy = new uint32_t[count];
+ if (nullptr == idsCopy) {
+ LOC_LOGE("%s]: new failed to allocate idsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(idsCopy, ids, count);
+ GeofenceOption* optionsCopy;
+ if (options == NULL) {
+ optionsCopy = NULL;
+ } else {
+ optionsCopy = new GeofenceOption[count];
+ if (nullptr == optionsCopy) {
+ LOC_LOGE("%s]: new failed to allocate optionsCopy", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(optionsCopy, options, count);
+ }
+
+ sendMsg(new MsgModifyGeofences(*this, *mLocApi, client, count, idsCopy, optionsCopy));
+}
+
+void
+GeofenceAdapter::saveGeofenceItem(LocationAPI* client, uint32_t clientId, uint32_t hwId,
+ const GeofenceOption& options, const GeofenceInfo& info)
+{
+ LOC_LOGD("%s]: hwId %u client %p clientId %u", __func__, hwId, client, clientId);
+ GeofenceKey key(client, clientId);
+ GeofenceObject object = {key,
+ options.breachTypeMask,
+ options.responsiveness,
+ options.dwellTime,
+ info.latitude,
+ info.longitude,
+ info.radius,
+ false};
+ mGeofences[hwId] = object;
+ mGeofenceIds[key] = hwId;
+ dump();
+}
+
+void
+GeofenceAdapter::removeGeofenceItem(uint32_t hwId)
+{
+ GeofenceKey key;
+ LocationError err = getGeofenceKeyFromHwId(hwId, key);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ LOC_LOGE("%s]: can not find the key for hwId %u", __func__, hwId);
+ } else {
+ auto it1 = mGeofenceIds.find(key);
+ if (it1 != mGeofenceIds.end()) {
+ mGeofenceIds.erase(it1);
+
+ auto it2 = mGeofences.find(hwId);
+ if (it2 != mGeofences.end()) {
+ mGeofences.erase(it2);
+ dump();
+ } else {
+ LOC_LOGE("%s]:geofence item to erase not found. hwId %u", __func__, hwId);
+ }
+ } else {
+ LOC_LOGE("%s]: geofence item to erase not found. hwId %u", __func__, hwId);
+ }
+ }
+}
+
+void
+GeofenceAdapter::pauseGeofenceItem(uint32_t hwId)
+{
+ auto it = mGeofences.find(hwId);
+ if (it != mGeofences.end()) {
+ it->second.paused = true;
+ dump();
+ } else {
+ LOC_LOGE("%s]: geofence item to pause not found. hwId %u", __func__, hwId);
+ }
+}
+
+void
+GeofenceAdapter::resumeGeofenceItem(uint32_t hwId)
+{
+ auto it = mGeofences.find(hwId);
+ if (it != mGeofences.end()) {
+ it->second.paused = false;
+ dump();
+ } else {
+ LOC_LOGE("%s]: geofence item to resume not found. hwId %u", __func__, hwId);
+ }
+}
+
+void
+GeofenceAdapter::modifyGeofenceItem(uint32_t hwId, const GeofenceOption& options)
+{
+ auto it = mGeofences.find(hwId);
+ if (it != mGeofences.end()) {
+ it->second.breachMask = options.breachTypeMask;
+ it->second.responsiveness = options.responsiveness;
+ it->second.dwellTime = options.dwellTime;
+ dump();
+ } else {
+ LOC_LOGE("%s]: geofence item to modify not found. hwId %u", __func__, hwId);
+ }
+}
+
+
+void
+GeofenceAdapter::geofenceBreachEvent(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp)
+{
+
+ IF_LOC_LOGD {
+ std::string idsString = "[";
+ if (NULL != hwIds) {
+ for (size_t i=0; i < count; ++i) {
+ idsString += std::to_string(hwIds[i]) + " ";
+ }
+ }
+ idsString += "]";
+ LOC_LOGD("%s]: breachType %u count %zu ids %s",
+ __func__, breachType, count, idsString.c_str());
+ }
+
+ if (0 == count || NULL == hwIds)
+ return;
+
+ struct MsgGeofenceBreach : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ size_t mCount;
+ uint32_t* mHwIds;
+ Location mLocation;
+ GeofenceBreachType mBreachType;
+ uint64_t mTimestamp;
+ inline MsgGeofenceBreach(GeofenceAdapter& adapter,
+ size_t count,
+ uint32_t* hwIds,
+ Location& location,
+ GeofenceBreachType breachType,
+ uint64_t timestamp) :
+ LocMsg(),
+ mAdapter(adapter),
+ mCount(count),
+ mHwIds(new uint32_t[count]),
+ mLocation(location),
+ mBreachType(breachType),
+ mTimestamp(timestamp)
+ {
+ if (nullptr == mHwIds) {
+ LOC_LOGE("%s]: new failed to allocate mHwIds", __func__);
+ return;
+ }
+ COPY_IF_NOT_NULL(mHwIds, hwIds, mCount);
+ }
+ inline virtual ~MsgGeofenceBreach() {
+ delete[] mHwIds;
+ }
+ inline virtual void proc() const {
+ mAdapter.geofenceBreach(mCount, mHwIds, mLocation, mBreachType, mTimestamp);
+ }
+ };
+
+ sendMsg(new MsgGeofenceBreach(*this, count, hwIds, location, breachType, timestamp));
+
+}
+
+void
+GeofenceAdapter::geofenceBreach(size_t count, uint32_t* hwIds, const Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp)
+{
+
+ for (auto it = mClientData.begin(); it != mClientData.end(); ++it) {
+ uint32_t* clientIds = new uint32_t[count];
+ if (nullptr == clientIds) {
+ return;
+ }
+ uint32_t index = 0;
+ for (size_t i=0; i < count; ++i) {
+ GeofenceKey key;
+ LocationError err = getGeofenceKeyFromHwId(hwIds[i], key);
+ if (LOCATION_ERROR_SUCCESS == err) {
+ if (key.client == it->first) {
+ clientIds[index++] = key.id;
+ }
+ }
+ }
+ if (index > 0 && it->second.geofenceBreachCb != nullptr) {
+ GeofenceBreachNotification notify = {sizeof(GeofenceBreachNotification),
+ index,
+ clientIds,
+ location,
+ breachType,
+ timestamp};
+
+ it->second.geofenceBreachCb(notify);
+ }
+ delete[] clientIds;
+ }
+}
+
+void
+GeofenceAdapter::geofenceStatusEvent(GeofenceStatusAvailable available)
+{
+ LOC_LOGD("%s]: available %u ", __func__, available);
+
+ struct MsgGeofenceStatus : public LocMsg {
+ GeofenceAdapter& mAdapter;
+ GeofenceStatusAvailable mAvailable;
+ inline MsgGeofenceStatus(GeofenceAdapter& adapter,
+ GeofenceStatusAvailable available) :
+ LocMsg(),
+ mAdapter(adapter),
+ mAvailable(available) {}
+ inline virtual void proc() const {
+ mAdapter.geofenceStatus(mAvailable);
+ }
+ };
+
+ sendMsg(new MsgGeofenceStatus(*this, available));
+}
+
+void
+GeofenceAdapter::geofenceStatus(GeofenceStatusAvailable available)
+{
+ for (auto it = mClientData.begin(); it != mClientData.end(); ++it) {
+ if (it->second.geofenceStatusCb != nullptr) {
+ GeofenceStatusNotification notify = {sizeof(GeofenceStatusNotification),
+ available,
+ LOCATION_TECHNOLOGY_TYPE_GNSS};
+ it->second.geofenceStatusCb(notify);
+ }
+ }
+}
+
+void
+GeofenceAdapter::dump()
+{
+ IF_LOC_LOGV {
+ LOC_LOGV(
+ "HAL | hwId | mask | respon | latitude | longitude | radius | paused | Id | client");
+ for (auto it = mGeofences.begin(); it != mGeofences.end(); ++it) {
+ uint32_t hwId = it->first;
+ GeofenceObject object = it->second;
+ LOC_LOGV(" | %5u | %4u | %6u | %8.2f | %9.2f | %6.2f | %6u | %04x | %p ",
+ hwId, object.breachMask, object.responsiveness,
+ object.latitude, object.longitude, object.radius,
+ object.paused, object.key.id, object.key.client);
+ }
+ }
+}
+
diff --git a/gps/geofence/GeofenceAdapter.h b/gps/geofence/GeofenceAdapter.h
new file mode 100644
index 0000000..38f4823
--- /dev/null
+++ b/gps/geofence/GeofenceAdapter.h
@@ -0,0 +1,136 @@
+/* Copyright (c) 2013-2019, 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 GEOFENCE_ADAPTER_H
+#define GEOFENCE_ADAPTER_H
+
+#include <LocAdapterBase.h>
+#include <LocContext.h>
+#include <LocationAPI.h>
+#include <map>
+
+using namespace loc_core;
+
+#define COPY_IF_NOT_NULL(dest, src, len) do { \
+ if (NULL!=dest && NULL!=src) { \
+ for (size_t i=0; i<len; ++i) { \
+ dest[i] = src[i]; \
+ } \
+ } \
+} while (0)
+
+typedef struct GeofenceKey {
+ LocationAPI* client;
+ uint32_t id;
+ inline GeofenceKey() :
+ client(NULL), id(0) {}
+ inline GeofenceKey(LocationAPI* _client, uint32_t _id) :
+ client(_client), id(_id) {}
+} GeofenceKey;
+inline bool operator <(GeofenceKey const& left, GeofenceKey const& right) {
+ return left.id < right.id || (left.id == right.id && left.client < right.client);
+}
+inline bool operator ==(GeofenceKey const& left, GeofenceKey const& right) {
+ return left.id == right.id && left.client == right.client;
+}
+inline bool operator !=(GeofenceKey const& left, GeofenceKey const& right) {
+ return left.id != right.id || left.client != right.client;
+}
+typedef struct {
+ GeofenceKey key;
+ GeofenceBreachTypeMask breachMask;
+ uint32_t responsiveness;
+ uint32_t dwellTime;
+ double latitude;
+ double longitude;
+ double radius;
+ bool paused;
+} GeofenceObject;
+typedef std::map<uint32_t, GeofenceObject> GeofencesMap; //map of hwId to GeofenceObject
+typedef std::map<GeofenceKey, uint32_t> GeofenceIdMap; //map of GeofenceKey to hwId
+
+class GeofenceAdapter : public LocAdapterBase {
+
+ /* ==== GEOFENCES ====================================================================== */
+ GeofencesMap mGeofences; //map hwId to GeofenceObject
+ GeofenceIdMap mGeofenceIds; //map of GeofenceKey to hwId
+
+protected:
+
+ /* ==== CLIENT ========================================================================= */
+ virtual void updateClientsEventMask();
+ virtual void stopClientSessions(LocationAPI* client);
+
+public:
+
+ GeofenceAdapter();
+ virtual ~GeofenceAdapter() {}
+
+ /* ==== SSR ============================================================================ */
+ /* ======== EVENTS ====(Called from QMI Thread)========================================= */
+ virtual void handleEngineUpEvent();
+ /* ======== UTILITIES ================================================================== */
+ void restartGeofences();
+
+ /* ==== GEOFENCES ====================================================================== */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ uint32_t* addGeofencesCommand(LocationAPI* client, size_t count,
+ GeofenceOption* options, GeofenceInfo* info);
+ void removeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids);
+ void pauseGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids);
+ void resumeGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids);
+ void modifyGeofencesCommand(LocationAPI* client, size_t count, uint32_t* ids,
+ GeofenceOption* options);
+ /* ======== RESPONSES ================================================================== */
+ void reportResponse(LocationAPI* client, size_t count, LocationError* errs, uint32_t* ids);
+ /* ======== UTILITIES ================================================================== */
+ void saveGeofenceItem(LocationAPI* client,
+ uint32_t clientId,
+ uint32_t hwId,
+ const GeofenceOption& options,
+ const GeofenceInfo& info);
+ void removeGeofenceItem(uint32_t hwId);
+ void pauseGeofenceItem(uint32_t hwId);
+ void resumeGeofenceItem(uint32_t hwId);
+ void modifyGeofenceItem(uint32_t hwId, const GeofenceOption& options);
+ LocationError getHwIdFromClient(LocationAPI* client, uint32_t clientId, uint32_t& hwId);
+ LocationError getGeofenceKeyFromHwId(uint32_t hwId, GeofenceKey& key);
+ void dump();
+
+ /* ==== REPORTS ======================================================================== */
+ /* ======== EVENTS ====(Called from QMI Thread)========================================= */
+ void geofenceBreachEvent(size_t count, uint32_t* hwIds, Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp);
+ void geofenceStatusEvent(GeofenceStatusAvailable available);
+ /* ======== UTILITIES ================================================================== */
+ void geofenceBreach(size_t count, uint32_t* hwIds, const Location& location,
+ GeofenceBreachType breachType, uint64_t timestamp);
+ void geofenceStatus(GeofenceStatusAvailable available);
+};
+
+#endif /* GEOFENCE_ADAPTER_H */
diff --git a/gps/geofence/location_geofence.cpp b/gps/geofence/location_geofence.cpp
new file mode 100644
index 0000000..66729f4
--- /dev/null
+++ b/gps/geofence/location_geofence.cpp
@@ -0,0 +1,145 @@
+/* Copyright (c) 2017-2019, 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.
+ *
+ */
+#include "GeofenceAdapter.h"
+#include "location_interface.h"
+
+static GeofenceAdapter* gGeofenceAdapter = NULL;
+
+static void initialize();
+static void deinitialize();
+
+static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb);
+static void requestCapabilities(LocationAPI* client);
+
+static uint32_t* addGeofences(LocationAPI* client, size_t count, GeofenceOption*, GeofenceInfo*);
+static void removeGeofences(LocationAPI* client, size_t count, uint32_t* ids);
+static void modifyGeofences(LocationAPI* client, size_t count, uint32_t* ids,
+ GeofenceOption* options);
+static void pauseGeofences(LocationAPI* client, size_t count, uint32_t* ids);
+static void resumeGeofences(LocationAPI* client, size_t count, uint32_t* ids);
+
+static const GeofenceInterface gGeofenceInterface = {
+ sizeof(GeofenceInterface),
+ initialize,
+ deinitialize,
+ addClient,
+ removeClient,
+ requestCapabilities,
+ addGeofences,
+ removeGeofences,
+ modifyGeofences,
+ pauseGeofences,
+ resumeGeofences
+};
+
+#ifndef DEBUG_X86
+extern "C" const GeofenceInterface* getGeofenceInterface()
+#else
+const GeofenceInterface* getGeofenceInterface()
+#endif // DEBUG_X86
+{
+ return &gGeofenceInterface;
+}
+
+static void initialize()
+{
+ if (NULL == gGeofenceAdapter) {
+ gGeofenceAdapter = new GeofenceAdapter();
+ }
+}
+
+static void deinitialize()
+{
+ if (NULL != gGeofenceAdapter) {
+ delete gGeofenceAdapter;
+ gGeofenceAdapter = NULL;
+ }
+}
+
+static void addClient(LocationAPI* client, const LocationCallbacks& callbacks)
+{
+ if (NULL != gGeofenceAdapter) {
+ gGeofenceAdapter->addClientCommand(client, callbacks);
+ }
+}
+
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb)
+{
+ if (NULL != gGeofenceAdapter) {
+ gGeofenceAdapter->removeClientCommand(client, rmClientCb);
+ }
+}
+
+static void requestCapabilities(LocationAPI* client)
+{
+ if (NULL != gGeofenceAdapter) {
+ gGeofenceAdapter->requestCapabilitiesCommand(client);
+ }
+}
+
+static uint32_t* addGeofences(LocationAPI* client, size_t count,
+ GeofenceOption* options, GeofenceInfo* info)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->addGeofencesCommand(client, count, options, info);
+ } else {
+ return NULL;
+ }
+}
+
+static void removeGeofences(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->removeGeofencesCommand(client, count, ids);
+ }
+}
+
+static void modifyGeofences(LocationAPI* client, size_t count, uint32_t* ids,
+ GeofenceOption* options)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->modifyGeofencesCommand(client, count, ids, options);
+ }
+}
+
+static void pauseGeofences(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->pauseGeofencesCommand(client, count, ids);
+ }
+}
+
+static void resumeGeofences(LocationAPI* client, size_t count, uint32_t* ids)
+{
+ if (NULL != gGeofenceAdapter) {
+ return gGeofenceAdapter->resumeGeofencesCommand(client, count, ids);
+ }
+}
+
diff --git a/gps/gnss/Agps.cpp b/gps/gnss/Agps.cpp
index 6ce0c34..9255f88 100644
--- a/gps/gnss/Agps.cpp
+++ b/gps/gnss/Agps.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 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
@@ -26,13 +26,14 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-
+#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_Agps"
#include <Agps.h>
#include <loc_pla.h>
#include <ContextBase.h>
#include <loc_timer.h>
+#include <inttypes.h>
/* --------------------------------------------------------------------
* AGPS State Machine Methods
@@ -77,16 +78,8 @@ void AgpsStateMachine::processAgpsEventSubscribe(){
/* Add subscriber to list
* No notifications until we get RSRC_GRANTED */
addSubscriber(mCurrentSubscriber);
-
- /* Send data request
- * The if condition below 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 (requestOrReleaseDataConn(true) == 0) {
- // If data request successful, move to pending state
- transitionState(AGPS_STATE_PENDING);
- }
+ requestOrReleaseDataConn(true);
+ transitionState(AGPS_STATE_PENDING);
break;
case AGPS_STATE_PENDING:
@@ -293,24 +286,25 @@ void AgpsStateMachine::processAgpsEventDenied(){
* bool request :
* true = Request data connection
* false = Release data connection */
-int AgpsStateMachine::requestOrReleaseDataConn(bool request){
+void AgpsStateMachine::requestOrReleaseDataConn(bool request){
AGnssExtStatusIpV4 nifRequest;
memset(&nifRequest, 0, sizeof(nifRequest));
nifRequest.type = mAgpsType;
-
+ nifRequest.apnTypeMask = mApnTypeMask;
if (request) {
- LOC_LOGD("AGPS Data Conn Request");
+ LOC_LOGD("AGPS Data Conn Request mAgpsType=%d mApnTypeMask=0x%X",
+ mAgpsType, mApnTypeMask);
nifRequest.status = LOC_GPS_REQUEST_AGPS_DATA_CONN;
}
else{
- LOC_LOGD("AGPS Data Conn Release");
+ LOC_LOGD("AGPS Data Conn Release mAgpsType=%d mApnTypeMask=0x%X",
+ mAgpsType, mApnTypeMask);
nifRequest.status = LOC_GPS_RELEASE_AGPS_DATA_CONN;
}
- mAgpsManager->mFrameworkStatusV4Cb(nifRequest);
- return 0;
+ mFrameworkStatusV4Cb(nifRequest);
}
void AgpsStateMachine::notifyAllSubscribers(
@@ -360,14 +354,14 @@ void AgpsStateMachine::notifyEventToSubscriber(
case AGPS_EVENT_GRANTED:
mAgpsManager->mAtlOpenStatusCb(
- subscriberToNotify->mConnHandle, 1, getAPN(),
- getBearer(), mAgpsType);
+ subscriberToNotify->mConnHandle, 1, getAPN(), getAPNLen(),
+ getBearer(), mAgpsType, mApnTypeMask);
break;
case AGPS_EVENT_DENIED:
mAgpsManager->mAtlOpenStatusCb(
- subscriberToNotify->mConnHandle, 0, getAPN(),
- getBearer(), mAgpsType);
+ subscriberToNotify->mConnHandle, 0, getAPN(), getAPNLen(),
+ getBearer(), mAgpsType, mApnTypeMask);
break;
case AGPS_EVENT_UNSUBSCRIBE:
@@ -451,15 +445,14 @@ void AgpsStateMachine::setAPN(char* apn, unsigned int len){
if (NULL != mAPN) {
delete mAPN;
+ mAPN = NULL;
}
- if (apn == NULL || len <= 0) {
+ if (NULL == apn || len <= 0 || len > MAX_APN_LEN || strlen(apn) != len) {
LOC_LOGD("Invalid apn len (%d) or null apn", len);
mAPN = NULL;
mAPNLen = 0;
- }
-
- if (NULL != apn) {
+ } else {
mAPN = new char[len+1];
if (NULL != mAPN) {
memcpy(mAPN, apn, len);
@@ -513,194 +506,12 @@ void AgpsStateMachine::dropAllSubscribers(){
}
/* --------------------------------------------------------------------
- * DS State Machine Methods
- * -------------------------------------------------------------------*/
-const int DSStateMachine::MAX_START_DATA_CALL_RETRIES = 4;
-const int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500;
-
-/* Overridden method
- * DS SM needs to handle one scenario differently */
-void DSStateMachine::processAgpsEvent(AgpsEvent event) {
-
- LOC_LOGD("DSStateMachine::processAgpsEvent() %d", event);
-
- /* DS Client call setup APIs don't return failure/closure separately.
- * Hence we receive RELEASED event in both cases.
- * If we are in pending, we should consider RELEASED as DENIED */
- if (event == AGPS_EVENT_RELEASED && mState == AGPS_STATE_PENDING) {
-
- LOC_LOGD("Translating RELEASED to DENIED event");
- event = AGPS_EVENT_DENIED;
- }
-
- /* Redirect process to base class */
- AgpsStateMachine::processAgpsEvent(event);
-}
-
-/* Timer Callback
- * For the retry timer started in case of DS Client call setup failure */
-void delay_callback(void *callbackData, int result)
-{
- LOC_LOGD("delay_callback(): cbData %p", callbackData);
-
- (void)result;
-
- if (callbackData == NULL) {
- LOC_LOGE("delay_callback(): NULL argument received !");
- return;
- }
- DSStateMachine* dsStateMachine = (DSStateMachine *)callbackData;
- dsStateMachine->retryCallback();
-}
-
-/* Invoked from Timer Callback
- * For the retry timer started in case of DS Client call setup failure */
-void DSStateMachine :: retryCallback()
-{
- LOC_LOGD("DSStateMachine::retryCallback()");
-
- /* Request SUPL ES
- * There must be at least one active subscriber in list */
- AgpsSubscriber* subscriber = getFirstSubscriber(false);
- if (subscriber == NULL) {
-
- LOC_LOGE("No active subscriber for DS Client call setup");
- return;
- }
-
- /* Send message to retry */
- mAgpsManager->mSendMsgToAdapterQueueFn(
- new AgpsMsgRequestATL(
- mAgpsManager, subscriber->mConnHandle,
- LOC_AGPS_TYPE_SUPL_ES));
-}
-
-/* Overridden method
- * Request or Release data connection
- * bool request :
- * true = Request data connection
- * false = Release data connection */
-int DSStateMachine::requestOrReleaseDataConn(bool request){
-
- LOC_LOGD("DSStateMachine::requestOrReleaseDataConn(): "
- "request %d", request);
-
- /* Release data connection required ? */
- if (!request && mAgpsManager->mDSClientStopDataCallFn) {
-
- mAgpsManager->mDSClientStopDataCallFn();
- LOC_LOGD("DS Client release data call request sent !");
- return 0;
- }
-
- /* Setup data connection request
- * There must be at least one active subscriber in list */
- AgpsSubscriber* subscriber = getFirstSubscriber(false);
- if (subscriber == NULL) {
-
- LOC_LOGE("No active subscriber for DS Client call setup");
- return -1;
- }
-
- /* DS Client Fn registered ? */
- if (!mAgpsManager->mDSClientOpenAndStartDataCallFn) {
-
- LOC_LOGE("DS Client start fn not registered, fallback to SUPL ATL");
- notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
- return -1;
- }
-
- /* Setup the call */
- int ret = mAgpsManager->mDSClientOpenAndStartDataCallFn();
-
- /* Check if data call start failed */
- switch (ret) {
-
- case LOC_API_ADAPTER_ERR_ENGINE_BUSY:
- LOC_LOGE("DS Client open call failed, err: %d", ret);
- mRetries++;
- if (mRetries > MAX_START_DATA_CALL_RETRIES) {
-
- LOC_LOGE("DS Client call retries exhausted, "
- "falling back to normal SUPL ATL");
- notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
- }
- /* Retry DS Client call setup after some delay */
- else if(loc_timer_start(
- DATA_CALL_RETRY_DELAY_MSEC, delay_callback, this)) {
- LOC_LOGE("Error: Could not start delay thread\n");
- return -1;
- }
- break;
-
- case LOC_API_ADAPTER_ERR_UNSUPPORTED:
- LOC_LOGE("No emergency profile found. Fall back to normal SUPL ATL");
- notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false);
- break;
-
- case LOC_API_ADAPTER_ERR_SUCCESS:
- LOC_LOGD("Request to start data call sent");
- break;
-
- default:
- LOC_LOGE("Unrecognized return value: %d", ret);
- }
-
- return ret;
-}
-
-void DSStateMachine::notifyEventToSubscriber(
- AgpsEvent event, AgpsSubscriber* subscriberToNotify,
- bool deleteSubscriberPostNotify) {
-
- LOC_LOGD("DSStateMachine::notifyEventToSubscriber(): "
- "SM %p, Event %d Subscriber %p Delete %d",
- this, event, subscriberToNotify, deleteSubscriberPostNotify);
-
- switch (event) {
-
- case AGPS_EVENT_GRANTED:
- mAgpsManager->mAtlOpenStatusCb(
- subscriberToNotify->mConnHandle, 1, NULL,
- AGPS_APN_BEARER_INVALID, LOC_AGPS_TYPE_SUPL_ES);
- break;
-
- case AGPS_EVENT_DENIED:
- /* Now try with regular SUPL
- * We need to send request via message queue */
- mRetries = 0;
- mAgpsManager->mSendMsgToAdapterQueueFn(
- new AgpsMsgRequestATL(
- mAgpsManager, subscriberToNotify->mConnHandle,
- LOC_AGPS_TYPE_SUPL));
- break;
-
- case AGPS_EVENT_UNSUBSCRIBE:
- mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
- break;
-
- case AGPS_EVENT_RELEASED:
- mAgpsManager->mDSClientCloseDataCallFn();
- mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1);
- break;
-
- default:
- LOC_LOGE("Invalid event %d", event);
- }
-
- /* Search this subscriber in list and delete */
- if (deleteSubscriberPostNotify) {
- deleteSubscriber(subscriberToNotify);
- }
-}
-
-/* --------------------------------------------------------------------
* Loc AGPS Manager Methods
* -------------------------------------------------------------------*/
/* CREATE AGPS STATE MACHINES
* Must be invoked in Msg Handler context */
-void AgpsManager::createAgpsStateMachines() {
+void AgpsManager::createAgpsStateMachines(const AgpsCbInfo& cbInfo) {
LOC_LOGD("AgpsManager::createAgpsStateMachines");
@@ -708,31 +519,18 @@ void AgpsManager::createAgpsStateMachines() {
((loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA) ||
(loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB));
- if (NULL == mInternetNif) {
+ if (NULL == mInternetNif && (cbInfo.atlType & AGPS_ATL_TYPE_WWAN)) {
mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY);
+ mInternetNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb);
LOC_LOGD("Internet NIF: %p", mInternetNif);
}
if (agpsCapable) {
- if (NULL == mAgnssNif) {
+ if (NULL == mAgnssNif && (cbInfo.atlType & AGPS_ATL_TYPE_SUPL) &&
+ (cbInfo.atlType & AGPS_ATL_TYPE_SUPL_ES)) {
mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL);
+ mAgnssNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb);
LOC_LOGD("AGNSS NIF: %p", mAgnssNif);
}
- if (NULL == mDsNif &&
- loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
-
- if(!mDSClientInitFn){
-
- LOC_LOGE("DS Client Init Fn not registered !");
- return;
- }
- if (mDSClientInitFn(false) != 0) {
-
- LOC_LOGE("Failed to init data service client");
- return;
- }
- mDsNif = new DSStateMachine(this);
- LOC_LOGD("DS NIF: %p", mDsNif);
- }
}
}
@@ -744,21 +542,16 @@ AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) {
case LOC_AGPS_TYPE_INVALID:
case LOC_AGPS_TYPE_SUPL:
+ case LOC_AGPS_TYPE_SUPL_ES:
if (mAgnssNif == NULL) {
LOC_LOGE("NULL AGNSS NIF !");
}
return mAgnssNif;
-
- case LOC_AGPS_TYPE_SUPL_ES:
- if (loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
- if (mDsNif == NULL) {
- createAgpsStateMachines();
- }
- return mDsNif;
- } else {
- return mAgnssNif;
+ case LOC_AGPS_TYPE_WWAN_ANY:
+ if (mInternetNif == NULL) {
+ LOC_LOGE("NULL Internet NIF !");
}
-
+ return mInternetNif;
default:
return mInternetNif;
}
@@ -767,30 +560,38 @@ AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) {
return NULL;
}
-void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType){
+void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType,
+ LocApnTypeMask apnTypeMask){
- LOC_LOGD("AgpsManager::requestATL(): connHandle %d, agpsType %d",
- connHandle, agpsType);
+ LOC_LOGD("AgpsManager::requestATL(): connHandle %d, agpsType 0x%X apnTypeMask: 0x%X",
+ connHandle, agpsType, apnTypeMask);
+ if (0 == loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL &&
+ LOC_AGPS_TYPE_SUPL_ES == agpsType) {
+ agpsType = LOC_AGPS_TYPE_SUPL;
+ apnTypeMask &= ~LOC_APN_TYPE_MASK_EMERGENCY;
+ apnTypeMask |= LOC_APN_TYPE_MASK_SUPL;
+ LOC_LOGD("Changed agpsType to non-emergency when USE_EMERGENCY... is 0"
+ "and removed LOC_APN_TYPE_MASK_EMERGENCY from apnTypeMask"
+ "agpsType 0x%X apnTypeMask : 0x%X",
+ agpsType, apnTypeMask);
+ }
AgpsStateMachine* sm = getAgpsStateMachine(agpsType);
if (sm == NULL) {
- LOC_LOGE("No AGPS State Machine for agpsType: %d", agpsType);
+ LOC_LOGE("No AGPS State Machine for agpsType: %d apnTypeMask: 0x%X",
+ agpsType, apnTypeMask);
mAtlOpenStatusCb(
- connHandle, 0, NULL, AGPS_APN_BEARER_INVALID, agpsType);
+ connHandle, 0, NULL, 0, AGPS_APN_BEARER_INVALID, agpsType, apnTypeMask);
return;
}
+ sm->setType(agpsType);
+ sm->setApnTypeMask(apnTypeMask);
/* Invoke AGPS SM processing */
- AgpsSubscriber subscriber(connHandle, false, false);
+ AgpsSubscriber subscriber(connHandle, false, false, apnTypeMask);
sm->setCurrentSubscriber(&subscriber);
-
- /* If DS State Machine, wait for close complete */
- if (agpsType == LOC_AGPS_TYPE_SUPL_ES) {
- subscriber.mWaitForCloseComplete = true;
- }
-
/* Send subscriber event */
sm->processAgpsEvent(AGPS_EVENT_SUBSCRIBE);
}
@@ -812,15 +613,9 @@ void AgpsManager::releaseATL(int connHandle){
(subscriber = mInternetNif->getSubscriber(connHandle)) != NULL) {
sm = mInternetNif;
}
- else if (mDsNif &&
- (subscriber = mDsNif->getSubscriber(connHandle)) != NULL) {
- sm = mDsNif;
- }
-
if (sm == NULL) {
LOC_LOGE("Subscriber with connHandle %d not found in any SM",
connHandle);
- mAtlCloseStatusCb(connHandle, 0);
return;
}
@@ -829,24 +624,6 @@ void AgpsManager::releaseATL(int connHandle){
sm->processAgpsEvent(AGPS_EVENT_UNSUBSCRIBE);
}
-void AgpsManager::reportDataCallOpened(){
-
- LOC_LOGD("AgpsManager::reportDataCallOpened");
-
- if (mDsNif) {
- mDsNif->processAgpsEvent(AGPS_EVENT_GRANTED);
- }
-}
-
-void AgpsManager::reportDataCallClosed(){
-
- LOC_LOGD("AgpsManager::reportDataCallClosed");
-
- if (mDsNif) {
- mDsNif->processAgpsEvent(AGPS_EVENT_RELEASED);
- }
-}
-
void AgpsManager::reportAtlOpenSuccess(
AGpsExtType agpsType, char* apnName, int apnLen,
AGpsBearerType bearerType){
@@ -895,18 +672,4 @@ void AgpsManager::handleModemSSR(){
if (mInternetNif) {
mInternetNif->dropAllSubscribers();
}
- if (mDsNif) {
- mDsNif->dropAllSubscribers();
- }
-
- // reinitialize DS client in SSR mode
- if (loc_core::ContextBase::mGps_conf.
- USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
-
- mDSClientStopDataCallFn();
- mDSClientCloseDataCallFn();
- mDSClientReleaseFn();
-
- mDSClientInitFn(true);
- }
}
diff --git a/gps/gnss/Agps.h b/gps/gnss/Agps.h
index 703a475..d559377 100644
--- a/gps/gnss/Agps.h
+++ b/gps/gnss/Agps.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 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
@@ -40,18 +40,11 @@
/* ATL callback function pointers
* Passed in by Adapter to AgpsManager */
typedef std::function<void(
- int handle, int isSuccess, char* apn,
- AGpsBearerType bearerType, AGpsExtType agpsType)> AgpsAtlOpenStatusCb;
+ int handle, int isSuccess, char* apn, uint32_t apnLen,
+ AGpsBearerType bearerType, AGpsExtType agpsType,
+ LocApnTypeMask mask)> AgpsAtlOpenStatusCb;
-typedef std::function<void(int handle, int isSuccess)> AgpsAtlCloseStatusCb;
-
-/* DS Client control APIs
- * Passed in by Adapter to AgpsManager */
-typedef std::function<int(bool isDueToSSR)> AgpsDSClientInitFn;
-typedef std::function<int()> AgpsDSClientOpenAndStartDataCallFn;
-typedef std::function<void()> AgpsDSClientStopDataCallFn;
-typedef std::function<void()> AgpsDSClientCloseDataCallFn;
-typedef std::function<void()> AgpsDSClientReleaseFn;
+typedef std::function<void(int handle, int isSuccess)> AgpsAtlCloseStatusCb;
/* Post message to adapter's message queue */
typedef std::function<void(LocMsg* msg)> SendMsgToAdapterMsgQueueFn;
@@ -92,8 +85,6 @@ typedef enum {
class AgpsSubscriber;
class AgpsManager;
class AgpsStateMachine;
-class DSStateMachine;
-
/* SUBSCRIBER
* Each Subscriber instance corresponds to one AGPS request,
@@ -109,12 +100,15 @@ public:
* inactive state. */
bool mWaitForCloseComplete;
bool mIsInactive;
+ LocApnTypeMask mApnTypeMask;
inline AgpsSubscriber(
- int connHandle, bool waitForCloseComplete, bool isInactive) :
+ int connHandle, bool waitForCloseComplete, bool isInactive,
+ LocApnTypeMask apnTypeMask) :
mConnHandle(connHandle),
mWaitForCloseComplete(waitForCloseComplete),
- mIsInactive(isInactive) {}
+ mIsInactive(isInactive),
+ mApnTypeMask(apnTypeMask) {}
inline virtual ~AgpsSubscriber() {}
inline virtual bool equals(const AgpsSubscriber *s) const
@@ -122,7 +116,7 @@ public:
inline virtual AgpsSubscriber* clone()
{ return new AgpsSubscriber(
- mConnHandle, mWaitForCloseComplete, mIsInactive); }
+ mConnHandle, mWaitForCloseComplete, mIsInactive, mApnTypeMask); }
};
/* AGPS STATE MACHINE */
@@ -143,6 +137,7 @@ protected:
/* Current state for this state machine */
AgpsState mState;
+ AgnssStatusIpV4Cb mFrameworkStatusV4Cb;
private:
/* AGPS Type for this state machine
LOC_AGPS_TYPE_ANY 0
@@ -150,6 +145,7 @@ private:
LOC_AGPS_TYPE_WWAN_ANY 3
LOC_AGPS_TYPE_SUPL_ES 5 */
AGpsExtType mAgpsType;
+ LocApnTypeMask mApnTypeMask;
/* APN and IP Type info for AGPS Call */
char* mAPN;
@@ -159,6 +155,7 @@ private:
public:
/* CONSTRUCTOR */
AgpsStateMachine(AgpsManager* agpsManager, AGpsExtType agpsType):
+ mFrameworkStatusV4Cb(NULL),
mAgpsManager(agpsManager), mSubscriberList(),
mCurrentSubscriber(NULL), mState(AGPS_STATE_RELEASED),
mAgpsType(agpsType), mAPN(NULL), mAPNLen(0),
@@ -169,12 +166,21 @@ public:
/* Getter/Setter methods */
void setAPN(char* apn, unsigned int len);
inline char* getAPN() const { return (char*)mAPN; }
+ inline uint32_t getAPNLen() const { return mAPNLen; }
inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; }
+ inline LocApnTypeMask getApnTypeMask() const { return mApnTypeMask; }
+ inline void setApnTypeMask(LocApnTypeMask apnTypeMask)
+ { mApnTypeMask = apnTypeMask; }
inline AGpsBearerType getBearer() const { return mBearer; }
+ inline void setType(AGpsExtType type) { mAgpsType = type; }
inline AGpsExtType getType() const { return mAgpsType; }
inline void setCurrentSubscriber(AgpsSubscriber* subscriber)
{ mCurrentSubscriber = subscriber; }
+ inline void registerFrameworkStatusCallback(AgnssStatusIpV4Cb frameworkStatusV4Cb) {
+ mFrameworkStatusV4Cb = frameworkStatusV4Cb;
+ }
+
/* Fetch subscriber with specified handle */
AgpsSubscriber* getSubscriber(int connHandle);
@@ -199,7 +205,7 @@ private:
/* Send call setup request to framework
* sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN)
* sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */
- virtual int requestOrReleaseDataConn(bool request);
+ void requestOrReleaseDataConn(bool request);
/* Individual event processing methods */
void processAgpsEventSubscribe();
@@ -227,91 +233,33 @@ private:
void transitionState(AgpsState newState);
};
-/* DS STATE MACHINE */
-class DSStateMachine : public AgpsStateMachine {
-
-private:
- static const int MAX_START_DATA_CALL_RETRIES;
- static const int DATA_CALL_RETRY_DELAY_MSEC;
-
- int mRetries;
-
-public:
- /* CONSTRUCTOR */
- DSStateMachine(AgpsManager* agpsManager):
- AgpsStateMachine(agpsManager, LOC_AGPS_TYPE_SUPL_ES), mRetries(0) {}
-
- /* Overridden method
- * DS SM needs to handle one event differently */
- void processAgpsEvent(AgpsEvent event);
-
- /* Retry callback, used in case call failure */
- void retryCallback();
-
-private:
- /* Overridden method, different functionality for DS SM
- * Send call setup request to framework
- * sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN)
- * sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */
- int requestOrReleaseDataConn(bool request);
-
- /* Overridden method, different functionality for DS SM */
- void notifyEventToSubscriber(
- AgpsEvent event, AgpsSubscriber* subscriber,
- bool deleteSubscriberPostNotify);
-};
-
/* LOC AGPS MANAGER */
class AgpsManager {
friend class AgpsStateMachine;
- friend class DSStateMachine;
-
public:
/* CONSTRUCTOR */
AgpsManager():
- mFrameworkStatusV4Cb(NULL),
mAtlOpenStatusCb(), mAtlCloseStatusCb(),
- mDSClientInitFn(), mDSClientOpenAndStartDataCallFn(),
- mDSClientStopDataCallFn(), mDSClientCloseDataCallFn(), mDSClientReleaseFn(),
- mSendMsgToAdapterQueueFn(),
- mAgnssNif(NULL), mInternetNif(NULL), mDsNif(NULL) {}
+ mAgnssNif(NULL), mInternetNif(NULL)/*, mDsNif(NULL)*/ {}
/* Register callbacks */
inline void registerATLCallbacks(AgpsAtlOpenStatusCb atlOpenStatusCb,
- AgpsAtlCloseStatusCb atlCloseStatusCb,
- AgpsDSClientInitFn dsClientInitFn,
- AgpsDSClientOpenAndStartDataCallFn dsClientOpenAndStartDataCallFn,
- AgpsDSClientStopDataCallFn dsClientStopDataCallFn,
- AgpsDSClientCloseDataCallFn dsClientCloseDataCallFn,
- AgpsDSClientReleaseFn dsClientReleaseFn,
- SendMsgToAdapterMsgQueueFn sendMsgToAdapterQueueFn) {
+ AgpsAtlCloseStatusCb atlCloseStatusCb) {
mAtlOpenStatusCb = atlOpenStatusCb;
mAtlCloseStatusCb = atlCloseStatusCb;
- mDSClientInitFn = dsClientInitFn;
- mDSClientOpenAndStartDataCallFn = dsClientOpenAndStartDataCallFn;
- mDSClientStopDataCallFn = dsClientStopDataCallFn;
- mDSClientCloseDataCallFn = dsClientCloseDataCallFn;
- mDSClientReleaseFn = dsClientReleaseFn;
- mSendMsgToAdapterQueueFn = sendMsgToAdapterQueueFn;
}
- inline void registerFrameworkStatusCallback(AgnssStatusIpV4Cb frameworkStatusV4Cb) {
- mFrameworkStatusV4Cb = frameworkStatusV4Cb;
- }
+ /* Check if AGPS client is registered */
+ inline bool isRegistered() { return nullptr != mAgnssNif || nullptr != mInternetNif; }
/* Create all AGPS state machines */
- void createAgpsStateMachines();
+ void createAgpsStateMachines(const AgpsCbInfo& cbInfo);
/* Process incoming ATL requests */
- void requestATL(int connHandle, AGpsExtType agpsType);
+ void requestATL(int connHandle, AGpsExtType agpsType, LocApnTypeMask apnTypeMask);
void releaseATL(int connHandle);
-
- /* Process incoming DS Client data call events */
- void reportDataCallOpened();
- void reportDataCallClosed();
-
/* Process incoming framework data call events */
void reportAtlOpenSuccess(AGpsExtType agpsType, char* apnName, int apnLen,
AGpsBearerType bearerType);
@@ -322,23 +270,11 @@ public:
void handleModemSSR();
protected:
- AgnssStatusIpV4Cb mFrameworkStatusV4Cb;
AgpsAtlOpenStatusCb mAtlOpenStatusCb;
AgpsAtlCloseStatusCb mAtlCloseStatusCb;
-
- AgpsDSClientInitFn mDSClientInitFn;
- AgpsDSClientOpenAndStartDataCallFn mDSClientOpenAndStartDataCallFn;
- AgpsDSClientStopDataCallFn mDSClientStopDataCallFn;
- AgpsDSClientCloseDataCallFn mDSClientCloseDataCallFn;
- AgpsDSClientReleaseFn mDSClientReleaseFn;
-
- SendMsgToAdapterMsgQueueFn mSendMsgToAdapterQueueFn;
-
AgpsStateMachine* mAgnssNif;
AgpsStateMachine* mInternetNif;
- AgpsStateMachine* mDsNif;
-
private:
/* Fetch state machine for handling request ATL call */
AgpsStateMachine* getAgpsStateMachine(AGpsExtType agpsType);
@@ -353,11 +289,12 @@ struct AgpsMsgRequestATL: public LocMsg {
AgpsManager* mAgpsManager;
int mConnHandle;
AGpsExtType mAgpsType;
+ LocApnTypeMask mApnTypeMask;
inline AgpsMsgRequestATL(AgpsManager* agpsManager, int connHandle,
- AGpsExtType agpsType) :
- LocMsg(), mAgpsManager(agpsManager), mConnHandle(connHandle), mAgpsType(
- agpsType) {
+ AGpsExtType agpsType, LocApnTypeMask apnTypeMask) :
+ LocMsg(), mAgpsManager(agpsManager), mConnHandle(connHandle),
+ mAgpsType(agpsType), mApnTypeMask(apnTypeMask){
LOC_LOGV("AgpsMsgRequestATL");
}
@@ -365,7 +302,7 @@ struct AgpsMsgRequestATL: public LocMsg {
inline virtual void proc() const {
LOC_LOGV("AgpsMsgRequestATL::proc()");
- mAgpsManager->requestATL(mConnHandle, mAgpsType);
+ mAgpsManager->requestATL(mConnHandle, mAgpsType, mApnTypeMask);
}
};
diff --git a/gps/gnss/Android.mk b/gps/gnss/Android.mk
index d809bc2..c1b5944 100644
--- a/gps/gnss/Android.mk
+++ b/gps/gnss/Android.mk
@@ -6,6 +6,9 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libgnss
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
diff --git a/gps/gnss/GnssAdapter.cpp b/gps/gnss/GnssAdapter.cpp
index 751c148..980d489 100644
--- a/gps/gnss/GnssAdapter.cpp
+++ b/gps/gnss/GnssAdapter.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -26,6 +26,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_GnssAdapter"
#include <inttypes.h>
@@ -39,6 +40,7 @@
#include <netdb.h>
#include <GnssAdapter.h>
#include <string>
+#include <sstream>
#include <loc_log.h>
#include <loc_nmea.h>
#include <Agps.h>
@@ -47,6 +49,8 @@
#include <vector>
#define RAD2DEG (180.0 / M_PI)
+#define PROCESS_NAME_ENGINE_SERVICE "engine-service"
+#define MIN_TRACKING_INTERVAL (100) // 100 msec
using namespace loc_core;
@@ -60,30 +64,43 @@ static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userD
GnssAdapter::GnssAdapter() :
LocAdapterBase(0,
- LocDualContext::getLocFgContext(NULL,
+ LocContext::getLocContext(NULL,
NULL,
- LocDualContext::mLocationHalName,
- false)),
- mUlpProxy(new UlpProxyBase()),
- mUlpPositionMode(),
+ LocContext::mLocationHalName,
+ false), true, nullptr),
+ mEngHubProxy(new EngineHubProxyBase()),
+ mLocPositionMode(),
mGnssSvIdUsedInPosition(),
mGnssSvIdUsedInPosAvail(false),
mControlCallbacks(),
- mPowerVoteId(0),
+ mAfwControlId(0),
mNmeaMask(0),
+ mGnssSvIdConfig(),
+ mGnssSvTypeConfig(),
+ mGnssSvTypeConfigCb(nullptr),
mNiData(),
mAgpsManager(),
- mAgpsCbInfo(),
mOdcpiRequestCb(nullptr),
mOdcpiRequestActive(false),
mOdcpiTimer(this),
mOdcpiRequest(),
mSystemStatus(SystemStatus::getInstance(mMsgTask)),
mServerUrl(":"),
- mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask)
+ mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask),
+ mLocSystemInfo{},
+ mBlockCPIInfo{},
+ mNfwCb(NULL),
+ mPowerOn(false),
+ mAllowFlpNetworkFixes(0),
+ mGnssEnergyConsumedCb(nullptr),
+ mPowerStateCb(nullptr),
+ mIsE911Session(NULL),
+ mGnssMbSvIdUsedInPosition{},
+ mGnssMbSvIdUsedInPosAvail(false),
+ mSupportNfwControl(true)
{
LOC_LOGD("%s]: Constructor %p", __func__, this);
- mUlpPositionMode.mode = LOC_POSITION_MODE_INVALID;
+ mLocPositionMode.mode = LOC_POSITION_MODE_INVALID;
pthread_condattr_t condAttr;
pthread_condattr_init(&condAttr);
@@ -94,62 +111,22 @@ GnssAdapter::GnssAdapter() :
/* Set ATL open/close callbacks */
AgpsAtlOpenStatusCb atlOpenStatusCb =
- [this](int handle, int isSuccess, char* apn,
- AGpsBearerType bearerType, AGpsExtType agpsType) {
+ [this](int handle, int isSuccess, char* apn, uint32_t apnLen,
+ AGpsBearerType bearerType, AGpsExtType agpsType, LocApnTypeMask mask) {
mLocApi->atlOpenStatus(
- handle, isSuccess, apn, bearerType, agpsType);
+ handle, isSuccess, apn, apnLen, bearerType, agpsType, mask);
};
AgpsAtlCloseStatusCb atlCloseStatusCb =
[this](int handle, int isSuccess) {
mLocApi->atlCloseStatus(handle, isSuccess);
};
-
- /* Register DS Client APIs */
- AgpsDSClientInitFn dsClientInitFn =
- [this](bool isDueToSSR) {
-
- return mLocApi->initDataServiceClient(isDueToSSR);
- };
-
- AgpsDSClientOpenAndStartDataCallFn dsClientOpenAndStartDataCallFn =
- [this] {
-
- return mLocApi->openAndStartDataCall();
- };
-
- AgpsDSClientStopDataCallFn dsClientStopDataCallFn =
- [this] {
-
- mLocApi->stopDataCall();
- };
-
- AgpsDSClientCloseDataCallFn dsClientCloseDataCallFn =
- [this] {
-
- mLocApi->closeDataCall();
- };
-
- AgpsDSClientReleaseFn dsClientReleaseFn =
- [this] {
-
- mLocApi->releaseDataServiceClient();
- };
-
- /* Send Msg function */
- SendMsgToAdapterMsgQueueFn sendMsgFn =
- [this](LocMsg* msg) {
-
- sendMsg(msg);
- };
- mAgpsManager.registerATLCallbacks(atlOpenStatusCb, atlCloseStatusCb,
- dsClientInitFn, dsClientOpenAndStartDataCallFn, dsClientStopDataCallFn,
- dsClientCloseDataCallFn, dsClientReleaseFn, sendMsgFn);
+ mAgpsManager.registerATLCallbacks(atlOpenStatusCb, atlCloseStatusCb);
readConfigCommand();
- setConfigCommand();
initDefaultAgpsCommand();
+ initEngHubProxyCommand();
}
void
@@ -172,10 +149,9 @@ GnssAdapter::setControlCallbacksCommand(LocationControlCallbacks& controlCallbac
}
void
-GnssAdapter::convertOptions(LocPosMode& out, const LocationOptions& options)
+GnssAdapter::convertOptions(LocPosMode& out, const TrackingOptions& trackingOptions)
{
- LocPosMode locPosMode = {};
- switch (options.mode) {
+ switch (trackingOptions.mode) {
case GNSS_SUPL_MODE_MSB:
out.mode = LOC_POSITION_MODE_MS_BASED;
break;
@@ -187,36 +163,38 @@ GnssAdapter::convertOptions(LocPosMode& out, const LocationOptions& options)
break;
}
out.share_position = true;
- out.min_interval = options.minInterval;
+ out.min_interval = trackingOptions.minInterval;
+ out.powerMode = trackingOptions.powerMode;
+ out.timeBetweenMeasurements = trackingOptions.tbm;
}
void
-GnssAdapter::convertLocation(Location& out, const LocGpsLocation& locGpsLocation,
+GnssAdapter::convertLocation(Location& out, const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
const LocPosTechMask techMask)
{
memset(&out, 0, sizeof(Location));
out.size = sizeof(Location);
- if (LOC_GPS_LOCATION_HAS_LAT_LONG & locGpsLocation.flags) {
+ if (LOC_GPS_LOCATION_HAS_LAT_LONG & ulpLocation.gpsLocation.flags) {
out.flags |= LOCATION_HAS_LAT_LONG_BIT;
- out.latitude = locGpsLocation.latitude;
- out.longitude = locGpsLocation.longitude;
+ out.latitude = ulpLocation.gpsLocation.latitude;
+ out.longitude = ulpLocation.gpsLocation.longitude;
}
- if (LOC_GPS_LOCATION_HAS_ALTITUDE & locGpsLocation.flags) {
+ if (LOC_GPS_LOCATION_HAS_ALTITUDE & ulpLocation.gpsLocation.flags) {
out.flags |= LOCATION_HAS_ALTITUDE_BIT;
- out.altitude = locGpsLocation.altitude;
+ out.altitude = ulpLocation.gpsLocation.altitude;
}
- if (LOC_GPS_LOCATION_HAS_SPEED & locGpsLocation.flags) {
+ if (LOC_GPS_LOCATION_HAS_SPEED & ulpLocation.gpsLocation.flags) {
out.flags |= LOCATION_HAS_SPEED_BIT;
- out.speed = locGpsLocation.speed;
+ out.speed = ulpLocation.gpsLocation.speed;
}
- if (LOC_GPS_LOCATION_HAS_BEARING & locGpsLocation.flags) {
+ if (LOC_GPS_LOCATION_HAS_BEARING & ulpLocation.gpsLocation.flags) {
out.flags |= LOCATION_HAS_BEARING_BIT;
- out.bearing = locGpsLocation.bearing;
+ out.bearing = ulpLocation.gpsLocation.bearing;
}
- if (LOC_GPS_LOCATION_HAS_ACCURACY & locGpsLocation.flags) {
+ if (LOC_GPS_LOCATION_HAS_ACCURACY & ulpLocation.gpsLocation.flags) {
out.flags |= LOCATION_HAS_ACCURACY_BIT;
- out.accuracy = locGpsLocation.accuracy;
+ out.accuracy = ulpLocation.gpsLocation.accuracy;
}
if (GPS_LOCATION_EXTENDED_HAS_VERT_UNC & locationExtended.flags) {
out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
@@ -230,7 +208,7 @@ GnssAdapter::convertLocation(Location& out, const LocGpsLocation& locGpsLocation
out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
out.bearingAccuracy = locationExtended.bearing_unc;
}
- out.timestamp = locGpsLocation.timestamp;
+ out.timestamp = ulpLocation.gpsLocation.timestamp;
if (LOC_POS_TECH_MASK_SATELLITE & techMask) {
out.techMask |= LOCATION_TECHNOLOGY_GNSS_BIT;
}
@@ -243,6 +221,36 @@ GnssAdapter::convertLocation(Location& out, const LocGpsLocation& locGpsLocation
if (LOC_POS_TECH_MASK_SENSORS & techMask) {
out.techMask |= LOCATION_TECHNOLOGY_SENSORS_BIT;
}
+
+ if (LOC_GPS_LOCATION_HAS_SPOOF_MASK & ulpLocation.gpsLocation.flags) {
+ out.flags |= LOCATION_HAS_SPOOF_MASK;
+ out.spoofMask = ulpLocation.gpsLocation.spoof_mask;
+ }
+}
+
+/* This is utility routine that computes number of SV used
+ in the fix from the svUsedIdsMask.
+ */
+#define MAX_SV_CNT_SUPPORTED_IN_ONE_CONSTELLATION 64
+uint16_t GnssAdapter::getNumSvUsed(uint64_t svUsedIdsMask,
+ int totalSvCntInThisConstellation)
+{
+ if (totalSvCntInThisConstellation > MAX_SV_CNT_SUPPORTED_IN_ONE_CONSTELLATION) {
+ LOC_LOGe ("error: total SV count in this constellation %d exceeded limit of %d",
+ totalSvCntInThisConstellation, MAX_SV_CNT_SUPPORTED_IN_ONE_CONSTELLATION);
+ return 0;
+ }
+
+ uint16_t numSvUsed = 0;
+ uint64_t mask = 0x1;
+ for (int i = 0; i < totalSvCntInThisConstellation; i++) {
+ if (svUsedIdsMask & mask) {
+ numSvUsed++;
+ }
+ mask <<= 1;
+ }
+
+ return numSvUsed;
}
void
@@ -254,7 +262,14 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out,
out.flags |= GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT;
out.altitudeMeanSeaLevel = locationExtended.altitudeMeanSeaLevel;
}
- if (GPS_LOCATION_EXTENDED_HAS_DOP & locationExtended.flags) {
+ if (GPS_LOCATION_EXTENDED_HAS_EXT_DOP & locationExtended.flags) {
+ out.flags |= (GNSS_LOCATION_INFO_DOP_BIT|GNSS_LOCATION_INFO_EXT_DOP_BIT);
+ out.pdop = locationExtended.extDOP.PDOP;
+ out.hdop = locationExtended.extDOP.HDOP;
+ out.vdop = locationExtended.extDOP.VDOP;
+ out.gdop = locationExtended.extDOP.GDOP;
+ out.tdop = locationExtended.extDOP.TDOP;
+ } else if (GPS_LOCATION_EXTENDED_HAS_DOP & locationExtended.flags) {
out.flags |= GNSS_LOCATION_INFO_DOP_BIT;
out.pdop = locationExtended.pdop;
out.hdop = locationExtended.hdop;
@@ -316,40 +331,173 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out,
out.flags |= GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT;
out.horUncEllipseOrientAzimuth = locationExtended.horUncEllipseOrientAzimuth;
}
-}
+ if (GPS_LOCATION_EXTENDED_HAS_NORTH_STD_DEV & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_NORTH_STD_DEV_BIT;
+ out.northStdDeviation = locationExtended.northStdDeviation;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_EAST_STD_DEV & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_EAST_STD_DEV_BIT;
+ out.eastStdDeviation = locationExtended.eastStdDeviation;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_NORTH_VEL & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_NORTH_VEL_BIT;
+ out.northVelocity = locationExtended.northVelocity;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_NORTH_VEL_UNC & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_NORTH_VEL_UNC_BIT;
+ out.northVelocityStdDeviation = locationExtended.northVelocityStdDeviation;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_EAST_VEL & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_EAST_VEL_BIT;
+ out.eastVelocity = locationExtended.eastVelocity;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_EAST_VEL_UNC & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_EAST_VEL_UNC_BIT;
+ out.eastVelocityStdDeviation = locationExtended.eastVelocityStdDeviation;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_UP_VEL & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_UP_VEL_BIT;
+ out.upVelocity = locationExtended.upVelocity;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_UP_VEL_UNC & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_UP_VEL_UNC_BIT;
+ out.upVelocityStdDeviation = locationExtended.upVelocityStdDeviation;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_GNSS_SV_USED_DATA_BIT;
+ out.svUsedInPosition.gpsSvUsedIdsMask =
+ locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask;
+ out.svUsedInPosition.gloSvUsedIdsMask =
+ locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask;
+ out.svUsedInPosition.galSvUsedIdsMask =
+ locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask;
+ out.svUsedInPosition.bdsSvUsedIdsMask =
+ locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask;
+ out.svUsedInPosition.qzssSvUsedIdsMask =
+ locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask;
+
+ out.flags |= GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT;
+ out.numSvUsedInPosition = getNumSvUsed(out.svUsedInPosition.gpsSvUsedIdsMask,
+ GPS_SV_PRN_MAX - GPS_SV_PRN_MIN + 1);
+ out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.gloSvUsedIdsMask,
+ GLO_SV_PRN_MAX - GLO_SV_PRN_MIN + 1);
+ out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.qzssSvUsedIdsMask,
+ QZSS_SV_PRN_MAX - QZSS_SV_PRN_MIN + 1);
+ out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.bdsSvUsedIdsMask,
+ BDS_SV_PRN_MAX - BDS_SV_PRN_MIN + 1);
+ out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.galSvUsedIdsMask,
+ GAL_SV_PRN_MAX - GAL_SV_PRN_MIN + 1);
+
+ out.numOfMeasReceived = locationExtended.numOfMeasReceived;
+ for (int idx =0; idx < locationExtended.numOfMeasReceived; idx++) {
+ out.measUsageInfo[idx].gnssSignalType =
+ locationExtended.measUsageInfo[idx].gnssSignalType;
+ out.measUsageInfo[idx].gnssSvId =
+ locationExtended.measUsageInfo[idx].gnssSvId;
+ out.measUsageInfo[idx].gnssConstellation =
+ locationExtended.measUsageInfo[idx].gnssConstellation;
+ }
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_NAV_SOLUTION_MASK & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_NAV_SOLUTION_MASK_BIT;
+ out.navSolutionMask = locationExtended.navSolutionMask;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_POS_TECH_MASK_BIT;
+ out.posTechMask = locationExtended.tech_mask;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_POS_DYNAMICS_DATA & locationExtended.flags) {
+ out.flags |= GPS_LOCATION_EXTENDED_HAS_POS_DYNAMICS_DATA;
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_LONG_ACCEL_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LONG_ACCEL_BIT;
+ }
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_LAT_ACCEL_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_LAT_ACCEL_BIT;
+ }
+ if (locationExtended.bodyFrameData.bodyFrameDataMask &
+ LOCATION_NAV_DATA_HAS_VERT_ACCEL_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_VERT_ACCEL_BIT;
+ }
+ if (locationExtended.bodyFrameData.bodyFrameDataMask & LOCATION_NAV_DATA_HAS_YAW_RATE_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_YAW_RATE_BIT;
+ }
+ if (locationExtended.bodyFrameData.bodyFrameDataMask & LOCATION_NAV_DATA_HAS_PITCH_BIT) {
+ out.bodyFrameData.bodyFrameDataMask |= LOCATION_NAV_DATA_HAS_PITCH_BIT;
+ }
+ out.bodyFrameData.longAccel = locationExtended.bodyFrameData.longAccel;
+ out.bodyFrameData.latAccel = locationExtended.bodyFrameData.latAccel;
+ out.bodyFrameData.vertAccel = locationExtended.bodyFrameData.vertAccel;
+ out.bodyFrameData.yawRate = locationExtended.bodyFrameData.yawRate;
+ out.bodyFrameData.pitch = locationExtended.bodyFrameData.pitch;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_GPS_TIME & locationExtended.flags) {
+ out.flags |= GPS_LOCATION_EXTENDED_HAS_GPS_TIME;
+ out.gnssSystemTime.gnssSystemTimeSrc = locationExtended.gnssSystemTime.gnssSystemTimeSrc;
+ out.gnssSystemTime.u = locationExtended.gnssSystemTime.u;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_NORTH_VEL & locationExtended.flags) {
+ out.flags |= GPS_LOCATION_EXTENDED_HAS_NORTH_VEL;
+ out.northVelocity = locationExtended.northVelocity;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_EAST_VEL & locationExtended.flags) {
+ out.flags |= GPS_LOCATION_EXTENDED_HAS_EAST_VEL;
+ out.eastVelocity = locationExtended.eastVelocity;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_UP_VEL & locationExtended.flags) {
+ out.flags |= GPS_LOCATION_EXTENDED_HAS_UP_VEL;
+ out.upVelocity = locationExtended.upVelocity;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_NORTH_VEL_UNC & locationExtended.flags) {
+ out.flags |= GPS_LOCATION_EXTENDED_HAS_NORTH_VEL_UNC;
+ out.northVelocityStdDeviation = locationExtended.northVelocityStdDeviation;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_EAST_VEL_UNC & locationExtended.flags) {
+ out.flags |= GPS_LOCATION_EXTENDED_HAS_EAST_VEL_UNC;
+ out.eastVelocityStdDeviation = locationExtended.eastVelocityStdDeviation;
+ }
+ if (GPS_LOCATION_EXTENDED_HAS_UP_VEL_UNC & locationExtended.flags) {
+ out.flags |= GPS_LOCATION_EXTENDED_HAS_UP_VEL_UNC;
+ out.upVelocityStdDeviation = locationExtended.upVelocityStdDeviation;
+ }
-inline uint32_t
-GnssAdapter::convertGpsLock(const GnssConfigGpsLock gpsLock)
-{
- switch (gpsLock) {
- case GNSS_CONFIG_GPS_LOCK_MO:
- return 1;
- case GNSS_CONFIG_GPS_LOCK_NI:
- return 2;
- case GNSS_CONFIG_GPS_LOCK_MO_AND_NI:
- return 3;
- case GNSS_CONFIG_GPS_LOCK_NONE:
- default:
- return 0;
+ // Validity of this structure is established from the timeSrc of the GnssSystemTime structure.
+ out.gnssSystemTime = locationExtended.gnssSystemTime;
+
+ if (GPS_LOCATION_EXTENDED_HAS_LEAP_SECONDS & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_LEAP_SECONDS_BIT;
+ out.leapSeconds = locationExtended.leapSeconds;
}
-}
-inline GnssConfigGpsLock
-GnssAdapter::convertGpsLock(const uint32_t gpsLock)
-{
- switch (gpsLock) {
- case 1:
- return GNSS_CONFIG_GPS_LOCK_MO;
- case 2:
- return GNSS_CONFIG_GPS_LOCK_NI;
- case 3:
- return GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
- case 0:
- default:
- return GNSS_CONFIG_GPS_LOCK_NONE;
+ if (GPS_LOCATION_EXTENDED_HAS_TIME_UNC & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_TIME_UNC_BIT;
+ out.timeUncMs = locationExtended.timeUncMs;
+ }
+
+ if (GPS_LOCATION_EXTENDED_HAS_CALIBRATION_CONFIDENCE & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_CALIBRATION_CONFIDENCE_BIT;
+ out.calibrationConfidence = locationExtended.calibrationConfidence;
+ }
+
+ if (GPS_LOCATION_EXTENDED_HAS_CALIBRATION_STATUS & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT;
+ out.calibrationStatus = locationExtended.calibrationStatus;
+ }
+
+ if (GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT;
+ out.locOutputEngType = locationExtended.locOutputEngType;
+ }
+
+ if (GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK & locationExtended.flags) {
+ out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT;
+ out.locOutputEngMask = locationExtended.locOutputEngMask;
}
}
+
+
inline uint32_t
GnssAdapter::convertSuplVersion(const GnssConfigSuplVersion suplVersion)
{
@@ -364,20 +512,6 @@ GnssAdapter::convertSuplVersion(const GnssConfigSuplVersion suplVersion)
}
}
-inline GnssConfigSuplVersion
-GnssAdapter::convertSuplVersion(const uint32_t suplVersion)
-{
- switch (suplVersion) {
- case 0x00020000:
- return GNSS_CONFIG_SUPL_VERSION_2_0_0;
- case 0x00020002:
- return GNSS_CONFIG_SUPL_VERSION_2_0_2;
- case 0x00010000:
- default:
- return GNSS_CONFIG_SUPL_VERSION_1_0_0;
- }
-}
-
inline uint32_t
GnssAdapter::convertLppProfile(const GnssConfigLppProfile lppProfile)
{
@@ -394,22 +528,6 @@ GnssAdapter::convertLppProfile(const GnssConfigLppProfile lppProfile)
}
}
-inline GnssConfigLppProfile
-GnssAdapter::convertLppProfile(const uint32_t lppProfile)
-{
- switch (lppProfile) {
- case 1:
- return GNSS_CONFIG_LPP_PROFILE_USER_PLANE;
- case 2:
- return GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE;
- case 3:
- return GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE;
- case 0:
- default:
- return GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE;
- }
-}
-
uint32_t
GnssAdapter::convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask)
{
@@ -429,26 +547,6 @@ GnssAdapter::convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlane
return mask;
}
-GnssConfigLppeControlPlaneMask
-GnssAdapter::convertLppeCp(const uint32_t lppeControlPlaneMask)
-{
- GnssConfigLppeControlPlaneMask mask = 0;
- if ((1<<0) & lppeControlPlaneMask) {
- mask |= GNSS_CONFIG_LPPE_CONTROL_PLANE_DBH_BIT;
- }
- if ((1<<1) & lppeControlPlaneMask) {
- mask |= GNSS_CONFIG_LPPE_CONTROL_PLANE_WLAN_AP_MEASUREMENTS_BIT;
- }
- if ((1<<2) & lppeControlPlaneMask) {
- mask |= GNSS_CONFIG_LPPE_CONTROL_PLANE_SRN_AP_MEASUREMENTS_BIT;
- }
- if ((1<<3) & lppeControlPlaneMask) {
- mask |= GNSS_CONFIG_LPPE_CONTROL_PLANE_SENSOR_BARO_MEASUREMENTS_BIT;
- }
- return mask;
-}
-
-
uint32_t
GnssAdapter::convertLppeUp(const GnssConfigLppeUserPlaneMask lppeUserPlaneMask)
{
@@ -468,25 +566,6 @@ GnssAdapter::convertLppeUp(const GnssConfigLppeUserPlaneMask lppeUserPlaneMask)
return mask;
}
-GnssConfigLppeUserPlaneMask
-GnssAdapter::convertLppeUp(const uint32_t lppeUserPlaneMask)
-{
- GnssConfigLppeUserPlaneMask mask = 0;
- if ((1<<0) & lppeUserPlaneMask) {
- mask |= GNSS_CONFIG_LPPE_USER_PLANE_DBH_BIT;
- }
- if ((1<<1) & lppeUserPlaneMask) {
- mask |= GNSS_CONFIG_LPPE_USER_PLANE_WLAN_AP_MEASUREMENTS_BIT;
- }
- if ((1<<2) & lppeUserPlaneMask) {
- mask |= GNSS_CONFIG_LPPE_USER_PLANE_SRN_AP_MEASUREMENTS_BIT;
- }
- if ((1<<3) & lppeUserPlaneMask) {
- mask |= GNSS_CONFIG_LPPE_USER_PLANE_SENSOR_BARO_MEASUREMENTS_BIT;
- }
- return mask;
-}
-
uint32_t
GnssAdapter::convertAGloProt(const GnssConfigAGlonassPositionProtocolMask aGloPositionProtocolMask)
{
@@ -543,27 +622,6 @@ GnssAdapter::convertSuplMode(const GnssConfigSuplModeMask suplModeMask)
return mask;
}
-bool
-GnssAdapter::resolveInAddress(const char* hostAddress, struct in_addr* inAddress)
-{
- bool ret = true;
-
- struct hostent* hp;
- hp = gethostbyname(hostAddress);
- if (hp != NULL) { /* DNS OK */
- memcpy(inAddress, hp->h_addr_list[0], hp->h_length);
- } else {
- /* Try IP representation */
- if (inet_aton(hostAddress, inAddress) == 0) {
- /* IP not valid */
- LOC_LOGE("%s]: DNS query on '%s' failed", __func__, hostAddress);
- ret = false;
- }
- }
-
- return ret;
-}
-
void
GnssAdapter::readConfigCommand()
{
@@ -578,9 +636,21 @@ GnssAdapter::readConfigCommand()
mAdapter(adapter),
mContext(context) {}
inline virtual void proc() const {
- // reads config into mContext->mGps_conf
- mContext.readConfig();
- mContext.requestUlp((LocAdapterBase*)mAdapter, mContext.getCarrierCapabilities());
+ static bool confReadDone = false;
+ if (!confReadDone) {
+ confReadDone = true;
+ // reads config into mContext->mGps_conf
+ mContext.readConfig();
+
+ uint32_t allowFlpNetworkFixes = 0;
+ static const loc_param_s_type flp_conf_param_table[] =
+ {
+ {"ALLOW_NETWORK_FIXES", &allowFlpNetworkFixes, NULL, 'n'},
+ };
+ UTIL_READ_CONF(LOC_PATH_FLP_CONF, flp_conf_param_table);
+ LOC_LOGd("allowFlpNetworkFixes %u", allowFlpNetworkFixes);
+ mAdapter->setAllowFlpNetworkFixes(allowFlpNetworkFixes);
+ }
}
};
@@ -589,17 +659,14 @@ GnssAdapter::readConfigCommand()
}
}
-LocationError
-GnssAdapter::setSuplHostServer(const char* server, int port)
+void
+GnssAdapter::setSuplHostServer(const char* server, int port, LocServerType type)
{
- LocationError locErr = LOCATION_ERROR_SUCCESS;
if (ContextBase::mGps_conf.AGPS_CONFIG_INJECT) {
char serverUrl[MAX_URL_LEN] = {};
int32_t length = -1;
const char noHost[] = "NONE";
- locErr = LOCATION_ERROR_INVALID_PARAMETER;
-
if ((NULL == server) || (server[0] == 0) ||
(strncasecmp(noHost, server, sizeof(noHost)) == 0)) {
serverUrl[0] = '\0';
@@ -607,94 +674,347 @@ GnssAdapter::setSuplHostServer(const char* server, int port)
} else if (port > 0) {
length = snprintf(serverUrl, sizeof(serverUrl), "%s:%u", server, port);
}
-
- if (length >= 0 && strncasecmp(getServerUrl().c_str(),
- serverUrl, sizeof(serverUrl)) != 0) {
- setServerUrl(serverUrl);
- locErr = mLocApi->setServer(serverUrl, length);
- if (locErr != LOCATION_ERROR_SUCCESS) {
- LOC_LOGE("%s]:Error while setting SUPL_HOST server:%s",
- __func__, serverUrl);
+ if (LOC_AGPS_SUPL_SERVER != type && LOC_AGPS_MO_SUPL_SERVER != type) {
+ LOC_LOGe("Invalid type=%d", type);
+ } else if (length >= 0) {
+ if (LOC_AGPS_SUPL_SERVER == type) {
+ getServerUrl().assign(serverUrl);
+ strlcpy(ContextBase::mGps_conf.SUPL_HOST, server, LOC_MAX_PARAM_STRING);
+ ContextBase::mGps_conf.SUPL_PORT = port;
+ } else {
+ if (strncasecmp(getMoServerUrl().c_str(), serverUrl, sizeof(serverUrl)) != 0) {
+ getMoServerUrl().assign(serverUrl);
+ }
}
}
}
- return locErr;
}
void
-GnssAdapter::setConfigCommand()
+GnssAdapter::setConfig()
{
LOC_LOGD("%s]: ", __func__);
- struct MsgSetConfig : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- inline MsgSetConfig(GnssAdapter& adapter,
- LocApiBase& api) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api) {}
- inline virtual void proc() const {
- if (ContextBase::mGps_conf.AGPS_CONFIG_INJECT) {
- mApi.setSUPLVersion(mAdapter.convertSuplVersion(ContextBase::mGps_conf.SUPL_VER));
- mApi.setLPPConfig(mAdapter.convertLppProfile(ContextBase::mGps_conf.LPP_PROFILE));
- mApi.setAGLONASSProtocol(ContextBase::mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT);
- }
- mAdapter.setSuplHostServer(ContextBase::mGps_conf.SUPL_HOST,
- ContextBase::mGps_conf.SUPL_PORT);
- mApi.setSensorControlConfig(ContextBase::mSap_conf.SENSOR_USAGE,
- ContextBase::mSap_conf.SENSOR_PROVIDER);
- mApi.setLPPeProtocolCp(
- mAdapter.convertLppeCp(ContextBase::mGps_conf.LPPE_CP_TECHNOLOGY));
- mApi.setLPPeProtocolUp(
- mAdapter.convertLppeUp(ContextBase::mGps_conf.LPPE_UP_TECHNOLOGY));
-
- // set nmea mask type
- uint32_t mask = 0;
- if (NMEA_PROVIDER_MP == ContextBase::mGps_conf.NMEA_PROVIDER) {
- mask |= LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK;
- }
- if (mApi.isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
- mask |= LOC_NMEA_MASK_DEBUG_V02;
- }
- if (mask != 0) {
- mApi.setNMEATypes(mask);
- }
- mAdapter.mNmeaMask= mask;
-
- mApi.setXtraVersionCheck(ContextBase::mGps_conf.XTRA_VERSION_CHECK);
- if (ContextBase::mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID ||
- ContextBase::mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
- ContextBase::mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
- ContextBase::mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
- ContextBase::mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID ) {
- mApi.setSensorProperties(
- ContextBase::mSap_conf.GYRO_BIAS_RANDOM_WALK_VALID,
- ContextBase::mSap_conf.GYRO_BIAS_RANDOM_WALK,
- ContextBase::mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
- ContextBase::mSap_conf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,
- ContextBase::mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
- ContextBase::mSap_conf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,
- ContextBase::mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
- ContextBase::mSap_conf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,
- ContextBase::mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
- ContextBase::mSap_conf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY);
- }
- mApi.setSensorPerfControlConfig(
- ContextBase::mSap_conf.SENSOR_CONTROL_MODE,
- ContextBase::mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH,
- ContextBase::mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC,
- ContextBase::mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH,
- ContextBase::mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC,
- ContextBase::mSap_conf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH,
- ContextBase::mSap_conf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,
- ContextBase::mSap_conf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,
- ContextBase::mSap_conf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,
- ContextBase::mSap_conf.SENSOR_ALGORITHM_CONFIG_MASK);
+ // set nmea mask type
+ uint32_t mask = 0;
+ if (NMEA_PROVIDER_MP == ContextBase::mGps_conf.NMEA_PROVIDER) {
+ mask |= LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
+ mask |= LOC_NMEA_MASK_DEBUG_V02;
+ }
+ if (mNmeaMask != mask) {
+ mNmeaMask = mask;
+ if (mNmeaMask) {
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if ((it->second.gnssNmeaCb != nullptr)) {
+ updateEvtMask(LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT,
+ LOC_REGISTRATION_MASK_ENABLED);
+ break;
+ }
+ }
+ }
+ }
+
+ std::string oldMoServerUrl = getMoServerUrl();
+ setSuplHostServer(ContextBase::mGps_conf.SUPL_HOST,
+ ContextBase::mGps_conf.SUPL_PORT,
+ LOC_AGPS_SUPL_SERVER);
+ setSuplHostServer(ContextBase::mGps_conf.MO_SUPL_HOST,
+ ContextBase::mGps_conf.MO_SUPL_PORT,
+ LOC_AGPS_MO_SUPL_SERVER);
+
+ // inject the configurations into modem
+ loc_gps_cfg_s gpsConf = ContextBase::mGps_conf;
+ loc_sap_cfg_s_type sapConf = ContextBase::mSap_conf;
+
+ //cache the injected configuration with GnssConfigRequested struct
+ GnssConfig gnssConfigRequested = {};
+ gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT |
+ GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ /* Here we process an SSR. We need to set the GPS_LOCK to the proper values, as follows:
+ 1. Q behavior. This is identified by mSupportNfwControl being 1. In this case
+ ContextBase::mGps_conf.GPS_LOCK is a "state", meaning it should reflect the
+ NV value. Therefore we will set the NV to ContextBase::mGps_conf.GPS_LOCK
+ 2. P behavior. This is identified by mSupportNfwControl being 0. In this case
+ ContextBase::mGps_conf.GPS_LOCK is a "configuration", meaning it should hold
+ the "mask" for NI. There are two subcases:
+ a. Location enabled in GUI (1 == getAfwControlId()). We need to set
+ the NV to GNSS_CONFIG_GPS_LOCK_NONE (both MO and NI enabled)
+ b. Location disabled in GUI (0 == getAfwControlId()). We need to set
+ the NV to ContextBase::mGps_conf.GPS_LOCK (the "mask", which is SIM-card
+ specific)
+ */
+ if (mSupportNfwControl || (0 == getAfwControlId())) {
+ gnssConfigRequested.gpsLock = gpsConf.GPS_LOCK;
+ } else {
+ gnssConfigRequested.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+ }
+
+ if (gpsConf.AGPS_CONFIG_INJECT) {
+ gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT |
+ GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT |
+ GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT |
+ GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+ gnssConfigRequested.suplVersion =
+ mLocApi->convertSuplVersion(gpsConf.SUPL_VER);
+ gnssConfigRequested.lppProfile =
+ mLocApi->convertLppProfile(gpsConf.LPP_PROFILE);
+ gnssConfigRequested.aGlonassPositionProtocolMask =
+ gpsConf.A_GLONASS_POS_PROTOCOL_SELECT;
+ }
+ if (gpsConf.LPPE_CP_TECHNOLOGY) {
+ gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
+ gnssConfigRequested.lppeControlPlaneMask =
+ mLocApi->convertLppeCp(gpsConf.LPPE_CP_TECHNOLOGY);
+ }
+
+ if (gpsConf.LPPE_UP_TECHNOLOGY) {
+ gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
+ gnssConfigRequested.lppeUserPlaneMask =
+ mLocApi->convertLppeUp(gpsConf.LPPE_UP_TECHNOLOGY);
+ }
+ gnssConfigRequested.blacklistedSvIds.assign(mBlacklistedSvIds.begin(),
+ mBlacklistedSvIds.end());
+ mLocApi->sendMsg(new LocApiMsg(
+ [this, gpsConf, sapConf, oldMoServerUrl, gnssConfigRequested] () {
+ gnssUpdateConfig(oldMoServerUrl, gnssConfigRequested, gnssConfigRequested);
+
+ // set nmea mask type
+ uint32_t mask = 0;
+ if (NMEA_PROVIDER_MP == gpsConf.NMEA_PROVIDER) {
+ mask |= LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK;
+ }
+ if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
+ mask |= LOC_NMEA_MASK_DEBUG_V02;
}
- };
- sendMsg(new MsgSetConfig(*this, *mLocApi));
+ if (mask != 0) {
+ mLocApi->setNMEATypesSync(mask);
+ }
+
+ mLocApi->setXtraVersionCheckSync(gpsConf.XTRA_VERSION_CHECK);
+
+ mLocApi->setConstrainedTuncMode(
+ gpsConf.CONSTRAINED_TIME_UNCERTAINTY_ENABLED == 1,
+ (float)gpsConf.CONSTRAINED_TIME_UNCERTAINTY_THRESHOLD,
+ gpsConf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET);
+ mLocApi->setPositionAssistedClockEstimatorMode(
+ gpsConf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED == 1);
+
+ if (sapConf.GYRO_BIAS_RANDOM_WALK_VALID ||
+ sapConf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
+ sapConf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
+ sapConf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID ||
+ sapConf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID ) {
+ mLocApi->setSensorPropertiesSync(
+ sapConf.GYRO_BIAS_RANDOM_WALK_VALID,
+ sapConf.GYRO_BIAS_RANDOM_WALK,
+ sapConf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ sapConf.ACCEL_RANDOM_WALK_SPECTRAL_DENSITY,
+ sapConf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ sapConf.ANGLE_RANDOM_WALK_SPECTRAL_DENSITY,
+ sapConf.RATE_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ sapConf.RATE_RANDOM_WALK_SPECTRAL_DENSITY,
+ sapConf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY_VALID,
+ sapConf.VELOCITY_RANDOM_WALK_SPECTRAL_DENSITY);
+ }
+ mLocApi->setSensorPerfControlConfigSync(
+ sapConf.SENSOR_CONTROL_MODE,
+ sapConf.SENSOR_ACCEL_SAMPLES_PER_BATCH,
+ sapConf.SENSOR_ACCEL_BATCHES_PER_SEC,
+ sapConf.SENSOR_GYRO_SAMPLES_PER_BATCH,
+ sapConf.SENSOR_GYRO_BATCHES_PER_SEC,
+ sapConf.SENSOR_ACCEL_SAMPLES_PER_BATCH_HIGH,
+ sapConf.SENSOR_ACCEL_BATCHES_PER_SEC_HIGH,
+ sapConf.SENSOR_GYRO_SAMPLES_PER_BATCH_HIGH,
+ sapConf.SENSOR_GYRO_BATCHES_PER_SEC_HIGH,
+ sapConf.SENSOR_ALGORITHM_CONFIG_MASK);
+ } ));
+
+}
+
+std::vector<LocationError> GnssAdapter::gnssUpdateConfig(const std::string& oldMoServerUrl,
+ const GnssConfig& gnssConfigRequested,
+ const GnssConfig& gnssConfigNeedEngineUpdate, size_t count) {
+ loc_gps_cfg_s gpsConf = ContextBase::mGps_conf;
+ size_t index = 0;
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ std::vector<LocationError> errsList = {err};
+ if (count > 0) {
+ errsList.insert(errsList.begin(), count, LOCATION_ERROR_SUCCESS);
+ }
+
+
+ std::string serverUrl = getServerUrl();
+ std::string moServerUrl = getMoServerUrl();
+
+ int serverUrlLen = serverUrl.length();
+ int moServerUrlLen = moServerUrl.length();
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+ err = mLocApi->setGpsLockSync(gnssConfigRequested.gpsLock);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags &
+ GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.assistanceServer.type ==
+ GNSS_ASSISTANCE_TYPE_SUPL) {
+ err = mLocApi->setServerSync(
+ serverUrl.c_str(), serverUrlLen, LOC_AGPS_SUPL_SERVER);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ if (0 != oldMoServerUrl.compare(moServerUrl)) {
+ LocationError locErr =
+ mLocApi->setServerSync(moServerUrl.c_str(),
+ moServerUrlLen,
+ LOC_AGPS_MO_SUPL_SERVER);
+ if (locErr != LOCATION_ERROR_SUCCESS) {
+ LOC_LOGe("Error while setting MO SUPL_HOST server:%s",
+ moServerUrl.c_str());
+ }
+ }
+ } else if (gnssConfigNeedEngineUpdate.assistanceServer.type ==
+ GNSS_ASSISTANCE_TYPE_C2K) {
+ struct in_addr addr;
+ struct hostent* hp;
+ bool resolveAddrSuccess = true;
+
+ hp = gethostbyname(
+ gnssConfigNeedEngineUpdate.assistanceServer.hostName);
+ if (hp != NULL) { /* DNS OK */
+ memcpy(&addr, hp->h_addr_list[0], hp->h_length);
+ } else {
+ /* Try IP representation */
+ if (inet_aton(
+ gnssConfigNeedEngineUpdate.assistanceServer.hostName,
+ &addr) == 0) {
+ /* IP not valid */
+ LOC_LOGE("%s]: hostname '%s' cannot be resolved ",
+ __func__,
+ gnssConfigNeedEngineUpdate.assistanceServer.hostName);
+ if (index < count) {
+ errsList[index] = LOCATION_ERROR_INVALID_PARAMETER;
+ }
+ } else {
+ resolveAddrSuccess = false;
+ }
+ }
+
+ if (resolveAddrSuccess) {
+ unsigned int ip = htonl(addr.s_addr);
+ err = mLocApi->setServerSync(ip,
+ gnssConfigNeedEngineUpdate.assistanceServer.port,
+ LOC_AGPS_CDMA_PDE_SERVER);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+ err = mLocApi->setSUPLVersionSync(gnssConfigRequested.suplVersion);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+ err = mLocApi->setLPPConfigSync(gnssConfigRequested.lppProfile);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+ err = mLocApi->setLPPeProtocolCpSync(
+ gnssConfigRequested.lppeControlPlaneMask);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+ err = mLocApi->setLPPeProtocolUpSync(
+ gnssConfigRequested.lppeUserPlaneMask);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+
+ if (gnssConfigRequested.flags &
+ GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ err = mLocApi->setAGLONASSProtocolSync(
+ gnssConfigRequested.aGlonassPositionProtocolMask);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ // Check if feature is supported
+ if (!ContextBase::isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature constellation enablement not supported.");
+ err = LOCATION_ERROR_NOT_SUPPORTED;
+ } else {
+ // Send the SV ID Config to Modem
+ mBlacklistedSvIds.assign(gnssConfigRequested.blacklistedSvIds.begin(),
+ gnssConfigRequested.blacklistedSvIds.end());
+ err = gnssSvIdConfigUpdateSync(gnssConfigRequested.blacklistedSvIds);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ LOC_LOGe("Failed to send config to modem, err %d", err);
+ }
+ }
+ if (index < count) {
+ errsList[index] = err;
+ }
+ index++;
+ }
+ if (gnssConfigRequested.flags &
+ GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
+ if (gnssConfigNeedEngineUpdate.flags &
+ GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
+ err = mLocApi->setEmergencyExtensionWindowSync(
+ gnssConfigRequested.emergencyExtensionSeconds);
+ if (index < count) {
+ errsList[index] = err;
+ }
+ }
+ index++;
+ }
+ return errsList;
}
uint32_t*
@@ -732,8 +1052,8 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
GnssAdapter& mAdapter;
LocApiBase& mApi;
GnssConfig mConfig;
- uint32_t* mIds;
size_t mCount;
+ uint32_t* mIds;
inline MsgGnssUpdateConfig(GnssAdapter& adapter,
LocApiBase& api,
GnssConfig config,
@@ -743,175 +1063,741 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
mAdapter(adapter),
mApi(api),
mConfig(config),
+ mCount(count),
+ mIds(ids) {}
+ inline MsgGnssUpdateConfig(const MsgGnssUpdateConfig& obj) :
+ MsgGnssUpdateConfig(obj.mAdapter, obj.mApi, obj.mConfig,
+ new uint32_t[obj.mCount], obj.mCount) {
+ if (mIds != nullptr) {
+ for (int i = 0; i < mCount; ++i) {
+ mIds[i] = obj.mIds[i];
+ }
+ }
+ }
+ inline virtual ~MsgGnssUpdateConfig()
+ {
+ delete[] mIds;
+ }
+
+ inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgGnssUpdateConfig(*this));
+ return;
+ }
+ GnssAdapter& adapter = mAdapter;
+ size_t countOfConfigs = mCount;
+ GnssConfig gnssConfigRequested = mConfig;
+ GnssConfig gnssConfigNeedEngineUpdate = mConfig;
+
+ std::vector<uint32_t> sessionIds;
+ sessionIds.assign(mIds, mIds + mCount);
+ std::vector<LocationError> errs(mCount, LOCATION_ERROR_SUCCESS);
+ int index = 0;
+
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+ GnssConfigGpsLock newGpsLock = gnssConfigRequested.gpsLock;
+
+ newGpsLock |= GNSS_CONFIG_GPS_LOCK_MO;
+ ContextBase::mGps_conf.GPS_LOCK = newGpsLock;
+ /* If we get here it means that the changes in the framework to request for
+ 'P' behavior were made, and therefore we need to "behave" as in 'P'
+ However, we need to determine if enableCommand function has already been
+ called, since it could get called before this function.*/
+ if (0 != mAdapter.getAfwControlId()) {
+ /* enableCommand function has already been called since getAfwControlId
+ returns non zero. Now there are two possible cases:
+ 1. This is the first time this function is called
+ (mSupportNfwControl is true). We need to behave as in 'P', but
+ for the first time, meaning MO was enabled, but NI was not, so
+ we need to unlock NI
+ 2. This is not the first time this function is called, meaning we
+ are already behaving as in 'P'. No need to update the configuration
+ in this case (return to 'P' code) */
+ if (mAdapter.mSupportNfwControl) {
+ // case 1 above
+ newGpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+ } else {
+ // case 2 above
+ gnssConfigNeedEngineUpdate.flags &= ~(GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT);
+ }
+ }
+ gnssConfigRequested.gpsLock = newGpsLock;
+ mAdapter.mSupportNfwControl = false;
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+ uint32_t newSuplVersion =
+ mAdapter.convertSuplVersion(gnssConfigRequested.suplVersion);
+ ContextBase::mGps_conf.SUPL_VER = newSuplVersion;
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+ if (GNSS_ASSISTANCE_TYPE_SUPL == mConfig.assistanceServer.type) {
+ mAdapter.setSuplHostServer(mConfig.assistanceServer.hostName,
+ mConfig.assistanceServer.port,
+ LOC_AGPS_SUPL_SERVER);
+ } else {
+ LOC_LOGE("%s]: Not a valid gnss assistance type %u",
+ __func__, mConfig.assistanceServer.type);
+ errs.at(index) = LOCATION_ERROR_INVALID_PARAMETER;
+ gnssConfigNeedEngineUpdate.flags &=
+ ~(GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT);
+ }
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+ uint32_t newLppProfile = mAdapter.convertLppProfile(gnssConfigRequested.lppProfile);
+ ContextBase::mGps_conf.LPP_PROFILE = newLppProfile;
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+ uint32_t newLppeControlPlaneMask =
+ mAdapter.convertLppeCp(gnssConfigRequested.lppeControlPlaneMask);
+ ContextBase::mGps_conf.LPPE_CP_TECHNOLOGY = newLppeControlPlaneMask;
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+ uint32_t newLppeUserPlaneMask =
+ mAdapter.convertLppeUp(gnssConfigRequested.lppeUserPlaneMask);
+ ContextBase::mGps_conf.LPPE_UP_TECHNOLOGY = newLppeUserPlaneMask;
+ index++;
+ }
+ if (gnssConfigRequested.flags &
+ GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ uint32_t newAGloProtMask =
+ mAdapter.convertAGloProt(gnssConfigRequested.aGlonassPositionProtocolMask);
+ ContextBase::mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT = newAGloProtMask;
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
+ uint32_t newEP4ES = mAdapter.convertEP4ES(
+ gnssConfigRequested.emergencyPdnForEmergencySupl);
+ if (newEP4ES != ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
+ ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = newEP4ES;
+ }
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
+ uint32_t newSuplEs = mAdapter.convertSuplEs(
+ gnssConfigRequested.suplEmergencyServices);
+ if (newSuplEs != ContextBase::mGps_conf.SUPL_ES) {
+ ContextBase::mGps_conf.SUPL_ES = newSuplEs;
+ }
+ index++;
+ }
+ if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
+ uint32_t newSuplMode = mAdapter.convertSuplMode(gnssConfigRequested.suplModeMask);
+ ContextBase::mGps_conf.SUPL_MODE = newSuplMode;
+ mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
+ index++;
+ }
+
+ LocApiCollectiveResponse *configCollectiveResponse = new LocApiCollectiveResponse(
+ *adapter.getContext(),
+ [&adapter, sessionIds, countOfConfigs] (std::vector<LocationError> errs) {
+
+ std::vector<uint32_t> ids(sessionIds);
+ adapter.reportResponse(countOfConfigs, errs.data(), ids.data());
+ });
+
+ mApi.sendMsg(new LocApiMsg(
+ [&adapter, gnssConfigRequested, gnssConfigNeedEngineUpdate,
+ countOfConfigs, configCollectiveResponse, errs] () {
+ std::vector<LocationError> errsList = adapter.gnssUpdateConfig("",
+ gnssConfigRequested, gnssConfigNeedEngineUpdate, countOfConfigs);
+
+ configCollectiveResponse->returnToSender(errsList);
+ }));
+ }
+ };
+
+ if (NULL != ids) {
+ sendMsg(new MsgGnssUpdateConfig(*this, *mLocApi, config, ids, count));
+ } else {
+ LOC_LOGE("%s]: No GNSS config items to update", __func__);
+ }
+
+ return ids;
+}
+
+void
+GnssAdapter::gnssSvIdConfigUpdate(const std::vector<GnssSvIdSource>& blacklistedSvIds)
+{
+ // Clear the existing config
+ memset(&mGnssSvIdConfig, 0, sizeof(GnssSvIdConfig));
+
+ // Convert the sv id lists to masks
+ bool convertSuccess = convertToGnssSvIdConfig(blacklistedSvIds, mGnssSvIdConfig);
+
+ // Now send to Modem if conversion successful
+ if (convertSuccess) {
+ gnssSvIdConfigUpdate();
+ } else {
+ LOC_LOGe("convertToGnssSvIdConfig failed");
+ }
+}
+
+void
+GnssAdapter::gnssSvIdConfigUpdate()
+{
+ LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64,
+ mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
+ mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask);
+
+ // Now set required blacklisted SVs
+ mLocApi->setBlacklistSv(mGnssSvIdConfig);
+}
+
+LocationError
+GnssAdapter::gnssSvIdConfigUpdateSync(const std::vector<GnssSvIdSource>& blacklistedSvIds)
+{
+ // Clear the existing config
+ memset(&mGnssSvIdConfig, 0, sizeof(GnssSvIdConfig));
+
+ // Convert the sv id lists to masks
+ convertToGnssSvIdConfig(blacklistedSvIds, mGnssSvIdConfig);
+
+ // Now send to Modem
+ return gnssSvIdConfigUpdateSync();
+}
+
+LocationError
+GnssAdapter::gnssSvIdConfigUpdateSync()
+{
+ LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64,
+ mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
+ mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask);
+
+ // Now set required blacklisted SVs
+ return mLocApi->setBlacklistSvSync(mGnssSvIdConfig);
+}
+
+uint32_t*
+GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) {
+
+ // count the number of bits set
+ GnssConfigFlagsMask flagsCopy = configMask;
+ size_t count = 0;
+ while (flagsCopy > 0) {
+ if (flagsCopy & 1) {
+ count++;
+ }
+ flagsCopy >>= 1;
+ }
+ std::string idsString = "[";
+ uint32_t* ids = NULL;
+ if (count > 0) {
+ ids = new uint32_t[count];
+ if (nullptr == ids) {
+ LOC_LOGe("new allocation failed, fatal error.");
+ return nullptr;
+ }
+ for (size_t i=0; i < count; ++i) {
+ ids[i] = generateSessionId();
+ IF_LOC_LOGD {
+ idsString += std::to_string(ids[i]) + " ";
+ }
+ }
+ }
+ idsString += "]";
+
+ LOC_LOGd("ids %s flags 0x%X", idsString.c_str(), configMask);
+
+ struct MsgGnssGetConfig : public LocMsg {
+ GnssAdapter& mAdapter;
+ LocApiBase& mApi;
+ GnssConfigFlagsMask mConfigMask;
+ uint32_t* mIds;
+ size_t mCount;
+ inline MsgGnssGetConfig(GnssAdapter& adapter,
+ LocApiBase& api,
+ GnssConfigFlagsMask configMask,
+ uint32_t* ids,
+ size_t count) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mConfigMask(configMask),
mIds(ids),
mCount(count) {}
- inline virtual ~MsgGnssUpdateConfig()
+
+ inline MsgGnssGetConfig(const MsgGnssGetConfig& obj) :
+ MsgGnssGetConfig(obj.mAdapter, obj.mApi, obj.mConfigMask,
+ new uint32_t[obj.mCount], obj.mCount) {
+ if (mIds != nullptr) {
+ for (int i = 0; i < mCount; ++i) {
+ mIds[i] = obj.mIds[i];
+ }
+ }
+ }
+ inline virtual ~MsgGnssGetConfig()
{
delete[] mIds;
}
inline virtual void proc() const {
+ if (!mAdapter.isEngineCapabilitiesKnown()) {
+ mAdapter.mPendingMsgs.push_back(new MsgGnssGetConfig(*this));
+ return;
+ }
LocationError* errs = new LocationError[mCount];
LocationError err = LOCATION_ERROR_SUCCESS;
uint32_t index = 0;
- if (errs == nullptr) {
+ if (nullptr == errs) {
LOC_LOGE("%s] new allocation failed, fatal error.", __func__);
return;
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
- uint32_t newGpsLock = mAdapter.convertGpsLock(mConfig.gpsLock);
- ContextBase::mGps_conf.GPS_LOCK = newGpsLock;
- if (0 == mAdapter.getPowerVoteId()) {
- err = mApi.setGpsLock(mConfig.gpsLock);
- }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
if (index < mCount) {
- errs[index++] = err;
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
- uint32_t newSuplVersion = mAdapter.convertSuplVersion(mConfig.suplVersion);
- if (newSuplVersion != ContextBase::mGps_conf.SUPL_VER &&
- ContextBase::mGps_conf.AGPS_CONFIG_INJECT) {
- ContextBase::mGps_conf.SUPL_VER = newSuplVersion;
- err = mApi.setSUPLVersion(mConfig.suplVersion);
- } else {
- err = LOCATION_ERROR_SUCCESS;
- }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
if (index < mCount) {
- errs[index++] = err;
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
- if (GNSS_ASSISTANCE_TYPE_SUPL == mConfig.assistanceServer.type) {
- err = mAdapter.setSuplHostServer(mConfig.assistanceServer.hostName,
- mConfig.assistanceServer.port);
- } else if (GNSS_ASSISTANCE_TYPE_C2K == mConfig.assistanceServer.type) {
- if (ContextBase::mGps_conf.AGPS_CONFIG_INJECT) {
- struct in_addr addr;
- if (!mAdapter.resolveInAddress(mConfig.assistanceServer.hostName,
- &addr)) {
- LOC_LOGE("%s]: hostName %s cannot be resolved",
- __func__, mConfig.assistanceServer.hostName);
- err = LOCATION_ERROR_INVALID_PARAMETER;
- } else {
- unsigned int ip = htonl(addr.s_addr);
- err = mApi.setServer(ip, mConfig.assistanceServer.port,
- LOC_AGPS_CDMA_PDE_SERVER);
- }
- } else {
- err = LOCATION_ERROR_SUCCESS;
- }
- } else {
- LOC_LOGE("%s]: Not a valid gnss assistance type %u",
- __func__, mConfig.assistanceServer.type);
- err = LOCATION_ERROR_INVALID_PARAMETER;
- }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
if (index < mCount) {
- errs[index++] = err;
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
- uint32_t newLppProfile = mAdapter.convertLppProfile(mConfig.lppProfile);
- if (newLppProfile != ContextBase::mGps_conf.LPP_PROFILE &&
- ContextBase::mGps_conf.AGPS_CONFIG_INJECT) {
- ContextBase::mGps_conf.LPP_PROFILE = newLppProfile;
- err = mApi.setLPPConfig(mConfig.lppProfile);
- } else {
- err = LOCATION_ERROR_SUCCESS;
- }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
if (index < mCount) {
- errs[index++] = err;
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
- uint32_t newLppeControlPlaneMask =
- mAdapter.convertLppeCp(mConfig.lppeControlPlaneMask);
- if (newLppeControlPlaneMask != ContextBase::mGps_conf.LPPE_CP_TECHNOLOGY) {
- ContextBase::mGps_conf.LPPE_CP_TECHNOLOGY = newLppeControlPlaneMask;
- err = mApi.setLPPeProtocolCp(mConfig.lppeControlPlaneMask);
- } else {
- err = LOCATION_ERROR_SUCCESS;
- }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
if (index < mCount) {
- errs[index++] = err;
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
- uint32_t newLppeUserPlaneMask =
- mAdapter.convertLppeUp(mConfig.lppeUserPlaneMask);
- if (newLppeUserPlaneMask != ContextBase::mGps_conf.LPPE_UP_TECHNOLOGY) {
- ContextBase::mGps_conf.LPPE_UP_TECHNOLOGY = newLppeUserPlaneMask;
- err = mApi.setLPPeProtocolUp(mConfig.lppeUserPlaneMask);
- } else {
- err = LOCATION_ERROR_SUCCESS;
- }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
if (index < mCount) {
- errs[index++] = err;
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
- uint32_t newAGloProtMask =
- mAdapter.convertAGloProt(mConfig.aGlonassPositionProtocolMask);
- if (newAGloProtMask != ContextBase::mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT &&
- ContextBase::mGps_conf.AGPS_CONFIG_INJECT) {
- ContextBase::mGps_conf.A_GLONASS_POS_PROTOCOL_SELECT = newAGloProtMask;
- err = mApi.setAGLONASSProtocol(mConfig.aGlonassPositionProtocolMask);
- } else {
- err = LOCATION_ERROR_SUCCESS;
+ if (mConfigMask & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
if (index < mCount) {
- errs[index++] = err;
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
- uint32_t newEP4ES = mAdapter.convertEP4ES(mConfig.emergencyPdnForEmergencySupl);
- if (newEP4ES != ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) {
- ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = newEP4ES;
+ if (mConfigMask & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
- err = LOCATION_ERROR_SUCCESS;
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
+ err = LOCATION_ERROR_NOT_SUPPORTED;
if (index < mCount) {
- errs[index++] = err;
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
- uint32_t newSuplEs = mAdapter.convertSuplEs(mConfig.suplEmergencyServices);
- if (newSuplEs != ContextBase::mGps_conf.SUPL_ES) {
- ContextBase::mGps_conf.SUPL_ES = newSuplEs;
+ if (mConfigMask & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ // Check if feature is supported
+ if (!ContextBase::isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature not supported.");
+ err = LOCATION_ERROR_NOT_SUPPORTED;
+ } else {
+ // Send request to Modem to fetch the config
+ mApi.getBlacklistSv();
+ err = LOCATION_ERROR_SUCCESS;
}
- err = LOCATION_ERROR_SUCCESS;
if (index < mCount) {
errs[index++] = err;
}
}
- if (mConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
- uint32_t newSuplMode = mAdapter.convertSuplMode(mConfig.suplModeMask);
- if (newSuplMode != ContextBase::mGps_conf.SUPL_MODE) {
- ContextBase::mGps_conf.SUPL_MODE = newSuplMode;
- mAdapter.getUlpProxy()->setCapabilities(
- ContextBase::getCarrierCapabilities());
- mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
- }
- err = LOCATION_ERROR_SUCCESS;
+ if (mConfigMask & GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT) {
+ err = LOCATION_ERROR_NOT_SUPPORTED;
if (index < mCount) {
- errs[index++] = err;
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
}
}
mAdapter.reportResponse(index, errs, mIds);
delete[] errs;
+
}
};
if (NULL != ids) {
- sendMsg(new MsgGnssUpdateConfig(*this, *mLocApi, config, ids, count));
+ sendMsg(new MsgGnssGetConfig(*this, *mLocApi, configMask, ids, count));
} else {
- LOC_LOGE("%s]: No GNSS config items to update", __func__);
+ LOC_LOGe("No GNSS config items to Get");
}
return ids;
}
+bool
+GnssAdapter::convertToGnssSvIdConfig(
+ const std::vector<GnssSvIdSource>& blacklistedSvIds, GnssSvIdConfig& config)
+{
+ bool retVal = false;
+ config.size = sizeof(GnssSvIdConfig);
+
+ // Empty vector => Clear any previous blacklisted SVs
+ if (0 == blacklistedSvIds.size()) {
+ config.gloBlacklistSvMask = 0;
+ config.bdsBlacklistSvMask = 0;
+ config.qzssBlacklistSvMask = 0;
+ config.galBlacklistSvMask = 0;
+ retVal = true;
+ } else {
+ // Parse the vector and convert SV IDs to mask values
+ for (GnssSvIdSource source : blacklistedSvIds) {
+ uint64_t* svMaskPtr = NULL;
+ GnssSvId initialSvId = 0;
+ switch(source.constellation) {
+ case GNSS_SV_TYPE_GLONASS:
+ svMaskPtr = &config.gloBlacklistSvMask;
+ initialSvId = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ svMaskPtr = &config.bdsBlacklistSvMask;
+ initialSvId = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ svMaskPtr = &config.qzssBlacklistSvMask;
+ initialSvId = GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ svMaskPtr = &config.galBlacklistSvMask;
+ initialSvId = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID;
+ break;
+ default:
+ break;
+ }
+
+ if (NULL == svMaskPtr) {
+ LOC_LOGe("Invalid constellation %d", source.constellation);
+ } else {
+ // SV ID 0 = All SV IDs
+ if (0 == source.svId) {
+ *svMaskPtr = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ } else if (source.svId < initialSvId || source.svId >= initialSvId + 64) {
+ LOC_LOGe("Invalid sv id %d for sv type %d",
+ source.svId, source.constellation);
+ } else {
+ *svMaskPtr |= (1 << (source.svId - initialSvId));
+ }
+ }
+ }
+
+ // Return true if any one source is valid
+ if (0 != config.gloBlacklistSvMask ||
+ 0 != config.bdsBlacklistSvMask ||
+ 0 != config.galBlacklistSvMask ||
+ 0 != config.qzssBlacklistSvMask) {
+ retVal = true;
+ }
+ }
+
+ return retVal;
+}
+
+void GnssAdapter::convertFromGnssSvIdConfig(
+ const GnssSvIdConfig& svConfig, GnssConfig& config)
+{
+ // Convert blacklisted SV mask values to vectors
+ if (svConfig.bdsBlacklistSvMask) {
+ convertGnssSvIdMaskToList(
+ svConfig.bdsBlacklistSvMask, config.blacklistedSvIds,
+ GNSS_SV_CONFIG_BDS_INITIAL_SV_ID, GNSS_SV_TYPE_BEIDOU);
+ config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+ if (svConfig.galBlacklistSvMask) {
+ convertGnssSvIdMaskToList(
+ svConfig.galBlacklistSvMask, config.blacklistedSvIds,
+ GNSS_SV_CONFIG_GAL_INITIAL_SV_ID, GNSS_SV_TYPE_GALILEO);
+ config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+ if (svConfig.gloBlacklistSvMask) {
+ convertGnssSvIdMaskToList(
+ svConfig.gloBlacklistSvMask, config.blacklistedSvIds,
+ GNSS_SV_CONFIG_GLO_INITIAL_SV_ID, GNSS_SV_TYPE_GLONASS);
+ config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+ if (svConfig.qzssBlacklistSvMask) {
+ convertGnssSvIdMaskToList(
+ svConfig.qzssBlacklistSvMask, config.blacklistedSvIds,
+ GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID, GNSS_SV_TYPE_QZSS);
+ config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+}
+
+void GnssAdapter::convertGnssSvIdMaskToList(
+ uint64_t svIdMask, std::vector<GnssSvIdSource>& svIds,
+ GnssSvId initialSvId, GnssSvType svType)
+{
+ GnssSvIdSource source = {};
+ source.size = sizeof(GnssSvIdSource);
+ source.constellation = svType;
+
+ // SV ID 0 => All SV IDs in mask
+ if (GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK == svIdMask) {
+ source.svId = 0;
+ svIds.push_back(source);
+ return;
+ }
+
+ // Convert each bit in svIdMask to vector entry
+ uint32_t bitNumber = 0;
+ while (svIdMask > 0) {
+ if (svIdMask & 0x1) {
+ source.svId = bitNumber + initialSvId;
+ svIds.push_back(source);
+ }
+ bitNumber++;
+ svIdMask >>= 1;
+ }
+}
+
+void GnssAdapter::reportGnssSvIdConfigEvent(const GnssSvIdConfig& config)
+{
+ struct MsgReportGnssSvIdConfig : public LocMsg {
+ GnssAdapter& mAdapter;
+ const GnssSvIdConfig mConfig;
+ inline MsgReportGnssSvIdConfig(GnssAdapter& adapter,
+ const GnssSvIdConfig& config) :
+ LocMsg(),
+ mAdapter(adapter),
+ mConfig(config) {}
+ inline virtual void proc() const {
+ mAdapter.reportGnssSvIdConfig(mConfig);
+ }
+ };
+
+ sendMsg(new MsgReportGnssSvIdConfig(*this, config));
+}
+
+void GnssAdapter::reportGnssSvIdConfig(const GnssSvIdConfig& svIdConfig)
+{
+ GnssConfig config = {};
+ config.size = sizeof(GnssConfig);
+
+ // Invoke control clients config callback
+ if (nullptr != mControlCallbacks.gnssConfigCb &&
+ svIdConfig.size == sizeof(GnssSvIdConfig)) {
+ convertFromGnssSvIdConfig(svIdConfig, config);
+ LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64,
+ svIdConfig.bdsBlacklistSvMask, svIdConfig.gloBlacklistSvMask,
+ svIdConfig.qzssBlacklistSvMask, svIdConfig.galBlacklistSvMask);
+ mControlCallbacks.gnssConfigCb(config);
+ } else {
+ LOC_LOGe("Failed to report, size %d", (uint32_t)config.size);
+ }
+}
+
+void
+GnssAdapter::gnssUpdateSvTypeConfigCommand(GnssSvTypeConfig config)
+{
+ struct MsgGnssUpdateSvTypeConfig : public LocMsg {
+ GnssAdapter* mAdapter;
+ LocApiBase* mApi;
+ GnssSvTypeConfig mConfig;
+ inline MsgGnssUpdateSvTypeConfig(
+ GnssAdapter* adapter,
+ LocApiBase* api,
+ GnssSvTypeConfig& config) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mConfig(config) {}
+ inline virtual void proc() const {
+ if (!mAdapter->isEngineCapabilitiesKnown()) {
+ mAdapter->mPendingMsgs.push_back(new MsgGnssUpdateSvTypeConfig(*this));
+ return;
+ }
+ // Check if feature is supported
+ if (!ContextBase::isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature not supported.");
+ } else {
+ // Send update request to modem
+ mAdapter->gnssSvTypeConfigUpdate(mConfig);
+ }
+ }
+ };
+
+ sendMsg(new MsgGnssUpdateSvTypeConfig(this, mLocApi, config));
+}
+
+void
+GnssAdapter::gnssSvTypeConfigUpdate(const GnssSvTypeConfig& config)
+{
+ // Gather bits removed from enabled mask
+ GnssSvTypesMask enabledRemoved = mGnssSvTypeConfig.enabledSvTypesMask &
+ (mGnssSvTypeConfig.enabledSvTypesMask ^ config.enabledSvTypesMask);
+ // Send reset if any constellation is removed from the enabled list
+ bool sendReset = (enabledRemoved != 0);
+ // Save new config and update
+ gnssSetSvTypeConfig(config);
+ gnssSvTypeConfigUpdate(sendReset);
+}
+
+void
+GnssAdapter::gnssSvTypeConfigUpdate(bool sendReset)
+{
+ LOC_LOGd("size %" PRIu32" constellations blacklisted 0x%" PRIx64 ", enabled 0x%" PRIx64
+ ", sendReset %d",
+ mGnssSvTypeConfig.size, mGnssSvTypeConfig.blacklistedSvTypesMask,
+ mGnssSvTypeConfig.enabledSvTypesMask, sendReset);
+
+ if (mGnssSvTypeConfig.size == sizeof(mGnssSvTypeConfig)) {
+
+ if (sendReset) {
+ mLocApi->resetConstellationControl();
+ }
+
+ GnssSvIdConfig blacklistConfig = {};
+ // Revert to previously blacklisted SVs for each enabled constellation
+ blacklistConfig = mGnssSvIdConfig;
+ // Blacklist all SVs for each disabled constellation
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask) {
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_GLO_BIT) {
+ blacklistConfig.gloBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ }
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_BDS_BIT) {
+ blacklistConfig.bdsBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ }
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_QZSS_BIT) {
+ blacklistConfig.qzssBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ }
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_GAL_BIT) {
+ blacklistConfig.galBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ }
+ }
+
+ // Send blacklist info
+ mLocApi->setBlacklistSv(blacklistConfig);
+
+ // Send only enabled constellation config
+ if (mGnssSvTypeConfig.enabledSvTypesMask) {
+ GnssSvTypeConfig svTypeConfig = {sizeof(GnssSvTypeConfig), 0, 0};
+ svTypeConfig.enabledSvTypesMask = mGnssSvTypeConfig.enabledSvTypesMask;
+ mLocApi->setConstellationControl(svTypeConfig);
+ }
+ }
+}
+
+void
+GnssAdapter::gnssGetSvTypeConfigCommand(GnssSvTypeConfigCallback callback)
+{
+ struct MsgGnssGetSvTypeConfig : public LocMsg {
+ GnssAdapter* mAdapter;
+ LocApiBase* mApi;
+ GnssSvTypeConfigCallback mCallback;
+ inline MsgGnssGetSvTypeConfig(
+ GnssAdapter* adapter,
+ LocApiBase* api,
+ GnssSvTypeConfigCallback callback) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mCallback(callback) {}
+ inline virtual void proc() const {
+ if (!mAdapter->isEngineCapabilitiesKnown()) {
+ mAdapter->mPendingMsgs.push_back(new MsgGnssGetSvTypeConfig(*this));
+ return;
+ }
+ if (!ContextBase::isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature not supported.");
+ } else {
+ // Save the callback
+ mAdapter->gnssSetSvTypeConfigCallback(mCallback);
+ // Send GET request to modem
+ mApi->getConstellationControl();
+ }
+ }
+ };
+
+ sendMsg(new MsgGnssGetSvTypeConfig(this, mLocApi, callback));
+}
+
+void
+GnssAdapter::gnssResetSvTypeConfigCommand()
+{
+ struct MsgGnssResetSvTypeConfig : public LocMsg {
+ GnssAdapter* mAdapter;
+ LocApiBase* mApi;
+ inline MsgGnssResetSvTypeConfig(
+ GnssAdapter* adapter,
+ LocApiBase* api) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api) {}
+ inline virtual void proc() const {
+ if (!mAdapter->isEngineCapabilitiesKnown()) {
+ mAdapter->mPendingMsgs.push_back(new MsgGnssResetSvTypeConfig(*this));
+ return;
+ }
+ if (!ContextBase::isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature not supported.");
+ } else {
+ // Reset constellation config
+ mAdapter->gnssSetSvTypeConfig({sizeof(GnssSvTypeConfig), 0, 0});
+ // Re-enforce SV blacklist config
+ mAdapter->gnssSvIdConfigUpdate();
+ // Send reset request to modem
+ mApi->resetConstellationControl();
+ }
+ }
+ };
+
+ sendMsg(new MsgGnssResetSvTypeConfig(this, mLocApi));
+}
+
+void GnssAdapter::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config)
+{
+ struct MsgReportGnssSvTypeConfig : public LocMsg {
+ GnssAdapter& mAdapter;
+ const GnssSvTypeConfig mConfig;
+ inline MsgReportGnssSvTypeConfig(GnssAdapter& adapter,
+ const GnssSvTypeConfig& config) :
+ LocMsg(),
+ mAdapter(adapter),
+ mConfig(config) {}
+ inline virtual void proc() const {
+ mAdapter.reportGnssSvTypeConfig(mConfig);
+ }
+ };
+
+ sendMsg(new MsgReportGnssSvTypeConfig(*this, config));
+}
+
+void GnssAdapter::reportGnssSvTypeConfig(const GnssSvTypeConfig& config)
+{
+ // Invoke Get SV Type Callback
+ if (NULL != mGnssSvTypeConfigCb &&
+ config.size == sizeof(GnssSvTypeConfig)) {
+ LOC_LOGd("constellations blacklisted 0x%" PRIx64 ", enabled 0x%" PRIx64,
+ config.blacklistedSvTypesMask, config.enabledSvTypesMask);
+ mGnssSvTypeConfigCb(config);
+ } else {
+ LOC_LOGe("Failed to report, size %d", (uint32_t)config.size);
+ }
+}
+
+void GnssAdapter::deleteAidingData(const GnssAidingData &data, uint32_t sessionId) {
+ mLocApi->deleteAidingData(data, new LocApiResponse(*getContext(),
+ [this, sessionId] (LocationError err) {
+ reportResponse(err, sessionId);
+ }));
+}
+
uint32_t
GnssAdapter::gnssDeleteAidingDataCommand(GnssAidingData& data)
{
@@ -920,30 +1806,30 @@ GnssAdapter::gnssDeleteAidingDataCommand(GnssAidingData& data)
struct MsgDeleteAidingData : public LocMsg {
GnssAdapter& mAdapter;
- LocApiBase& mApi;
uint32_t mSessionId;
GnssAidingData mData;
inline MsgDeleteAidingData(GnssAdapter& adapter,
- LocApiBase& api,
uint32_t sessionId,
GnssAidingData& data) :
LocMsg(),
mAdapter(adapter),
- mApi(api),
mSessionId(sessionId),
mData(data) {}
inline virtual void proc() const {
- LocationError err = LOCATION_ERROR_SUCCESS;
- err = mApi.deleteAidingData(mData);
- mAdapter.reportResponse(err, mSessionId);
- SystemStatus* s = mAdapter.getSystemStatus();
- if ((nullptr != s) && (mData.deleteAll)) {
- s->setDefaultGnssEngineStates();
+ if ((mData.posEngineMask & STANDARD_POSITIONING_ENGINE) != 0) {
+ mAdapter.deleteAidingData(mData, mSessionId);
+
+ SystemStatus* s = mAdapter.getSystemStatus();
+ if ((nullptr != s) && (mData.deleteAll)) {
+ s->setDefaultGnssEngineStates();
+ }
}
+
+ mAdapter.mEngHubProxy->gnssDeleteAidingData(mData);
}
};
- sendMsg(new MsgDeleteAidingData(*this, *mLocApi, sessionId, data));
+ sendMsg(new MsgDeleteAidingData(*this, sessionId, data));
return sessionId;
}
@@ -976,28 +1862,66 @@ GnssAdapter::injectLocationCommand(double latitude, double longitude, float accu
struct MsgInjectLocation : public LocMsg {
LocApiBase& mApi;
ContextBase& mContext;
+ BlockCPIInfo& mBlockCPI;
double mLatitude;
double mLongitude;
float mAccuracy;
inline MsgInjectLocation(LocApiBase& api,
ContextBase& context,
+ BlockCPIInfo& blockCPIInfo,
double latitude,
double longitude,
float accuracy) :
LocMsg(),
mApi(api),
mContext(context),
+ mBlockCPI(blockCPIInfo),
mLatitude(latitude),
mLongitude(longitude),
mAccuracy(accuracy) {}
inline virtual void proc() const {
- if (!mContext.hasCPIExtendedCapabilities()) {
+ if ((uptimeMillis() <= mBlockCPI.blockedTillTsMs) &&
+ (fabs(mLatitude-mBlockCPI.latitude) <= mBlockCPI.latLonDiffThreshold) &&
+ (fabs(mLongitude-mBlockCPI.longitude) <= mBlockCPI.latLonDiffThreshold)) {
+
+ LOC_LOGD("%s]: positon injeciton blocked: lat: %f, lon: %f, accuracy: %f",
+ __func__, mLatitude, mLongitude, mAccuracy);
+
+ } else {
mApi.injectPosition(mLatitude, mLongitude, mAccuracy);
}
}
};
- sendMsg(new MsgInjectLocation(*mLocApi, *mContext, latitude, longitude, accuracy));
+ sendMsg(new MsgInjectLocation(*mLocApi, *mContext, mBlockCPIInfo,
+ latitude, longitude, accuracy));
+}
+
+void
+GnssAdapter::injectLocationExtCommand(const GnssLocationInfoNotification &locationInfo)
+{
+ LOC_LOGd("latitude %8.4f longitude %8.4f accuracy %8.4f, tech mask 0x%x",
+ locationInfo.location.latitude, locationInfo.location.longitude,
+ locationInfo.location.accuracy, locationInfo.location.techMask);
+
+ struct MsgInjectLocationExt : public LocMsg {
+ LocApiBase& mApi;
+ ContextBase& mContext;
+ GnssLocationInfoNotification mLocationInfo;
+ inline MsgInjectLocationExt(LocApiBase& api,
+ ContextBase& context,
+ GnssLocationInfoNotification locationInfo) :
+ LocMsg(),
+ mApi(api),
+ mContext(context),
+ mLocationInfo(locationInfo) {}
+ inline virtual void proc() const {
+ // false to indicate for none-ODCPI
+ mApi.injectPosition(mLocationInfo, false);
+ }
+ };
+
+ sendMsg(new MsgInjectLocationExt(*mLocApi, *mContext, locationInfo));
}
void
@@ -1031,56 +1955,41 @@ GnssAdapter::injectTimeCommand(int64_t time, int64_t timeReference, int32_t unce
sendMsg(new MsgInjectTime(*mLocApi, *mContext, time, timeReference, uncertainty));
}
+// This command is to called to block the position to be injected to the modem.
+// This can happen for network position that comes from modem.
void
-GnssAdapter::setUlpProxyCommand(UlpProxyBase* ulp)
+GnssAdapter::blockCPICommand(double latitude, double longitude,
+ float accuracy, int blockDurationMsec,
+ double latLonDiffThreshold)
{
- LOC_LOGD("%s]: ", __func__);
-
- struct MsgSetUlpProxy : public LocMsg {
- GnssAdapter& mAdapter;
- UlpProxyBase* mUlp;
- inline MsgSetUlpProxy(GnssAdapter& adapter,
- UlpProxyBase* ulp) :
- LocMsg(),
- mAdapter(adapter),
- mUlp(ulp) {}
+ struct MsgBlockCPI : public LocMsg {
+ BlockCPIInfo& mDstCPIInfo;
+ BlockCPIInfo mSrcCPIInfo;
+
+ inline MsgBlockCPI(BlockCPIInfo& dstCPIInfo,
+ BlockCPIInfo& srcCPIInfo) :
+ mDstCPIInfo(dstCPIInfo),
+ mSrcCPIInfo(srcCPIInfo) {}
inline virtual void proc() const {
- mAdapter.setUlpProxy(mUlp);
- if (mUlp) {
- mUlp->setCapabilities(ContextBase::getCarrierCapabilities());
- }
+ // in the same hal thread, save the cpi to be blocked
+ // the global variable
+ mDstCPIInfo = mSrcCPIInfo;
}
};
- sendMsg(new MsgSetUlpProxy(*this, ulp));
-}
-
-void
-GnssAdapter::setUlpProxy(UlpProxyBase* ulp)
-{
- if (ulp == mUlpProxy) {
- //This takes care of the case when double initalization happens
- //and we get the same object back for UlpProxyBase . Do nothing
- return;
- }
-
- LOC_LOGV("%s]: %p", __func__, ulp);
- if (NULL == ulp) {
- LOC_LOGE("%s]: ulp pointer is NULL", __func__);
- ulp = new UlpProxyBase();
- }
-
- if (LOC_POSITION_MODE_INVALID != mUlpProxy->mPosMode.mode) {
- // need to send this mode and start msg to ULP
- ulp->sendFixMode(mUlpProxy->mPosMode);
- }
-
- if (mUlpProxy->mFixSet) {
- ulp->sendStartFix();
- }
-
- delete mUlpProxy;
- mUlpProxy = ulp;
+ // construct the new block CPI info and queue on the same thread
+ // for processing
+ BlockCPIInfo blockCPIInfo;
+ blockCPIInfo.latitude = latitude;
+ blockCPIInfo.longitude = longitude;
+ blockCPIInfo.accuracy = accuracy;
+ blockCPIInfo.blockedTillTsMs = uptimeMillis() + blockDurationMsec;
+ blockCPIInfo.latLonDiffThreshold = latLonDiffThreshold;
+
+ LOC_LOGD("%s]: block CPI lat: %f, lon: %f ", __func__, latitude, longitude);
+ // send a message to record down the coarse position
+ // to be blocked from injection in the master copy (mBlockCPIInfo)
+ sendMsg(new MsgBlockCPI(mBlockCPIInfo, blockCPIInfo));
}
void
@@ -1100,6 +2009,8 @@ GnssAdapter::addClientCommand(LocationAPI* client, const LocationCallbacks& call
mClient(client),
mCallbacks(callbacks) {}
inline virtual void proc() const {
+ // check whether we need to notify client of cached location system info
+ mAdapter.notifyClientOfCachedLocationSystemInfo(mClient, mCallbacks);
mAdapter.saveClient(mClient, mCallbacks);
}
};
@@ -1108,38 +2019,32 @@ GnssAdapter::addClientCommand(LocationAPI* client, const LocationCallbacks& call
}
void
-GnssAdapter::removeClientCommand(LocationAPI* client)
+GnssAdapter::stopClientSessions(LocationAPI* client)
{
LOC_LOGD("%s]: client %p", __func__, client);
- struct MsgRemoveClient : public LocMsg {
- GnssAdapter& mAdapter;
- LocationAPI* mClient;
- inline MsgRemoveClient(GnssAdapter& adapter,
- LocationAPI* client) :
- LocMsg(),
- mAdapter(adapter),
- mClient(client) {}
- inline virtual void proc() const {
- mAdapter.stopClientSessions(mClient);
- mAdapter.eraseClient(mClient);
+ /* Time-based Tracking */
+ std::vector<LocationSessionKey> vTimeBasedTrackingClient;
+ for (auto it : mTimeBasedTrackingSessions) {
+ if (client == it.first.client) {
+ vTimeBasedTrackingClient.emplace_back(it.first.client, it.first.id);
}
- };
-
- sendMsg(new MsgRemoveClient(*this, client));
-}
+ }
+ for (auto key : vTimeBasedTrackingClient) {
+ stopTimeBasedTrackingMultiplex(key.client, key.id);
+ }
-void
-GnssAdapter::stopClientSessions(LocationAPI* client)
-{
- LOC_LOGD("%s]: client %p", __func__, client);
- for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end();) {
+ /* Distance-based Tracking */
+ for (auto it = mDistanceBasedTrackingSessions.begin();
+ it != mDistanceBasedTrackingSessions.end(); /* no increment here*/) {
if (client == it->first.client) {
- LocationError err = stopTrackingMultiplex(it->first.client, it->first.id);
- if (LOCATION_ERROR_SUCCESS == err) {
- it = mTrackingSessions.erase(it);
- continue;
- }
+ mLocApi->stopDistanceBasedTracking(it->first.id, new LocApiResponse(*getContext(),
+ [this, client, id=it->first.id] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ eraseTrackingSession(client, id);
+ }
+ }
+ ));
}
++it; // increment only when not erasing an iterator
}
@@ -1151,12 +2056,9 @@ GnssAdapter::updateClientsEventMask()
{
LOC_API_ADAPTER_EVENT_MASK_T mask = 0;
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (it->second.trackingCb != nullptr) {
+ if (it->second.trackingCb != nullptr || it->second.gnssLocationInfoCb != nullptr) {
mask |= LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT;
}
- if (it->second.gnssNiCb != nullptr) {
- mask |= LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST;
- }
if (it->second.gnssSvCb != nullptr) {
mask |= LOC_API_ADAPTER_BIT_SATELLITE_REPORT;
}
@@ -1166,46 +2068,78 @@ GnssAdapter::updateClientsEventMask()
if (it->second.gnssMeasurementsCb != nullptr) {
mask |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
}
+ if (it->second.gnssDataCb != nullptr) {
+ mask |= LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT;
+ mask |= LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT;
+ updateNmeaMask(mNmeaMask | LOC_NMEA_MASK_DEBUG_V02);
+ }
}
/*
- ** For Automotive use cases we need to enable MEASUREMENT and POLY
- ** when QDR is enabled
+ ** For Automotive use cases we need to enable MEASUREMENT, POLY and EPHEMERIS
+ ** when QDR is enabled (e.g.: either enabled via conf file or
+ ** engine hub is loaded successfully).
+ ** Note: this need to be called from msg queue thread.
*/
- if(1 == ContextBase::mGps_conf.EXTERNAL_DR_ENABLED) {
+ if((1 == ContextBase::mGps_conf.EXTERNAL_DR_ENABLED) ||
+ (true == initEngHubProxy())) {
mask |= LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT;
+ mask |= LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT;
mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT;
+ mask |= LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT;
+ mask |= LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT;
+ mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO;
+ mask |= LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO;
- LOC_LOGD("%s]: Auto usecase, Enable MEAS/POLY - mask 0x%" PRIu64 "", __func__, mask);
+ LOC_LOGd("Auto usecase, Enable MEAS/POLY/EPHEMERIS - mask 0x%" PRIx64 "",
+ mask);
}
- if (mAgpsCbInfo.statusV4Cb != NULL) {
+ if (mAgpsManager.isRegistered()) {
mask |= LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST;
}
-
// Add ODCPI handling
if (nullptr != mOdcpiRequestCb) {
mask |= LOC_API_ADAPTER_BIT_REQUEST_WIFI;
}
+ // need to register for leap second info
+ // for proper nmea generation
+ mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO;
+
+ // always register for NI NOTIFY VERIFY to handle internally in HAL
+ mask |= LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST;
+
updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
}
void
GnssAdapter::handleEngineUpEvent()
{
- struct MsgRestartSessions : public LocMsg {
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgHandleEngineUpEvent : public LocMsg {
GnssAdapter& mAdapter;
- inline MsgRestartSessions(GnssAdapter& adapter) :
+ inline MsgHandleEngineUpEvent(GnssAdapter& adapter) :
LocMsg(),
mAdapter(adapter) {}
virtual void proc() const {
+ mAdapter.setEngineCapabilitiesKnown(true);
+ mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
+ // must be called only after capabilities are known
+ mAdapter.setConfig();
mAdapter.restartSessions();
+ mAdapter.gnssSvIdConfigUpdate();
+ mAdapter.gnssSvTypeConfigUpdate();
+ for (auto msg: mAdapter.mPendingMsgs) {
+ mAdapter.sendMsg(msg);
+ }
+ mAdapter.mPendingMsgs.clear();
}
};
- setConfigCommand();
- sendMsg(new MsgRestartSessions(*this));
+ readConfigCommand();
+ sendMsg(new MsgHandleEngineUpEvent(*this));
}
void
@@ -1216,131 +2150,87 @@ GnssAdapter::restartSessions()
// odcpi session is no longer active after restart
mOdcpiRequestActive = false;
- if (mTrackingSessions.empty()) {
- return;
- }
-
- // get the LocationOptions that has the smallest interval, which should be the active one
- LocationOptions smallestIntervalOptions = {}; // size is zero until set for the first time
- for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end(); ++it) {
- if (0 == smallestIntervalOptions.size || //size of zero means we havent set it yet
- it->second.minInterval < smallestIntervalOptions.minInterval) {
- smallestIntervalOptions = it->second;
+ if (!mTimeBasedTrackingSessions.empty()) {
+ // get the LocationOptions that has the smallest interval, which should be the active one
+ TrackingOptions smallestIntervalOptions; // size is zero until set for the first time
+ TrackingOptions highestPowerTrackingOptions;
+ memset(&smallestIntervalOptions, 0, sizeof(smallestIntervalOptions));
+ memset(&highestPowerTrackingOptions, 0, sizeof(highestPowerTrackingOptions));
+ for (auto it = mTimeBasedTrackingSessions.begin(); it != mTimeBasedTrackingSessions.end(); ++it) {
+ // size of zero means we havent set it yet
+ if (0 == smallestIntervalOptions.size ||
+ it->second.minInterval < smallestIntervalOptions.minInterval) {
+ smallestIntervalOptions = it->second;
+ }
+ GnssPowerMode powerMode = it->second.powerMode;
+ // Size of zero means we havent set it yet
+ if (0 == highestPowerTrackingOptions.size ||
+ (GNSS_POWER_MODE_INVALID != powerMode &&
+ powerMode < highestPowerTrackingOptions.powerMode)) {
+ highestPowerTrackingOptions = it->second;
+ }
}
+
+ highestPowerTrackingOptions.setLocationOptions(smallestIntervalOptions);
+ mLocApi->startTimeBasedTracking(highestPowerTrackingOptions, nullptr);
}
- LocPosMode locPosMode = {};
- convertOptions(locPosMode, smallestIntervalOptions);
- mLocApi->startFix(locPosMode);
+ for (auto it = mDistanceBasedTrackingSessions.begin();
+ it != mDistanceBasedTrackingSessions.end(); ++it) {
+ mLocApi->startDistanceBasedTracking(it->first.id, it->second,
+ new LocApiResponse(*getContext(),
+ [] (LocationError /*err*/) {}));
+ }
}
void
-GnssAdapter::requestCapabilitiesCommand(LocationAPI* client)
-{
- LOC_LOGD("%s]: ", __func__);
-
- struct MsgRequestCapabilities : public LocMsg {
- GnssAdapter& mAdapter;
- LocationAPI* mClient;
- inline MsgRequestCapabilities(GnssAdapter& adapter,
- LocationAPI* client) :
- LocMsg(),
- mAdapter(adapter),
- mClient(client) {}
- inline virtual void proc() const {
- LocationCallbacks callbacks = mAdapter.getClientCallbacks(mClient);
- if (callbacks.capabilitiesCb == nullptr) {
- LOC_LOGE("%s]: capabilitiesCb is NULL", __func__);
- return;
+GnssAdapter::notifyClientOfCachedLocationSystemInfo(
+ LocationAPI* client, const LocationCallbacks& callbacks) {
+
+ if (mLocSystemInfo.systemInfoMask) {
+ // client need to be notified if client has not yet previously registered
+ // for the info but now register for it.
+ bool notifyClientOfSystemInfo = false;
+ // check whether we need to notify client of cached location system info
+ //
+ // client need to be notified if client has not yet previously registered
+ // for the info but now register for it.
+ if (callbacks.locationSystemInfoCb) {
+ notifyClientOfSystemInfo = true;
+ auto it = mClientData.find(client);
+ if (it != mClientData.end()) {
+ LocationCallbacks oldCallbacks = it->second;
+ if (oldCallbacks.locationSystemInfoCb) {
+ notifyClientOfSystemInfo = false;
+ }
}
-
- LocationCapabilitiesMask mask = mAdapter.getCapabilities();
- callbacks.capabilitiesCb(mask);
}
- };
-
- sendMsg(new MsgRequestCapabilities(*this, client));
-}
-LocationCapabilitiesMask
-GnssAdapter::getCapabilities()
-{
- LocationCapabilitiesMask mask = 0;
- uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities();
- // time based tracking always supported
- mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT;
- // geofence always supported
- mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT;
- if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) {
- mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT;
- }
- if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) {
- mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT;
- }
- if (mLocApi == nullptr)
- return mask;
- if (mLocApi->isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)) {
- mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT |
- LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT;
- }
- if (mLocApi->isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
- mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT;
- }
- if (mLocApi->isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) {
- mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT;
- }
- if (mLocApi->gnssConstellationConfig()) {
- mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT;
- }
- if (mLocApi->isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) {
- mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT;
- }
- return mask;
-}
-
-void
-GnssAdapter::broadcastCapabilities(LocationCapabilitiesMask mask)
-{
- for (auto it = mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.capabilitiesCb) {
- it->second.capabilitiesCb(mask);
+ if (notifyClientOfSystemInfo) {
+ callbacks.locationSystemInfoCb(mLocSystemInfo);
}
}
}
-LocationCallbacks
-GnssAdapter::getClientCallbacks(LocationAPI* client)
+bool
+GnssAdapter::hasTrackingCallback(LocationAPI* client)
{
- LocationCallbacks callbacks = {};
auto it = mClientData.find(client);
- if (it != mClientData.end()) {
- callbacks = it->second;
- }
- return callbacks;
+ return (it != mClientData.end() && (it->second.trackingCb || it->second.gnssLocationInfoCb));
}
-void
-GnssAdapter::saveClient(LocationAPI* client, const LocationCallbacks& callbacks)
-{
- mClientData[client] = callbacks;
- updateClientsEventMask();
-}
-
-void
-GnssAdapter::eraseClient(LocationAPI* client)
+bool
+GnssAdapter::isTimeBasedTrackingSession(LocationAPI* client, uint32_t sessionId)
{
- auto it = mClientData.find(client);
- if (it != mClientData.end()) {
- mClientData.erase(it);
- }
- updateClientsEventMask();
+ LocationSessionKey key(client, sessionId);
+ return (mTimeBasedTrackingSessions.find(key) != mTimeBasedTrackingSessions.end());
}
bool
-GnssAdapter::hasTrackingCallback(LocationAPI* client)
+GnssAdapter::isDistanceBasedTrackingSession(LocationAPI* client, uint32_t sessionId)
{
- auto it = mClientData.find(client);
- return (it != mClientData.end() && it->second.trackingCb);
+ LocationSessionKey key(client, sessionId);
+ return (mDistanceBasedTrackingSessions.find(key) != mDistanceBasedTrackingSessions.end());
}
bool
@@ -1354,31 +2244,78 @@ bool
GnssAdapter::isTrackingSession(LocationAPI* client, uint32_t sessionId)
{
LocationSessionKey key(client, sessionId);
- return (mTrackingSessions.find(key) != mTrackingSessions.end());
+ return (mTimeBasedTrackingSessions.find(key) != mTimeBasedTrackingSessions.end());
+}
+
+void
+GnssAdapter::reportPowerStateIfChanged()
+{
+ bool newPowerOn = !mTimeBasedTrackingSessions.empty() ||
+ !mDistanceBasedTrackingSessions.empty();
+ if (newPowerOn != mPowerOn) {
+ mPowerOn = newPowerOn;
+ if (mPowerStateCb != nullptr) {
+ mPowerStateCb(mPowerOn);
+ }
+ }
+}
+
+void
+GnssAdapter::getPowerStateChangesCommand(void* powerStateCb)
+{
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgReportLocation : public LocMsg {
+ GnssAdapter& mAdapter;
+ powerStateCallback mPowerStateCb;
+ inline MsgReportLocation(GnssAdapter& adapter,
+ powerStateCallback powerStateCb) :
+ LocMsg(),
+ mAdapter(adapter),
+ mPowerStateCb(powerStateCb) {}
+ inline virtual void proc() const {
+ mAdapter.savePowerStateCallback(mPowerStateCb);
+ mPowerStateCb(mAdapter.getPowerState());
+ }
+ };
+
+ sendMsg(new MsgReportLocation(*this, (powerStateCallback)powerStateCb));
}
void
GnssAdapter::saveTrackingSession(LocationAPI* client, uint32_t sessionId,
- const LocationOptions& options)
+ const TrackingOptions& options)
{
LocationSessionKey key(client, sessionId);
- mTrackingSessions[key] = options;
+ if ((options.minDistance > 0) &&
+ ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
+ mDistanceBasedTrackingSessions[key] = options;
+ } else {
+ mTimeBasedTrackingSessions[key] = options;
+ }
+ reportPowerStateIfChanged();
}
void
GnssAdapter::eraseTrackingSession(LocationAPI* client, uint32_t sessionId)
{
LocationSessionKey key(client, sessionId);
- auto it = mTrackingSessions.find(key);
- if (it != mTrackingSessions.end()) {
- mTrackingSessions.erase(it);
+ auto it = mTimeBasedTrackingSessions.find(key);
+ if (it != mTimeBasedTrackingSessions.end()) {
+ mTimeBasedTrackingSessions.erase(it);
+ } else {
+ auto itr = mDistanceBasedTrackingSessions.find(key);
+ if (itr != mDistanceBasedTrackingSessions.end()) {
+ mDistanceBasedTrackingSessions.erase(itr);
+ }
}
-
+ reportPowerStateIfChanged();
}
-bool GnssAdapter::setUlpPositionMode(const LocPosMode& mode) {
- if (!mUlpPositionMode.equals(mode)) {
- mUlpPositionMode = mode;
+
+bool GnssAdapter::setLocPositionMode(const LocPosMode& mode) {
+ if (!mLocPositionMode.equals(mode)) {
+ mLocPositionMode = mode;
return true;
} else {
return false;
@@ -1391,8 +2328,7 @@ GnssAdapter::reportResponse(LocationAPI* client, LocationError err, uint32_t ses
LOC_LOGD("%s]: client %p id %u err %u", __func__, client, sessionId, err);
auto it = mClientData.find(client);
- if (it != mClientData.end() &&
- it->second.responseCb != nullptr) {
+ if (it != mClientData.end() && it->second.responseCb != nullptr) {
it->second.responseCb(err, sessionId);
} else {
LOC_LOGW("%s]: client %p id %u not found in data", __func__, client, sessionId);
@@ -1438,23 +2374,24 @@ GnssAdapter::reportResponse(size_t count, LocationError* errs, uint32_t* ids)
}
uint32_t
-GnssAdapter::startTrackingCommand(LocationAPI* client, LocationOptions& options)
+GnssAdapter::startTrackingCommand(LocationAPI* client, TrackingOptions& options)
{
uint32_t sessionId = generateSessionId();
- LOC_LOGD("%s]: client %p id %u minInterval %u mode %u",
- __func__, client, sessionId, options.minInterval, options.mode);
+ LOC_LOGD("%s]: client %p id %u minInterval %u minDistance %u mode %u powermode %u tbm %u",
+ __func__, client, sessionId, options.minInterval, options.minDistance, options.mode,
+ options.powerMode, options.tbm);
struct MsgStartTracking : public LocMsg {
GnssAdapter& mAdapter;
LocApiBase& mApi;
LocationAPI* mClient;
uint32_t mSessionId;
- LocationOptions mOptions;
+ mutable TrackingOptions mOptions;
inline MsgStartTracking(GnssAdapter& adapter,
LocApiBase& api,
LocationAPI* client,
uint32_t sessionId,
- LocationOptions options) :
+ TrackingOptions options) :
LocMsg(),
mAdapter(adapter),
mApi(api),
@@ -1462,6 +2399,11 @@ GnssAdapter::startTrackingCommand(LocationAPI* client, LocationOptions& options)
mSessionId(sessionId),
mOptions(options) {}
inline virtual void proc() const {
+ // distance based tracking will need to know engine capabilities before it can start
+ if (!mAdapter.isEngineCapabilitiesKnown() && mOptions.minDistance > 0) {
+ mAdapter.mPendingMsgs.push_back(new MsgStartTracking(*this));
+ return;
+ }
LocationError err = LOCATION_ERROR_SUCCESS;
if (!mAdapter.hasTrackingCallback(mClient) &&
!mAdapter.hasMeasurementsCallback(mClient)) {
@@ -1469,13 +2411,39 @@ GnssAdapter::startTrackingCommand(LocationAPI* client, LocationOptions& options)
} else if (0 == mOptions.size) {
err = LOCATION_ERROR_INVALID_PARAMETER;
} else {
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- err = mAdapter.startTrackingMultiplex(mOptions);
- if (LOCATION_ERROR_SUCCESS == err) {
+ if (mOptions.minInterval < MIN_TRACKING_INTERVAL) {
+ mOptions.minInterval = MIN_TRACKING_INTERVAL;
+ }
+ if (mOptions.minDistance > 0 &&
+ ContextBase::isMessageSupported(
+ LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) {
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+ mApi.startDistanceBasedTracking(mSessionId, mOptions,
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mClient = mClient]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ }
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ } else {
+ if (GNSS_POWER_MODE_M4 == mOptions.powerMode &&
+ mOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
+ LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
+ mOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
+ mOptions.powerMode = GNSS_POWER_MODE_M2;
+ }
+ // Api doesn't support multiple clients for time based tracking, so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.startTimeBasedTrackingMultiplex(mClient, mSessionId, mOptions);
mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
}
}
- mAdapter.reportResponse(mClient, err, mSessionId);
}
};
@@ -1484,110 +2452,110 @@ GnssAdapter::startTrackingCommand(LocationAPI* client, LocationOptions& options)
}
-LocationError
-GnssAdapter::startTrackingMultiplex(const LocationOptions& options)
+bool
+GnssAdapter::startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& options)
{
- LocationError err = LOCATION_ERROR_SUCCESS;
+ bool reportToClientWithNoWait = true;
- if (mTrackingSessions.empty()) {
- err = startTracking(options);
+ if (mTimeBasedTrackingSessions.empty()) {
+ startTimeBasedTracking(client, sessionId, options);
+ // need to wait for QMI callback
+ reportToClientWithNoWait = false;
} else {
- // get the LocationOptions that has the smallest interval, which should be the active one
- LocationOptions smallestIntervalOptions = {}; // size is zero until set for the first time
- for (auto it = mTrackingSessions.begin(); it != mTrackingSessions.end(); ++it) {
- if (0 == smallestIntervalOptions.size || //size of zero means we havent set it yet
- it->second.minInterval < smallestIntervalOptions.minInterval) {
- smallestIntervalOptions = it->second;
+ // find the smallest interval and powerMode
+ TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
+ GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
+ memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
+ for (auto it = mTimeBasedTrackingSessions.begin(); it != mTimeBasedTrackingSessions.end(); ++it) {
+ // if not set or there is a new smallest interval, then set the new interval
+ if (0 == multiplexedOptions.size ||
+ it->second.minInterval < multiplexedOptions.minInterval) {
+ multiplexedOptions = it->second;
+ }
+ // if session is not the one we are updating and either powerMode
+ // is not set or there is a new smallest powerMode, then set the new powerMode
+ if (GNSS_POWER_MODE_INVALID == multiplexedPowerMode ||
+ it->second.powerMode < multiplexedPowerMode) {
+ multiplexedPowerMode = it->second.powerMode;
}
}
- // if new session's minInterval is smaller than any in other sessions
- if (options.minInterval < smallestIntervalOptions.minInterval) {
- // restart time based tracking with new options
- err = startTracking(options);
+ bool updateOptions = false;
+ // if session we are starting has smaller interval then next smallest
+ if (options.minInterval < multiplexedOptions.minInterval) {
+ multiplexedOptions.minInterval = options.minInterval;
+ updateOptions = true;
}
- }
-
- return err;
-}
+ // if session we are starting has smaller powerMode then next smallest
+ if (options.powerMode < multiplexedPowerMode) {
+ multiplexedOptions.powerMode = options.powerMode;
+ updateOptions = true;
+ }
+ if (updateOptions) {
+ // restart time based tracking with the newly updated options
-LocationError
-GnssAdapter::startTracking(const LocationOptions& options)
-{
- LocationError err = LOCATION_ERROR_SUCCESS;
- LocPosMode locPosMode = {};
- convertOptions(locPosMode, options);
- if (!mUlpProxy->sendFixMode(locPosMode)) {
- // do nothing
- }
- if (!mUlpProxy->sendStartFix()) {
- loc_api_adapter_err apiErr = mLocApi->startFix(locPosMode);
- if (LOC_API_ADAPTER_ERR_SUCCESS == apiErr) {
- err = LOCATION_ERROR_SUCCESS;
- } else {
- err = LOCATION_ERROR_GENERAL_FAILURE;
+ startTimeBasedTracking(client, sessionId, multiplexedOptions);
+ // need to wait for QMI callback
+ reportToClientWithNoWait = false;
}
+ // else part: no QMI call is made, need to report back to client right away
}
- return err;
+ return reportToClientWithNoWait;
}
void
-GnssAdapter::setPositionModeCommand(LocPosMode& locPosMode)
+GnssAdapter::startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& trackingOptions)
{
- LOC_LOGD("%s]: min_interval %u mode %u",
- __func__, locPosMode.min_interval, locPosMode.mode);
+ LOC_LOGd("minInterval %u minDistance %u mode %u powermode %u tbm %u",
+ trackingOptions.minInterval, trackingOptions.minDistance,
+ trackingOptions.mode, trackingOptions.powerMode, trackingOptions.tbm);
- struct MsgSetPositionMode : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- LocPosMode mLocPosMode;
- inline MsgSetPositionMode(GnssAdapter& adapter,
- LocApiBase& api,
- LocPosMode& locPosMode) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api),
- mLocPosMode(locPosMode) {}
- inline virtual void proc() const {
- // saves the mode in adapter to be used when startTrackingCommand is called from ULP
- if (mAdapter.setUlpPositionMode(mLocPosMode)) {
- mApi.setPositionMode(mLocPosMode);
+ LocPosMode locPosMode = {};
+ convertOptions(locPosMode, trackingOptions);
+
+ // inform engine hub that GNSS session is about to start
+ mEngHubProxy->gnssSetFixMode(locPosMode);
+ mEngHubProxy->gnssStartFix();
+
+ mLocApi->startTimeBasedTracking(trackingOptions, new LocApiResponse(*getContext(),
+ [this, client, sessionId] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ eraseTrackingSession(client, sessionId);
}
- }
- };
- sendMsg(new MsgSetPositionMode(*this, *mLocApi, locPosMode));
+ reportResponse(client, err, sessionId);
+ }
+ ));
}
void
-GnssAdapter::startTrackingCommand()
+GnssAdapter::updateTracking(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions)
{
- LOC_LOGD("%s]: ", __func__);
+ LocPosMode locPosMode = {};
+ convertOptions(locPosMode, updatedOptions);
- struct MsgStartTracking : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- inline MsgStartTracking(GnssAdapter& adapter,
- LocApiBase& api) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api) {}
- inline virtual void proc() const {
- // we get this call from ULP, so just call LocApi without multiplexing because
- // ulp would be doing the multiplexing for us if it is present
- if (!mAdapter.isInSession()) {
- LocPosMode& ulpPositionMode = mAdapter.getUlpPositionMode();
- mApi.startFix(ulpPositionMode);
+ // inform engine hub that GNSS session is about to start
+ mEngHubProxy->gnssSetFixMode(locPosMode);
+ mEngHubProxy->gnssStartFix();
+
+ mLocApi->startTimeBasedTracking(updatedOptions, new LocApiResponse(*getContext(),
+ [this, client, sessionId, oldOptions] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS != err) {
+ // restore the old LocationOptions
+ saveTrackingSession(client, sessionId, oldOptions);
}
- }
- };
- sendMsg(new MsgStartTracking(*this, *mLocApi));
+ reportResponse(client, err, sessionId);
+ }
+ ));
}
void
GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id,
- LocationOptions& options)
+ TrackingOptions& options)
{
LOC_LOGD("%s]: client %p id %u minInterval %u mode %u",
__func__, client, id, options.minInterval, options.mode);
@@ -1597,12 +2565,12 @@ GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id,
LocApiBase& mApi;
LocationAPI* mClient;
uint32_t mSessionId;
- LocationOptions mOptions;
+ mutable TrackingOptions mOptions;
inline MsgUpdateTracking(GnssAdapter& adapter,
LocApiBase& api,
LocationAPI* client,
uint32_t sessionId,
- LocationOptions options) :
+ TrackingOptions options) :
LocMsg(),
mAdapter(adapter),
mApi(api),
@@ -1610,65 +2578,163 @@ GnssAdapter::updateTrackingOptionsCommand(LocationAPI* client, uint32_t id,
mSessionId(sessionId),
mOptions(options) {}
inline virtual void proc() const {
- if (mAdapter.isTrackingSession(mClient, mSessionId)) {
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (0 == mOptions.size) {
- err = LOCATION_ERROR_INVALID_PARAMETER;
- } else {
+ // distance based tracking will need to know engine capabilities before it can start
+ if (!mAdapter.isEngineCapabilitiesKnown() && mOptions.minDistance > 0) {
+ mAdapter.mPendingMsgs.push_back(new MsgUpdateTracking(*this));
+ return;
+ }
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ bool isTimeBased = mAdapter.isTimeBasedTrackingSession(mClient, mSessionId);
+ bool isDistanceBased = mAdapter.isDistanceBasedTrackingSession(mClient, mSessionId);
+ if (!isTimeBased && !isDistanceBased) {
+ err = LOCATION_ERROR_ID_UNKNOWN;
+ } else if (0 == mOptions.size) {
+ err = LOCATION_ERROR_INVALID_PARAMETER;
+ }
+ if (LOCATION_ERROR_SUCCESS != err) {
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ } else {
+ if (GNSS_POWER_MODE_M4 == mOptions.powerMode &&
+ mOptions.tbm > TRACKING_TBM_THRESHOLD_MILLIS) {
+ LOC_LOGd("TBM (%d) > %d Falling back to M2 power mode",
+ mOptions.tbm, TRACKING_TBM_THRESHOLD_MILLIS);
+ mOptions.powerMode = GNSS_POWER_MODE_M2;
+ }
+ if (mOptions.minInterval < MIN_TRACKING_INTERVAL) {
+ mOptions.minInterval = MIN_TRACKING_INTERVAL;
+ }
+ // Now update session as required
+ if (isTimeBased && mOptions.minDistance > 0) {
+ // switch from time based to distance based
// Api doesn't support multiple clients for time based tracking, so mutiplex
- err = mAdapter.updateTrackingMultiplex(mClient, mSessionId, mOptions);
- if (LOCATION_ERROR_SUCCESS == err) {
+ bool reportToClientWithNoWait =
+ mAdapter.stopTimeBasedTrackingMultiplex(mClient, mSessionId);
+ // erases the time based Session
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
+ // saves as distance based Session
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+ mApi.startDistanceBasedTracking(mSessionId, mOptions,
+ new LocApiResponse(*mAdapter.getContext(),
+ [] (LocationError /*err*/) {}));
+ } else if (isDistanceBased && mOptions.minDistance == 0) {
+ // switch from distance based to time based
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
+ *mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mOptions = mOptions,
+ mClient = mClient] (LocationError /*err*/) {
+ // Api doesn't support multiple clients for time based tracking,
+ // so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.startTimeBasedTrackingMultiplex(mClient, mSessionId,
+ mOptions);
mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
+ }));
+ } else if (isTimeBased) {
+ // update time based tracking
+ // Api doesn't support multiple clients for time based tracking, so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.updateTrackingMultiplex(mClient, mSessionId, mOptions);
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, err, mSessionId);
}
+ } else if (isDistanceBased) {
+ // restart distance based tracking
+ mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
+ *mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mOptions = mOptions,
+ mClient = mClient, &mApi = mApi] (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mApi.startDistanceBasedTracking(mSessionId, mOptions,
+ new LocApiResponse(*mAdapter.getContext(),
+ [&mAdapter, mClient, mSessionId, mOptions]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.saveTrackingSession(mClient, mSessionId, mOptions);
+ }
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
+ }
+ }));
}
- mAdapter.reportResponse(mClient, err, mSessionId);
}
- // we do not reportResponse for the case where there is no existing tracking session
- // for the client and id being used, since updateTrackingCommand can be sent to both
- // GnssAdapter & FlpAdapter by LocationAPI and we want to avoid incorrect error response
}
};
sendMsg(new MsgUpdateTracking(*this, *mLocApi, client, id, options));
}
-LocationError
+bool
GnssAdapter::updateTrackingMultiplex(LocationAPI* client, uint32_t id,
- const LocationOptions& options)
+ const TrackingOptions& trackingOptions)
{
- LocationError err = LOCATION_ERROR_SUCCESS;
-
- if (1 == mTrackingSessions.size()) {
- err = startTracking(options);
- } else {
- LocationSessionKey key(client, id);
-
- // get the session we are updating
- auto it = mTrackingSessions.find(key);
- if (it != mTrackingSessions.end()) {
- // find the smallest interval, other than the session we are updating
- LocationOptions smallestIntervalOptions = {}; // size is 0 until set for the first time
- for (auto it2 = mTrackingSessions.begin(); it2 != mTrackingSessions.end(); ++it2) {
- // if session is not the one we are updating and either smallest interval is not set
- // or there is a new smallest interval, then set the new smallest interval
- if (it2->first != key && (0 == smallestIntervalOptions.size ||
- it2->second.minInterval < smallestIntervalOptions.minInterval)) {
- smallestIntervalOptions = it2->second;
- }
+ bool reportToClientWithNoWait = true;
+
+ LocationSessionKey key(client, id);
+ // get the session we are updating
+ auto it = mTimeBasedTrackingSessions.find(key);
+
+ // cache the clients existing LocationOptions
+ TrackingOptions oldOptions = it->second;
+
+ // if session we are updating exists and the minInterval or powerMode has changed
+ if (it != mTimeBasedTrackingSessions.end() &&
+ (it->second.minInterval != trackingOptions.minInterval ||
+ it->second.powerMode != trackingOptions.powerMode)) {
+ // find the smallest interval and powerMode, other than the session we are updating
+ TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
+ GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
+ memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
+ for (auto it2 = mTimeBasedTrackingSessions.begin();
+ it2 != mTimeBasedTrackingSessions.end(); ++it2) {
+ // if session is not the one we are updating and either interval
+ // is not set or there is a new smallest interval, then set the new interval
+ if (it2->first != key && (0 == multiplexedOptions.size ||
+ it2->second.minInterval < multiplexedOptions.minInterval)) {
+ multiplexedOptions = it2->second;
}
- // if session we are updating has smaller interval then next smallest
- if (options.minInterval < smallestIntervalOptions.minInterval) {
- // restart time based tracking with the newly updated interval
- err = startTracking(options);
- // else if the session we are updating used to be the smallest
- } else if (it->second.minInterval < smallestIntervalOptions.minInterval) {
- // restart time based tracking with the next smallest
- err = startTracking(smallestIntervalOptions);
+ // if session is not the one we are updating and either powerMode
+ // is not set or there is a new smallest powerMode, then set the new powerMode
+ if (it2->first != key && (GNSS_POWER_MODE_INVALID == multiplexedPowerMode ||
+ it2->second.powerMode < multiplexedPowerMode)) {
+ multiplexedPowerMode = it2->second.powerMode;
}
+ // else part: no QMI call is made, need to report back to client right away
+ }
+ bool updateOptions = false;
+ // if session we are updating has smaller interval then next smallest
+ if (trackingOptions.minInterval < multiplexedOptions.minInterval) {
+ multiplexedOptions.minInterval = trackingOptions.minInterval;
+ updateOptions = true;
+ }
+ // if session we are updating has smaller powerMode then next smallest
+ if (trackingOptions.powerMode < multiplexedPowerMode) {
+ multiplexedOptions.powerMode = trackingOptions.powerMode;
+ updateOptions = true;
+ }
+ // if only one session exists, then tracking should be updated with it
+ if (1 == mTimeBasedTrackingSessions.size()) {
+ multiplexedOptions = trackingOptions;
+ updateOptions = true;
+ }
+ if (updateOptions) {
+ // restart time based tracking with the newly updated options
+ updateTracking(client, id, multiplexedOptions, oldOptions);
+ // need to wait for QMI callback
+ reportToClientWithNoWait = false;
}
}
- return err;
+ return reportToClientWithNoWait;
}
void
@@ -1691,18 +2757,32 @@ GnssAdapter::stopTrackingCommand(LocationAPI* client, uint32_t id)
mClient(client),
mSessionId(sessionId) {}
inline virtual void proc() const {
- if (mAdapter.isTrackingSession(mClient, mSessionId)) {
- LocationError err = LOCATION_ERROR_SUCCESS;
- // Api doesn't support multiple clients for time based tracking, so mutiplex
- err = mAdapter.stopTrackingMultiplex(mClient, mSessionId);
- if (LOCATION_ERROR_SUCCESS == err) {
+ bool isTimeBased = mAdapter.isTimeBasedTrackingSession(mClient, mSessionId);
+ bool isDistanceBased = mAdapter.isDistanceBasedTrackingSession(mClient, mSessionId);
+ if (isTimeBased || isDistanceBased) {
+ if (isTimeBased) {
+ // Api doesn't support multiple clients for time based tracking, so mutiplex
+ bool reportToClientWithNoWait =
+ mAdapter.stopTimeBasedTrackingMultiplex(mClient, mSessionId);
mAdapter.eraseTrackingSession(mClient, mSessionId);
+
+ if (reportToClientWithNoWait) {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_SUCCESS, mSessionId);
+ }
+ } else if (isDistanceBased) {
+ mApi.stopDistanceBasedTracking(mSessionId, new LocApiResponse(
+ *mAdapter.getContext(),
+ [&mAdapter = mAdapter, mSessionId = mSessionId, mClient = mClient]
+ (LocationError err) {
+ if (LOCATION_ERROR_SUCCESS == err) {
+ mAdapter.eraseTrackingSession(mClient, mSessionId);
+ }
+ mAdapter.reportResponse(mClient, err, mSessionId);
+ }));
}
- mAdapter.reportResponse(mClient, err, mSessionId);
+ } else {
+ mAdapter.reportResponse(mClient, LOCATION_ERROR_ID_UNKNOWN, mSessionId);
}
- // we do not reportResponse for the case where there is no existing tracking session
- // for the client and id being used, since stopTrackingCommand can be sent to both
- // GnssAdapter & FlpAdapter by LocationAPI and we want to avoid incorrect error response
}
};
@@ -1710,115 +2790,67 @@ GnssAdapter::stopTrackingCommand(LocationAPI* client, uint32_t id)
sendMsg(new MsgStopTracking(*this, *mLocApi, client, id));
}
-LocationError
-GnssAdapter::stopTrackingMultiplex(LocationAPI* client, uint32_t id)
+bool
+GnssAdapter::stopTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t id)
{
- LocationError err = LOCATION_ERROR_SUCCESS;
+ bool reportToClientWithNoWait = true;
- if (1 == mTrackingSessions.size()) {
- err = stopTracking();
+ if (1 == mTimeBasedTrackingSessions.size()) {
+ stopTracking(client, id);
+ // need to wait for QMI callback
+ reportToClientWithNoWait = false;
} else {
LocationSessionKey key(client, id);
// get the session we are stopping
- auto it = mTrackingSessions.find(key);
- if (it != mTrackingSessions.end()) {
- // find the next smallest interval, other than the session we are stopping
- LocationOptions smallestIntervalOptions = {}; // size is 0 until set for the first time
- for (auto it2 = mTrackingSessions.begin(); it2 != mTrackingSessions.end(); ++it2) {
- // if session is not the one we are stopping and either smallest interval is not set
- // or there is a new smallest interval, then set the new smallest interval
- if (it2->first != key && (0 == smallestIntervalOptions.size ||
- it2->second.minInterval < smallestIntervalOptions.minInterval)) {
- smallestIntervalOptions = it2->second;
+ auto it = mTimeBasedTrackingSessions.find(key);
+ if (it != mTimeBasedTrackingSessions.end()) {
+ // find the smallest interval and powerMode, other than the session we are stopping
+ TrackingOptions multiplexedOptions = {}; // size is 0 until set for the first time
+ GnssPowerMode multiplexedPowerMode = GNSS_POWER_MODE_INVALID;
+ memset(&multiplexedOptions, 0, sizeof(multiplexedOptions));
+ for (auto it2 = mTimeBasedTrackingSessions.begin();
+ it2 != mTimeBasedTrackingSessions.end(); ++it2) {
+ // if session is not the one we are stopping and either interval
+ // is not set or there is a new smallest interval, then set the new interval
+ if (it2->first != key && (0 == multiplexedOptions.size ||
+ it2->second.minInterval < multiplexedOptions.minInterval)) {
+ multiplexedOptions = it2->second;
+ }
+ // if session is not the one we are stopping and either powerMode
+ // is not set or there is a new smallest powerMode, then set the new powerMode
+ if (it2->first != key && (GNSS_POWER_MODE_INVALID == multiplexedPowerMode ||
+ it2->second.powerMode < multiplexedPowerMode)) {
+ multiplexedPowerMode = it2->second.powerMode;
}
}
- // if session we are stopping has smaller interval then next smallest
- if (it->second.minInterval < smallestIntervalOptions.minInterval) {
- // restart time based tracking with next smallest interval
- err = startTracking(smallestIntervalOptions);
+ // if session we are stopping has smaller interval then next smallest or
+ // if session we are stopping has smaller powerMode then next smallest
+ if (it->second.minInterval < multiplexedOptions.minInterval ||
+ it->second.powerMode < multiplexedPowerMode) {
+ multiplexedOptions.powerMode = multiplexedPowerMode;
+ // restart time based tracking with the newly updated options
+ startTimeBasedTracking(client, id, multiplexedOptions);
+ // need to wait for QMI callback
+ reportToClientWithNoWait = false;
}
+ // else part: no QMI call is made, need to report back to client right away
}
}
- return err;
-}
-
-LocationError
-GnssAdapter::stopTracking()
-{
- LocationError err = LOCATION_ERROR_SUCCESS;
- if (!mUlpProxy->sendStopFix()) {
- loc_api_adapter_err apiErr = mLocApi->stopFix();
- if (LOC_API_ADAPTER_ERR_SUCCESS == apiErr) {
- err = LOCATION_ERROR_SUCCESS;
- } else {
- err = LOCATION_ERROR_GENERAL_FAILURE;
- }
- }
-
- return err;
+ return reportToClientWithNoWait;
}
void
-GnssAdapter::stopTrackingCommand()
+GnssAdapter::stopTracking(LocationAPI* client, uint32_t id)
{
- LOC_LOGD("%s]: ", __func__);
+ // inform engine hub that GNSS session has stopped
+ mEngHubProxy->gnssStopFix();
- struct MsgStopTracking : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- inline MsgStopTracking(GnssAdapter& adapter,
- LocApiBase& api) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api) {}
- inline virtual void proc() const {
- // clear the position mode
- LocPosMode mLocPosMode = {};
- mLocPosMode.mode = LOC_POSITION_MODE_INVALID;
- mAdapter.setUlpPositionMode(mLocPosMode);
- // don't need to multiplex because ULP will do that for us if it is present
- mApi.stopFix();
- }
- };
-
- sendMsg(new MsgStopTracking(*this, *mLocApi));
-}
-
-void
-GnssAdapter::getZppCommand()
-{
- LOC_LOGD("%s]: ", __func__);
-
- struct MsgGetZpp : public LocMsg {
- GnssAdapter& mAdapter;
- LocApiBase& mApi;
- inline MsgGetZpp(GnssAdapter& adapter,
- LocApiBase& api) :
- LocMsg(),
- mAdapter(adapter),
- mApi(api) {}
- inline virtual void proc() const {
- UlpLocation location = {};
- LocPosTechMask techMask = LOC_POS_TECH_MASK_DEFAULT;
- GpsLocationExtended locationExtended = {};
- locationExtended.size = sizeof(locationExtended);
-
- mApi.getBestAvailableZppFix(location.gpsLocation, locationExtended,
- techMask);
- //Mark the location source as from ZPP
- location.gpsLocation.flags |= LOCATION_HAS_SOURCE_INFO;
- location.position_source = ULP_LOCATION_IS_FROM_ZPP;
-
- mAdapter.getUlpProxy()->reportPosition(location,
- locationExtended,
- LOC_SESS_SUCCESS,
- techMask);
- }
- };
-
- sendMsg(new MsgGetZpp(*this, *mLocApi));
+ mLocApi->stopFix(new LocApiResponse(*getContext(),
+ [this, client, id] (LocationError err) {
+ reportResponse(client, err, id);
+ }));
}
bool
@@ -1901,28 +2933,27 @@ GnssAdapter::gnssNiResponseCommand(GnssNiResponse response, void* rawRequest)
LOC_LOGD("%s]: response %u", __func__, response);
struct MsgGnssNiResponse : public LocMsg {
+ GnssAdapter& mAdapter;
LocApiBase& mApi;
const GnssNiResponse mResponse;
const void* mPayload;
- inline MsgGnssNiResponse(LocApiBase& api,
+ inline MsgGnssNiResponse(GnssAdapter& adapter,
+ LocApiBase& api,
const GnssNiResponse response,
const void* rawRequest) :
LocMsg(),
+ mAdapter(adapter),
mApi(api),
mResponse(response),
mPayload(rawRequest) {}
inline virtual ~MsgGnssNiResponse() {
- // this is a bit weird since mPayload is not
- // allocated by this class. But there is no better way.
- // mPayload actually won't be NULL here.
- free((void*)mPayload);
}
inline virtual void proc() const {
mApi.informNiResponse(mResponse, mPayload);
}
};
- sendMsg(new MsgGnssNiResponse(*mLocApi, response, rawRequest));
+ sendMsg(new MsgGnssNiResponse(*this, *mLocApi, response, rawRequest));
}
@@ -1951,17 +2982,24 @@ GnssAdapter::enableCommand(LocationTechnologyType techType)
mTechType(techType) {}
inline virtual void proc() const {
LocationError err = LOCATION_ERROR_SUCCESS;
- uint32_t powerVoteId = mAdapter.getPowerVoteId();
+ uint32_t afwControlId = mAdapter.getAfwControlId();
if (mTechType != LOCATION_TECHNOLOGY_TYPE_GNSS) {
err = LOCATION_ERROR_INVALID_PARAMETER;
- } else if (powerVoteId > 0) {
+ } else if (afwControlId > 0) {
err = LOCATION_ERROR_ALREADY_STARTED;
} else {
mContext.modemPowerVote(true);
- mAdapter.setPowerVoteId(mSessionId);
- mApi.setGpsLock(GNSS_CONFIG_GPS_LOCK_NONE);
- mAdapter.mXtraObserver.updateLockStatus(
- mAdapter.convertGpsLock(GNSS_CONFIG_GPS_LOCK_NONE));
+ mAdapter.setAfwControlId(mSessionId);
+
+ GnssConfigGpsLock gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+ if (mAdapter.mSupportNfwControl) {
+ ContextBase::mGps_conf.GPS_LOCK &= GNSS_CONFIG_GPS_LOCK_NI;
+ gpsLock = ContextBase::mGps_conf.GPS_LOCK;
+ }
+ mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() {
+ mApi.setGpsLockSync(gpsLock);
+ }));
+ mAdapter.mXtraObserver.updateLockStatus(gpsLock);
}
mAdapter.reportResponse(err, mSessionId);
}
@@ -1997,15 +3035,22 @@ GnssAdapter::disableCommand(uint32_t id)
mSessionId(sessionId) {}
inline virtual void proc() const {
LocationError err = LOCATION_ERROR_SUCCESS;
- uint32_t powerVoteId = mAdapter.getPowerVoteId();
- if (powerVoteId != mSessionId) {
+ uint32_t afwControlId = mAdapter.getAfwControlId();
+ if (afwControlId != mSessionId) {
err = LOCATION_ERROR_ID_UNKNOWN;
} else {
mContext.modemPowerVote(false);
- mAdapter.setPowerVoteId(0);
- mApi.setGpsLock(mAdapter.convertGpsLock(ContextBase::mGps_conf.GPS_LOCK));
- mAdapter.mXtraObserver.updateLockStatus(
- mAdapter.convertGpsLock(ContextBase::mGps_conf.GPS_LOCK));
+ mAdapter.setAfwControlId(0);
+
+ if (mAdapter.mSupportNfwControl) {
+ /* We need to disable MO (AFW) */
+ ContextBase::mGps_conf.GPS_LOCK |= GNSS_CONFIG_GPS_LOCK_MO;
+ }
+ GnssConfigGpsLock gpsLock = ContextBase::mGps_conf.GPS_LOCK;
+ mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() {
+ mApi.setGpsLockSync(gpsLock);
+ }));
+ mAdapter.mXtraObserver.updateLockStatus(gpsLock);
}
mAdapter.reportResponse(err, mSessionId);
}
@@ -2022,35 +3067,56 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
enum loc_sess_status status,
LocPosTechMask techMask,
- bool fromUlp)
+ GnssDataNotification* pDataNotify,
+ int msInWeek)
{
- LOC_LOGD("%s]: fromUlp %u status %u", __func__, fromUlp, status);
+ // this position is from QMI LOC API, then send report to engine hub
+ // if sending is successful, we return as we will wait for final report from engine hub
+ // if the position is called from engine hub, then send it out directly
- // if this event is not called from ULP, then try to call into ULP and return if successfull
- if (!fromUlp) {
- if (mUlpProxy->reportPosition(ulpLocation, locationExtended,
- status, techMask)) {
- return;
- }
+ if (true == initEngHubProxy()){
+ mEngHubProxy->gnssReportPosition(ulpLocation, locationExtended, status);
+ return;
}
+ if (true == ulpLocation.unpropagatedPosition) {
+ return;
+ }
+
+ // Fix is from QMI, and it is not an
+ // unpropagated position and engine hub is not loaded, queue the msg
+ // when message is queued, the position can be dispatched to requesting client
struct MsgReportPosition : public LocMsg {
GnssAdapter& mAdapter;
const UlpLocation mUlpLocation;
const GpsLocationExtended mLocationExtended;
loc_sess_status mStatus;
LocPosTechMask mTechMask;
+ GnssDataNotification mDataNotify;
+ int mMsInWeek;
+ bool mbIsDataValid;
inline MsgReportPosition(GnssAdapter& adapter,
const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
loc_sess_status status,
- LocPosTechMask techMask) :
+ LocPosTechMask techMask,
+ GnssDataNotification* pDataNotify,
+ int msInWeek) :
LocMsg(),
mAdapter(adapter),
mUlpLocation(ulpLocation),
mLocationExtended(locationExtended),
mStatus(status),
- mTechMask(techMask) {}
+ mTechMask(techMask),
+ mMsInWeek(msInWeek) {
+ memset(&mDataNotify, 0, sizeof(mDataNotify));
+ if (pDataNotify != nullptr) {
+ mDataNotify = *pDataNotify;
+ mbIsDataValid = true;
+ } else {
+ mbIsDataValid = false;
+ }
+ }
inline virtual void proc() const {
// extract bug report info - this returns true if consumed by systemstatus
SystemStatus* s = mAdapter.getSystemStatus();
@@ -2059,98 +3125,215 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation,
s->eventPosition(mUlpLocation, mLocationExtended);
}
mAdapter.reportPosition(mUlpLocation, mLocationExtended, mStatus, mTechMask);
+ if (true == mbIsDataValid) {
+ if (-1 != mMsInWeek) {
+ mAdapter.getDataInformation((GnssDataNotification&)mDataNotify,
+ mMsInWeek);
+ }
+ mAdapter.reportData((GnssDataNotification&)mDataNotify);
+ }
}
};
- sendMsg(new MsgReportPosition(*this, ulpLocation, locationExtended, status, techMask));
+ sendMsg(new MsgReportPosition(*this, ulpLocation, locationExtended,
+ status, techMask,
+ pDataNotify, msInWeek));
+}
+
+void
+GnssAdapter::reportEnginePositionsEvent(unsigned int count,
+ EngineLocationInfo* locationArr)
+{
+ struct MsgReportEnginePositions : public LocMsg {
+ GnssAdapter& mAdapter;
+ unsigned int mCount;
+ EngineLocationInfo mEngLocInfo[LOC_OUTPUT_ENGINE_COUNT];
+ inline MsgReportEnginePositions(GnssAdapter& adapter,
+ unsigned int count,
+ EngineLocationInfo* locationArr) :
+ LocMsg(),
+ mAdapter(adapter),
+ mCount(count) {
+ if (mCount > LOC_OUTPUT_ENGINE_COUNT) {
+ mCount = LOC_OUTPUT_ENGINE_COUNT;
+ }
+ if (mCount > 0) {
+ memcpy(mEngLocInfo, locationArr, sizeof(EngineLocationInfo)*mCount);
+ }
+ }
+ inline virtual void proc() const {
+ mAdapter.reportEnginePositions(mCount, mEngLocInfo);
+ }
+ };
+
+ sendMsg(new MsgReportEnginePositions(*this, count, locationArr));
}
bool
-GnssAdapter::needReport(const UlpLocation& ulpLocation,
- enum loc_sess_status status,
- LocPosTechMask techMask) {
+GnssAdapter::needReportForGnssClient(const UlpLocation& ulpLocation,
+ enum loc_sess_status status,
+ LocPosTechMask techMask) {
bool reported = false;
- if (LOC_SESS_SUCCESS == status) {
- // this is a final fix
- LocPosTechMask mask =
- LOC_POS_TECH_MASK_SATELLITE | LOC_POS_TECH_MASK_SENSORS | LOC_POS_TECH_MASK_HYBRID;
- // it is a Satellite fix or a sensor fix
- reported = (mask & techMask);
- } else if (LOC_SESS_INTERMEDIATE == status &&
- LOC_SESS_INTERMEDIATE == ContextBase::mGps_conf.INTERMEDIATE_POS) {
- // this is a intermediate fix and we accepte intermediate
-
- // it is NOT the case that
- // there is inaccuracy; and
- // we care about inaccuracy; and
- // the inaccuracy exceeds our tolerance
- reported = !((ulpLocation.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ACCURACY) &&
- (ContextBase::mGps_conf.ACCURACY_THRES != 0) &&
- (ulpLocation.gpsLocation.accuracy > ContextBase::mGps_conf.ACCURACY_THRES));
- }
+ // if engine hub is enabled, aka, any of the engine services is enabled,
+ // then always output position reported by engine hub to requesting client
+ if (true == initEngHubProxy()) {
+ reported = true;
+ } else {
+ reported = LocApiBase::needReport(ulpLocation, status, techMask);
+ }
return reported;
}
+bool
+GnssAdapter::needReportForFlpClient(enum loc_sess_status status,
+ LocPosTechMask techMask) {
+ if ((status == LOC_SESS_INTERMEDIATE) &&
+ !(techMask & LOC_POS_TECH_MASK_SENSORS) &&
+ (!getAllowFlpNetworkFixes())) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool
+GnssAdapter::isFlpClient(LocationCallbacks& locationCallbacks)
+{
+ return (locationCallbacks.gnssLocationInfoCb == nullptr &&
+ locationCallbacks.gnssSvCb == nullptr &&
+ locationCallbacks.gnssNmeaCb == nullptr &&
+ locationCallbacks.gnssDataCb == nullptr &&
+ locationCallbacks.gnssMeasurementsCb == nullptr);
+}
+
void
GnssAdapter::reportPosition(const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
enum loc_sess_status status,
LocPosTechMask techMask)
{
- bool reported = needReport(ulpLocation, status, techMask);
- if (reported) {
- if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA) {
- mGnssSvIdUsedInPosAvail = true;
- mGnssSvIdUsedInPosition = locationExtended.gnss_sv_used_ids;
- }
+ bool reportToGnssClient = needReportForGnssClient(ulpLocation, status, techMask);
+ bool reportToFlpClient = needReportForFlpClient(status, techMask);
+
+ if (reportToGnssClient || reportToFlpClient) {
+ GnssLocationInfoNotification locationInfo = {};
+ convertLocationInfo(locationInfo, locationExtended);
+ convertLocation(locationInfo.location, ulpLocation, locationExtended, techMask);
+
for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
- if (nullptr != it->second.trackingCb) {
- Location location = {};
- convertLocation(location, ulpLocation.gpsLocation, locationExtended, techMask);
- it->second.trackingCb(location);
+ if ((reportToFlpClient && isFlpClient(it->second)) ||
+ (reportToGnssClient && !isFlpClient(it->second))) {
+ if (nullptr != it->second.gnssLocationInfoCb) {
+ it->second.gnssLocationInfoCb(locationInfo);
+ } else if ((nullptr != it->second.engineLocationsInfoCb) &&
+ (false == initEngHubProxy())) {
+ // if engine hub is disabled, this is SPE fix from modem
+ // we need to mark one copy marked as fused and one copy marked as PPE
+ // and dispatch it to the engineLocationsInfoCb
+ GnssLocationInfoNotification engLocationsInfo[2];
+ engLocationsInfo[0] = locationInfo;
+ engLocationsInfo[0].locOutputEngType = LOC_OUTPUT_ENGINE_FUSED;
+ engLocationsInfo[0].flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT;
+ engLocationsInfo[1] = locationInfo;
+ it->second.engineLocationsInfoCb(2, engLocationsInfo);
+ } else if (nullptr != it->second.trackingCb) {
+ it->second.trackingCb(locationInfo.location);
+ }
}
- if (nullptr != it->second.gnssLocationInfoCb) {
- GnssLocationInfoNotification locationInfo = {};
- convertLocationInfo(locationInfo, locationExtended);
- it->second.gnssLocationInfoCb(locationInfo);
+ }
+
+ mGnssSvIdUsedInPosAvail = false;
+ mGnssMbSvIdUsedInPosAvail = false;
+ if (reportToGnssClient) {
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA) {
+ mGnssSvIdUsedInPosAvail = true;
+ mGnssSvIdUsedInPosition = locationExtended.gnss_sv_used_ids;
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_MULTIBAND) {
+ mGnssMbSvIdUsedInPosAvail = true;
+ mGnssMbSvIdUsedInPosition = locationExtended.gnss_mb_sv_used_ids;
+ }
+ }
+
+ // if engine hub is running and the fix is from sensor, e.g.: DRE,
+ // inject DRE fix to modem
+ if ((1 == ContextBase::mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED) &&
+ (true == initEngHubProxy()) && (LOC_POS_TECH_MASK_SENSORS & techMask)) {
+ mLocApi->injectPosition(locationInfo, false);
}
}
}
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER && !mTrackingSessions.empty()) {
+ if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
+ !mTimeBasedTrackingSessions.empty()) {
/*Only BlankNMEA sentence needs to be processed and sent, if both lat, long is 0 &
horReliability is not set. */
bool blank_fix = ((0 == ulpLocation.gpsLocation.latitude) &&
(0 == ulpLocation.gpsLocation.longitude) &&
(LOC_RELIABILITY_NOT_SET == locationExtended.horizontal_reliability));
- uint8_t generate_nmea = (reported && status != LOC_SESS_FAILURE && !blank_fix);
+ uint8_t generate_nmea = (reportToGnssClient && status != LOC_SESS_FAILURE && !blank_fix);
+ bool custom_nmea_gga = (1 == ContextBase::mGps_conf.CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED);
std::vector<std::string> nmeaArraystr;
- loc_nmea_generate_pos(ulpLocation, locationExtended, generate_nmea, nmeaArraystr);
- for (auto sentence : nmeaArraystr) {
- reportNmea(sentence.c_str(), sentence.length());
+ loc_nmea_generate_pos(ulpLocation, locationExtended, mLocSystemInfo,
+ generate_nmea, custom_nmea_gga, nmeaArraystr);
+ stringstream ss;
+ for (auto itor = nmeaArraystr.begin(); itor != nmeaArraystr.end(); ++itor) {
+ ss << *itor;
+ }
+ string s = ss.str();
+ reportNmea(s.c_str(), s.length());
+ }
+}
+
+void
+GnssAdapter::reportEnginePositions(unsigned int count,
+ const EngineLocationInfo* locationArr)
+{
+ bool needReportEnginePositions = false;
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if (nullptr != it->second.engineLocationsInfoCb) {
+ needReportEnginePositions = true;
+ break;
}
}
- // Free the allocated memory for rawData
- UlpLocation* gp = (UlpLocation*)&(ulpLocation);
- if (gp != NULL && gp->rawData != NULL)
- {
- delete (char*)gp->rawData;
- gp->rawData = NULL;
- gp->rawDataSize = 0;
+ GnssLocationInfoNotification locationInfo[LOC_OUTPUT_ENGINE_COUNT] = {};
+ for (unsigned int i = 0; i < count; i++) {
+ const EngineLocationInfo* engLocation = (locationArr+i);
+ // if it is fused/default location, call reportPosition maintain legacy behavior
+ if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) &&
+ (LOC_OUTPUT_ENGINE_FUSED == engLocation->locationExtended.locOutputEngType)) {
+ reportPosition(engLocation->location,
+ engLocation->locationExtended,
+ engLocation->sessionStatus,
+ engLocation->location.tech_mask);
+ }
+
+ if (needReportEnginePositions) {
+ convertLocationInfo(locationInfo[i], engLocation->locationExtended);
+ convertLocation(locationInfo[i].location,
+ engLocation->location,
+ engLocation->locationExtended,
+ engLocation->location.tech_mask);
+ }
+ }
+
+ if (needReportEnginePositions) {
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if (nullptr != it->second.engineLocationsInfoCb) {
+ it->second.engineLocationsInfoCb(count, locationInfo);
+ }
+ }
}
}
void
GnssAdapter::reportSvEvent(const GnssSvNotification& svNotify,
- bool fromUlp)
+ bool fromEngineHub)
{
- LOC_LOGD("%s]: fromUlp %u", __func__, fromUlp);
-
- // if this event is not called from ULP, then try to call into ULP and return if successfull
- if (!fromUlp) {
- if (mUlpProxy->reportSv(svNotify)) {
+ if (!fromEngineHub) {
+ mEngHubProxy->gnssReportSv(svNotify);
+ if (true == initEngHubProxy()){
return;
}
}
@@ -2180,36 +3363,121 @@ GnssAdapter::reportSv(GnssSvNotification& svNotify)
for (int i=0; i < numSv; i++) {
svUsedIdMask = 0;
gnssSvId = svNotify.gnssSvs[i].svId;
+ GnssSignalTypeMask signalTypeMask = svNotify.gnssSvs[i].gnssSignalTypeMask;
switch (svNotify.gnssSvs[i].type) {
case GNSS_SV_TYPE_GPS:
if (mGnssSvIdUsedInPosAvail) {
- svUsedIdMask = mGnssSvIdUsedInPosition.gps_sv_used_ids_mask;
+ if (mGnssMbSvIdUsedInPosAvail) {
+ switch (signalTypeMask) {
+ case GNSS_SIGNAL_GPS_L1CA:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.gps_l1ca_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_GPS_L1C:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.gps_l1c_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_GPS_L2:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.gps_l2_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_GPS_L5:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.gps_l5_sv_used_ids_mask;
+ break;
+ }
+ } else {
+ svUsedIdMask = mGnssSvIdUsedInPosition.gps_sv_used_ids_mask;
+ }
}
break;
case GNSS_SV_TYPE_GLONASS:
if (mGnssSvIdUsedInPosAvail) {
- svUsedIdMask = mGnssSvIdUsedInPosition.glo_sv_used_ids_mask;
+ if (mGnssMbSvIdUsedInPosAvail) {
+ switch (signalTypeMask) {
+ case GNSS_SIGNAL_GLONASS_G1:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.glo_g1_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_GLONASS_G2:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.glo_g2_sv_used_ids_mask;
+ break;
+ }
+ } else {
+ svUsedIdMask = mGnssSvIdUsedInPosition.glo_sv_used_ids_mask;
+ }
}
break;
case GNSS_SV_TYPE_BEIDOU:
if (mGnssSvIdUsedInPosAvail) {
- svUsedIdMask = mGnssSvIdUsedInPosition.bds_sv_used_ids_mask;
+ if (mGnssMbSvIdUsedInPosAvail) {
+ switch (signalTypeMask) {
+ case GNSS_SIGNAL_BEIDOU_B1I:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b1i_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B1C:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b1c_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B2I:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b2i_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B2AI:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b2ai_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B2AQ:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.bds_b2aq_sv_used_ids_mask;
+ break;
+ }
+ } else {
+ svUsedIdMask = mGnssSvIdUsedInPosition.bds_sv_used_ids_mask;
+ }
}
break;
case GNSS_SV_TYPE_GALILEO:
if (mGnssSvIdUsedInPosAvail) {
- svUsedIdMask = mGnssSvIdUsedInPosition.gal_sv_used_ids_mask;
+ if (mGnssMbSvIdUsedInPosAvail) {
+ switch (signalTypeMask) {
+ case GNSS_SIGNAL_GALILEO_E1:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.gal_e1_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_GALILEO_E5A:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.gal_e5a_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_GALILEO_E5B:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.gal_e5b_sv_used_ids_mask;
+ break;
+ }
+ } else {
+ svUsedIdMask = mGnssSvIdUsedInPosition.gal_sv_used_ids_mask;
+ }
}
break;
case GNSS_SV_TYPE_QZSS:
if (mGnssSvIdUsedInPosAvail) {
- svUsedIdMask = mGnssSvIdUsedInPosition.qzss_sv_used_ids_mask;
+ if (mGnssMbSvIdUsedInPosAvail) {
+ switch (signalTypeMask) {
+ case GNSS_SIGNAL_QZSS_L1CA:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.qzss_l1ca_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_QZSS_L1S:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.qzss_l1s_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_QZSS_L2:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.qzss_l2_sv_used_ids_mask;
+ break;
+ case GNSS_SIGNAL_QZSS_L5:
+ svUsedIdMask = mGnssMbSvIdUsedInPosition.qzss_l5_sv_used_ids_mask;
+ break;
+ }
+ } else {
+ svUsedIdMask = mGnssSvIdUsedInPosition.qzss_sv_used_ids_mask;
+ }
}
// QZSS SV id's need to reported as it is to framework, since
// framework expects it as it is. See GnssStatus.java.
// SV id passed to here by LocApi is 1-based.
svNotify.gnssSvs[i].svId += (QZSS_SV_PRN_MIN - 1);
break;
+ case GNSS_SV_TYPE_NAVIC:
+ if (mGnssSvIdUsedInPosAvail) {
+ svUsedIdMask = mGnssSvIdUsedInPosition.navic_sv_used_ids_mask;
+ }
+ break;
default:
svUsedIdMask = 0;
break;
@@ -2217,7 +3485,7 @@ GnssAdapter::reportSv(GnssSvNotification& svNotify)
// If SV ID was used in previous position fix, then set USED_IN_FIX
// flag, else clear the USED_IN_FIX flag.
- if (svUsedIdMask & (1 << (gnssSvId - 1))) {
+ if ((gnssSvId < 64) && (svUsedIdMask & (1ULL << (gnssSvId - 1)))) {
svNotify.gnssSvs[i].gnssSvOptionsMask |= GNSS_SV_OPTIONS_USED_IN_FIX_BIT;
}
}
@@ -2228,25 +3496,27 @@ GnssAdapter::reportSv(GnssSvNotification& svNotify)
}
}
- if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER && !mTrackingSessions.empty()) {
+ if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
+ !mTimeBasedTrackingSessions.empty()) {
std::vector<std::string> nmeaArraystr;
loc_nmea_generate_sv(svNotify, nmeaArraystr);
- for (auto sentence : nmeaArraystr) {
- reportNmea(sentence.c_str(), sentence.length());
+ stringstream ss;
+ for (auto itor = nmeaArraystr.begin(); itor != nmeaArraystr.end(); ++itor) {
+ ss << *itor;
}
+ string s = ss.str();
+ reportNmea(s.c_str(), s.length());
}
mGnssSvIdUsedInPosAvail = false;
}
void
-GnssAdapter::reportNmeaEvent(const char* nmea, size_t length, bool fromUlp)
+GnssAdapter::reportNmeaEvent(const char* nmea, size_t length)
{
- // if this event is not called from ULP, then try to call into ULP and return if successfull
- if (!fromUlp && !loc_nmea_is_debug(nmea, length)) {
- if (mUlpProxy->reportNmea(nmea, length)) {
- return;
- }
+ if (NMEA_PROVIDER_AP == ContextBase::mGps_conf.NMEA_PROVIDER &&
+ !loc_nmea_is_debug(nmea, length)) {
+ return;
}
struct MsgReportNmea : public LocMsg {
@@ -2307,8 +3577,57 @@ GnssAdapter::reportNmea(const char* nmea, size_t length)
}
}
+void
+GnssAdapter::reportDataEvent(const GnssDataNotification& dataNotify,
+ int msInWeek)
+{
+ struct MsgReportData : public LocMsg {
+ GnssAdapter& mAdapter;
+ GnssDataNotification mDataNotify;
+ int mMsInWeek;
+ inline MsgReportData(GnssAdapter& adapter,
+ const GnssDataNotification& dataNotify,
+ int msInWeek) :
+ LocMsg(),
+ mAdapter(adapter),
+ mDataNotify(dataNotify),
+ mMsInWeek(msInWeek) {
+ }
+ inline virtual void proc() const {
+ if (-1 != mMsInWeek) {
+ mAdapter.getDataInformation((GnssDataNotification&)mDataNotify,
+ mMsInWeek);
+ }
+ mAdapter.reportData((GnssDataNotification&)mDataNotify);
+ }
+ };
+
+ sendMsg(new MsgReportData(*this, dataNotify, msInWeek));
+}
+
+void
+GnssAdapter::reportData(GnssDataNotification& dataNotify)
+{
+ for (int sig = 0; sig < GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES; sig++) {
+ if (GNSS_LOC_DATA_JAMMER_IND_BIT ==
+ (dataNotify.gnssDataMask[sig] & GNSS_LOC_DATA_JAMMER_IND_BIT)) {
+ LOC_LOGv("jammerInd[%d]=%f", sig, dataNotify.jammerInd[sig]);
+ }
+ if (GNSS_LOC_DATA_AGC_BIT ==
+ (dataNotify.gnssDataMask[sig] & GNSS_LOC_DATA_AGC_BIT)) {
+ LOC_LOGv("agc[%d]=%f", sig, dataNotify.agc[sig]);
+ }
+ }
+ for (auto it = mClientData.begin(); it != mClientData.end(); ++it) {
+ if (nullptr != it->second.gnssDataCb) {
+ it->second.gnssDataCb(dataNotify);
+ }
+ }
+}
+
bool
-GnssAdapter::requestNiNotifyEvent(const GnssNiNotification &notify, const void* data)
+GnssAdapter::requestNiNotifyEvent(const GnssNiNotification &notify, const void* data,
+ const LocInEmergency emergencyState)
{
LOC_LOGI("%s]: notif_type: %d, timeout: %d, default_resp: %d"
"requestor_id: %s (encoding: %d) text: %s text (encoding: %d) extras: %s",
@@ -2318,25 +3637,112 @@ GnssAdapter::requestNiNotifyEvent(const GnssNiNotification &notify, const void*
struct MsgReportNiNotify : public LocMsg {
GnssAdapter& mAdapter;
+ LocApiBase& mApi;
const GnssNiNotification mNotify;
const void* mData;
+ const LocInEmergency mEmergencyState;
inline MsgReportNiNotify(GnssAdapter& adapter,
+ LocApiBase& api,
const GnssNiNotification& notify,
- const void* data) :
+ const void* data,
+ const LocInEmergency emergencyState) :
LocMsg(),
mAdapter(adapter),
+ mApi(api),
mNotify(notify),
- mData(data) {}
+ mData(data),
+ mEmergencyState(emergencyState) {}
inline virtual void proc() const {
- mAdapter.requestNiNotify(mNotify, mData);
+ bool bIsInEmergency = false;
+ bool bInformNiAccept = false;
+
+ bIsInEmergency = ((LOC_IN_EMERGENCY_UNKNOWN == mEmergencyState) &&
+ mAdapter.getE911State()) || // older modems
+ (LOC_IN_EMERGENCY_SET == mEmergencyState); // newer modems
+
+ if (GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type) {
+ bInformNiAccept = bIsInEmergency ||
+ (GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO == ContextBase::mGps_conf.SUPL_ES);
+
+ if (bInformNiAccept) {
+ mAdapter.requestNiNotify(mNotify, mData, bInformNiAccept);
+ } else {
+ mApi.informNiResponse(GNSS_NI_RESPONSE_DENY, mData);
+ }
+ } else if (GNSS_NI_TYPE_CONTROL_PLANE == mNotify.type) {
+ if (bIsInEmergency && (1 == ContextBase::mGps_conf.CP_MTLR_ES)) {
+ mApi.informNiResponse(GNSS_NI_RESPONSE_ACCEPT, mData);
+ }
+ else {
+ mAdapter.requestNiNotify(mNotify, mData, false);
+ }
+ } else {
+ mAdapter.requestNiNotify(mNotify, mData, false);
+ }
}
};
- sendMsg(new MsgReportNiNotify(*this, notify, data));
+ sendMsg(new MsgReportNiNotify(*this, *mLocApi, notify, data, emergencyState));
return true;
}
+void
+GnssAdapter::reportLocationSystemInfoEvent(const LocationSystemInfo & locationSystemInfo) {
+
+ // send system info to engine hub
+ mEngHubProxy->gnssReportSystemInfo(locationSystemInfo);
+
+ struct MsgLocationSystemInfo : public LocMsg {
+ GnssAdapter& mAdapter;
+ LocationSystemInfo mSystemInfo;
+ inline MsgLocationSystemInfo(GnssAdapter& adapter,
+ const LocationSystemInfo& systemInfo) :
+ LocMsg(),
+ mAdapter(adapter),
+ mSystemInfo(systemInfo) {}
+ inline virtual void proc() const {
+ mAdapter.reportLocationSystemInfo(mSystemInfo);
+ }
+ };
+
+ sendMsg(new MsgLocationSystemInfo(*this, locationSystemInfo));
+}
+
+void
+GnssAdapter::reportLocationSystemInfo(const LocationSystemInfo & locationSystemInfo) {
+ // save the info into the master copy piece by piece, as other system info
+ // may come at different time
+ if (locationSystemInfo.systemInfoMask & LOCATION_SYS_INFO_LEAP_SECOND) {
+ mLocSystemInfo.systemInfoMask |= LOCATION_SYS_INFO_LEAP_SECOND;
+
+ const LeapSecondSystemInfo &srcLeapSecondSysInfo = locationSystemInfo.leapSecondSysInfo;
+ LeapSecondSystemInfo &dstLeapSecondSysInfo = mLocSystemInfo.leapSecondSysInfo;
+ if (srcLeapSecondSysInfo.leapSecondInfoMask &
+ LEAP_SECOND_SYS_INFO_CURRENT_LEAP_SECONDS_BIT) {
+ dstLeapSecondSysInfo.leapSecondInfoMask |=
+ LEAP_SECOND_SYS_INFO_CURRENT_LEAP_SECONDS_BIT;
+ dstLeapSecondSysInfo.leapSecondCurrent = srcLeapSecondSysInfo.leapSecondCurrent;
+ }
+ // once leap second change event is complete, modem may send up event invalidate the leap
+ // second change info while AP is still processing report during leap second transition
+ // so, we choose to keep this info around even though it is old
+ if (srcLeapSecondSysInfo.leapSecondInfoMask & LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT) {
+ dstLeapSecondSysInfo.leapSecondInfoMask |= LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT;
+ dstLeapSecondSysInfo.leapSecondChangeInfo = srcLeapSecondSysInfo.leapSecondChangeInfo;
+ }
+ }
+
+ // we received new info, inform client of the newly received info
+ if (locationSystemInfo.systemInfoMask) {
+ for (auto it=mClientData.begin(); it != mClientData.end(); ++it) {
+ if (it->second.locationSystemInfoCb != nullptr) {
+ it->second.locationSystemInfoCb(locationSystemInfo);
+ }
+ }
+ }
+}
+
static void* niThreadProc(void *args)
{
NiSession* pSession = (NiSession*)args;
@@ -2399,7 +3805,8 @@ static void* niThreadProc(void *args)
}
bool
-GnssAdapter::requestNiNotify(const GnssNiNotification& notify, const void* data)
+GnssAdapter::requestNiNotify(const GnssNiNotification& notify, const void* data,
+ const bool bInformNiAccept)
{
NiSession* pSession = NULL;
gnssNiCallback gnssNiCb = nullptr;
@@ -2411,6 +3818,20 @@ GnssAdapter::requestNiNotify(const GnssNiNotification& notify, const void* data)
}
}
if (nullptr == gnssNiCb) {
+ if (GNSS_NI_TYPE_EMERGENCY_SUPL == notify.type) {
+ if (bInformNiAccept) {
+ mLocApi->informNiResponse(GNSS_NI_RESPONSE_ACCEPT, data);
+ NiData& niData = getNiData();
+ // ignore any SUPL NI non-Es session if a SUPL NI ES is accepted
+ if (NULL != niData.session.rawRequest) {
+ pthread_mutex_lock(&niData.session.tLock);
+ niData.session.resp = GNSS_NI_RESPONSE_IGNORE;
+ niData.session.respRecvd = true;
+ pthread_cond_signal(&niData.session.tCond);
+ pthread_mutex_unlock(&niData.session.tLock);
+ }
+ }
+ }
EXIT_LOG(%s, "no clients with gnssNiCb.");
return false;
}
@@ -2471,30 +3892,34 @@ GnssAdapter::requestNiNotify(const GnssNiNotification& notify, const void* data)
}
void
-GnssAdapter::reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
+GnssAdapter::reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements,
int msInWeek)
{
LOC_LOGD("%s]: msInWeek=%d", __func__, msInWeek);
- struct MsgReportGnssMeasurementData : public LocMsg {
- GnssAdapter& mAdapter;
- GnssMeasurementsNotification mMeasurementsNotify;
- inline MsgReportGnssMeasurementData(GnssAdapter& adapter,
- const GnssMeasurementsNotification& measurements,
- int msInWeek) :
- LocMsg(),
- mAdapter(adapter),
- mMeasurementsNotify(measurements) {
- if (-1 != msInWeek) {
- mAdapter.getAgcInformation(mMeasurementsNotify, msInWeek);
+ if (0 != gnssMeasurements.gnssMeasNotification.count) {
+ struct MsgReportGnssMeasurementData : public LocMsg {
+ GnssAdapter& mAdapter;
+ GnssMeasurements mGnssMeasurements;
+ GnssMeasurementsNotification mMeasurementsNotify;
+ inline MsgReportGnssMeasurementData(GnssAdapter& adapter,
+ const GnssMeasurements& gnssMeasurements,
+ int msInWeek) :
+ LocMsg(),
+ mAdapter(adapter),
+ mMeasurementsNotify(gnssMeasurements.gnssMeasNotification) {
+ if (-1 != msInWeek) {
+ mAdapter.getAgcInformation(mMeasurementsNotify, msInWeek);
+ }
}
- }
- inline virtual void proc() const {
- mAdapter.reportGnssMeasurementData(mMeasurementsNotify);
- }
- };
+ inline virtual void proc() const {
+ mAdapter.reportGnssMeasurementData(mMeasurementsNotify);
+ }
+ };
- sendMsg(new MsgReportGnssMeasurementData(*this, measurements, msInWeek));
+ sendMsg(new MsgReportGnssMeasurementData(*this, gnssMeasurements, msInWeek));
+ }
+ mEngHubProxy->gnssReportSvMeasurement(gnssMeasurements.gnssSvMeasurementSet);
}
void
@@ -2508,43 +3933,40 @@ GnssAdapter::reportGnssMeasurementData(const GnssMeasurementsNotification& measu
}
void
-GnssAdapter::reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet)
+GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial)
{
LOC_LOGD("%s]: ", __func__);
-
- // We send SvMeasurementSet to AmtProxy/ULPProxy to be forwarded as necessary.
- mUlpProxy->reportSvMeasurement(svMeasurementSet);
+ mEngHubProxy->gnssReportSvPolynomial(svPolynomial);
}
void
-GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial)
+GnssAdapter::reportSvEphemerisEvent(GnssSvEphemerisReport & svEphemeris)
{
- LOC_LOGD("%s]: ", __func__);
-
- // We send SvMeasurementSet to AmtProxy/ULPProxy to be forwarded as necessary.
- mUlpProxy->reportSvPolynomial(svPolynomial);
+ LOC_LOGD("%s]:", __func__);
+ mEngHubProxy->gnssReportSvEphemeris(svEphemeris);
}
+
bool
-GnssAdapter::reportOdcpiRequestEvent(OdcpiRequestInfo& request)
+GnssAdapter::requestOdcpiEvent(OdcpiRequestInfo& request)
{
- struct MsgReportOdcpiRequest : public LocMsg {
+ struct MsgRequestOdcpi : public LocMsg {
GnssAdapter& mAdapter;
OdcpiRequestInfo mOdcpiRequest;
- inline MsgReportOdcpiRequest(GnssAdapter& adapter, OdcpiRequestInfo& request) :
+ inline MsgRequestOdcpi(GnssAdapter& adapter, OdcpiRequestInfo& request) :
LocMsg(),
mAdapter(adapter),
mOdcpiRequest(request) {}
inline virtual void proc() const {
- mAdapter.reportOdcpiRequest(mOdcpiRequest);
+ mAdapter.requestOdcpi(mOdcpiRequest);
}
};
- sendMsg(new MsgReportOdcpiRequest(*this, request));
+ sendMsg(new MsgRequestOdcpi(*this, request));
return true;
}
-void GnssAdapter::reportOdcpiRequest(const OdcpiRequestInfo& request)
+void GnssAdapter::requestOdcpi(const OdcpiRequestInfo& request)
{
if (nullptr != mOdcpiRequestCb) {
LOC_LOGd("request: type %d, tbf %d, isEmergency %d"
@@ -2589,6 +4011,28 @@ void GnssAdapter::reportOdcpiRequest(const OdcpiRequestInfo& request)
}
}
+bool GnssAdapter::reportDeleteAidingDataEvent(GnssAidingData& aidingData)
+{
+ LOC_LOGD("%s]:", __func__);
+ mEngHubProxy->gnssDeleteAidingData(aidingData);
+ return true;
+}
+
+bool GnssAdapter::reportKlobucharIonoModelEvent(GnssKlobucharIonoModel & ionoModel)
+{
+ LOC_LOGD("%s]:", __func__);
+ mEngHubProxy->gnssReportKlobucharIonoModel(ionoModel);
+ return true;
+}
+
+bool GnssAdapter::reportGnssAdditionalSystemInfoEvent(
+ GnssAdditionalSystemInfo & additionalSystemInfo)
+{
+ LOC_LOGD("%s]:", __func__);
+ mEngHubProxy->gnssReportAdditionalSystemInfo(additionalSystemInfo);
+ return true;
+}
+
void GnssAdapter::initOdcpiCommand(const OdcpiRequestCallback& callback)
{
struct MsgInitOdcpi : public LocMsg {
@@ -2640,10 +4084,7 @@ void GnssAdapter::injectOdcpi(const Location& location)
mOdcpiRequestActive, mOdcpiTimer.isActive(),
location.latitude, location.longitude);
- loc_api_adapter_err err = mLocApi->injectPosition(location);
- if (LOC_API_ADAPTER_ERR_SUCCESS != err) {
- LOC_LOGe("Inject Position API error %d", err);
- }
+ mLocApi->injectPosition(location, true);
}
// Called in the context of LocTimer thread
@@ -2683,6 +4124,35 @@ void GnssAdapter::odcpiTimerExpire()
}
}
+void
+GnssAdapter::invokeGnssEnergyConsumedCallback(uint64_t energyConsumedSinceFirstBoot) {
+ if (mGnssEnergyConsumedCb) {
+ mGnssEnergyConsumedCb(energyConsumedSinceFirstBoot);
+ mGnssEnergyConsumedCb = nullptr;
+ }
+}
+
+bool
+GnssAdapter::reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot){
+ LOC_LOGD("%s]: %" PRIu64 " ", __func__, energyConsumedSinceFirstBoot);
+
+ struct MsgReportGnssGnssEngEnergyConsumed : public LocMsg {
+ GnssAdapter& mAdapter;
+ uint64_t mGnssEnergyConsumedSinceFirstBoot;
+ inline MsgReportGnssGnssEngEnergyConsumed(GnssAdapter& adapter,
+ uint64_t energyConsumed) :
+ LocMsg(),
+ mAdapter(adapter),
+ mGnssEnergyConsumedSinceFirstBoot(energyConsumed) {}
+ inline virtual void proc() const {
+ mAdapter.invokeGnssEnergyConsumedCallback(mGnssEnergyConsumedSinceFirstBoot);
+ }
+ };
+
+ sendMsg(new MsgReportGnssGnssEngEnergyConsumed(*this, energyConsumedSinceFirstBoot));
+ return true;
+}
+
void GnssAdapter::initDefaultAgps() {
LOC_LOGD("%s]: ", __func__);
@@ -2696,6 +4166,7 @@ void GnssAdapter::initDefaultAgps() {
dlsym(handle, "LocNetIfaceAgps_getAgpsCbInfo");
if (getAgpsCbInfo == nullptr) {
LOC_LOGE("%s]: Failed to get method LocNetIfaceAgps_getStatusCb", __func__);
+ dlclose(handle);
return;
}
@@ -2703,6 +4174,7 @@ void GnssAdapter::initDefaultAgps() {
if (cbInfo.statusV4Cb == nullptr) {
LOC_LOGE("%s]: statusV4Cb is nullptr!", __func__);
+ dlclose(handle);
return;
}
@@ -2729,27 +4201,17 @@ void GnssAdapter::initDefaultAgpsCommand() {
/* INIT LOC AGPS MANAGER */
void GnssAdapter::initAgps(const AgpsCbInfo& cbInfo) {
- LOC_LOGD("%s]: mAgpsCbInfo.cbPriority - %d; cbInfo.cbPriority - %d",
- __func__, mAgpsCbInfo.cbPriority, cbInfo.cbPriority)
+ LOC_LOGD("%s]:cbInfo.atlType - %d", __func__, cbInfo.atlType);
if (!((ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB) ||
(ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA))) {
return;
}
- if (mAgpsCbInfo.cbPriority > cbInfo.cbPriority) {
- return;
- } else {
- mAgpsCbInfo = cbInfo;
-
- mAgpsManager.registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb);
-
- mAgpsManager.createAgpsStateMachines();
-
- /* Register for AGPS event mask */
- updateEvtMask(LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST,
- LOC_REGISTRATION_MASK_ENABLED);
- }
+ mAgpsManager.createAgpsStateMachines(cbInfo);
+ /* Register for AGPS event mask */
+ updateEvtMask(LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST,
+ LOC_REGISTRATION_MASK_ENABLED);
}
void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){
@@ -2776,33 +4238,68 @@ void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){
sendMsg(new AgpsMsgInit(cbInfo, *this));
}
-/* GnssAdapter::requestATL
- * Method triggered in QMI thread as part of handling below message:
- * eQMI_LOC_SERVER_REQUEST_OPEN_V02
- * Triggers the AGPS state machine to setup AGPS call for below WWAN types:
- * eQMI_LOC_WWAN_TYPE_INTERNET_V02
- * eQMI_LOC_WWAN_TYPE_AGNSS_V02 */
-bool GnssAdapter::requestATL(int connHandle, LocAGpsType agpsType){
+void GnssAdapter::initNfwCommand(const NfwCbInfo& cbInfo) {
+ LOC_LOGi("GnssAdapter::initNfwCommand");
- LOC_LOGI("GnssAdapter::requestATL");
+ /* Message to initialize NFW */
+ struct MsgInitNfw : public LocMsg {
+ const NfwCbInfo mCbInfo;
+ GnssAdapter& mAdapter;
- sendMsg( new AgpsMsgRequestATL(
- &mAgpsManager, connHandle, (AGpsExtType)agpsType));
+ inline MsgInitNfw(const NfwCbInfo& cbInfo,
+ GnssAdapter& adapter) :
+ LocMsg(), mCbInfo(cbInfo), mAdapter(adapter) {
+ LOC_LOGv("MsgInitNfw");
+ }
- return true;
+ inline virtual void proc() const {
+ LOC_LOGv("MsgInitNfw::proc()");
+ mAdapter.initNfw(mCbInfo);
+ }
+ };
+
+ /* Send message to initialize NFW */
+ sendMsg(new MsgInitNfw(cbInfo, *this));
+}
+
+void GnssAdapter::reportNfwNotificationEvent(GnssNfwNotification& notification) {
+ LOC_LOGi("GnssAdapter::reportNfwNotificationEvent");
+
+ struct MsgReportNfwNotification : public LocMsg {
+ const GnssNfwNotification mNotification;
+ GnssAdapter& mAdapter;
+
+ inline MsgReportNfwNotification(const GnssNfwNotification& notification,
+ GnssAdapter& adapter) :
+ LocMsg(), mNotification(notification), mAdapter(adapter) {
+ LOC_LOGv("MsgReportNfwNotification");
+ }
+
+ inline virtual void proc() const {
+ LOC_LOGv("MsgReportNfwNotification::proc()");
+ mAdapter.reportNfwNotification(mNotification);
+ }
+ };
+
+ sendMsg(new MsgReportNfwNotification(notification, *this));
}
-/* GnssAdapter::requestSuplES
+/* GnssAdapter::requestATL
* Method triggered in QMI thread as part of handling below message:
* eQMI_LOC_SERVER_REQUEST_OPEN_V02
* Triggers the AGPS state machine to setup AGPS call for below WWAN types:
+ * eQMI_LOC_WWAN_TYPE_INTERNET_V02
+ * eQMI_LOC_WWAN_TYPE_AGNSS_V02
* eQMI_LOC_WWAN_TYPE_AGNSS_EMERGENCY_V02 */
-bool GnssAdapter::requestSuplES(int connHandle){
+bool GnssAdapter::requestATL(int connHandle, LocAGpsType agpsType,
+ LocApnTypeMask apnTypeMask){
- LOC_LOGI("GnssAdapter::requestSuplES");
+ LOC_LOGI("GnssAdapter::requestATL handle=%d agpsType=0x%X apnTypeMask=0x%X",
+ connHandle, agpsType, apnTypeMask);
sendMsg( new AgpsMsgRequestATL(
- &mAgpsManager, connHandle, LOC_AGPS_TYPE_SUPL_ES));
+ &mAgpsManager, connHandle, (AGpsExtType)agpsType,
+ apnTypeMask));
return true;
}
@@ -2839,64 +4336,6 @@ bool GnssAdapter::releaseATL(int connHandle){
return true;
}
-/* GnssAdapter::reportDataCallOpened
- * DS Client data call opened successfully.
- * Send message to AGPS Manager to handle. */
-bool GnssAdapter::reportDataCallOpened(){
-
- LOC_LOGI("GnssAdapter::reportDataCallOpened");
-
- struct AgpsMsgSuplEsOpened: public LocMsg {
-
- AgpsManager* mAgpsManager;
-
- inline AgpsMsgSuplEsOpened(AgpsManager* agpsManager) :
- LocMsg(), mAgpsManager(agpsManager) {
-
- LOC_LOGV("AgpsMsgSuplEsOpened");
- }
-
- inline virtual void proc() const {
-
- LOC_LOGV("AgpsMsgSuplEsOpened::proc()");
- mAgpsManager->reportDataCallOpened();
- }
- };
-
- sendMsg( new AgpsMsgSuplEsOpened(&mAgpsManager));
-
- return true;
-}
-
-/* GnssAdapter::reportDataCallClosed
- * DS Client data call closed.
- * Send message to AGPS Manager to handle. */
-bool GnssAdapter::reportDataCallClosed(){
-
- LOC_LOGI("GnssAdapter::reportDataCallClosed");
-
- struct AgpsMsgSuplEsClosed: public LocMsg {
-
- AgpsManager* mAgpsManager;
-
- inline AgpsMsgSuplEsClosed(AgpsManager* agpsManager) :
- LocMsg(), mAgpsManager(agpsManager) {
-
- LOC_LOGV("AgpsMsgSuplEsClosed");
- }
-
- inline virtual void proc() const {
-
- LOC_LOGV("AgpsMsgSuplEsClosed::proc()");
- mAgpsManager->reportDataCallClosed();
- }
- };
-
- sendMsg( new AgpsMsgSuplEsClosed(&mAgpsManager));
-
- return true;
-}
-
void GnssAdapter::dataConnOpenCommand(
AGpsExtType agpsType,
const char* apnName, int apnLen, AGpsBearerType bearerType){
@@ -2919,6 +4358,8 @@ void GnssAdapter::dataConnOpenCommand(
LOC_LOGV("AgpsMsgAtlOpenSuccess");
if (mApnName == nullptr) {
LOC_LOGE("%s] new allocation failed, fatal error.", __func__);
+ // Reporting the failure here
+ mAgpsManager->reportAtlClosed(mAgpsType);
return;
}
memcpy(mApnName, apnName, apnLen);
@@ -2935,9 +4376,15 @@ void GnssAdapter::dataConnOpenCommand(
mAgpsManager->reportAtlOpenSuccess(mAgpsType, mApnName, mApnLen, mBearerType);
}
};
-
- sendMsg( new AgpsMsgAtlOpenSuccess(
- &mAgpsManager, agpsType, apnName, apnLen, bearerType));
+ // Added inital length checks for apnlen check to avoid security issues
+ // In case of failure reporting the same
+ if (NULL == apnName || apnLen <= 0 || apnLen > MAX_APN_LEN || (strlen(apnName) != apnLen)) {
+ LOC_LOGe("%s]: incorrect apnlen length or incorrect apnName", __func__);
+ mAgpsManager.reportAtlClosed(agpsType);
+ } else {
+ sendMsg( new AgpsMsgAtlOpenSuccess(
+ &mAgpsManager, agpsType, apnName, apnLen, bearerType));
+ }
}
void GnssAdapter::dataConnClosedCommand(AGpsExtType agpsType){
@@ -3071,6 +4518,19 @@ void GnssAdapter::convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
server_perdiction_age = (float)(in.mXtra.back().mGalXtraAge);
}
break;
+ case GNSS_SV_TYPE_NAVIC:
+ svid_min = GNSS_BUGREPORT_NAVIC_MIN;
+ svid_num = NAVIC_NUM;
+ svid_idx = GPS_NUM+GLO_NUM+QZSS_NUM+BDS_NUM+GAL_NUM;
+ if (!in.mSvHealth.empty()) {
+ eph_health_good_mask = in.mSvHealth.back().mNavicGoodMask;
+ eph_health_bad_mask = in.mSvHealth.back().mNavicBadMask;
+ }
+ if (!in.mXtra.empty()) {
+ server_perdiction_available_mask = in.mXtra.back().mNavicXtraValid;
+ server_perdiction_age = (float)(in.mXtra.back().mNavicXtraAge);
+ }
+ break;
default:
return;
}
@@ -3200,9 +4660,18 @@ bool GnssAdapter::getDebugReport(GnssDebugReport& r)
(int64_t)(reports.mTimeAndClock.back().mLeapSeconds))*1000ULL +
(int64_t)(reports.mTimeAndClock.back().mGpsTowMs);
- r.mTime.timeUncertaintyNs =
- ((float)(reports.mTimeAndClock.back().mTimeUnc) +
- (float)(reports.mTimeAndClock.back().mLeapSecUnc))*1000.0f;
+ if (reports.mTimeAndClock.back().mTimeUncNs > 0) {
+ // TimeUncNs value is available
+ r.mTime.timeUncertaintyNs =
+ (float)(reports.mTimeAndClock.back().mLeapSecUnc)*1000.0f +
+ (float)(reports.mTimeAndClock.back().mTimeUncNs);
+ } else {
+ // fall back to legacy TimeUnc
+ r.mTime.timeUncertaintyNs =
+ ((float)(reports.mTimeAndClock.back().mTimeUnc) +
+ (float)(reports.mTimeAndClock.back().mLeapSecUnc))*1000.0f;
+ }
+
r.mTime.frequencyUncertaintyNsPerSec =
(float)(reports.mTimeAndClock.back().mClockFreqBiasUnc);
LOC_LOGV("getDebugReport - timeestimate=%" PRIu64 " unc=%f frequnc=%f",
@@ -3219,6 +4688,7 @@ bool GnssAdapter::getDebugReport(GnssDebugReport& r)
convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_QZSS, reports);
convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_BEIDOU, reports);
convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GALILEO, reports);
+ convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_NAVIC, reports);
LOC_LOGV("getDebugReport - satellite=%zu", r.mSatelliteInfo.size());
return true;
@@ -3278,6 +4748,94 @@ GnssAdapter::getAgcInformation(GnssMeasurementsNotification& measurements, int m
}
}
+/* get Data information from system status and fill it */
+void
+GnssAdapter::getDataInformation(GnssDataNotification& data, int msInWeek)
+{
+ SystemStatus* systemstatus = getSystemStatus();
+
+ LOC_LOGV("%s]: msInWeek=%d", __func__, msInWeek);
+ if (nullptr != systemstatus) {
+ SystemStatusReports reports = {};
+ systemstatus->getReport(reports, true);
+
+ if ((!reports.mRfAndParams.empty()) && (!reports.mTimeAndClock.empty()) &&
+ (abs(msInWeek - (int)reports.mTimeAndClock.back().mGpsTowMs) < 2000)) {
+
+ for (int sig = GNSS_LOC_SIGNAL_TYPE_GPS_L1CA;
+ sig < GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES; sig++) {
+ data.gnssDataMask[sig] = 0;
+ data.jammerInd[sig] = 0.0;
+ data.agc[sig] = 0.0;
+ }
+ if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mAgcGps) {
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] |=
+ GNSS_LOC_DATA_AGC_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] =
+ reports.mRfAndParams.back().mAgcGps;
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] |=
+ GNSS_LOC_DATA_AGC_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] =
+ reports.mRfAndParams.back().mAgcGps;
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] |=
+ GNSS_LOC_DATA_AGC_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] =
+ reports.mRfAndParams.back().mAgcGps;
+ }
+ if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerGps) {
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] |=
+ GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GPS_L1CA] =
+ (double)reports.mRfAndParams.back().mJammerGps;
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] |=
+ GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.jammerInd[GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA] =
+ (double)reports.mRfAndParams.back().mJammerGps;
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] |=
+ GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.jammerInd[GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA] =
+ (double)reports.mRfAndParams.back().mJammerGps;
+ }
+ if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mAgcGlo) {
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] |=
+ GNSS_LOC_DATA_AGC_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] =
+ reports.mRfAndParams.back().mAgcGlo;
+ }
+ if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerGlo) {
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] |=
+ GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GLONASS_G1] =
+ (double)reports.mRfAndParams.back().mJammerGlo;
+ }
+ if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mAgcBds) {
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] |=
+ GNSS_LOC_DATA_AGC_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] =
+ reports.mRfAndParams.back().mAgcBds;
+ }
+ if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerBds) {
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] |=
+ GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.jammerInd[GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I] =
+ (double)reports.mRfAndParams.back().mJammerBds;
+ }
+ if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mAgcGal) {
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] |=
+ GNSS_LOC_DATA_AGC_BIT;
+ data.agc[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] =
+ reports.mRfAndParams.back().mAgcGal;
+ }
+ if (GNSS_INVALID_JAMMER_IND != reports.mRfAndParams.back().mJammerGal) {
+ data.gnssDataMask[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] |=
+ GNSS_LOC_DATA_JAMMER_IND_BIT;
+ data.jammerInd[GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C] =
+ (double)reports.mRfAndParams.back().mJammerGal;
+ }
+ }
+ }
+}
+
/* Callbacks registered with loc_net_iface library */
static void agpsOpenResultCb (bool isSuccess, AGpsExtType agpsType, const char* apn,
AGpsBearerType bearerType, void* userDataPtr) {
@@ -3311,3 +4869,179 @@ static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userD
adapter->dataConnFailedCommand(agpsType);
}
}
+
+void
+GnssAdapter::saveGnssEnergyConsumedCallback(GnssEnergyConsumedCallback energyConsumedCb) {
+ mGnssEnergyConsumedCb = energyConsumedCb;
+}
+
+void
+GnssAdapter::getGnssEnergyConsumedCommand(GnssEnergyConsumedCallback energyConsumedCb) {
+ struct MsgGetGnssEnergyConsumed : public LocMsg {
+ GnssAdapter& mAdapter;
+ LocApiBase& mApi;
+ GnssEnergyConsumedCallback mEnergyConsumedCb;
+ inline MsgGetGnssEnergyConsumed(GnssAdapter& adapter, LocApiBase& api,
+ GnssEnergyConsumedCallback energyConsumedCb) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mEnergyConsumedCb(energyConsumedCb){}
+ inline virtual void proc() const {
+ mAdapter.saveGnssEnergyConsumedCallback(mEnergyConsumedCb);
+ mApi.getGnssEnergyConsumed();
+ }
+ };
+
+ sendMsg(new MsgGetGnssEnergyConsumed(*this, *mLocApi, energyConsumedCb));
+}
+
+void
+GnssAdapter::nfwControlCommand(bool enable) {
+ struct MsgControlNfwLocationAccess : public LocMsg {
+ GnssAdapter& mAdapter;
+ LocApiBase& mApi;
+ bool mEnable;
+ inline MsgControlNfwLocationAccess(GnssAdapter& adapter, LocApiBase& api,
+ bool enable) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mEnable(enable) {}
+ inline virtual void proc() const {
+ GnssConfigGpsLock gpsLock;
+
+ gpsLock = ContextBase::mGps_conf.GPS_LOCK;
+ if (mEnable) {
+ gpsLock &= ~GNSS_CONFIG_GPS_LOCK_NI;
+ } else {
+ gpsLock |= GNSS_CONFIG_GPS_LOCK_NI;
+ }
+ ContextBase::mGps_conf.GPS_LOCK = gpsLock;
+ mApi.sendMsg(new LocApiMsg([&mApi = mApi, gpsLock]() {
+ mApi.setGpsLockSync((GnssConfigGpsLock)gpsLock);
+ }));
+ }
+ };
+
+ if (mSupportNfwControl) {
+ sendMsg(new MsgControlNfwLocationAccess(*this, *mLocApi, enable));
+ } else {
+ LOC_LOGw("NFW control is not supported, do not use this for NFW");
+ }
+}
+
+/* ==== Eng Hub Proxy ================================================================= */
+/* ======== UTILITIES ================================================================= */
+void
+GnssAdapter::initEngHubProxyCommand() {
+ LOC_LOGD("%s]: ", __func__);
+
+ struct MsgInitEngHubProxy : public LocMsg {
+ GnssAdapter* mAdapter;
+ inline MsgInitEngHubProxy(GnssAdapter* adapter) :
+ LocMsg(),
+ mAdapter(adapter) {}
+ inline virtual void proc() const {
+ mAdapter->initEngHubProxy();
+ }
+ };
+
+ sendMsg(new MsgInitEngHubProxy(this));
+}
+
+bool
+GnssAdapter::initEngHubProxy() {
+ static bool firstTime = true;
+ static bool engHubLoadSuccessful = false;
+
+ const char *error = nullptr;
+ unsigned int processListLength = 0;
+ loc_process_info_s_type* processInfoList = nullptr;
+
+ do {
+ // load eng hub only once
+ if (firstTime == false) {
+ break;
+ }
+
+ int rc = loc_read_process_conf(LOC_PATH_IZAT_CONF, &processListLength,
+ &processInfoList);
+ if (rc != 0) {
+ LOC_LOGE("%s]: failed to parse conf file", __func__);
+ break;
+ }
+
+ bool pluginDaemonEnabled = false;
+ // go over the conf table to see whether any plugin daemon is enabled
+ for (unsigned int i = 0; i < processListLength; i++) {
+ if ((strncmp(processInfoList[i].name[0], PROCESS_NAME_ENGINE_SERVICE,
+ strlen(PROCESS_NAME_ENGINE_SERVICE)) == 0) &&
+ (processInfoList[i].proc_status == ENABLED)) {
+ pluginDaemonEnabled = true;
+ break;
+ }
+ }
+
+ // no plugin daemon is enabled for this platform, no need to load eng hub .so
+ if (pluginDaemonEnabled == false) {
+ break;
+ }
+
+ // load the engine hub .so, if the .so is not present
+ // all EngHubProxyBase calls will turn into no-op.
+ void *handle = nullptr;
+ if ((handle = dlopen("libloc_eng_hub.so", RTLD_NOW)) == nullptr) {
+ if ((error = dlerror()) != nullptr) {
+ LOC_LOGE("%s]: libloc_eng_hub.so not found %s !", __func__, error);
+ }
+ break;
+ }
+
+ // prepare the callback functions
+ // callback function for engine hub to report back position event
+ GnssAdapterReportEnginePositionsEventCb reportPositionEventCb =
+ [this](int count, EngineLocationInfo* locationArr) {
+ // report from engine hub on behalf of PPE will be treated as fromUlp
+ reportEnginePositionsEvent(count, locationArr);
+ };
+
+ // callback function for engine hub to report back sv event
+ GnssAdapterReportSvEventCb reportSvEventCb =
+ [this](const GnssSvNotification& svNotify, bool fromEngineHub) {
+ reportSvEvent(svNotify, fromEngineHub);
+ };
+
+ // callback function for engine hub to request for complete aiding data
+ GnssAdapterReqAidingDataCb reqAidingDataCb =
+ [this] (const GnssAidingDataSvMask& svDataMask) {
+ mLocApi->requestForAidingData(svDataMask);
+ };
+
+ getEngHubProxyFn* getter = (getEngHubProxyFn*) dlsym(handle, "getEngHubProxy");
+ if(getter != nullptr) {
+ EngineHubProxyBase* hubProxy = (*getter) (mMsgTask, mSystemStatus->getOsObserver(),
+ reportPositionEventCb,
+ reportSvEventCb, reqAidingDataCb);
+ if (hubProxy != nullptr) {
+ mEngHubProxy = hubProxy;
+ engHubLoadSuccessful = true;
+ }
+ }
+ else {
+ LOC_LOGD("%s]: entered, did not find function", __func__);
+ }
+
+ LOC_LOGD("%s]: first time initialization %d, returned %d",
+ __func__, firstTime, engHubLoadSuccessful);
+
+ } while (0);
+
+ if (processInfoList != nullptr) {
+ free (processInfoList);
+ processInfoList = nullptr;
+ }
+
+ firstTime = false;
+ return engHubLoadSuccessful;
+}
diff --git a/gps/gnss/GnssAdapter.h b/gps/gnss/GnssAdapter.h
index 0609e6d..3ccdd96 100644
--- a/gps/gnss/GnssAdapter.h
+++ b/gps/gnss/GnssAdapter.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -30,12 +30,14 @@
#define GNSS_ADAPTER_H
#include <LocAdapterBase.h>
-#include <LocDualContext.h>
-#include <UlpProxyBase.h>
+#include <LocContext.h>
+#include <IOsObserver.h>
+#include <EngineHubProxyBase.h>
#include <LocationAPI.h>
#include <Agps.h>
#include <SystemStatus.h>
#include <XtraSystemStatusObserver.h>
+#include <map>
#define MAX_URL_LEN 256
#define NMEA_SENTENCE_MAX_LENGTH 200
@@ -47,6 +49,9 @@
class GnssAdapter;
+typedef std::map<LocationSessionKey, LocationOptions> LocationSessionMap;
+typedef std::map<LocationSessionKey, TrackingOptions> TrackingOptionsMap;
+
class OdcpiTimer : public LocTimer {
public:
OdcpiTimer(GnssAdapter* adapter) :
@@ -104,31 +109,53 @@ typedef struct {
uint32_t svIdOffset;
} NmeaSvMeta;
+typedef struct {
+ double latitude;
+ double longitude;
+ float accuracy;
+ // the CPI will be blocked until the boot time
+ // specified in blockedTillTsMs
+ int64_t blockedTillTsMs;
+ // CPIs whose both latitude and longitude differ
+ // no more than latLonThreshold will be blocked
+ // in units of degree
+ double latLonDiffThreshold;
+} BlockCPIInfo;
+
using namespace loc_core;
namespace loc_core {
class SystemStatus;
}
-class GnssAdapter : public LocAdapterBase {
+typedef std::function<void(
+ uint64_t gnssEnergyConsumedFromFirstBoot
+)> GnssEnergyConsumedCallback;
- /* ==== ULP ============================================================================ */
- UlpProxyBase* mUlpProxy;
+typedef void (*powerStateCallback)(bool on);
- /* ==== CLIENT ========================================================================= */
- typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
- ClientDataMap mClientData;
+class GnssAdapter : public LocAdapterBase {
+
+ /* ==== Engine Hub ===================================================================== */
+ EngineHubProxyBase* mEngHubProxy;
/* ==== TRACKING ======================================================================= */
- LocationSessionMap mTrackingSessions;
- LocPosMode mUlpPositionMode;
+ TrackingOptionsMap mTimeBasedTrackingSessions;
+ LocationSessionMap mDistanceBasedTrackingSessions;
+ LocPosMode mLocPositionMode;
GnssSvUsedInPosition mGnssSvIdUsedInPosition;
bool mGnssSvIdUsedInPosAvail;
+ GnssSvMbUsedInPosition mGnssMbSvIdUsedInPosition;
+ bool mGnssMbSvIdUsedInPosAvail;
/* ==== CONTROL ======================================================================== */
LocationControlCallbacks mControlCallbacks;
- uint32_t mPowerVoteId;
+ uint32_t mAfwControlId;
uint32_t mNmeaMask;
+ GnssSvIdConfig mGnssSvIdConfig;
+ GnssSvTypeConfig mGnssSvTypeConfig;
+ GnssSvTypeConfigCallback mGnssSvTypeConfigCb;
+ bool mSupportNfwControl;
/* ==== NI ============================================================================= */
NiData mNiData;
@@ -136,9 +163,16 @@ class GnssAdapter : public LocAdapterBase {
/* ==== AGPS =========================================================================== */
// This must be initialized via initAgps()
AgpsManager mAgpsManager;
- AgpsCbInfo mAgpsCbInfo;
void initAgps(const AgpsCbInfo& cbInfo);
+ /* ==== NFW =========================================================================== */
+ NfwStatusCb mNfwCb;
+ IsInEmergencySession mIsE911Session;
+ inline void initNfw(const NfwCbInfo& cbInfo) {
+ mNfwCb = (NfwStatusCb)cbInfo.visibilityControlCb;
+ mIsE911Session = (IsInEmergencySession)cbInfo.isInEmergencySession;
+ }
+
/* ==== ODCPI ========================================================================== */
OdcpiRequestCallback mOdcpiRequestCb;
bool mOdcpiRequestActive;
@@ -149,20 +183,45 @@ class GnssAdapter : public LocAdapterBase {
/* === SystemStatus ===================================================================== */
SystemStatus* mSystemStatus;
std::string mServerUrl;
+ std::string mMoServerUrl;
XtraSystemStatusObserver mXtraObserver;
+ LocationSystemInfo mLocSystemInfo;
+ std::vector<GnssSvIdSource> mBlacklistedSvIds;
+
+ /* === Misc ===================================================================== */
+ BlockCPIInfo mBlockCPIInfo;
+ bool mPowerOn;
+ uint32_t mAllowFlpNetworkFixes;
+
+ /* === Misc callback from QMI LOC API ============================================== */
+ GnssEnergyConsumedCallback mGnssEnergyConsumedCb;
+ powerStateCallback mPowerStateCb;
/*==== CONVERSION ===================================================================*/
- static void convertOptions(LocPosMode& out, const LocationOptions& options);
- static void convertLocation(Location& out, const LocGpsLocation& locGpsLocation,
+ static void convertOptions(LocPosMode& out, const TrackingOptions& trackingOptions);
+ static void convertLocation(Location& out, const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
const LocPosTechMask techMask);
static void convertLocationInfo(GnssLocationInfoNotification& out,
const GpsLocationExtended& locationExtended);
+ static uint16_t getNumSvUsed(uint64_t svUsedIdsMask,
+ int totalSvCntInThisConstellation);
+
+ /* ======== UTILITIES ================================================================== */
+ inline void initOdcpi(const OdcpiRequestCallback& callback);
+ inline void injectOdcpi(const Location& location);
+ static bool isFlpClient(LocationCallbacks& locationCallbacks);
+
+protected:
+
+ /* ==== CLIENT ========================================================================= */
+ virtual void updateClientsEventMask();
+ virtual void stopClientSessions(LocationAPI* client);
public:
GnssAdapter();
- virtual inline ~GnssAdapter() { delete mUlpProxy; }
+ virtual inline ~GnssAdapter() { }
/* ==== SSR ============================================================================ */
/* ======== EVENTS ====(Called from QMI Thread)========================================= */
@@ -170,55 +229,42 @@ public:
/* ======== UTILITIES ================================================================== */
void restartSessions();
- /* ==== ULP ============================================================================ */
- /* ======== COMMANDS ====(Called from ULP Thread)==================================== */
- virtual void setUlpProxyCommand(UlpProxyBase* ulp);
- /* ======== UTILITIES ================================================================== */
- void setUlpProxy(UlpProxyBase* ulp);
- inline UlpProxyBase* getUlpProxy() { return mUlpProxy; }
-
/* ==== CLIENT ========================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
- void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
- void removeClientCommand(LocationAPI* client);
- void requestCapabilitiesCommand(LocationAPI* client);
- /* ======== UTILITIES ================================================================== */
- void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
- void eraseClient(LocationAPI* client);
- void updateClientsEventMask();
- void stopClientSessions(LocationAPI* client);
- LocationCallbacks getClientCallbacks(LocationAPI* client);
- LocationCapabilitiesMask getCapabilities();
- void broadcastCapabilities(LocationCapabilitiesMask);
- LocationError setSuplHostServer(const char* server, int port);
+ virtual void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
/* ==== TRACKING ======================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
- uint32_t startTrackingCommand(LocationAPI* client, LocationOptions& options);
- void updateTrackingOptionsCommand(LocationAPI* client, uint32_t id, LocationOptions& options);
+ uint32_t startTrackingCommand(
+ LocationAPI* client, TrackingOptions& trackingOptions);
+ void updateTrackingOptionsCommand(
+ LocationAPI* client, uint32_t id, TrackingOptions& trackingOptions);
void stopTrackingCommand(LocationAPI* client, uint32_t id);
- /* ======================(Called from ULP Thread)======================================= */
- virtual void setPositionModeCommand(LocPosMode& locPosMode);
- virtual void startTrackingCommand();
- virtual void stopTrackingCommand();
- virtual void getZppCommand();
/* ======== RESPONSES ================================================================== */
void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
/* ======== UTILITIES ================================================================== */
bool hasTrackingCallback(LocationAPI* client);
+ bool isTimeBasedTrackingSession(LocationAPI* client, uint32_t sessionId);
+ bool isDistanceBasedTrackingSession(LocationAPI* client, uint32_t sessionId);
bool hasMeasurementsCallback(LocationAPI* client);
bool isTrackingSession(LocationAPI* client, uint32_t sessionId);
void saveTrackingSession(LocationAPI* client, uint32_t sessionId,
- const LocationOptions& options);
+ const TrackingOptions& trackingOptions);
void eraseTrackingSession(LocationAPI* client, uint32_t sessionId);
- bool setUlpPositionMode(const LocPosMode& mode);
- LocPosMode& getUlpPositionMode() { return mUlpPositionMode; }
- LocationError startTrackingMultiplex(const LocationOptions& options);
- LocationError startTracking(const LocationOptions& options);
- LocationError stopTrackingMultiplex(LocationAPI* client, uint32_t id);
- LocationError stopTracking();
- LocationError updateTrackingMultiplex(LocationAPI* client, uint32_t id,
- const LocationOptions& options);
+
+ bool setLocPositionMode(const LocPosMode& mode);
+ LocPosMode& getLocPositionMode() { return mLocPositionMode; }
+
+ bool startTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& trackingOptions);
+ void startTimeBasedTracking(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& trackingOptions);
+ bool stopTimeBasedTrackingMultiplex(LocationAPI* client, uint32_t id);
+ void stopTracking(LocationAPI* client, uint32_t id);
+ bool updateTrackingMultiplex(LocationAPI* client, uint32_t id,
+ const TrackingOptions& trackingOptions);
+ void updateTracking(LocationAPI* client, uint32_t sessionId,
+ const TrackingOptions& updatedOptions, const TrackingOptions& oldOptions);
/* ==== NI ============================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
@@ -229,33 +275,61 @@ public:
bool hasNiNotifyCallback(LocationAPI* client);
NiData& getNiData() { return mNiData; }
- /* ==== CONTROL ======================================================================== */
+ /* ==== CONTROL CLIENT ================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
uint32_t enableCommand(LocationTechnologyType techType);
void disableCommand(uint32_t id);
void setControlCallbacksCommand(LocationControlCallbacks& controlCallbacks);
void readConfigCommand();
- void setConfigCommand();
+ void requestUlpCommand();
+ void initEngHubProxyCommand();
uint32_t* gnssUpdateConfigCommand(GnssConfig config);
+ uint32_t* gnssGetConfigCommand(GnssConfigFlagsMask mask);
uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
+ void deleteAidingData(const GnssAidingData &data, uint32_t sessionId);
void gnssUpdateXtraThrottleCommand(const bool enabled);
-
+ std::vector<LocationError> gnssUpdateConfig(const std::string& oldMoServerUrl,
+ const GnssConfig& gnssConfigRequested,
+ const GnssConfig& gnssConfigNeedEngineUpdate, size_t count = 0);
+
+ /* ==== GNSS SV TYPE CONFIG ============================================================ */
+ /* ==== COMMANDS ====(Called from Client Thread)======================================== */
+ /* ==== These commands are received directly from client bypassing Location API ======== */
+ void gnssUpdateSvTypeConfigCommand(GnssSvTypeConfig config);
+ void gnssGetSvTypeConfigCommand(GnssSvTypeConfigCallback callback);
+ void gnssResetSvTypeConfigCommand();
+
+ /* ==== UTILITIES ====================================================================== */
+ LocationError gnssSvIdConfigUpdateSync(const std::vector<GnssSvIdSource>& blacklistedSvIds);
+ LocationError gnssSvIdConfigUpdateSync();
+ void gnssSvIdConfigUpdate(const std::vector<GnssSvIdSource>& blacklistedSvIds);
+ void gnssSvIdConfigUpdate();
+ void gnssSvTypeConfigUpdate(const GnssSvTypeConfig& config);
+ void gnssSvTypeConfigUpdate(bool sendReset = false);
+ inline void gnssSetSvTypeConfig(const GnssSvTypeConfig& config)
+ { mGnssSvTypeConfig = config; }
+ inline void gnssSetSvTypeConfigCallback(GnssSvTypeConfigCallback callback)
+ { mGnssSvTypeConfigCb = callback; }
+ inline GnssSvTypeConfigCallback gnssGetSvTypeConfigCallback()
+ { return mGnssSvTypeConfigCb; }
+ void setConfig();
+
+ /* ========= AGPS ====================================================================== */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
void initDefaultAgpsCommand();
void initAgpsCommand(const AgpsCbInfo& cbInfo);
+ void initNfwCommand(const NfwCbInfo& cbInfo);
void dataConnOpenCommand(AGpsExtType agpsType,
const char* apnName, int apnLen, AGpsBearerType bearerType);
void dataConnClosedCommand(AGpsExtType agpsType);
void dataConnFailedCommand(AGpsExtType agpsType);
+ void getGnssEnergyConsumedCommand(GnssEnergyConsumedCallback energyConsumedCb);
+ void nfwControlCommand(bool enable);
/* ========= ODCPI ===================================================================== */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
void initOdcpiCommand(const OdcpiRequestCallback& callback);
void injectOdcpiCommand(const Location& location);
- /* ======== UTILITIES ================================================================== */
- void initOdcpi(const OdcpiRequestCallback& callback);
- void injectOdcpi(const Location& location);
- void odcpiTimerExpireEvent();
-
/* ======== RESPONSES ================================================================== */
void reportResponse(LocationError err, uint32_t sessionId);
void reportResponse(size_t count, LocationError* errs, uint32_t* ids);
@@ -263,79 +337,133 @@ public:
LocationControlCallbacks& getControlCallbacks() { return mControlCallbacks; }
void setControlCallbacks(const LocationControlCallbacks& controlCallbacks)
{ mControlCallbacks = controlCallbacks; }
- void setPowerVoteId(uint32_t id) { mPowerVoteId = id; }
- uint32_t getPowerVoteId() { return mPowerVoteId; }
- bool resolveInAddress(const char* hostAddress, struct in_addr* inAddress);
- virtual bool isInSession() { return !mTrackingSessions.empty(); }
+ void setAfwControlId(uint32_t id) { mAfwControlId = id; }
+ uint32_t getAfwControlId() { return mAfwControlId; }
+ virtual bool isInSession() { return !mTimeBasedTrackingSessions.empty(); }
void initDefaultAgps();
+ bool initEngHubProxy();
+ void odcpiTimerExpireEvent();
/* ==== REPORTS ======================================================================== */
- /* ======== EVENTS ====(Called from QMI/ULP Thread)===================================== */
+ /* ======== EVENTS ====(Called from QMI/EngineHub Thread)===================================== */
virtual void reportPositionEvent(const UlpLocation& ulpLocation,
const GpsLocationExtended& locationExtended,
enum loc_sess_status status,
LocPosTechMask techMask,
- bool fromUlp=false);
- virtual void reportSvEvent(const GnssSvNotification& svNotify, bool fromUlp=false);
- virtual void reportNmeaEvent(const char* nmea, size_t length, bool fromUlp=false);
- virtual bool requestNiNotifyEvent(const GnssNiNotification& notify, const void* data);
- virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
+ GnssDataNotification* pDataNotify = nullptr,
+ int msInWeek = -1);
+ virtual void reportEnginePositionsEvent(unsigned int count,
+ EngineLocationInfo* locationArr);
+
+ virtual void reportSvEvent(const GnssSvNotification& svNotify,
+ bool fromEngineHub=false);
+ virtual void reportNmeaEvent(const char* nmea, size_t length);
+ virtual void reportDataEvent(const GnssDataNotification& dataNotify, int msInWeek);
+ virtual bool requestNiNotifyEvent(const GnssNiNotification& notify, const void* data,
+ const LocInEmergency emergencyState);
+ virtual void reportGnssMeasurementsEvent(const GnssMeasurements& gnssMeasurements,
int msInWeek);
- virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
+ virtual void reportSvEphemerisEvent(GnssSvEphemerisReport & svEphemeris);
+ virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
+ virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config);
+ virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot);
+ virtual void reportLocationSystemInfoEvent(const LocationSystemInfo& locationSystemInfo);
- virtual bool requestATL(int connHandle, LocAGpsType agps_type);
+ virtual bool requestATL(int connHandle, LocAGpsType agps_type, LocApnTypeMask apn_type_mask);
virtual bool releaseATL(int connHandle);
- virtual bool requestSuplES(int connHandle);
- virtual bool reportDataCallOpened();
- virtual bool reportDataCallClosed();
- virtual bool reportOdcpiRequestEvent(OdcpiRequestInfo& request);
+ virtual bool requestOdcpiEvent(OdcpiRequestInfo& request);
+ virtual bool reportDeleteAidingDataEvent(GnssAidingData& aidingData);
+ virtual bool reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& ionoModel);
+ virtual bool reportGnssAdditionalSystemInfoEvent(
+ GnssAdditionalSystemInfo& additionalSystemInfo);
+ virtual void reportNfwNotificationEvent(GnssNfwNotification& notification);
/* ======== UTILITIES ================================================================= */
- bool needReport(const UlpLocation& ulpLocation,
+ bool needReportForGnssClient(const UlpLocation& ulpLocation,
enum loc_sess_status status, LocPosTechMask techMask);
+ bool needReportForFlpClient(enum loc_sess_status status, LocPosTechMask techMask);
void reportPosition(const UlpLocation &ulpLocation,
const GpsLocationExtended &locationExtended,
enum loc_sess_status status,
LocPosTechMask techMask);
+ void reportEnginePositions(unsigned int count,
+ const EngineLocationInfo* locationArr);
void reportSv(GnssSvNotification& svNotify);
void reportNmea(const char* nmea, size_t length);
- bool requestNiNotify(const GnssNiNotification& notify, const void* data);
+ void reportData(GnssDataNotification& dataNotify);
+ bool requestNiNotify(const GnssNiNotification& notify, const void* data,
+ const bool bInformNiAccept);
void reportGnssMeasurementData(const GnssMeasurementsNotification& measurements);
- void reportOdcpiRequest(const OdcpiRequestInfo& request);
+ void reportGnssSvIdConfig(const GnssSvIdConfig& config);
+ void reportGnssSvTypeConfig(const GnssSvTypeConfig& config);
+ void requestOdcpi(const OdcpiRequestInfo& request);
+ void invokeGnssEnergyConsumedCallback(uint64_t energyConsumedSinceFirstBoot);
+ void saveGnssEnergyConsumedCallback(GnssEnergyConsumedCallback energyConsumedCb);
+ void reportLocationSystemInfo(const LocationSystemInfo & locationSystemInfo);
+ inline void reportNfwNotification(const GnssNfwNotification& notification) {
+ if (NULL != mNfwCb) {
+ mNfwCb(notification);
+ }
+ }
+ inline bool getE911State(void) {
+ if (NULL != mIsE911Session) {
+ return mIsE911Session();
+ }
+ return false;
+ }
/*======== GNSSDEBUG ================================================================*/
bool getDebugReport(GnssDebugReport& report);
/* get AGC information from system status and fill it */
void getAgcInformation(GnssMeasurementsNotification& measurements, int msInWeek);
+ /* get Data information from system status and fill it */
+ void getDataInformation(GnssDataNotification& data, int msInWeek);
/*==== SYSTEM STATUS ================================================================*/
inline SystemStatus* getSystemStatus(void) { return mSystemStatus; }
std::string& getServerUrl(void) { return mServerUrl; }
- void setServerUrl(const char* server) { mServerUrl.assign(server); }
+ std::string& getMoServerUrl(void) { return mMoServerUrl; }
/*==== CONVERSION ===================================================================*/
- static uint32_t convertGpsLock(const GnssConfigGpsLock gpsLock);
- static GnssConfigGpsLock convertGpsLock(const uint32_t gpsLock);
static uint32_t convertSuplVersion(const GnssConfigSuplVersion suplVersion);
- static GnssConfigSuplVersion convertSuplVersion(const uint32_t suplVersion);
static uint32_t convertLppProfile(const GnssConfigLppProfile lppProfile);
- static GnssConfigLppProfile convertLppProfile(const uint32_t lppProfile);
static uint32_t convertEP4ES(const GnssConfigEmergencyPdnForEmergencySupl);
static uint32_t convertSuplEs(const GnssConfigSuplEmergencyServices suplEmergencyServices);
static uint32_t convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask);
- static GnssConfigLppeControlPlaneMask convertLppeCp(const uint32_t lppeControlPlaneMask);
static uint32_t convertLppeUp(const GnssConfigLppeUserPlaneMask lppeUserPlaneMask);
- static GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask);
static uint32_t convertAGloProt(const GnssConfigAGlonassPositionProtocolMask);
static uint32_t convertSuplMode(const GnssConfigSuplModeMask suplModeMask);
static void convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
const GnssSvType& in_constellation,
const SystemStatusReports& in);
+ static bool convertToGnssSvIdConfig(
+ const std::vector<GnssSvIdSource>& blacklistedSvIds, GnssSvIdConfig& config);
+ static void convertFromGnssSvIdConfig(
+ const GnssSvIdConfig& svConfig, GnssConfig& config);
+ static void convertGnssSvIdMaskToList(
+ uint64_t svIdMask, std::vector<GnssSvIdSource>& svIds,
+ GnssSvId initialSvId, GnssSvType svType);
void injectLocationCommand(double latitude, double longitude, float accuracy);
+ void injectLocationExtCommand(const GnssLocationInfoNotification &locationInfo);
+
void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
+ void blockCPICommand(double latitude, double longitude, float accuracy,
+ int blockDurationMsec, double latLonDiffThreshold);
+ /* ==== MISCELLANEOUS ================================================================== */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
+ void getPowerStateChangesCommand(void* powerStateCb);
+ /* ======== UTILITIES ================================================================== */
+ void reportPowerStateIfChanged();
+ void savePowerStateCallback(powerStateCallback powerStateCb){ mPowerStateCb = powerStateCb; }
+ bool getPowerState() { return mPowerOn; }
+ void setAllowFlpNetworkFixes(uint32_t allow) { mAllowFlpNetworkFixes = allow; }
+ uint32_t getAllowFlpNetworkFixes() { return mAllowFlpNetworkFixes; }
+ void setSuplHostServer(const char* server, int port, LocServerType type);
+ void notifyClientOfCachedLocationSystemInfo(LocationAPI* client,
+ const LocationCallbacks& callbacks);
};
#endif //GNSS_ADAPTER_H
diff --git a/gps/gnss/Makefile.am b/gps/gnss/Makefile.am
deleted file mode 100644
index c818cae..0000000
--- a/gps/gnss/Makefile.am
+++ /dev/null
@@ -1,31 +0,0 @@
-AM_CFLAGS = \
- $(LOCPLA_CFLAGS) \
- $(LOCHAL_CFLAGS) \
- $(GPSUTILS_CFLAGS) \
- $(LOCCORE_CFLAGS) \
- -I./ \
- -I../utils \
- -I$(WORKSPACE)/hardware/qcom/gps/core/data-items \
- -I../location \
- -std=c++11
-
-libgnss_la_SOURCES = \
- location_gnss.cpp \
- GnssAdapter.cpp \
- XtraSystemStatusObserver.cpp \
- Agps.cpp
-
-if USE_GLIB
-libgnss_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
-libgnss_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -avoid-version
-libgnss_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
-else
-libgnss_la_CFLAGS = $(AM_CFLAGS)
-libgnss_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
-libgnss_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
-endif
-
-libgnss_la_LIBADD = -lstdc++ $(GPSUTILS_LIBS) $(LOCCORE_LIBS)
-
-#Create and Install libraries
-lib_LTLIBRARIES = libgnss.la
diff --git a/gps/gnss/XtraSystemStatusObserver.cpp b/gps/gnss/XtraSystemStatusObserver.cpp
index de7d49a..a58f735 100644
--- a/gps/gnss/XtraSystemStatusObserver.cpp
+++ b/gps/gnss/XtraSystemStatusObserver.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 2019, 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
@@ -49,6 +49,7 @@
#include <DataItemsFactoryProxy.h>
#include <DataItemConcreteTypesBase.h>
+using namespace loc_util;
using namespace loc_core;
#ifdef LOG_TAG
@@ -56,8 +57,66 @@ using namespace loc_core;
#endif
#define LOG_TAG "LocSvc_XSSO"
-bool XtraSystemStatusObserver::updateLockStatus(uint32_t lock) {
- mGpsLock = lock;
+class XtraIpcListener : public ILocIpcListener {
+ IOsObserver* mSystemStatusObsrvr;
+ const MsgTask* mMsgTask;
+ XtraSystemStatusObserver& mXSSO;
+public:
+ inline XtraIpcListener(IOsObserver* observer, const MsgTask* msgTask,
+ XtraSystemStatusObserver& xsso) :
+ mSystemStatusObsrvr(observer), mMsgTask(msgTask), mXSSO(xsso) {}
+ virtual void onReceive(const char* data, uint32_t length,
+ const LocIpcRecver* recver) override {
+#define STRNCMP(str, constStr) strncmp(str, constStr, sizeof(constStr)-1)
+ if (!STRNCMP(data, "ping")) {
+ LOC_LOGd("ping received");
+#ifdef USE_GLIB
+ } else if (!STRNCMP(data, "connectBackhaul")) {
+ mSystemStatusObsrvr->connectBackhaul();
+ } else if (!STRNCMP(data, "disconnectBackhaul")) {
+ mSystemStatusObsrvr->disconnectBackhaul();
+#endif
+ } else if (!STRNCMP(data, "requestStatus")) {
+ int32_t xtraStatusUpdated = 0;
+ sscanf(data, "%*s %d", &xtraStatusUpdated);
+
+ struct HandleStatusRequestMsg : public LocMsg {
+ XtraSystemStatusObserver& mXSSO;
+ int32_t mXtraStatusUpdated;
+ inline HandleStatusRequestMsg(XtraSystemStatusObserver& xsso,
+ int32_t xtraStatusUpdated) :
+ mXSSO(xsso), mXtraStatusUpdated(xtraStatusUpdated) {}
+ inline void proc() const override {
+ mXSSO.onStatusRequested(mXtraStatusUpdated);
+ }
+ };
+ mMsgTask->sendMsg(new HandleStatusRequestMsg(mXSSO, xtraStatusUpdated));
+ } else {
+ LOC_LOGw("unknown event: %s", data);
+ }
+ }
+};
+
+XtraSystemStatusObserver::XtraSystemStatusObserver(IOsObserver* sysStatObs,
+ const MsgTask* msgTask) :
+ mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask),
+ mGpsLock(-1), mConnections(~0), mXtraThrottle(true),
+ mReqStatusReceived(false),
+ mIsConnectivityStatusKnown(false),
+ mSender(LocIpc::getLocIpcLocalSender(LOC_IPC_XTRA)),
+ mDelayLocTimer(*mSender) {
+ subscribe(true);
+ auto recver = LocIpc::getLocIpcLocalRecver(
+ make_shared<XtraIpcListener>(sysStatObs, msgTask, *this),
+ LOC_IPC_HAL);
+ mIpc.startNonBlockingListening(recver);
+ mDelayLocTimer.start(100 /*.1 sec*/, false);
+}
+
+bool XtraSystemStatusObserver::updateLockStatus(GnssConfigGpsLock lock) {
+ // mask NI(NFW bit) since from XTRA's standpoint GPS is enabled if
+ // MO(AFW bit) is enabled and disabled when MO is disabled
+ mGpsLock = lock & ~GNSS_CONFIG_GPS_LOCK_NI;
if (!mReqStatusReceived) {
return true;
@@ -65,22 +124,41 @@ bool XtraSystemStatusObserver::updateLockStatus(uint32_t lock) {
stringstream ss;
ss << "gpslock";
- ss << " " << lock;
- return ( send(LOC_IPC_XTRA, ss.str()) );
+ ss << " " << mGpsLock;
+ string s = ss.str();
+ return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}
-bool XtraSystemStatusObserver::updateConnections(uint64_t allConnections) {
+bool XtraSystemStatusObserver::updateConnections(uint64_t allConnections,
+ NetworkInfoType* networkHandleInfo) {
mIsConnectivityStatusKnown = true;
mConnections = allConnections;
+ LOC_LOGd("updateConnections mConnections:%" PRIx64, mConnections);
+ for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
+ mNetworkHandle[i] = networkHandleInfo[i];
+ LOC_LOGd("updateConnections [%d] networkHandle:%" PRIx64 " networkType:%u",
+ i, mNetworkHandle[i].networkHandle, mNetworkHandle[i].networkType);
+ }
+
if (!mReqStatusReceived) {
return true;
}
stringstream ss;
- ss << "connection";
- ss << " " << mConnections;
- return ( send(LOC_IPC_XTRA, ss.str()) );
+ ss << "connection" << endl << mConnections << endl
+ << mNetworkHandle[0].toString() << endl
+ << mNetworkHandle[1].toString() << endl
+ << mNetworkHandle[2].toString() << endl
+ << mNetworkHandle[3].toString() << endl
+ << mNetworkHandle[4].toString() << endl
+ << mNetworkHandle[5].toString() << endl
+ << mNetworkHandle[6].toString() << endl
+ << mNetworkHandle[7].toString() << endl
+ << mNetworkHandle[8].toString() << endl
+ << mNetworkHandle[MAX_NETWORK_HANDLES-1].toString();
+ string s = ss.str();
+ return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}
bool XtraSystemStatusObserver::updateTac(const string& tac) {
@@ -93,7 +171,8 @@ bool XtraSystemStatusObserver::updateTac(const string& tac) {
stringstream ss;
ss << "tac";
ss << " " << tac.c_str();
- return ( send(LOC_IPC_XTRA, ss.str()) );
+ string s = ss.str();
+ return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}
bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) {
@@ -106,7 +185,8 @@ bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) {
stringstream ss;
ss << "mncmcc";
ss << " " << mccmnc.c_str();
- return ( send(LOC_IPC_XTRA, ss.str()) );
+ string s = ss.str();
+ return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}
bool XtraSystemStatusObserver::updateXtraThrottle(const bool enabled) {
@@ -119,7 +199,8 @@ bool XtraSystemStatusObserver::updateXtraThrottle(const bool enabled) {
stringstream ss;
ss << "xtrathrottle";
ss << " " << (enabled ? 1 : 0);
- return ( send(LOC_IPC_XTRA, ss.str()) );
+ string s = ss.str();
+ return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}
inline bool XtraSystemStatusObserver::onStatusRequested(int32_t xtraStatusUpdated) {
@@ -132,41 +213,22 @@ inline bool XtraSystemStatusObserver::onStatusRequested(int32_t xtraStatusUpdate
stringstream ss;
ss << "respondStatus" << endl;
- (mGpsLock == -1 ? ss : ss << mGpsLock) << endl << mConnections << endl
+ (mGpsLock == -1 ? ss : ss << mGpsLock) << endl;
+ (mConnections == (uint64_t)~0 ? ss : ss << mConnections) << endl
+ << mNetworkHandle[0].toString() << endl
+ << mNetworkHandle[1].toString() << endl
+ << mNetworkHandle[2].toString() << endl
+ << mNetworkHandle[3].toString() << endl
+ << mNetworkHandle[4].toString() << endl
+ << mNetworkHandle[5].toString() << endl
+ << mNetworkHandle[6].toString() << endl
+ << mNetworkHandle[7].toString() << endl
+ << mNetworkHandle[8].toString() << endl
+ << mNetworkHandle[MAX_NETWORK_HANDLES-1].toString() << endl
<< mTac << endl << mMccmnc << endl << mIsConnectivityStatusKnown;
- return ( send(LOC_IPC_XTRA, ss.str()) );
-}
-
-void XtraSystemStatusObserver::onReceive(const std::string& data) {
- if (!strncmp(data.c_str(), "ping", sizeof("ping") - 1)) {
- LOC_LOGd("ping received");
-
-#ifdef USE_GLIB
- } else if (!strncmp(data.c_str(), "connectBackhaul", sizeof("connectBackhaul") - 1)) {
- mSystemStatusObsrvr->connectBackhaul();
-
- } else if (!strncmp(data.c_str(), "disconnectBackhaul", sizeof("disconnectBackhaul") - 1)) {
- mSystemStatusObsrvr->disconnectBackhaul();
-#endif
-
- } else if (!strncmp(data.c_str(), "requestStatus", sizeof("requestStatus") - 1)) {
- int32_t xtraStatusUpdated = 0;
- sscanf(data.c_str(), "%*s %d", &xtraStatusUpdated);
-
- struct HandleStatusRequestMsg : public LocMsg {
- XtraSystemStatusObserver& mXSSO;
- int32_t mXtraStatusUpdated;
- inline HandleStatusRequestMsg(XtraSystemStatusObserver& xsso,
- int32_t xtraStatusUpdated) :
- mXSSO(xsso), mXtraStatusUpdated(xtraStatusUpdated) {}
- inline void proc() const override { mXSSO.onStatusRequested(mXtraStatusUpdated); }
- };
- mMsgTask->sendMsg(new (nothrow) HandleStatusRequestMsg(*this, xtraStatusUpdated));
-
- } else {
- LOC_LOGw("unknown event: %s", data.c_str());
- }
+ string s = ss.str();
+ return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
}
void XtraSystemStatusObserver::subscribe(bool yes)
@@ -218,8 +280,11 @@ void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist)
}
inline ~HandleOsObserverUpdateMsg() {
- for (auto each : mDataItemList) {
- delete each;
+ for (auto itor = mDataItemList.begin(); itor != mDataItemList.end(); ++itor) {
+ if (*itor != nullptr) {
+ delete *itor;
+ *itor = nullptr;
+ }
}
}
@@ -231,7 +296,10 @@ void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist)
{
NetworkInfoDataItemBase* networkInfo =
static_cast<NetworkInfoDataItemBase*>(each);
- mXtraSysStatObj->updateConnections(networkInfo->getAllTypes());
+ NetworkInfoType* networkHandleInfo =
+ static_cast<NetworkInfoType*>(networkInfo->getNetworkHandle());
+ mXtraSysStatObj->updateConnections(networkInfo->getAllTypes(),
+ networkHandleInfo);
}
break;
diff --git a/gps/gnss/XtraSystemStatusObserver.h b/gps/gnss/XtraSystemStatusObserver.h
index 6d3e789..3a5259d 100644
--- a/gps/gnss/XtraSystemStatusObserver.h
+++ b/gps/gnss/XtraSystemStatusObserver.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -35,63 +35,56 @@
#include <LocTimer.h>
using namespace std;
+using namespace loc_util;
using loc_core::IOsObserver;
using loc_core::IDataItemObserver;
using loc_core::IDataItemCore;
-using loc_util::LocIpc;
-class XtraSystemStatusObserver : public IDataItemObserver, public LocIpc{
+class XtraSystemStatusObserver : public IDataItemObserver {
public :
// constructor & destructor
- inline XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask):
- mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask),
- mGpsLock(-1), mConnections(0), mXtraThrottle(true), mReqStatusReceived(false),
- mIsConnectivityStatusKnown (false), mDelayLocTimer(*this) {
- subscribe(true);
- startListeningNonBlocking(LOC_IPC_HAL);
- mDelayLocTimer.start(100 /*.1 sec*/, false);
- }
+ XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask);
inline virtual ~XtraSystemStatusObserver() {
subscribe(false);
- stopListening();
+ mIpc.stopNonBlockingListening();
}
// IDataItemObserver overrides
inline virtual void getName(string& name);
virtual void notify(const list<IDataItemCore*>& dlist);
- bool updateLockStatus(uint32_t lock);
- bool updateConnections(uint64_t allConnections);
+ bool updateLockStatus(GnssConfigGpsLock lock);
+ bool updateConnections(uint64_t allConnections,
+ loc_core::NetworkInfoType* networkHandleInfo);
bool updateTac(const string& tac);
bool updateMccMnc(const string& mccmnc);
bool updateXtraThrottle(const bool enabled);
inline const MsgTask* getMsgTask() { return mMsgTask; }
void subscribe(bool yes);
-
-protected:
- void onReceive(const std::string& data) override;
+ bool onStatusRequested(int32_t xtraStatusUpdated);
private:
IOsObserver* mSystemStatusObsrvr;
const MsgTask* mMsgTask;
- int32_t mGpsLock;
+ GnssConfigGpsLock mGpsLock;
+ LocIpc mIpc;
uint64_t mConnections;
+ loc_core::NetworkInfoType mNetworkHandle[MAX_NETWORK_HANDLES];
string mTac;
string mMccmnc;
bool mXtraThrottle;
bool mReqStatusReceived;
bool mIsConnectivityStatusKnown;
+ shared_ptr<LocIpcSender> mSender;
class DelayLocTimer : public LocTimer {
- XtraSystemStatusObserver& mXSSO;
+ LocIpcSender& mSender;
public:
- DelayLocTimer(XtraSystemStatusObserver& xsso) : mXSSO(xsso) {}
+ DelayLocTimer(LocIpcSender& sender) : mSender(sender) {}
void timeOutCallback() override {
- mXSSO.send(LOC_IPC_XTRA, "halinit");
+ LocIpc::send(mSender, (const uint8_t*)"halinit", sizeof("halinit"));
}
} mDelayLocTimer;
-
- bool onStatusRequested(int32_t xtraStatusUpdated);
};
#endif
diff --git a/gps/gnss/location_gnss.cpp b/gps/gnss/location_gnss.cpp
index 21763dd..76839b6 100644
--- a/gps/gnss/location_gnss.cpp
+++ b/gps/gnss/location_gnss.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -36,11 +36,11 @@ static void initialize();
static void deinitialize();
static void addClient(LocationAPI* client, const LocationCallbacks& callbacks);
-static void removeClient(LocationAPI* client);
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb);
static void requestCapabilities(LocationAPI* client);
-static uint32_t startTracking(LocationAPI* client, LocationOptions& options);
-static void updateTrackingOptions(LocationAPI* client, uint32_t id, LocationOptions& options);
+static uint32_t startTracking(LocationAPI* client, TrackingOptions&);
+static void updateTrackingOptions(LocationAPI* client, uint32_t id, TrackingOptions&);
static void stopTracking(LocationAPI* client, uint32_t id);
static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse response);
@@ -51,8 +51,14 @@ static void setControlCallbacks(LocationControlCallbacks& controlCallbacks);
static uint32_t enable(LocationTechnologyType techType);
static void disable(uint32_t id);
static uint32_t* gnssUpdateConfig(GnssConfig config);
+static uint32_t* gnssGetConfig(GnssConfigFlagsMask mask);
+
+static void gnssUpdateSvTypeConfig(GnssSvTypeConfig& config);
+static void gnssGetSvTypeConfig(GnssSvTypeConfigCallback& callback);
+static void gnssResetSvTypeConfig();
static void injectLocation(double latitude, double longitude, float accuracy);
+static void injectLocationExt(const GnssLocationInfoNotification &locationInfo);
static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty);
static void agpsInit(const AgpsCbInfo& cbInfo);
@@ -60,11 +66,20 @@ static void agpsDataConnOpen(AGpsExtType agpsType, const char* apnName, int apnL
static void agpsDataConnClosed(AGpsExtType agpsType);
static void agpsDataConnFailed(AGpsExtType agpsType);
static void getDebugReport(GnssDebugReport& report);
-static void updateConnectionStatus(bool connected, int8_t type);
+static void updateConnectionStatus(bool connected, int8_t type, bool roaming = false,
+ NetworkHandle networkHandle = NETWORK_HANDLE_UNKNOWN);
+static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb);
+static void enableNfwLocationAccess(bool enable);
+static void nfwInit(const NfwCbInfo& cbInfo);
+static void getPowerStateChanges(void* powerStateCb);
static void odcpiInit(const OdcpiRequestCallback& callback);
static void odcpiInject(const Location& location);
+static void blockCPI(double latitude, double longitude, float accuracy,
+ int blockDurationMsec, double latLonDiffThreshold);
+static void updateBatteryStatus(bool charging);
+
static const GnssInterface gGnssInterface = {
sizeof(GnssInterface),
initialize,
@@ -80,6 +95,10 @@ static const GnssInterface gGnssInterface = {
enable,
disable,
gnssUpdateConfig,
+ gnssGetConfig,
+ gnssUpdateSvTypeConfig,
+ gnssGetSvTypeConfig,
+ gnssResetSvTypeConfig,
gnssDeleteAidingData,
gnssUpdateXtraThrottle,
injectLocation,
@@ -92,6 +111,13 @@ static const GnssInterface gGnssInterface = {
updateConnectionStatus,
odcpiInit,
odcpiInject,
+ blockCPI,
+ getGnssEnergyConsumed,
+ enableNfwLocationAccess,
+ nfwInit,
+ getPowerStateChanges,
+ injectLocationExt,
+ updateBatteryStatus
};
#ifndef DEBUG_X86
@@ -125,10 +151,10 @@ static void addClient(LocationAPI* client, const LocationCallbacks& callbacks)
}
}
-static void removeClient(LocationAPI* client)
+static void removeClient(LocationAPI* client, removeClientCompleteCallback rmClientCb)
{
if (NULL != gGnssAdapter) {
- gGnssAdapter->removeClientCommand(client);
+ gGnssAdapter->removeClientCommand(client, rmClientCb);
}
}
@@ -139,19 +165,22 @@ static void requestCapabilities(LocationAPI* client)
}
}
-static uint32_t startTracking(LocationAPI* client, LocationOptions& options)
+static uint32_t startTracking(
+ LocationAPI* client, TrackingOptions& trackingOptions)
{
if (NULL != gGnssAdapter) {
- return gGnssAdapter->startTrackingCommand(client, options);
+ return gGnssAdapter->startTrackingCommand(client, trackingOptions);
} else {
return 0;
}
}
-static void updateTrackingOptions(LocationAPI* client, uint32_t id, LocationOptions& options)
+static void updateTrackingOptions(
+ LocationAPI* client, uint32_t id, TrackingOptions& trackingOptions)
{
if (NULL != gGnssAdapter) {
- gGnssAdapter->updateTrackingOptionsCommand(client, id, options);
+ gGnssAdapter->updateTrackingOptionsCommand(
+ client, id, trackingOptions);
}
}
@@ -172,7 +201,7 @@ static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse resp
static void setControlCallbacks(LocationControlCallbacks& controlCallbacks)
{
if (NULL != gGnssAdapter) {
- return gGnssAdapter->setControlCallbacksCommand(controlCallbacks);
+ gGnssAdapter->setControlCallbacksCommand(controlCallbacks);
}
}
@@ -188,7 +217,7 @@ static uint32_t enable(LocationTechnologyType techType)
static void disable(uint32_t id)
{
if (NULL != gGnssAdapter) {
- return gGnssAdapter->disableCommand(id);
+ gGnssAdapter->disableCommand(id);
}
}
@@ -201,6 +230,36 @@ static uint32_t* gnssUpdateConfig(GnssConfig config)
}
}
+static uint32_t* gnssGetConfig(GnssConfigFlagsMask mask)
+{
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->gnssGetConfigCommand(mask);
+ } else {
+ return NULL;
+ }
+}
+
+static void gnssUpdateSvTypeConfig(GnssSvTypeConfig& config)
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->gnssUpdateSvTypeConfigCommand(config);
+ }
+}
+
+static void gnssGetSvTypeConfig(GnssSvTypeConfigCallback& callback)
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->gnssGetSvTypeConfigCommand(callback);
+ }
+}
+
+static void gnssResetSvTypeConfig()
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->gnssResetSvTypeConfigCommand();
+ }
+}
+
static uint32_t gnssDeleteAidingData(GnssAidingData& data)
{
if (NULL != gGnssAdapter) {
@@ -265,9 +324,11 @@ static void getDebugReport(GnssDebugReport& report) {
}
}
-static void updateConnectionStatus(bool connected, int8_t type) {
+static void updateConnectionStatus(bool connected, int8_t type,
+ bool roaming, NetworkHandle networkHandle) {
if (NULL != gGnssAdapter) {
- gGnssAdapter->getSystemStatus()->eventConnectionStatus(connected, type);
+ gGnssAdapter->getSystemStatus()->eventConnectionStatus(
+ connected, type, roaming, networkHandle);
}
}
@@ -285,3 +346,47 @@ static void odcpiInject(const Location& location)
}
}
+static void blockCPI(double latitude, double longitude, float accuracy,
+ int blockDurationMsec, double latLonDiffThreshold) {
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->blockCPICommand(latitude, longitude, accuracy,
+ blockDurationMsec, latLonDiffThreshold);
+ }
+}
+
+static void getGnssEnergyConsumed(GnssEnergyConsumedCallback energyConsumedCb) {
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->getGnssEnergyConsumedCommand(energyConsumedCb);
+ }
+}
+
+static void enableNfwLocationAccess(bool enable) {
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->nfwControlCommand(enable);
+ }
+}
+
+static void nfwInit(const NfwCbInfo& cbInfo) {
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->initNfwCommand(cbInfo);
+ }
+}
+static void getPowerStateChanges(void* powerStateCb)
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->getPowerStateChangesCommand(powerStateCb);
+ }
+}
+
+static void injectLocationExt(const GnssLocationInfoNotification &locationInfo)
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->injectLocationExtCommand(locationInfo);
+ }
+}
+
+static void updateBatteryStatus(bool charging) {
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->getSystemStatus()->updatePowerConnectState(charging);
+ }
+}
diff --git a/gps/gnsspps/Android.mk b/gps/gnsspps/Android.mk
index f87b674..ef43979 100644
--- a/gps/gnsspps/Android.mk
+++ b/gps/gnsspps/Android.mk
@@ -4,6 +4,9 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libgnsspps
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
LOCAL_MODULE_TAGS := optional
diff --git a/gps/gnsspps/Makefile.am b/gps/gnsspps/Makefile.am
deleted file mode 100644
index c990be0..0000000
--- a/gps/gnsspps/Makefile.am
+++ /dev/null
@@ -1,37 +0,0 @@
-AM_CFLAGS = \
- $(LOCPLA_CFLAGS) \
- $(GPSUTILS_CFLAGS) \
- -I$(WORKSPACE)/system/core/include \
- -I./
-
-ACLOCAL_AMFLAGS = -I m4
-
-libgnsspps_la_SOURCES = \
- gnsspps.c
-
-if USE_GLIB
-libgnsspps_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
-libgnsspps_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
-libgnsspps_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
-else
-libgnsspps_la_CFLAGS = $(AM_CFLAGS)
-libgnsspps_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
-libgnsspps_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
-endif
-
-libgnsspps_la_LIBADD = -lstdc++ $(GPSUTILS_LIBS)
-
-library_include_HEADERS = \
- gnsspps.h
-
-#Create and Install libraries
-lib_LTLIBRARIES = libgnsspps.la
-
-library_includedir = $(pkgincludedir)
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = gnsspps.pc
-EXTRA_DIST = $(pkgconfig_DATA)
-
-
-
-
diff --git a/gps/gnsspps/configure.ac b/gps/gnsspps/configure.ac
deleted file mode 100644
index eb87bc1..0000000
--- a/gps/gnsspps/configure.ac
+++ /dev/null
@@ -1,70 +0,0 @@
-# configure.ac -- Autoconf script for gps lbs-core
-#
-# Process this file with autoconf to produce a configure script
-
-# Requires autoconf tool later than 2.61
-AC_PREREQ(2.61)
-# Initialize the gps lbs-core package version 1.0.0
-AC_INIT([gnsspps],1.0.0)
-# Does not strictly follow GNU Coding standards
-AM_INIT_AUTOMAKE([foreign])
-# Disables auto rebuilding of configure, Makefile.ins
-AM_MAINTAINER_MODE
-# Verifies the --srcdir is correct by checking for the path
-AC_CONFIG_SRCDIR([Makefile.am])
-# defines some macros variable to be included by source
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_MACRO_DIR([m4])
-
-# Checks for programs.
-AC_PROG_LIBTOOL
-AC_PROG_CXX
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_AWK
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-PKG_PROG_PKG_CONFIG
-
-# Checks for libraries.
-PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
-AC_SUBST([GPSUTILS_CFLAGS])
-AC_SUBST([GPSUTILS_LIBS])
-
-AC_ARG_WITH([locpla_includes],
- AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@],
- [Specify the path to locpla-includes in loc-pla_git.bb]),
- [locpla_incdir=$withval],
- with_locpla_includes=no)
-
-if test "x${with_locpla_includes}" != "xno"; then
- AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}")
-fi
-
-AC_ARG_WITH([glib],
- AC_HELP_STRING([--with-glib],
- [enable glib, building HLOS systems which use glib]))
-
-if (test "x${with_glib}" = "xyes"); then
- AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
- PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GThread >= 2.16 is required))
- PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GLib >= 2.16 is required))
- GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
- GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
-
- AC_SUBST(GLIB_CFLAGS)
- AC_SUBST(GLIB_LIBS)
-fi
-
-AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
-
-AC_CONFIG_FILES([ \
- Makefile \
- gnsspps.pc
- ])
-
-AC_OUTPUT
diff --git a/gps/gnsspps/gnsspps.c b/gps/gnsspps/gnsspps.c
index 70b23f5..b27fd77 100644
--- a/gps/gnsspps/gnsspps.c
+++ b/gps/gnsspps/gnsspps.c
@@ -35,16 +35,42 @@
#include <pthread.h>
#include <timepps.h>
#include <linux/types.h>
+#include <stdbool.h>
+#include "loc_cfg.h"
+#include <inttypes.h>
+#include <time.h>
+#include <math.h>
+
+#define BILLION_NSEC (1E9)
+
+typedef struct timespec pps_sync_time;
//DRsync kernel timestamp
static struct timespec drsyncKernelTs = {0,0};
//DRsync userspace timestamp
static struct timespec drsyncUserTs = {0,0};
+
+static struct timespec prevDrsyncKernelTs = {0,0};
+
//flag to stop fetching timestamp
static int isActive = 0;
static pps_handle handle;
static pthread_mutex_t ts_lock;
+static int skipPPSPulseCnt = 0;
+static int gnssOutageInSec = 1;
+static loc_param_s_type gps_conf_param_table[] =
+{
+ {"IGNORE_PPS_PULSE_COUNT", &skipPPSPulseCnt, NULL, 'n'},
+ {"GNSS_OUTAGE_DURATION", &gnssOutageInSec, NULL, 'n'}
+};
+
+typedef enum {
+ KERNEL_REPORTED_CLOCK_BOOTTIME = 0,
+ KERNEL_REPORTED_CLOCK_REALTIME,
+ KERNEL_REPORTED_CLOCK_UNKNOWN = 0xfe,
+ KERNEL_REPORTED_CLOCK_MAX = 0xff
+} kernel_reported_time_e;
/* checks the PPS source and opens it */
int check_device(char *path, pps_handle *handle)
@@ -52,7 +78,7 @@ int check_device(char *path, pps_handle *handle)
int ret;
/* Try to find the source by using the supplied "path" name */
- ret = open(path, O_RDWR);
+ ret = open(path, O_RDONLY);
if (ret < 0)
{
LOC_LOGV("%s:%d unable to open device %s", __func__, __LINE__, path);
@@ -69,34 +95,205 @@ int check_device(char *path, pps_handle *handle)
return 0;
}
+
+/* calculate the time difference between two given times in argument -
+** returns the result in timeDifference parametter*/
+static inline void calculate_time_difference(pps_sync_time time1,
+ pps_sync_time time2, pps_sync_time* timeDifference)
+{
+ if (time2.tv_nsec < time1.tv_nsec) {
+ timeDifference->tv_sec = time2.tv_sec - 1 - time1.tv_sec;
+ timeDifference->tv_nsec = BILLION_NSEC + time2.tv_nsec - time1.tv_nsec;
+ } else {
+ timeDifference->tv_sec = time2.tv_sec - time1.tv_sec;
+ timeDifference->tv_nsec = time2.tv_nsec - time1.tv_nsec;
+ }
+}
+
+/*add two timespec values and return the result in third resultTime parameter*/
+static inline void pps_sync_time_add(pps_sync_time time1,
+ pps_sync_time time2, pps_sync_time* resultTime)
+{
+ if (time2.tv_nsec + time1.tv_nsec >= BILLION_NSEC) {
+ resultTime->tv_sec = time2.tv_sec + time1.tv_sec + 1;
+ resultTime->tv_nsec = time2.tv_nsec + time1.tv_nsec - BILLION_NSEC;
+ } else {
+ resultTime->tv_sec = time2.tv_sec + time1.tv_sec;
+ resultTime->tv_nsec = time2.tv_nsec + time1.tv_nsec;
+ }
+}
+
+#define MAX_REALTIME_OFFSET_DELTA_DIFFERENCE 10
+#define MAX_PPS_KERNEL_TO_USERSPACE_LATENCY 100 /*in milli-second*/
+
+static inline double convertTimeToMilliSec(pps_sync_time timeToConvert)
+{
+ return ((double)(timeToConvert.tv_sec * 1000) + (double)(timeToConvert.tv_nsec * 0.000001));
+}
+
+/*returnValue: 1 = offsetTime OK, 0 = offsetTime NOT OK*/
+static inline bool isTimeOffsetOk(pps_sync_time offsetTime)
+{
+ double offsetInMillis = convertTimeToMilliSec(offsetTime);
+ return (fabs(offsetInMillis) <= MAX_REALTIME_OFFSET_DELTA_DIFFERENCE)? true: false;
+}
+
+/*check whether kernel PPS timestamp is a CLOCK_BOOTTIME or CLOCK_REALTIME*/
+static kernel_reported_time_e get_reported_time_type(pps_sync_time userBootTs,
+ pps_sync_time userRealTs,
+ pps_sync_time kernelTs)
+{
+ double userRealMs, userBootMs, kernelTsMs;
+ kernel_reported_time_e reportedTime = KERNEL_REPORTED_CLOCK_UNKNOWN;
+
+ userRealMs = convertTimeToMilliSec(userRealTs);
+ userBootMs = convertTimeToMilliSec(userBootTs);
+ kernelTsMs = convertTimeToMilliSec(kernelTs);
+
+ if(fabs(userBootMs - kernelTsMs) <= MAX_PPS_KERNEL_TO_USERSPACE_LATENCY) {
+ reportedTime = KERNEL_REPORTED_CLOCK_BOOTTIME;
+ } else if (fabs(userRealMs - kernelTsMs) <= MAX_PPS_KERNEL_TO_USERSPACE_LATENCY) {
+ reportedTime = KERNEL_REPORTED_CLOCK_REALTIME;
+ } else {
+ reportedTime = KERNEL_REPORTED_CLOCK_UNKNOWN;
+ }
+
+ LOC_LOGV("[%s] Detected PPS timestamp type (0:Boot, 1:Real, 0xfe:Unknown):0x%x",
+ __func__, reportedTime);
+
+ return reportedTime;
+}
+
+/*compute_real_to_boot_time - converts the kernel real time stamp to boot time reference*/
+static int compute_real_to_boot_time(pps_info ppsFetchTime)
+{
+ int retVal = 0;
+ /*Offset between REAL_TIME to BOOT_TIME*/
+ static pps_sync_time time_offset = {0, 0};
+ pps_sync_time drSyncUserRealTs, drSyncUserBootTs;
+ pps_sync_time deltaRealToBootTime = {0, 0};
+ pps_sync_time deltaOffsetTime = {0, 0};
+ kernel_reported_time_e ppsTimeType;
+
+ retVal = clock_gettime(CLOCK_BOOTTIME,&drSyncUserBootTs);
+ if (retVal != 0) {
+ LOC_LOGE("[%s]Error Reading CLOCK_BOOTTIME", __func__);
+ retVal = -1;
+ goto exit0;
+ }
+ retVal = clock_gettime(CLOCK_REALTIME,&drSyncUserRealTs);
+ if (retVal != 0){
+ LOC_LOGE("[%s]Error Reading CLOCK_REALTIME", __func__);
+ retVal = -1;
+ goto exit0;
+ }
+
+ ppsTimeType = get_reported_time_type(drSyncUserBootTs, drSyncUserRealTs, ppsFetchTime);
+
+ if (KERNEL_REPORTED_CLOCK_BOOTTIME == ppsTimeType) {
+
+ /*Store PPS kernel time*/
+ drsyncKernelTs.tv_sec = ppsFetchTime.tv_sec;
+ drsyncKernelTs.tv_nsec = ppsFetchTime.tv_nsec;
+ /*Store User PPS fetch time*/
+ drsyncUserTs.tv_sec = drSyncUserBootTs.tv_sec;
+ drsyncUserTs.tv_nsec = drSyncUserBootTs.tv_nsec;
+
+ LOC_LOGV("[compute_real_to_boot] PPS TimeType CLOCK_BOOTTIME -- report as is");
+ retVal = 0;
+ } else if (KERNEL_REPORTED_CLOCK_REALTIME == ppsTimeType) {
+
+ /* Calculate time difference between REALTIME to BOOT_TIME*/
+ calculate_time_difference(drSyncUserRealTs, drSyncUserBootTs, &deltaRealToBootTime);
+
+ /* Calculate the time difference between stored offset and computed one now*/
+ calculate_time_difference(time_offset, deltaRealToBootTime, &deltaOffsetTime);
+
+ if ((0 == time_offset.tv_sec && 0 == time_offset.tv_nsec) ||
+ (isTimeOffsetOk(deltaOffsetTime))) {
+ /* if Time Offset does not change beyond threshold then
+ ** convert to boot time*/
+ drsyncUserTs.tv_sec = drSyncUserBootTs.tv_sec;
+ drsyncUserTs.tv_nsec = drSyncUserBootTs.tv_nsec;
+ pps_sync_time_add(ppsFetchTime, deltaRealToBootTime, &drsyncKernelTs);
+ retVal = 0;
+ } else {
+ /*The offset is too high, jump detected in realTime tick, either
+ ** wall clock changed by user of NTP, skip PPS, re-sync @ next tick
+ */
+ LOC_LOGE("[%s] Jump detected in CLOCK_REALTIME - Offset %ld:%ld", __func__,
+ deltaOffsetTime.tv_sec, deltaOffsetTime.tv_nsec);
+ retVal = -1;
+ }
+ time_offset.tv_sec = deltaRealToBootTime.tv_sec;
+ time_offset.tv_nsec = deltaRealToBootTime.tv_nsec;
+
+ LOC_LOGV("[compute_real_to_boot] KernelRealTs %ld:%ld ComputedTs %ld:%ld RealTs %ld:%ld BootTs %ld:%ld Offset %ld:%ld retVal %d ",
+ ppsFetchTime.tv_sec, ppsFetchTime.tv_nsec,
+ drsyncKernelTs.tv_sec, drsyncKernelTs.tv_nsec, drSyncUserRealTs.tv_sec,
+ drSyncUserRealTs.tv_nsec, drsyncUserTs.tv_sec, drsyncUserTs.tv_nsec,
+ time_offset.tv_sec, time_offset.tv_nsec, retVal);
+ } else {
+ LOC_LOGV("[compute_real_to_boot] PPS TimeType Unknown -- KernelTs %ld:%ld userRealTs %ld:%ld userBootTs %ld:%ld",
+ ppsFetchTime.tv_sec, ppsFetchTime.tv_nsec,
+ drSyncUserRealTs.tv_sec, drSyncUserRealTs.tv_nsec,
+ drsyncUserTs.tv_sec, drsyncUserTs.tv_nsec);
+ retVal = -1;
+ }
+
+exit0:
+ return retVal;
+
+}
+
+
/* fetches the timestamp from the PPS source */
int read_pps(pps_handle *handle)
{
struct timespec timeout;
pps_info infobuf;
int ret;
+ static bool isFirstPulseReceived = false;
+ static unsigned int skipPulseCnt = 0;
// 3sec timeout
timeout.tv_sec = 3;
timeout.tv_nsec = 0;
- ret = pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,&timeout);
+ ret = pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf, &timeout);
- if (ret < 0 && ret !=-EINTR)
- {
- LOC_LOGV("%s:%d pps_fetch() error %d", __func__, __LINE__, ret);
- return -1;
- }
+ if (ret < 0 && ret !=-EINTR)
+ {
+ LOC_LOGV("%s:%d pps_fetch() error %d", __func__, __LINE__, ret);
+ return -1;
+ }
+ if (!isFirstPulseReceived && (skipPPSPulseCnt > 0)) {
+ skipPulseCnt = skipPPSPulseCnt;
+ isFirstPulseReceived = true;
+ LOC_LOGV("%s:%d first pps pulse received %ld (sec) %ld (nsec)",
+ __func__, __LINE__, infobuf.tv_sec, infobuf.tv_nsec)
+ }else if (isFirstPulseReceived && (skipPPSPulseCnt > 0) &&
+ ((infobuf.tv_sec - prevDrsyncKernelTs.tv_sec) > gnssOutageInSec)) {
+ LOC_LOGV("%s:%d long RF outage detected, ignore next %d PPS Pulses",
+ __func__, __LINE__, skipPPSPulseCnt)
+ skipPulseCnt = skipPPSPulseCnt;
+ }
+ prevDrsyncKernelTs.tv_sec = infobuf.tv_sec;
+ prevDrsyncKernelTs.tv_nsec = infobuf.tv_nsec;
+ /* check if this dr sync pulse need to be ignored or not*/
+ if (skipPulseCnt > 0) {
+ LOC_LOGV("%s:%d skip pps count %d, ignoring this pps pulse %ld (sec) %ld (nsec)",
+ __func__,__LINE__, skipPulseCnt, infobuf.tv_sec, infobuf.tv_nsec);
+ skipPulseCnt--;
+ return 0;
+ }
+ /* update dr syncpulse time*/
- pthread_mutex_lock(&ts_lock);
- drsyncKernelTs.tv_sec = infobuf.tv_sec;
- drsyncKernelTs.tv_nsec = infobuf.tv_nsec;
- ret = clock_gettime(CLOCK_BOOTTIME,&drsyncUserTs);
- pthread_mutex_unlock(&ts_lock);
+ pthread_mutex_lock(&ts_lock);
+
+ ret = compute_real_to_boot_time(infobuf);
+
+ pthread_mutex_unlock(&ts_lock);
- if(ret != 0)
- {
- LOC_LOGV("%s:%d clock_gettime() error",__func__,__LINE__);
- }
return 0;
}
@@ -136,7 +333,7 @@ int initPPS(char *devname)
LOC_LOGV("%s:%d Could not find PPS source", __func__, __LINE__);
return 0;
}
-
+ UTIL_READ_CONF(LOC_PATH_GPS_CONF, gps_conf_param_table);
pthread_mutex_init(&ts_lock,NULL);
pid = pthread_create(&thread,NULL,&thread_handle,NULL);
diff --git a/gps/gnsspps/gnsspps.pc.in b/gps/gnsspps/gnsspps.pc.in
deleted file mode 100644
index 8931ebd..0000000
--- a/gps/gnsspps/gnsspps.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: gnsspps
-Description: QTI GPS gnsspps
-Version: @VERSION
-Libs: -L${libdir} -lgnsspps
-Cflags: -I${includedir}/gnsspps
diff --git a/gps/loc-hal.pc.in b/gps/loc-hal.pc.in
deleted file mode 100644
index 22d174b..0000000
--- a/gps/loc-hal.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: loc-hal
-Description: QTI GPS Loc HAL
-Version: @VERSION
-Libs: -L${libdir} -lgnss
-Cflags: -I${includedir} -I${includedir}/utils -I${includedir}/core -I${includedir}/loc-hal
diff --git a/gps/location/Android.mk b/gps/location/Android.mk
index bbd6fbd..2a59541 100644
--- a/gps/location/Android.mk
+++ b/gps/location/Android.mk
@@ -6,6 +6,9 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := liblocation_api
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
diff --git a/gps/location/ILocationAPI.h b/gps/location/ILocationAPI.h
new file mode 100644
index 0000000..3df6f79
--- /dev/null
+++ b/gps/location/ILocationAPI.h
@@ -0,0 +1,194 @@
+/* Copyright (c) 2018 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 ILOCATIONAPI_H
+#define ILOCATIONAPI_H
+
+#include "LocationDataTypes.h"
+
+class ILocationAPI
+{
+public:
+ virtual ~ILocationAPI(){};
+
+ /** @brief Updates/changes the callbacks that will be called.
+ mandatory callbacks must be present for callbacks to be successfully updated
+ no return value */
+ virtual void updateCallbacks(LocationCallbacks&) = 0;
+
+ /* ================================== TRACKING ================================== */
+
+ /** @brief Starts a tracking session, which returns a session id that will be
+ used by the other tracking APIs and also in the responseCallback to match command
+ with response. locations are reported on the registered trackingCallback
+ periodically according to LocationOptions.
+ @return session id
+ responseCallback returns:
+ LOCATION_ERROR_SUCCESS if session was successfully started
+ LOCATION_ERROR_ALREADY_STARTED if a startTracking session is already in progress
+ LOCATION_ERROR_CALLBACK_MISSING if no trackingCallback was passed
+ LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameter is invalid */
+ virtual uint32_t startTracking(TrackingOptions&) = 0;
+
+ /** @brief Stops a tracking session associated with id parameter.
+ responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
+ virtual void stopTracking(uint32_t id) = 0;
+
+ /** @brief Changes the LocationOptions of a tracking session associated with id.
+ responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid
+ LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
+ virtual void updateTrackingOptions(uint32_t id, TrackingOptions&) = 0;
+
+ /* ================================== BATCHING ================================== */
+
+ /** @brief starts a batching session, which returns a session id that will be
+ used by the other batching APIs and also in the responseCallback to match command
+ with response. locations are reported on the batchingCallback passed in createInstance
+ periodically according to LocationOptions. A batching session starts tracking on
+ the low power processor and delivers them in batches by the batchingCallback when
+ the batch is full or when getBatchedLocations is called. This allows for the processor
+ that calls this API to sleep when the low power processor can batch locations in the
+ backgroup and wake up the processor calling the API only when the batch is full, thus
+ saving power.
+ @return session id
+ responseCallback returns:
+ LOCATION_ERROR_SUCCESS if session was successful
+ LOCATION_ERROR_ALREADY_STARTED if a startBatching session is already in progress
+ LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback
+ LOCATION_ERROR_INVALID_PARAMETER if a parameter is invalid
+ LOCATION_ERROR_NOT_SUPPORTED if batching is not supported */
+ virtual uint32_t startBatching(BatchingOptions&) = 0;
+
+ /** @brief Stops a batching session associated with id parameter.
+ responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_ID_UNKNOWN if id is not associated with batching session */
+ virtual void stopBatching(uint32_t id) = 0;
+
+ /** @brief Changes the LocationOptions of a batching session associated with id.
+ responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid
+ LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
+ virtual void updateBatchingOptions(uint32_t id, BatchingOptions&) = 0;
+
+ /** @brief Gets a number of locations that are currently stored/batched
+ on the low power processor, delivered by the batchingCallback passed in createInstance.
+ Location are then deleted from the batch stored on the low power processor.
+ responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful, will be followed by batchingCallback call
+ LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback
+ LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
+ virtual void getBatchedLocations(uint32_t id, size_t count) = 0;
+
+ /* ================================== GEOFENCE ================================== */
+
+ /** @brief Adds any number of geofences and returns an array of geofence ids that
+ will be used by the other geofence APIs and also in the collectiveResponseCallback to
+ match command with response. The geofenceBreachCallback will deliver the status of each
+ geofence according to the GeofenceOption for each. The geofence id array returned will
+ be valid until the collectiveResponseCallback is called and has returned.
+ @return id array
+ collectiveResponseCallback returns:
+ LOCATION_ERROR_SUCCESS if session was successful
+ LOCATION_ERROR_CALLBACK_MISSING if no geofenceBreachCallback
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ LOCATION_ERROR_NOT_SUPPORTED if geofence is not supported */
+ virtual uint32_t* addGeofences(size_t count, GeofenceOption*, GeofenceInfo*) = 0;
+
+ /** @brief Removes any number of geofences. Caller should delete ids array after
+ removeGeofences returneds.
+ collectiveResponseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
+ virtual void removeGeofences(size_t count, uint32_t* ids) = 0;
+
+ /** @brief Modifies any number of geofences. Caller should delete ids array after
+ modifyGeofences returns.
+ collectiveResponseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid */
+ virtual void modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options) = 0;
+
+ /** @brief Pauses any number of geofences, which is similar to removeGeofences,
+ only that they can be resumed at any time. Caller should delete ids array after
+ pauseGeofences returns.
+ collectiveResponseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
+ virtual void pauseGeofences(size_t count, uint32_t* ids) = 0;
+
+ /** @brief Resumes any number of geofences that are currently paused. Caller should
+ delete ids array after resumeGeofences returns.
+ collectiveResponseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
+ virtual void resumeGeofences(size_t count, uint32_t* ids) = 0;
+
+ /* ================================== GNSS ====================================== */
+
+ /** @brief gnssNiResponse is called in response to a gnssNiCallback.
+ responseCallback returns:
+ LOCATION_ERROR_SUCCESS if session was successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters in GnssNiResponse are invalid
+ LOCATION_ERROR_ID_UNKNOWN if id does not match a gnssNiCallback */
+ virtual void gnssNiResponse(uint32_t id, GnssNiResponse response) = 0;
+};
+
+class ILocationControlAPI
+{
+public:
+ virtual ~ILocationControlAPI(){};
+
+ /** @brief Updates the gnss specific configuration, which returns a session id array
+ with an id for each of the bits set in GnssConfig.flags, order from low bits to high bits.
+ The response for each config that is set will be returned in collectiveResponseCallback.
+ The session id array returned will be valid until the collectiveResponseCallback is called
+ and has returned. This effect is global for all clients of ILocationAPI.
+ collectiveResponseCallback returns:
+ LOCATION_ERROR_SUCCESS if session was successful
+ LOCATION_ERROR_INVALID_PARAMETER if any other parameters are invalid
+ LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
+ virtual uint32_t* gnssUpdateConfig(GnssConfig config) = 0;
+
+ /** @brief Delete specific gnss aiding data for testing, which returns a session id
+ that will be returned in responseCallback to match command with response.
+ Only allowed in userdebug builds. This effect is global for all clients of ILocationAPI.
+ responseCallback returns:
+ LOCATION_ERROR_SUCCESS if successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
+ LOCATION_ERROR_NOT_SUPPORTED if build is not userdebug */
+ virtual uint32_t gnssDeleteAidingData(GnssAidingData& data) = 0;
+};
+
+#endif /* ILOCATIONAPI_H */
diff --git a/gps/location/LocationAPI.cpp b/gps/location/LocationAPI.cpp
index 0111a9c..4348c27 100644
--- a/gps/location/LocationAPI.cpp
+++ b/gps/location/LocationAPI.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019 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
@@ -25,6 +25,7 @@
* 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_LocationAPI"
#include <location_interface.h>
@@ -33,42 +34,64 @@
#include <log_util.h>
#include <pthread.h>
#include <map>
+#include <loc_misc_utils.h>
+
+typedef const GnssInterface* (getGnssInterface)();
+typedef const GeofenceInterface* (getGeofenceInterface)();
+typedef const BatchingInterface* (getBatchingInterface)();
+
+typedef struct {
+ // bit mask of the adpaters that we need to wait for the removeClientCompleteCallback
+ // before we invoke the registered locationApiDestroyCompleteCallback
+ LocationAdapterTypeMask waitAdapterMask;
+ locationApiDestroyCompleteCallback destroyCompleteCb;
+} LocationAPIDestroyCbData;
+
+// This is the map for the client that has requested destroy with
+// destroy callback provided.
+typedef std::map<LocationAPI*, LocationAPIDestroyCbData>
+ LocationClientDestroyCbMap;
-typedef void* (getLocationInterface)();
typedef std::map<LocationAPI*, LocationCallbacks> LocationClientMap;
typedef struct {
LocationClientMap clientData;
+ LocationClientDestroyCbMap destroyClientData;
LocationControlAPI* controlAPI;
LocationControlCallbacks controlCallbacks;
GnssInterface* gnssInterface;
GeofenceInterface* geofenceInterface;
- FlpInterface* flpInterface;
+ BatchingInterface* batchingInterface;
} LocationAPIData;
+
static LocationAPIData gData = {};
static pthread_mutex_t gDataMutex = PTHREAD_MUTEX_INITIALIZER;
static bool gGnssLoadFailed = false;
-static bool gFlpLoadFailed = false;
+static bool gBatchingLoadFailed = false;
static bool gGeofenceLoadFailed = false;
-static bool needsGnssTrackingInfo(LocationCallbacks& locationCallbacks)
-{
- return (locationCallbacks.gnssLocationInfoCb != nullptr ||
- locationCallbacks.gnssSvCb != nullptr ||
- locationCallbacks.gnssNmeaCb != nullptr ||
- locationCallbacks.gnssMeasurementsCb != nullptr);
+template <typename T1, typename T2>
+static const T1* loadLocationInterface(const char* library, const char* name) {
+ void* libhandle = nullptr;
+ T2* getter = (T2*)dlGetSymFromLib(libhandle, library, name);
+ if (nullptr == getter) {
+ return (const T1*) getter;
+ }else {
+ return (*getter)();
+ }
}
static bool isGnssClient(LocationCallbacks& locationCallbacks)
{
return (locationCallbacks.gnssNiCb != nullptr ||
locationCallbacks.trackingCb != nullptr ||
+ locationCallbacks.gnssLocationInfoCb != nullptr ||
+ locationCallbacks.engineLocationsInfoCb != nullptr ||
locationCallbacks.gnssMeasurementsCb != nullptr);
}
-static bool isFlpClient(LocationCallbacks& locationCallbacks)
+static bool isBatchingClient(LocationCallbacks& locationCallbacks)
{
- return (locationCallbacks.trackingCb != nullptr ||
- locationCallbacks.batchingCb != nullptr);
+ return (locationCallbacks.batchingCb != nullptr);
}
static bool isGeofenceClient(LocationCallbacks& locationCallbacks)
@@ -77,32 +100,48 @@ static bool isGeofenceClient(LocationCallbacks& locationCallbacks)
locationCallbacks.geofenceStatusCb != nullptr);
}
-static void* loadLocationInterface(const char* library, const char* name) {
- LOC_LOGD("%s]: loading %s::%s ...", __func__, library, name);
- if (NULL == library || NULL == name) {
- return NULL;
- }
- getLocationInterface* getter = NULL;
- const char *error = NULL;
- dlerror();
- void *handle = dlopen(library, RTLD_NOW);
- if (NULL == handle || (error = dlerror()) != NULL) {
- LOC_LOGW("dlopen for %s failed, error = %s", library, error);
- } else {
- getter = (getLocationInterface*)dlsym(handle, name);
- if ((error = dlerror()) != NULL) {
- LOC_LOGW("dlsym for %s::%s failed, error = %s", library, name, error);
- getter = NULL;
+
+void LocationAPI::onRemoveClientCompleteCb (LocationAdapterTypeMask adapterType)
+{
+ bool invokeCallback = false;
+ locationApiDestroyCompleteCallback destroyCompleteCb;
+ LOC_LOGd("adatper type %x", adapterType);
+ pthread_mutex_lock(&gDataMutex);
+ auto it = gData.destroyClientData.find(this);
+ if (it != gData.destroyClientData.end()) {
+ it->second.waitAdapterMask &= ~adapterType;
+ if (it->second.waitAdapterMask == 0) {
+ invokeCallback = true;
+ destroyCompleteCb = it->second.destroyCompleteCb;
+ gData.destroyClientData.erase(it);
}
}
+ pthread_mutex_unlock(&gDataMutex);
- if (NULL == getter) {
- return (void*)getter;
- } else {
- return (*getter)();
+ if ((true == invokeCallback) && (nullptr != destroyCompleteCb)) {
+ LOC_LOGd("invoke client destroy cb");
+ (destroyCompleteCb) ();
+ LOC_LOGd("finish invoke client destroy cb");
+
+ delete this;
}
}
+void onGnssRemoveClientCompleteCb (LocationAPI* client)
+{
+ client->onRemoveClientCompleteCb (LOCATION_ADAPTER_GNSS_TYPE_BIT);
+}
+
+void onBatchingRemoveClientCompleteCb (LocationAPI* client)
+{
+ client->onRemoveClientCompleteCb (LOCATION_ADAPTER_BATCHING_TYPE_BIT);
+}
+
+void onGeofenceRemoveClientCompleteCb (LocationAPI* client)
+{
+ client->onRemoveClientCompleteCb (LOCATION_ADAPTER_GEOFENCE_TYPE_BIT);
+}
+
LocationAPI*
LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
{
@@ -120,7 +159,8 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
if (isGnssClient(locationCallbacks)) {
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
gData.gnssInterface =
- (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
+ (GnssInterface*)loadLocationInterface<GnssInterface,
+ getGnssInterface>("libgnss.so", "getGnssInterface");
if (NULL == gData.gnssInterface) {
gGnssLoadFailed = true;
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
@@ -137,21 +177,22 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
}
}
- if (isFlpClient(locationCallbacks)) {
- if (NULL == gData.flpInterface && !gFlpLoadFailed) {
- gData.flpInterface =
- (FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface");
- if (NULL == gData.flpInterface) {
- gFlpLoadFailed = true;
- LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__);
+ if (isBatchingClient(locationCallbacks)) {
+ if (NULL == gData.batchingInterface && !gBatchingLoadFailed) {
+ gData.batchingInterface =
+ (BatchingInterface*)loadLocationInterface<BatchingInterface,
+ getBatchingInterface>("libbatching.so", "getBatchingInterface");
+ if (NULL == gData.batchingInterface) {
+ gBatchingLoadFailed = true;
+ LOC_LOGW("%s:%d]: No batching interface available", __func__, __LINE__);
} else {
- gData.flpInterface->initialize();
+ gData.batchingInterface->initialize();
}
}
- if (NULL != gData.flpInterface) {
- gData.flpInterface->addClient(newLocationAPI, locationCallbacks);
+ if (NULL != gData.batchingInterface) {
+ gData.batchingInterface->addClient(newLocationAPI, locationCallbacks);
if (!requestedCapabilities) {
- gData.flpInterface->requestCapabilities(newLocationAPI);
+ gData.batchingInterface->requestCapabilities(newLocationAPI);
requestedCapabilities = true;
}
}
@@ -160,7 +201,8 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
if (isGeofenceClient(locationCallbacks)) {
if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
gData.geofenceInterface =
- (GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface");
+ (GeofenceInterface*)loadLocationInterface<GeofenceInterface,
+ getGeofenceInterface>("libgeofencing.so", "getGeofenceInterface");
if (NULL == gData.geofenceInterface) {
gGeofenceLoadFailed = true;
LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
@@ -185,39 +227,79 @@ LocationAPI::createInstance(LocationCallbacks& locationCallbacks)
}
void
-LocationAPI::destroy()
+LocationAPI::destroy(locationApiDestroyCompleteCallback destroyCompleteCb)
{
- delete this;
-}
+ bool invokeDestroyCb = false;
-LocationAPI::LocationAPI()
-{
- LOC_LOGD("LOCATION API CONSTRUCTOR");
-}
-
-LocationAPI::~LocationAPI()
-{
- LOC_LOGD("LOCATION API DESTRUCTOR");
pthread_mutex_lock(&gDataMutex);
-
auto it = gData.clientData.find(this);
if (it != gData.clientData.end()) {
- if (isGnssClient(it->second) && NULL != gData.gnssInterface) {
- gData.gnssInterface->removeClient(it->first);
+ bool removeFromGnssInf =
+ (isGnssClient(it->second) && NULL != gData.gnssInterface);
+ bool removeFromBatchingInf =
+ (isBatchingClient(it->second) && NULL != gData.batchingInterface);
+ bool removeFromGeofenceInf =
+ (isGeofenceClient(it->second) && NULL != gData.geofenceInterface);
+ bool needToWait = (removeFromGnssInf || removeFromBatchingInf || removeFromGeofenceInf);
+ LOC_LOGe("removeFromGnssInf: %d, removeFromBatchingInf: %d, removeFromGeofenceInf: %d,"
+ "need %d", removeFromGnssInf, removeFromBatchingInf, removeFromGeofenceInf,
+ needToWait);
+
+ if ((NULL != destroyCompleteCb) && (true == needToWait)) {
+ LocationAPIDestroyCbData destroyCbData = {};
+ destroyCbData.destroyCompleteCb = destroyCompleteCb;
+ // record down from which adapter we need to wait for the destroy complete callback
+ // only when we have received all the needed callbacks from all the associated stacks,
+ // we shall notify the client.
+ destroyCbData.waitAdapterMask =
+ (removeFromGnssInf ? LOCATION_ADAPTER_GNSS_TYPE_BIT : 0);
+ destroyCbData.waitAdapterMask |=
+ (removeFromBatchingInf ? LOCATION_ADAPTER_BATCHING_TYPE_BIT : 0);
+ destroyCbData.waitAdapterMask |=
+ (removeFromGeofenceInf ? LOCATION_ADAPTER_GEOFENCE_TYPE_BIT : 0);
+ gData.destroyClientData[this] = destroyCbData;
+ LOC_LOGe("destroy data stored in the map: 0x%x", destroyCbData.waitAdapterMask);
}
- if (isFlpClient(it->second) && NULL != gData.flpInterface) {
- gData.flpInterface->removeClient(it->first);
+
+ if (removeFromGnssInf) {
+ gData.gnssInterface->removeClient(it->first,
+ onGnssRemoveClientCompleteCb);
}
- if (isGeofenceClient(it->second) && NULL != gData.geofenceInterface) {
- gData.geofenceInterface->removeClient(it->first);
+ if (removeFromBatchingInf) {
+ gData.batchingInterface->removeClient(it->first,
+ onBatchingRemoveClientCompleteCb);
}
+ if (removeFromGeofenceInf) {
+ gData.geofenceInterface->removeClient(it->first,
+ onGeofenceRemoveClientCompleteCb);
+ }
+
gData.clientData.erase(it);
+
+ if ((NULL != destroyCompleteCb) && (false == needToWait)) {
+ invokeDestroyCb = true;
+ }
} else {
LOC_LOGE("%s:%d]: Location API client %p not found in client data",
__func__, __LINE__, this);
}
pthread_mutex_unlock(&gDataMutex);
+ if (invokeDestroyCb == true) {
+ (destroyCompleteCb) ();
+ delete this;
+ }
+}
+
+LocationAPI::LocationAPI()
+{
+ LOC_LOGD("LOCATION API CONSTRUCTOR");
+}
+
+// private destructor
+LocationAPI::~LocationAPI()
+{
+ LOC_LOGD("LOCATION API DESTRUCTOR");
}
void
@@ -234,7 +316,8 @@ LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks)
if (isGnssClient(locationCallbacks)) {
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
gData.gnssInterface =
- (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
+ (GnssInterface*)loadLocationInterface<GnssInterface,
+ getGnssInterface>("libgnss.so", "getGnssInterface");
if (NULL == gData.gnssInterface) {
gGnssLoadFailed = true;
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
@@ -248,27 +331,29 @@ LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks)
}
}
- if (isFlpClient(locationCallbacks)) {
- if (NULL == gData.flpInterface && !gFlpLoadFailed) {
- gData.flpInterface =
- (FlpInterface*)loadLocationInterface("libflp.so", "getFlpInterface");
- if (NULL == gData.flpInterface) {
- gFlpLoadFailed = true;
- LOC_LOGW("%s:%d]: No flp interface available", __func__, __LINE__);
+ if (isBatchingClient(locationCallbacks)) {
+ if (NULL == gData.batchingInterface && !gBatchingLoadFailed) {
+ gData.batchingInterface =
+ (BatchingInterface*)loadLocationInterface<BatchingInterface,
+ getBatchingInterface>("libbatching.so", "getBatchingInterface");
+ if (NULL == gData.batchingInterface) {
+ gBatchingLoadFailed = true;
+ LOC_LOGW("%s:%d]: No batching interface available", __func__, __LINE__);
} else {
- gData.flpInterface->initialize();
+ gData.batchingInterface->initialize();
}
}
- if (NULL != gData.flpInterface) {
+ if (NULL != gData.batchingInterface) {
// either adds new Client or updates existing Client
- gData.flpInterface->addClient(this, locationCallbacks);
+ gData.batchingInterface->addClient(this, locationCallbacks);
}
}
if (isGeofenceClient(locationCallbacks)) {
if (NULL == gData.geofenceInterface && !gGeofenceLoadFailed) {
gData.geofenceInterface =
- (GeofenceInterface*)loadLocationInterface("libgeofence.so", "getGeofenceInterface");
+ (GeofenceInterface*)loadLocationInterface<GeofenceInterface,
+ getGeofenceInterface>("libgeofencing.so", "getGeofenceInterface");
if (NULL == gData.geofenceInterface) {
gGeofenceLoadFailed = true;
LOC_LOGW("%s:%d]: No geofence interface available", __func__, __LINE__);
@@ -288,23 +373,17 @@ LocationAPI::updateCallbacks(LocationCallbacks& locationCallbacks)
}
uint32_t
-LocationAPI::startTracking(LocationOptions& locationOptions)
+LocationAPI::startTracking(TrackingOptions& trackingOptions)
{
uint32_t id = 0;
pthread_mutex_lock(&gDataMutex);
auto it = gData.clientData.find(this);
if (it != gData.clientData.end()) {
- if (gData.flpInterface != NULL && locationOptions.minDistance > 0) {
- id = gData.flpInterface->startTracking(this, locationOptions);
- } else if (gData.gnssInterface != NULL && needsGnssTrackingInfo(it->second)) {
- id = gData.gnssInterface->startTracking(this, locationOptions);
- } else if (gData.flpInterface != NULL) {
- id = gData.flpInterface->startTracking(this, locationOptions);
- } else if (gData.gnssInterface != NULL) {
- id = gData.gnssInterface->startTracking(this, locationOptions);
+ if (NULL != gData.gnssInterface) {
+ id = gData.gnssInterface->startTracking(this, trackingOptions);
} else {
- LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ",
__func__, __LINE__, this);
}
} else {
@@ -323,16 +402,10 @@ LocationAPI::stopTracking(uint32_t id)
auto it = gData.clientData.find(this);
if (it != gData.clientData.end()) {
- // we don't know if tracking was started on flp or gnss, so we call stop on both, where
- // stopTracking call to the incorrect interface will fail without response back to client
if (gData.gnssInterface != NULL) {
gData.gnssInterface->stopTracking(this, id);
- }
- if (gData.flpInterface != NULL) {
- gData.flpInterface->stopTracking(this, id);
- }
- if (gData.flpInterface == NULL && gData.gnssInterface == NULL) {
- LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
+ } else {
+ LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ",
__func__, __LINE__, this);
}
} else {
@@ -344,22 +417,17 @@ LocationAPI::stopTracking(uint32_t id)
}
void
-LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions)
+LocationAPI::updateTrackingOptions(
+ uint32_t id, TrackingOptions& trackingOptions)
{
pthread_mutex_lock(&gDataMutex);
auto it = gData.clientData.find(this);
if (it != gData.clientData.end()) {
- // we don't know if tracking was started on flp or gnss, so we call update on both, where
- // updateTracking call to the incorrect interface will fail without response back to client
if (gData.gnssInterface != NULL) {
- gData.gnssInterface->updateTrackingOptions(this, id, locationOptions);
- }
- if (gData.flpInterface != NULL) {
- gData.flpInterface->updateTrackingOptions(this, id, locationOptions);
- }
- if (gData.flpInterface == NULL && gData.gnssInterface == NULL) {
- LOC_LOGE("%s:%d]: No gnss/flp interface available for Location API client %p ",
+ gData.gnssInterface->updateTrackingOptions(this, id, trackingOptions);
+ } else {
+ LOC_LOGE("%s:%d]: No gnss interface available for Location API client %p ",
__func__, __LINE__, this);
}
} else {
@@ -371,15 +439,15 @@ LocationAPI::updateTrackingOptions(uint32_t id, LocationOptions& locationOptions
}
uint32_t
-LocationAPI::startBatching(LocationOptions& locationOptions, BatchingOptions &batchingOptions)
+LocationAPI::startBatching(BatchingOptions &batchingOptions)
{
uint32_t id = 0;
pthread_mutex_lock(&gDataMutex);
- if (gData.flpInterface != NULL) {
- id = gData.flpInterface->startBatching(this, locationOptions, batchingOptions);
+ if (NULL != gData.batchingInterface) {
+ id = gData.batchingInterface->startBatching(this, batchingOptions);
} else {
- LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ",
__func__, __LINE__, this);
}
@@ -392,10 +460,10 @@ LocationAPI::stopBatching(uint32_t id)
{
pthread_mutex_lock(&gDataMutex);
- if (gData.flpInterface != NULL) {
- gData.flpInterface->stopBatching(this, id);
+ if (NULL != gData.batchingInterface) {
+ gData.batchingInterface->stopBatching(this, id);
} else {
- LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ",
__func__, __LINE__, this);
}
@@ -403,18 +471,14 @@ LocationAPI::stopBatching(uint32_t id)
}
void
-LocationAPI::updateBatchingOptions(uint32_t id,
- LocationOptions& locationOptions, BatchingOptions& batchOptions)
+LocationAPI::updateBatchingOptions(uint32_t id, BatchingOptions& batchOptions)
{
pthread_mutex_lock(&gDataMutex);
- if (gData.flpInterface != NULL) {
- gData.flpInterface->updateBatchingOptions(this,
- id,
- locationOptions,
- batchOptions);
+ if (NULL != gData.batchingInterface) {
+ gData.batchingInterface->updateBatchingOptions(this, id, batchOptions);
} else {
- LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ",
__func__, __LINE__, this);
}
@@ -426,10 +490,10 @@ LocationAPI::getBatchedLocations(uint32_t id, size_t count)
{
pthread_mutex_lock(&gDataMutex);
- if (gData.flpInterface != NULL) {
- gData.flpInterface->getBatchedLocations(this, id, count);
+ if (gData.batchingInterface != NULL) {
+ gData.batchingInterface->getBatchedLocations(this, id, count);
} else {
- LOC_LOGE("%s:%d]: No flp interface available for Location API client %p ",
+ LOC_LOGE("%s:%d]: No batching interface available for Location API client %p ",
__func__, __LINE__, this);
}
@@ -537,7 +601,8 @@ LocationControlAPI::createInstance(LocationControlCallbacks& locationControlCall
if (nullptr != locationControlCallbacks.responseCb && NULL == gData.controlAPI) {
if (NULL == gData.gnssInterface && !gGnssLoadFailed) {
gData.gnssInterface =
- (GnssInterface*)loadLocationInterface("libgnss.so", "getGnssInterface");
+ (GnssInterface*)loadLocationInterface<GnssInterface,
+ getGnssInterface>("libgnss.so", "getGnssInterface");
if (NULL == gData.gnssInterface) {
gGnssLoadFailed = true;
LOC_LOGW("%s:%d]: No gnss interface available", __func__, __LINE__);
@@ -627,6 +692,21 @@ LocationControlAPI::gnssUpdateConfig(GnssConfig config)
return ids;
}
+uint32_t* LocationControlAPI::gnssGetConfig(GnssConfigFlagsMask mask) {
+
+ uint32_t* ids = NULL;
+ pthread_mutex_lock(&gDataMutex);
+
+ if (NULL != gData.gnssInterface) {
+ ids = gData.gnssInterface->gnssGetConfig(mask);
+ } else {
+ LOC_LOGe("No gnss interface available for Control API client %p", this);
+ }
+
+ pthread_mutex_unlock(&gDataMutex);
+ return ids;
+}
+
uint32_t
LocationControlAPI::gnssDeleteAidingData(GnssAidingData& data)
{
diff --git a/gps/location/LocationAPI.h b/gps/location/LocationAPI.h
index 530b1b0..6f5987c 100644
--- a/gps/location/LocationAPI.h
+++ b/gps/location/LocationAPI.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018 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
@@ -26,742 +26,12 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef LOCATION_H
-#define LOCATION_H
-
-#include <vector>
-#include <stdint.h>
-#include <functional>
-#include <list>
-
-#define GNSS_NI_REQUESTOR_MAX 256
-#define GNSS_NI_MESSAGE_ID_MAX 2048
-#define GNSS_SV_MAX 64
-#define GNSS_MEASUREMENTS_MAX 64
-#define GNSS_UTC_TIME_OFFSET (3657)
-
-#define GNSS_BUGREPORT_GPS_MIN (1)
-#define GNSS_BUGREPORT_SBAS_MIN (120)
-#define GNSS_BUGREPORT_GLO_MIN (1)
-#define GNSS_BUGREPORT_QZSS_MIN (193)
-#define GNSS_BUGREPORT_BDS_MIN (1)
-#define GNSS_BUGREPORT_GAL_MIN (1)
-
-typedef enum {
- LOCATION_ERROR_SUCCESS = 0,
- LOCATION_ERROR_GENERAL_FAILURE,
- LOCATION_ERROR_CALLBACK_MISSING,
- LOCATION_ERROR_INVALID_PARAMETER,
- LOCATION_ERROR_ID_EXISTS,
- LOCATION_ERROR_ID_UNKNOWN,
- LOCATION_ERROR_ALREADY_STARTED,
- LOCATION_ERROR_GEOFENCES_AT_MAX,
- LOCATION_ERROR_NOT_SUPPORTED
-} LocationError;
-
-// Flags to indicate which values are valid in a Location
-typedef uint16_t LocationFlagsMask;
-typedef enum {
- LOCATION_HAS_LAT_LONG_BIT = (1<<0), // location has valid latitude and longitude
- LOCATION_HAS_ALTITUDE_BIT = (1<<1), // location has valid altitude
- LOCATION_HAS_SPEED_BIT = (1<<2), // location has valid speed
- LOCATION_HAS_BEARING_BIT = (1<<3), // location has valid bearing
- LOCATION_HAS_ACCURACY_BIT = (1<<4), // location has valid accuracy
- LOCATION_HAS_VERTICAL_ACCURACY_BIT = (1<<5), // location has valid vertical accuracy
- LOCATION_HAS_SPEED_ACCURACY_BIT = (1<<6), // location has valid speed accuracy
- LOCATION_HAS_BEARING_ACCURACY_BIT = (1<<7), // location has valid bearing accuracy
-} LocationFlagsBits;
-
-typedef uint16_t LocationTechnologyMask;
-typedef enum {
- LOCATION_TECHNOLOGY_GNSS_BIT = (1<<0), // location was calculated using GNSS
- LOCATION_TECHNOLOGY_CELL_BIT = (1<<1), // location was calculated using Cell
- LOCATION_TECHNOLOGY_WIFI_BIT = (1<<2), // location was calculated using WiFi
- LOCATION_TECHNOLOGY_SENSORS_BIT = (1<<3), // location was calculated using Sensors
-} LocationTechnologyBits;
-
-typedef enum {
- LOCATION_RELIABILITY_NOT_SET = 0,
- LOCATION_RELIABILITY_VERY_LOW,
- LOCATION_RELIABILITY_LOW,
- LOCATION_RELIABILITY_MEDIUM,
- LOCATION_RELIABILITY_HIGH,
-} LocationReliability;
-
-typedef uint32_t GnssLocationInfoFlagMask;
-typedef enum {
- GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT = (1<<0), // valid altitude mean sea level
- GNSS_LOCATION_INFO_DOP_BIT = (1<<1), // valid pdop, hdop, and vdop
- GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT = (1<<2), // valid magnetic deviation
- GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT = (1<<3), // valid horizontal reliability
- GNSS_LOCATION_INFO_VER_RELIABILITY_BIT = (1<<4), // valid vertical reliability
- GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT = (1<<5), // valid elipsode semi major
- GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT = (1<<6), // valid elipsode semi minor
- GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT = (1<<7),// valid accuracy elipsode azimuth
-} GnssLocationInfoFlagBits;
-
-typedef enum {
- GEOFENCE_BREACH_ENTER = 0,
- GEOFENCE_BREACH_EXIT,
- GEOFENCE_BREACH_DWELL_IN,
- GEOFENCE_BREACH_DWELL_OUT,
- GEOFENCE_BREACH_UNKNOWN,
-} GeofenceBreachType;
-
-typedef uint16_t GeofenceBreachTypeMask;
-typedef enum {
- GEOFENCE_BREACH_ENTER_BIT = (1<<0),
- GEOFENCE_BREACH_EXIT_BIT = (1<<1),
- GEOFENCE_BREACH_DWELL_IN_BIT = (1<<2),
- GEOFENCE_BREACH_DWELL_OUT_BIT = (1<<3),
-} GeofenceBreachTypeBits;
-
-typedef enum {
- GEOFENCE_STATUS_AVAILABILE_NO = 0,
- GEOFENCE_STATUS_AVAILABILE_YES,
-} GeofenceStatusAvailable;
-
-typedef uint32_t LocationCapabilitiesMask;
-typedef enum {
- // supports startTracking API with minInterval param
- LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT = (1<<0),
- // supports startBatching API with minInterval param
- LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT = (1<<1),
- // supports startTracking API with minDistance param
- LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT = (1<<2),
- // supports startBatching API with minDistance param
- LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT = (1<<3),
- // supports addGeofences API
- LOCATION_CAPABILITIES_GEOFENCE_BIT = (1<<4),
- // supports GnssMeasurementsCallback
- LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT = (1<<5),
- // supports startTracking/startBatching API with LocationOptions.mode of MSB (Ms Based)
- LOCATION_CAPABILITIES_GNSS_MSB_BIT = (1<<6),
- // supports startTracking/startBatching API with LocationOptions.mode of MSA (MS Assisted)
- LOCATION_CAPABILITIES_GNSS_MSA_BIT = (1<<7),
- // supports debug nmea sentences in the debugNmeaCallback
- LOCATION_CAPABILITIES_DEBUG_NMEA_BIT = (1<<8),
- // support outdoor trip batching
- LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT = (1<<9)
-} LocationCapabilitiesBits;
-
-typedef enum {
- LOCATION_TECHNOLOGY_TYPE_GNSS = 0,
-} LocationTechnologyType;
-
-// Configures how GPS is locked when GPS is disabled (through GnssDisable)
-typedef enum {
- GNSS_CONFIG_GPS_LOCK_NONE = 0, // gps is not locked when GPS is disabled (GnssDisable)
- GNSS_CONFIG_GPS_LOCK_MO, // gps mobile originated (MO) is locked when GPS is disabled
- GNSS_CONFIG_GPS_LOCK_NI, // gps network initiated (NI) is locked when GPS is disabled
- GNSS_CONFIG_GPS_LOCK_MO_AND_NI,// gps MO and NI is locked when GPS is disabled
-} GnssConfigGpsLock;
-
-// SUPL version
-typedef enum {
- GNSS_CONFIG_SUPL_VERSION_1_0_0 = 1,
- GNSS_CONFIG_SUPL_VERSION_2_0_0,
- GNSS_CONFIG_SUPL_VERSION_2_0_2,
-} GnssConfigSuplVersion;
-
-// LTE Positioning Profile
-typedef enum {
- GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE = 0, // RRLP on LTE (Default)
- GNSS_CONFIG_LPP_PROFILE_USER_PLANE, // LPP User Plane (UP) on LTE
- GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE, // LPP_Control_Plane (CP)
- GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE, // Both LPP UP and CP
-} GnssConfigLppProfile;
-
-// Technology for LPPe Control Plane
-typedef uint16_t GnssConfigLppeControlPlaneMask;
-typedef enum {
- GNSS_CONFIG_LPPE_CONTROL_PLANE_DBH_BIT = (1<<0), // DBH
- GNSS_CONFIG_LPPE_CONTROL_PLANE_WLAN_AP_MEASUREMENTS_BIT = (1<<1), // WLAN_AP_MEASUREMENTS
- GNSS_CONFIG_LPPE_CONTROL_PLANE_SRN_AP_MEASUREMENTS_BIT = (1<<2), // SRN_AP_MEASUREMENTS
- GNSS_CONFIG_LPPE_CONTROL_PLANE_SENSOR_BARO_MEASUREMENTS_BIT = (1<<3),
- // SENSOR_BARO_MEASUREMENTS
-} GnssConfigLppeControlPlaneBits;
-
-// Technology for LPPe User Plane
-typedef uint16_t GnssConfigLppeUserPlaneMask;
-typedef enum {
- GNSS_CONFIG_LPPE_USER_PLANE_DBH_BIT = (1<<0), // DBH
- GNSS_CONFIG_LPPE_USER_PLANE_WLAN_AP_MEASUREMENTS_BIT = (1<<1), // WLAN_AP_MEASUREMENTS
- GNSS_CONFIG_LPPE_USER_PLANE_SRN_AP_MEASUREMENTS_BIT = (1<<2), // SRN_AP_MEASUREMENTS
- GNSS_CONFIG_LPPE_USER_PLANE_SENSOR_BARO_MEASUREMENTS_BIT = (1<<3),
- // SENSOR_BARO_MEASUREMENTS
-} GnssConfigLppeUserPlaneBits;
-
-// Positioning Protocol on A-GLONASS system
-typedef uint16_t GnssConfigAGlonassPositionProtocolMask;
-typedef enum {
- GNSS_CONFIG_RRC_CONTROL_PLANE_BIT = (1<<0), // RRC Control Plane
- GNSS_CONFIG_RRLP_USER_PLANE_BIT = (1<<1), // RRLP User Plane
- GNSS_CONFIG_LLP_USER_PLANE_BIT = (1<<2), // LPP User Plane
- GNSS_CONFIG_LLP_CONTROL_PLANE_BIT = (1<<3), // LPP Control Plane
-} GnssConfigAGlonassPositionProtocolBits;
-
-typedef enum {
- GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO = 0,
- GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES,
-} GnssConfigEmergencyPdnForEmergencySupl;
-
-typedef enum {
- GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO = 0,
- GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_YES,
-} GnssConfigSuplEmergencyServices;
-
-typedef uint16_t GnssConfigSuplModeMask;
-typedef enum {
- GNSS_CONFIG_SUPL_MODE_MSB_BIT = (1<<0),
- GNSS_CONFIG_SUPL_MODE_MSA_BIT = (1<<1),
-} GnssConfigSuplModeBits;
-
-typedef uint32_t GnssConfigFlagsMask;
-typedef enum {
- GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT = (1<<0),
- GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT = (1<<1),
- GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT = (1<<2),
- GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT = (1<<3),
- GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT = (1<<4),
- GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT = (1<<5),
- GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT = (1<<6),
- GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT = (1<<7),
- GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT = (1<<8),
- GNSS_CONFIG_FLAGS_SUPL_MODE_BIT = (1<<9),
-} GnssConfigFlagsBits;
-
-typedef enum {
- GNSS_NI_ENCODING_TYPE_NONE = 0,
- GNSS_NI_ENCODING_TYPE_GSM_DEFAULT,
- GNSS_NI_ENCODING_TYPE_UTF8,
- GNSS_NI_ENCODING_TYPE_UCS2,
-} GnssNiEncodingType;
-
-typedef enum {
- GNSS_NI_TYPE_VOICE = 0,
- GNSS_NI_TYPE_SUPL,
- GNSS_NI_TYPE_CONTROL_PLANE,
- GNSS_NI_TYPE_EMERGENCY_SUPL
-} GnssNiType;
-
-typedef uint16_t GnssNiOptionsMask;
-typedef enum {
- GNSS_NI_OPTIONS_NOTIFICATION_BIT = (1<<0),
- GNSS_NI_OPTIONS_VERIFICATION_BIT = (1<<1),
- GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT = (1<<2),
-} GnssNiOptionsBits;
-
-typedef enum {
- GNSS_NI_RESPONSE_ACCEPT = 1,
- GNSS_NI_RESPONSE_DENY,
- GNSS_NI_RESPONSE_NO_RESPONSE,
- GNSS_NI_RESPONSE_IGNORE,
-} GnssNiResponse;
-
-typedef enum {
- GNSS_SV_TYPE_UNKNOWN = 0,
- GNSS_SV_TYPE_GPS,
- GNSS_SV_TYPE_SBAS,
- GNSS_SV_TYPE_GLONASS,
- GNSS_SV_TYPE_QZSS,
- GNSS_SV_TYPE_BEIDOU,
- GNSS_SV_TYPE_GALILEO,
-} GnssSvType;
-
-typedef enum {
- GNSS_EPH_TYPE_UNKNOWN = 0,
- GNSS_EPH_TYPE_EPHEMERIS,
- GNSS_EPH_TYPE_ALMANAC,
-} GnssEphemerisType;
-
-typedef enum {
- GNSS_EPH_SOURCE_UNKNOWN = 0,
- GNSS_EPH_SOURCE_DEMODULATED,
- GNSS_EPH_SOURCE_SUPL_PROVIDED,
- GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED,
- GNSS_EPH_SOURCE_LOCAL,
-} GnssEphemerisSource;
-
-typedef enum {
- GNSS_EPH_HEALTH_UNKNOWN = 0,
- GNSS_EPH_HEALTH_GOOD,
- GNSS_EPH_HEALTH_BAD,
-} GnssEphemerisHealth;
-
-typedef uint16_t GnssSvOptionsMask;
-typedef enum {
- GNSS_SV_OPTIONS_HAS_EPHEMER_BIT = (1<<0),
- GNSS_SV_OPTIONS_HAS_ALMANAC_BIT = (1<<1),
- GNSS_SV_OPTIONS_USED_IN_FIX_BIT = (1<<2),
-} GnssSvOptionsBits;
-
-typedef enum {
- GNSS_ASSISTANCE_TYPE_SUPL = 0,
- GNSS_ASSISTANCE_TYPE_C2K,
-} GnssAssistanceType;
-
-typedef enum {
- GNSS_SUPL_MODE_STANDALONE = 0,
- GNSS_SUPL_MODE_MSB,
- GNSS_SUPL_MODE_MSA,
-} GnssSuplMode;
-
-typedef enum {
- BATCHING_MODE_ROUTINE = 0, // positions are reported when batched positions memory is full
- BATCHING_MODE_TRIP, // positions are reported when a certain distance is covered
- BATCHING_MODE_NO_AUTO_REPORT // no report of positions automatically, instead queried on demand
-} BatchingMode;
-
-typedef enum {
- BATCHING_STATUS_TRIP_COMPLETED = 0,
- BATCHING_STATUS_POSITION_AVAILABE,
- BATCHING_STATUS_POSITION_UNAVAILABLE
-} BatchingStatus;
-
-typedef uint16_t GnssMeasurementsAdrStateMask;
-typedef enum {
- GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_UNKNOWN = 0,
- GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT = (1<<0),
- GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT = (1<<1),
- GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT = (1<<2),
-} GnssMeasurementsAdrStateBits;
-
-typedef uint32_t GnssMeasurementsDataFlagsMask;
-typedef enum {
- GNSS_MEASUREMENTS_DATA_SV_ID_BIT = (1<<0),
- GNSS_MEASUREMENTS_DATA_SV_TYPE_BIT = (1<<1),
- GNSS_MEASUREMENTS_DATA_STATE_BIT = (1<<2),
- GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_BIT = (1<<3),
- GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_UNCERTAINTY_BIT = (1<<4),
- GNSS_MEASUREMENTS_DATA_CARRIER_TO_NOISE_BIT = (1<<5),
- GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_BIT = (1<<6),
- GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_UNCERTAINTY_BIT = (1<<7),
- GNSS_MEASUREMENTS_DATA_ADR_STATE_BIT = (1<<8),
- GNSS_MEASUREMENTS_DATA_ADR_BIT = (1<<9),
- GNSS_MEASUREMENTS_DATA_ADR_UNCERTAINTY_BIT = (1<<10),
- GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT = (1<<11),
- GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT = (1<<12),
- GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT = (1<<13),
- GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT = (1<<14),
- GNSS_MEASUREMENTS_DATA_MULTIPATH_INDICATOR_BIT = (1<<15),
- GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT = (1<<16),
- GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT = (1<<17),
-} GnssMeasurementsDataFlagsBits;
-
-typedef uint32_t GnssMeasurementsStateMask;
-typedef enum {
- GNSS_MEASUREMENTS_STATE_UNKNOWN_BIT = 0,
- GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT = (1<<0),
- GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT = (1<<1),
- GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT = (1<<2),
- GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT = (1<<3),
- GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT = (1<<4),
- GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT = (1<<5),
- GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT = (1<<6),
- GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT = (1<<7),
- GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT = (1<<8),
- GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT = (1<<9),
- GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT = (1<<10),
- GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT = (1<<11),
- GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT = (1<<12),
- GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT = (1<<13),
-} GnssMeasurementsStateBits;
-
-typedef enum {
- GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_UNKNOWN = 0,
- GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT,
- GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT,
-} GnssMeasurementsMultipathIndicator;
-
-typedef uint32_t GnssMeasurementsClockFlagsMask;
-typedef enum {
- GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT = (1<<0),
- GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_BIT = (1<<1),
- GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT = (1<<2),
- GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT = (1<<3),
- GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT = (1<<4),
- GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT = (1<<5),
- GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT = (1<<6),
- GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT = (1<<7),
- GNSS_MEASUREMENTS_CLOCK_FLAGS_HW_CLOCK_DISCONTINUITY_COUNT_BIT = (1<<8),
-} GnssMeasurementsClockFlagsBits;
-
-typedef uint32_t GnssAidingDataSvMask;
-typedef enum {
- GNSS_AIDING_DATA_SV_EPHEMERIS_BIT = (1<<0), // ephemeris
- GNSS_AIDING_DATA_SV_ALMANAC_BIT = (1<<1), // almanac
- GNSS_AIDING_DATA_SV_HEALTH_BIT = (1<<2), // health
- GNSS_AIDING_DATA_SV_DIRECTION_BIT = (1<<3), // direction
- GNSS_AIDING_DATA_SV_STEER_BIT = (1<<4), // steer
- GNSS_AIDING_DATA_SV_ALMANAC_CORR_BIT = (1<<5), // almanac correction
- GNSS_AIDING_DATA_SV_BLACKLIST_BIT = (1<<6), // blacklist SVs
- GNSS_AIDING_DATA_SV_SA_DATA_BIT = (1<<7), // sensitivity assistance data
- GNSS_AIDING_DATA_SV_NO_EXIST_BIT = (1<<8), // SV does not exist
- GNSS_AIDING_DATA_SV_IONOSPHERE_BIT = (1<<9), // ionosphere correction
- GNSS_AIDING_DATA_SV_TIME_BIT = (1<<10),// reset satellite time
-} GnssAidingDataSvBits;
-
-typedef uint32_t GnssAidingDataSvTypeMask;
-typedef enum {
- GNSS_AIDING_DATA_SV_TYPE_GPS_BIT = (1<<0),
- GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT = (1<<1),
- GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT = (1<<2),
- GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT = (1<<3),
- GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT = (1<<4),
-} GnssAidingDataSvTypeBits;
+#ifndef LOCATIONAPI_H
+#define LOCATIONAPI_H
-typedef struct {
- GnssAidingDataSvMask svMask; // bitwise OR of GnssAidingDataSvBits
- GnssAidingDataSvTypeMask svTypeMask; // bitwise OR of GnssAidingDataSvTypeBits
-} GnssAidingDataSv;
-
-typedef uint32_t GnssAidingDataCommonMask;
-typedef enum {
- GNSS_AIDING_DATA_COMMON_POSITION_BIT = (1<<0), // position estimate
- GNSS_AIDING_DATA_COMMON_TIME_BIT = (1<<1), // reset all clock values
- GNSS_AIDING_DATA_COMMON_UTC_BIT = (1<<2), // UTC estimate
- GNSS_AIDING_DATA_COMMON_RTI_BIT = (1<<3), // RTI
- GNSS_AIDING_DATA_COMMON_FREQ_BIAS_EST_BIT = (1<<4), // frequency bias estimate
- GNSS_AIDING_DATA_COMMON_CELLDB_BIT = (1<<5), // all celldb info
-} GnssAidingDataCommonBits;
-
-typedef struct {
- GnssAidingDataCommonMask mask; // bitwise OR of GnssAidingDataCommonBits
-} GnssAidingDataCommon;
-
-typedef struct {
- bool deleteAll; // if true, delete all aiding data and ignore other params
- GnssAidingDataSv sv; // SV specific aiding data
- GnssAidingDataCommon common; // common aiding data
-} GnssAidingData;
-
-typedef struct {
- size_t size; // set to sizeof(Location)
- LocationFlagsMask flags; // bitwise OR of LocationFlagsBits to mark which params are valid
- uint64_t timestamp; // UTC timestamp for location fix, milliseconds since January 1, 1970
- double latitude; // in degrees
- double longitude; // in degrees
- double altitude; // in meters above the WGS 84 reference ellipsoid
- float speed; // in meters per second
- float bearing; // in degrees; range [0, 360)
- float accuracy; // in meters
- float verticalAccuracy; // in meters
- float speedAccuracy; // in meters/second
- float bearingAccuracy; // in degrees (0 to 359.999)
- LocationTechnologyMask techMask;
-} Location;
-
-typedef struct {
- size_t size; // set to sizeof(LocationOptions)
- uint32_t minInterval; // in milliseconds
- uint32_t minDistance; // in meters. if minDistance > 0, gnssSvCallback/gnssNmeaCallback/
- // gnssMeasurementsCallback may not be called
- GnssSuplMode mode; // Standalone/MS-Based/MS-Assisted
-} LocationOptions;
-
-typedef struct {
- size_t size;
- BatchingMode batchingMode;
-} BatchingOptions;
-
-typedef struct {
- size_t size;
- BatchingStatus batchingStatus;
-} BatchingStatusInfo;
-
-typedef struct {
- size_t size; // set to sizeof(GeofenceOption)
- GeofenceBreachTypeMask breachTypeMask; // bitwise OR of GeofenceBreachTypeBits
- uint32_t responsiveness; // in milliseconds
- uint32_t dwellTime; // in seconds
-} GeofenceOption;
-
-typedef struct {
- size_t size; // set to sizeof(GeofenceInfo)
- double latitude; // in degrees
- double longitude; // in degrees
- double radius; // in meters
-} GeofenceInfo;
-
-typedef struct {
- size_t size; // set to sizeof(GeofenceBreachNotification)
- size_t count; // number of ids in array
- uint32_t* ids; // array of ids that have breached
- Location location; // location associated with breach
- GeofenceBreachType type; // type of breach
- uint64_t timestamp; // timestamp of breach
-} GeofenceBreachNotification;
-
-typedef struct {
- size_t size; // set to sizeof(GeofenceBreachNotification)
- GeofenceStatusAvailable available; // GEOFENCE_STATUS_AVAILABILE_NO/_YES
- LocationTechnologyType techType; // GNSS
-} GeofenceStatusNotification;
-
-typedef struct {
- size_t size; // set to sizeof(GnssLocationInfo)
- GnssLocationInfoFlagMask flags; // bitwise OR of GnssLocationInfoBits for param validity
- float altitudeMeanSeaLevel; // altitude wrt mean sea level
- float pdop; // position dilusion of precision
- float hdop; // horizontal dilusion of precision
- float vdop; // vertical dilusion of precision
- float magneticDeviation; // magnetic deviation
- LocationReliability horReliability; // horizontal reliability
- LocationReliability verReliability; // vertical reliability
- float horUncEllipseSemiMajor; // horizontal elliptical accuracy semi-major axis
- float horUncEllipseSemiMinor; // horizontal elliptical accuracy semi-minor axis
- float horUncEllipseOrientAzimuth; // horizontal elliptical accuracy azimuth
-} GnssLocationInfoNotification;
-
-typedef struct {
- size_t size; // set to sizeof(GnssNiNotification)
- GnssNiType type; // type of NI (Voice, SUPL, Control Plane)
- GnssNiOptionsMask options; // bitwise OR of GnssNiOptionsBits
- uint32_t timeout; // time (seconds) to wait for user input
- GnssNiResponse timeoutResponse; // the response that should be sent when timeout expires
- char requestor[GNSS_NI_REQUESTOR_MAX]; // the requestor that is making the request
- GnssNiEncodingType requestorEncoding; // the encoding type for requestor
- char message[GNSS_NI_MESSAGE_ID_MAX]; // the message to show user
- GnssNiEncodingType messageEncoding; // the encoding type for message
- char extras[GNSS_NI_MESSAGE_ID_MAX];
-} GnssNiNotification;
+#include "ILocationAPI.h"
-typedef struct {
- size_t size; // set to sizeof(GnssSv)
- uint16_t svId; // Unique Identifier
- GnssSvType type; // type of SV (GPS, SBAS, GLONASS, QZSS, BEIDOU, GALILEO)
- float cN0Dbhz; // signal strength
- float elevation; // elevation of SV (in degrees)
- float azimuth; // azimuth of SV (in degrees)
- GnssSvOptionsMask gnssSvOptionsMask; // Bitwise OR of GnssSvOptionsBits
-} GnssSv;
-
-typedef struct {
- size_t size; // set to sizeof(GnssConfigSetAssistanceServer)
- GnssAssistanceType type; // SUPL or C2K
- const char* hostName; // null terminated string
- uint32_t port; // port of server
-} GnssConfigSetAssistanceServer;
-
-typedef struct {
- size_t size; // set to sizeof(GnssMeasurementsData)
- GnssMeasurementsDataFlagsMask flags; // bitwise OR of GnssMeasurementsDataFlagsBits
- int16_t svId;
- GnssSvType svType;
- double timeOffsetNs;
- GnssMeasurementsStateMask stateMask; // bitwise OR of GnssMeasurementsStateBits
- int64_t receivedSvTimeNs;
- int64_t receivedSvTimeUncertaintyNs;
- double carrierToNoiseDbHz;
- double pseudorangeRateMps;
- double pseudorangeRateUncertaintyMps;
- GnssMeasurementsAdrStateMask adrStateMask; // bitwise OR of GnssMeasurementsAdrStateBits
- double adrMeters;
- double adrUncertaintyMeters;
- float carrierFrequencyHz;
- int64_t carrierCycles;
- double carrierPhase;
- double carrierPhaseUncertainty;
- GnssMeasurementsMultipathIndicator multipathIndicator;
- double signalToNoiseRatioDb;
- double agcLevelDb;
-} GnssMeasurementsData;
-
-typedef struct {
- size_t size; // set to sizeof(GnssMeasurementsClock)
- GnssMeasurementsClockFlagsMask flags; // bitwise OR of GnssMeasurementsClockFlagsBits
- int16_t leapSecond;
- int64_t timeNs;
- double timeUncertaintyNs;
- int64_t fullBiasNs;
- double biasNs;
- double biasUncertaintyNs;
- double driftNsps;
- double driftUncertaintyNsps;
- uint32_t hwClockDiscontinuityCount;
-} GnssMeasurementsClock;
-
-typedef struct {
- size_t size; // set to sizeof(GnssSvNotification)
- size_t count; // number of SVs in the GnssSv array
- GnssSv gnssSvs[GNSS_SV_MAX]; // information on a number of SVs
-} GnssSvNotification;
-
-typedef struct {
- size_t size; // set to sizeof(GnssNmeaNotification)
- uint64_t timestamp; // timestamp
- const char* nmea; // nmea text
- size_t length; // length of the nmea text
-} GnssNmeaNotification;
-
-typedef struct {
- size_t size; // set to sizeof(GnssMeasurementsNotification)
- size_t count; // number of items in GnssMeasurements array
- GnssMeasurementsData measurements[GNSS_MEASUREMENTS_MAX];
- GnssMeasurementsClock clock; // clock
-} GnssMeasurementsNotification;
-
-typedef struct {
- size_t size; // set to sizeof(GnssConfig)
- GnssConfigFlagsMask flags; // bitwise OR of GnssConfigFlagsBits to mark which params are valid
- GnssConfigGpsLock gpsLock;
- GnssConfigSuplVersion suplVersion;
- GnssConfigSetAssistanceServer assistanceServer;
- GnssConfigLppProfile lppProfile;
- GnssConfigLppeControlPlaneMask lppeControlPlaneMask;
- GnssConfigLppeUserPlaneMask lppeUserPlaneMask;
- GnssConfigAGlonassPositionProtocolMask aGlonassPositionProtocolMask;
- GnssConfigEmergencyPdnForEmergencySupl emergencyPdnForEmergencySupl;
- GnssConfigSuplEmergencyServices suplEmergencyServices;
- GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits
-} GnssConfig;
-
-typedef struct {
- size_t size; // set to sizeof
- bool mValid;
- Location mLocation;
- double verticalAccuracyMeters;
- double speedAccuracyMetersPerSecond;
- double bearingAccuracyDegrees;
- timespec mUtcReported;
-} GnssDebugLocation;
-
-typedef struct {
- size_t size; // set to sizeof
- bool mValid;
- int64_t timeEstimate;
- float timeUncertaintyNs;
- float frequencyUncertaintyNsPerSec;
-} GnssDebugTime;
-
-typedef struct {
- size_t size; // set to sizeof
- uint32_t svid;
- GnssSvType constellation;
- GnssEphemerisType mEphemerisType;
- GnssEphemerisSource mEphemerisSource;
- GnssEphemerisHealth mEphemerisHealth;
- float ephemerisAgeSeconds;
- bool serverPredictionIsAvailable;
- float serverPredictionAgeSeconds;
-} GnssDebugSatelliteInfo;
-
-typedef struct {
- size_t size; // set to sizeof
- GnssDebugLocation mLocation;
- GnssDebugTime mTime;
- std::vector<GnssDebugSatelliteInfo> mSatelliteInfo;
-} GnssDebugReport;
-
-/* Provides the capabilities of the system
- capabilities callback is called once soon after createInstance is called */
-typedef std::function<void(
- LocationCapabilitiesMask capabilitiesMask // bitwise OR of LocationCapabilitiesBits
-)> capabilitiesCallback;
-
-/* Used by tracking, batching, and miscellanous APIs
- responseCallback is called for every Tracking, Batching API, and Miscellanous API */
-typedef std::function<void(
- LocationError err, // if not SUCCESS, then id is not valid
- uint32_t id // id to be associated to the request
-)> responseCallback;
-
-/* Used by APIs that gets more than one LocationError in it's response
- collectiveResponseCallback is called for every geofence API call.
- ids array and LocationError array are only valid until collectiveResponseCallback returns. */
-typedef std::function<void(
- size_t count, // number of locations in arrays
- LocationError* errs, // array of LocationError associated to the request
- uint32_t* ids // array of ids to be associated to the request
-)> collectiveResponseCallback;
-
-/* Used for startTracking API, optional can be NULL
- trackingCallback is called when delivering a location in a tracking session
- broadcasted to all clients, no matter if a session has started by client */
-typedef std::function<void(
- Location location
-)> trackingCallback;
-
-/* Used for startBatching API, optional can be NULL
- batchingCallback is called when delivering locations in a batching session.
- broadcasted to all clients, no matter if a session has started by client */
-typedef std::function<void(
- size_t count, // number of locations in array
- Location* location, // array of locations
- BatchingOptions batchingOptions // Batching options
-)> batchingCallback;
-
-typedef std::function<void(
- BatchingStatusInfo batchingStatus, // batch status
- std::list<uint32_t> & listOfCompletedTrips
-)> batchingStatusCallback;
-
-/* Gives GNSS Location information, optional can be NULL
- gnssLocationInfoCallback is called only during a tracking session
- broadcasted to all clients, no matter if a session has started by client */
-typedef std::function<void(
- GnssLocationInfoNotification gnssLocationInfoNotification
-)> gnssLocationInfoCallback;
-
-/* Used for addGeofences API, optional can be NULL
- geofenceBreachCallback is called when any number of geofences have a state change */
-typedef std::function<void(
- GeofenceBreachNotification geofenceBreachNotification
-)> geofenceBreachCallback;
-
-/* Used for addGeofences API, optional can be NULL
- geofenceStatusCallback is called when any number of geofences have a status change */
-typedef std::function<void(
- GeofenceStatusNotification geofenceStatusNotification
-)> geofenceStatusCallback;
-
-/* Network Initiated request, optional can be NULL
- This callback should be responded to by calling gnssNiResponse */
-typedef std::function<void(
- uint32_t id, // id that should be used to respond by calling gnssNiResponse
- GnssNiNotification gnssNiNotification
-)> gnssNiCallback;
-
-/* Gives GNSS SV information, optional can be NULL
- gnssSvCallback is called only during a tracking session
- broadcasted to all clients, no matter if a session has started by client */
-typedef std::function<void(
- GnssSvNotification gnssSvNotification
-)> gnssSvCallback;
-
-/* Gives GNSS NMEA data, optional can be NULL
- gnssNmeaCallback is called only during a tracking session
- broadcasted to all clients, no matter if a session has started by client */
-typedef std::function<void(
- GnssNmeaNotification gnssNmeaNotification
-)> gnssNmeaCallback;
-
-/* Gives GNSS Measurements information, optional can be NULL
- gnssMeasurementsCallback is called only during a tracking session
- broadcasted to all clients, no matter if a session has started by client */
-typedef std::function<void(
- GnssMeasurementsNotification gnssMeasurementsNotification
-)> gnssMeasurementsCallback;
-
-typedef struct {
- size_t size; // set to sizeof(LocationCallbacks)
- capabilitiesCallback capabilitiesCb; // mandatory
- responseCallback responseCb; // mandatory
- collectiveResponseCallback collectiveResponseCb; // mandatory
- trackingCallback trackingCb; // optional
- batchingCallback batchingCb; // optional
- geofenceBreachCallback geofenceBreachCb; // optional
- geofenceStatusCallback geofenceStatusCb; // optional
- gnssLocationInfoCallback gnssLocationInfoCb; // optional
- gnssNiCallback gnssNiCb; // optional
- gnssSvCallback gnssSvCb; // optional
- gnssNmeaCallback gnssNmeaCb; // optional
- gnssMeasurementsCallback gnssMeasurementsCb; // optional
- batchingStatusCallback batchingStatusCb; // optional
-} LocationCallbacks;
-
-class LocationAPI
+class LocationAPI : public ILocationAPI
{
private:
LocationAPI();
@@ -773,15 +43,21 @@ public:
of instances have been reached */
static LocationAPI* createInstance(LocationCallbacks&);
- /* destroy/cleans up the instance, which should be called when LocationAPI object is
- no longer needed. LocationAPI* returned from createInstance will no longer valid
- after destroy is called */
- void destroy();
+ /* destroy/cleans up the instance, which should be called when LocationControlAPI object is
+ no longer needed. LocationControlAPI* returned from createInstance will no longer valid
+ after destroy is called.
+ If the caller allocates the memory for LocationControlCallbacks used in
+ LocationControlAPI::createInstance, then the caller must ensure that the memory still remains
+ valid until destroyCompleteCb is invoked.
+ */
+ void destroy(locationApiDestroyCompleteCallback destroyCompleteCb=nullptr);
+
+ void onRemoveClientCompleteCb (LocationAdapterTypeMask adapterType);
/* updates/changes the callbacks that will be called.
mandatory callbacks must be present for callbacks to be successfully updated
no return value */
- void updateCallbacks(LocationCallbacks&);
+ virtual void updateCallbacks(LocationCallbacks&) override;
/* ================================== TRACKING ================================== */
@@ -793,21 +69,21 @@ public:
LOCATION_ERROR_SUCCESS if session was successfully started
LOCATION_ERROR_ALREADY_STARTED if a startTracking session is already in progress
LOCATION_ERROR_CALLBACK_MISSING if no trackingCallback was passed in createInstance
- LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameter is invalid */
- uint32_t startTracking(LocationOptions&); // returns session id
+ LOCATION_ERROR_INVALID_PARAMETER if TrackingOptions parameter is invalid */
+ virtual uint32_t startTracking(TrackingOptions&) override;
/* stopTracking stops a tracking session associated with id parameter.
responseCallback returns:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
- void stopTracking(uint32_t id);
+ virtual void stopTracking(uint32_t id) override;
- /* updateTrackingOptions changes the LocationOptions of a tracking session associated with id
+ /* updateTrackingOptions changes the TrackingOptions of a tracking session associated with id
responseCallback returns:
LOCATION_ERROR_SUCCESS if successful
- LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid
+ LOCATION_ERROR_INVALID_PARAMETER if TrackingOptions parameters are invalid
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a tracking session */
- void updateTrackingOptions(uint32_t id, LocationOptions&);
+ virtual void updateTrackingOptions(uint32_t id, TrackingOptions&) override;
/* ================================== BATCHING ================================== */
@@ -826,20 +102,20 @@ public:
LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback was passed in createInstance
LOCATION_ERROR_INVALID_PARAMETER if a parameter is invalid
LOCATION_ERROR_NOT_SUPPORTED if batching is not supported */
- uint32_t startBatching(LocationOptions&, BatchingOptions&); // returns session id
+ virtual uint32_t startBatching(BatchingOptions&) override;
/* stopBatching stops a batching session associated with id parameter.
responseCallback returns:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_ID_UNKNOWN if id is not associated with batching session */
- void stopBatching(uint32_t id);
+ virtual void stopBatching(uint32_t id) override;
- /* updateBatchingOptions changes the LocationOptions of a batching session associated with id
+ /* updateBatchingOptions changes the BatchingOptions of a batching session associated with id
responseCallback returns:
LOCATION_ERROR_SUCCESS if successful
- LOCATION_ERROR_INVALID_PARAMETER if LocationOptions parameters are invalid
+ LOCATION_ERROR_INVALID_PARAMETER if BatchingOptions parameters are invalid
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
- void updateBatchingOptions(uint32_t id, LocationOptions&, BatchingOptions&);
+ virtual void updateBatchingOptions(uint32_t id, BatchingOptions&) override;
/* getBatchedLocations gets a number of locations that are currently stored/batched
on the low power processor, delivered by the batchingCallback passed in createInstance.
@@ -848,7 +124,7 @@ public:
LOCATION_ERROR_SUCCESS if successful, will be followed by batchingCallback call
LOCATION_ERROR_CALLBACK_MISSING if no batchingCallback was passed in createInstance
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a batching session */
- void getBatchedLocations(uint32_t id, size_t count);
+ virtual void getBatchedLocations(uint32_t id, size_t count) override;
/* ================================== GEOFENCE ================================== */
@@ -862,14 +138,14 @@ public:
LOCATION_ERROR_CALLBACK_MISSING if no geofenceBreachCallback
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
LOCATION_ERROR_NOT_SUPPORTED if geofence is not supported */
- uint32_t* addGeofences(size_t count, GeofenceOption*, GeofenceInfo*); // returns id array
+ virtual uint32_t* addGeofences(size_t count, GeofenceOption*, GeofenceInfo*) override;
/* removeGeofences removes any number of geofences. Caller should delete ids array after
removeGeofences returneds.
collectiveResponseCallback returns:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
- void removeGeofences(size_t count, uint32_t* ids);
+ virtual void removeGeofences(size_t count, uint32_t* ids) override;
/* modifyGeofences modifies any number of geofences. Caller should delete ids array after
modifyGeofences returns.
@@ -877,7 +153,7 @@ public:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid */
- void modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options);
+ virtual void modifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options) override;
/* pauseGeofences pauses any number of geofences, which is similar to removeGeofences,
only that they can be resumed at any time. Caller should delete ids array after
@@ -885,14 +161,14 @@ public:
collectiveResponseCallback returns:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
- void pauseGeofences(size_t count, uint32_t* ids);
+ virtual void pauseGeofences(size_t count, uint32_t* ids) override;
/* resumeGeofences resumes any number of geofences that are currently paused. Caller should
delete ids array after resumeGeofences returns.
collectiveResponseCallback returns:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_ID_UNKNOWN if id is not associated with a geofence session */
- void resumeGeofences(size_t count, uint32_t* ids);
+ virtual void resumeGeofences(size_t count, uint32_t* ids) override;
/* ================================== GNSS ====================================== */
@@ -901,16 +177,17 @@ public:
LOCATION_ERROR_SUCCESS if session was successful
LOCATION_ERROR_INVALID_PARAMETER if any parameters in GnssNiResponse are invalid
LOCATION_ERROR_ID_UNKNOWN if id does not match a gnssNiCallback */
- void gnssNiResponse(uint32_t id, GnssNiResponse response);
+ virtual void gnssNiResponse(uint32_t id, GnssNiResponse response) override;
};
typedef struct {
size_t size; // set to sizeof(LocationControlCallbacks)
responseCallback responseCb; // mandatory
collectiveResponseCallback collectiveResponseCb; // mandatory
+ gnssConfigCallback gnssConfigCb; // optional
} LocationControlCallbacks;
-class LocationControlAPI
+class LocationControlAPI : public ILocationControlAPI
{
private:
LocationControlAPI();
@@ -959,7 +236,22 @@ public:
LOCATION_ERROR_SUCCESS if session was successful
LOCATION_ERROR_INVALID_PARAMETER if any other parameters are invalid
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
- uint32_t* gnssUpdateConfig(GnssConfig config);
+ virtual uint32_t* gnssUpdateConfig(GnssConfig config) override;
+
+ /* gnssGetConfig fetches the current constellation and SV configuration
+ on the GNSS engine.
+ Returns a session id array with an id for each of the bits set in
+ the mask parameter, order from low bits to high bits.
+ Response is sent via the registered gnssConfigCallback.
+ This effect is global for all clients of LocationAPI
+ collectiveResponseCallback returns:
+ LOCATION_ERROR_SUCCESS if session was successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameter is invalid
+ LOCATION_ERROR_CALLBACK_MISSING If no gnssConfigCallback
+ was passed in createInstance
+ LOCATION_ERROR_NOT_SUPPORTED If read of requested configuration
+ is not supported */
+ uint32_t* gnssGetConfig(GnssConfigFlagsMask mask);
/* delete specific gnss aiding data for testing, which returns a session id
that will be returned in responseCallback to match command with response.
@@ -968,7 +260,7 @@ public:
LOCATION_ERROR_SUCCESS if successful
LOCATION_ERROR_INVALID_PARAMETER if any parameters are invalid
LOCATION_ERROR_NOT_SUPPORTED if build is not userdebug */
- uint32_t gnssDeleteAidingData(GnssAidingData& data);
+ virtual uint32_t gnssDeleteAidingData(GnssAidingData& data) override;
};
-#endif /* LOCATION_H */
+#endif /* LOCATIONAPI_H */
diff --git a/gps/location/LocationAPIClientBase.cpp b/gps/location/LocationAPIClientBase.cpp
index 626968c..5a09712 100644
--- a/gps/location/LocationAPIClientBase.cpp
+++ b/gps/location/LocationAPIClientBase.cpp
@@ -26,7 +26,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define LOG_NDDEBUG 0
+#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_APIClientBase"
#include <loc_pla.h>
@@ -45,7 +45,7 @@ LocationAPIControlClient::LocationAPIControlClient() :
pthread_mutex_init(&mMutex, nullptr);
for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
- mRequestQueues[i].reset(0);
+ mRequestQueues[i].reset((uint32_t)0);
}
memset(&mConfig, 0, sizeof(GnssConfig));
@@ -75,7 +75,7 @@ LocationAPIControlClient::~LocationAPIControlClient()
}
for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
- mRequestQueues[i].reset(0);
+ mRequestQueues[i].reset((uint32_t)0);
}
pthread_mutex_unlock(&mMutex);
@@ -142,24 +142,43 @@ void LocationAPIControlClient::locAPIDisable()
uint32_t LocationAPIControlClient::locAPIGnssUpdateConfig(GnssConfig config)
{
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
- if (memcmp(&mConfig, &config, sizeof(GnssConfig)) == 0) {
- LOC_LOGV("%s:%d] GnssConfig is identical to previous call", __FUNCTION__, __LINE__);
- retVal = LOCATION_ERROR_SUCCESS;
- return retVal;
- }
pthread_mutex_lock(&mMutex);
if (mLocationControlAPI) {
+ if (mConfig.equals(config)) {
+ LOC_LOGv("GnssConfig is identical to previous call");
+ retVal = LOCATION_ERROR_SUCCESS;
+ } else {
+ mConfig = config;
+ uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
+ LOC_LOGv("gnssUpdateConfig return array: %p", idArray);
+ if (nullptr != idArray) {
+ if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr()) {
+ mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].reset(idArray);
+ }
+ mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].push(new GnssUpdateConfigRequest(*this));
+ retVal = LOCATION_ERROR_SUCCESS;
+ }
+ }
+ }
+ pthread_mutex_unlock(&mMutex);
+ return retVal;
+}
- memcpy(&mConfig, &config, sizeof(GnssConfig));
+uint32_t LocationAPIControlClient::locAPIGnssGetConfig(GnssConfigFlagsMask mask)
+{
+ uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
+
+ pthread_mutex_lock(&mMutex);
+ if (mLocationControlAPI) {
- uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
- LOC_LOGV("%s:%d] gnssUpdateConfig return array: %p", __FUNCTION__, __LINE__, idArray);
- if (idArray != nullptr) {
- if (mRequestQueues[CTRL_REQUEST_CONFIG].getSession() != CONFIG_SESSION_ID) {
- mRequestQueues[CTRL_REQUEST_CONFIG].reset(CONFIG_SESSION_ID);
+ uint32_t* idArray = mLocationControlAPI->gnssGetConfig(mask);
+ LOC_LOGv("gnssGetConfig return array: %p", idArray);
+ if (nullptr != idArray) {
+ if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr()) {
+ mRequestQueues[CTRL_REQUEST_CONFIG_GET].reset(idArray);
}
- mRequestQueues[CTRL_REQUEST_CONFIG].push(new GnssUpdateConfigRequest(*this));
+ mRequestQueues[CTRL_REQUEST_CONFIG_GET].push(new GnssGetConfigRequest(*this));
retVal = LOCATION_ERROR_SUCCESS;
}
}
@@ -191,12 +210,7 @@ void LocationAPIControlClient::onCtrlCollectiveResponseCb(
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
}
}
- LocationAPIRequest* request = nullptr;
- pthread_mutex_lock(&mMutex);
- if (mRequestQueues[CTRL_REQUEST_CONFIG].getSession() == CONFIG_SESSION_ID) {
- request = mRequestQueues[CTRL_REQUEST_CONFIG].pop();
- }
- pthread_mutex_unlock(&mMutex);
+ LocationAPIRequest* request = getRequestBySessionArrayPtr(ids);
if (request) {
request->onCollectiveResponse(count, errors, ids);
delete request;
@@ -207,13 +221,30 @@ LocationAPIRequest* LocationAPIControlClient::getRequestBySession(uint32_t sessi
{
pthread_mutex_lock(&mMutex);
LocationAPIRequest* request = nullptr;
- for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
- if (i != CTRL_REQUEST_CONFIG &&
- mRequestQueues[i].getSession() == session) {
- request = mRequestQueues[i].pop();
- break;
- }
+
+ if (mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].getSession() == session) {
+ request = mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].pop();
+ } else if (mRequestQueues[CTRL_REQUEST_CONTROL].getSession() == session) {
+ request = mRequestQueues[CTRL_REQUEST_CONTROL].pop();
}
+
+ pthread_mutex_unlock(&mMutex);
+ return request;
+}
+
+LocationAPIRequest*
+LocationAPIControlClient::getRequestBySessionArrayPtr(
+ uint32_t* sessionArrayPtr)
+{
+ pthread_mutex_lock(&mMutex);
+ LocationAPIRequest* request = nullptr;
+
+ if (mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr() == sessionArrayPtr) {
+ request = mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].pop();
+ } else if (mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr() == sessionArrayPtr) {
+ request = mRequestQueues[CTRL_REQUEST_CONFIG_GET].pop();
+ }
+
pthread_mutex_unlock(&mMutex);
return request;
}
@@ -234,7 +265,7 @@ LocationAPIClientBase::LocationAPIClientBase() :
pthread_mutex_init(&mMutex, &attr);
for (int i = 0; i < REQUEST_MAX; i++) {
- mRequestQueues[i].reset(0);
+ mRequestQueues[i].reset((uint32_t)0);
}
}
@@ -291,7 +322,7 @@ LocationAPIClientBase::~LocationAPIClientBase()
}
for (int i = 0; i < REQUEST_MAX; i++) {
- mRequestQueues[i].reset(0);
+ mRequestQueues[i].reset((uint32_t)0);
}
pthread_mutex_unlock(&mMutex);
@@ -299,7 +330,7 @@ LocationAPIClientBase::~LocationAPIClientBase()
pthread_mutex_destroy(&mMutex);
}
-uint32_t LocationAPIClientBase::locAPIStartTracking(LocationOptions& options)
+uint32_t LocationAPIClientBase::locAPIStartTracking(TrackingOptions& options)
{
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
pthread_mutex_lock(&mMutex);
@@ -335,13 +366,13 @@ void LocationAPIClientBase::locAPIStopTracking()
mLocationAPI->stopTracking(session);
mTracking = false;
} else {
- LOC_LOGE("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
+ LOC_LOGD("%s:%d] invalid session: %d.", __FUNCTION__, __LINE__, session);
}
}
pthread_mutex_unlock(&mMutex);
}
-void LocationAPIClientBase::locAPIUpdateTrackingOptions(LocationOptions& options)
+void LocationAPIClientBase::locAPIUpdateTrackingOptions(TrackingOptions& options)
{
pthread_mutex_lock(&mMutex);
if (mLocationAPI) {
@@ -373,9 +404,8 @@ int32_t LocationAPIClientBase::locAPIGetBatchSize()
return mBatchSize;
}
-
-uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t sessionMode,
- LocationOptions& locationOptions)
+uint32_t LocationAPIClientBase::locAPIStartSession(
+ uint32_t id, uint32_t sessionMode, TrackingOptions&& options)
{
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
pthread_mutex_lock(&mMutex);
@@ -389,7 +419,7 @@ uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t session
uint32_t batchingSession = 0;
if (sessionMode == SESSION_MODE_ON_FIX) {
- trackingSession = mLocationAPI->startTracking(locationOptions);
+ trackingSession = mLocationAPI->startTracking(options);
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, trackingSession);
mRequestQueues[REQUEST_SESSION].push(new StartTrackingRequest(*this));
} else {
@@ -408,7 +438,12 @@ uint32_t LocationAPIClientBase::locAPIStartSession(uint32_t id, uint32_t session
break;
}
- batchingSession = mLocationAPI->startBatching(locationOptions, batchOptions);
+ // Populate location option values
+ batchOptions.minDistance = options.minDistance;
+ batchOptions.minInterval = options.minInterval;
+ batchOptions.mode = options.mode;
+
+ batchingSession = mLocationAPI->startBatching(batchOptions);
LOC_LOGI("%s:%d] start new session: %d", __FUNCTION__, __LINE__, batchingSession);
mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
mRequestQueues[REQUEST_SESSION].push(new StartBatchingRequest(*this));
@@ -465,8 +500,8 @@ uint32_t LocationAPIClientBase::locAPIStopSession(uint32_t id)
return retVal;
}
-uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode,
- LocationOptions& options)
+uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(
+ uint32_t id, uint32_t sessionMode, TrackingOptions&& options)
{
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
pthread_mutex_lock(&mMutex);
@@ -523,13 +558,18 @@ uint32_t LocationAPIClientBase::locAPIUpdateSessionOptions(uint32_t id, uint32_t
mLocationAPI->stopTracking(trackingSession);
trackingSession = 0;
+ // Populate location option values
+ batchOptions.minDistance = options.minDistance;
+ batchOptions.minInterval = options.minInterval;
+ batchOptions.mode = options.mode;
+
// start batching
- batchingSession = mLocationAPI->startBatching(options, batchOptions);
+ batchingSession = mLocationAPI->startBatching(batchOptions);
LOC_LOGI("%s:%d] start new session: %d",
__FUNCTION__, __LINE__, batchingSession);
mRequestQueues[REQUEST_SESSION].setSession(batchingSession);
} else {
- mLocationAPI->updateBatchingOptions(batchingSession, options, batchOptions);
+ mLocationAPI->updateBatchingOptions(batchingSession, batchOptions);
}
}
diff --git a/gps/location/LocationAPIClientBase.h b/gps/location/LocationAPIClientBase.h
index 4bd1466..098000c 100644
--- a/gps/location/LocationAPIClientBase.h
+++ b/gps/location/LocationAPIClientBase.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019 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
@@ -57,7 +57,8 @@ enum REQUEST_TYPE {
enum CTRL_REQUEST_TYPE {
CTRL_REQUEST_DELETEAIDINGDATA = 0,
CTRL_REQUEST_CONTROL,
- CTRL_REQUEST_CONFIG,
+ CTRL_REQUEST_CONFIG_UPDATE,
+ CTRL_REQUEST_CONFIG_GET,
CTRL_REQUEST_MAX,
};
@@ -74,12 +75,13 @@ public:
class RequestQueue {
public:
- RequestQueue(): mSession(0) {
+ RequestQueue(): mSession(0), mSessionArrayPtr(nullptr) {
}
virtual ~RequestQueue() {
- reset(0);
+ reset((uint32_t)0);
}
void inline setSession(uint32_t session) { mSession = session; }
+ void inline setSessionArrayPtr(uint32_t* ptr) { mSessionArrayPtr = ptr; }
void reset(uint32_t session) {
LocationAPIRequest* request = nullptr;
while (!mQueue.empty()) {
@@ -89,6 +91,10 @@ public:
}
mSession = session;
}
+ void reset(uint32_t* sessionArrayPtr) {
+ reset((uint32_t)0);
+ mSessionArrayPtr = sessionArrayPtr;
+ }
void push(LocationAPIRequest* request) {
mQueue.push(request);
}
@@ -101,8 +107,10 @@ public:
return request;
}
uint32_t getSession() { return mSession; }
+ uint32_t* getSessionArrayPtr() { return mSessionArrayPtr; }
private:
uint32_t mSession;
+ uint32_t* mSessionArrayPtr;
std::queue<LocationAPIRequest*> mQueue;
};
@@ -114,12 +122,15 @@ public:
LocationAPIControlClient& operator=(const LocationAPIControlClient&) = delete;
LocationAPIRequest* getRequestBySession(uint32_t session);
+ LocationAPIRequest* getRequestBySessionArrayPtr(uint32_t* sessionArrayPtr);
// LocationControlAPI
uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data);
uint32_t locAPIEnable(LocationTechnologyType techType);
void locAPIDisable();
uint32_t locAPIGnssUpdateConfig(GnssConfig config);
+ uint32_t locAPIGnssGetConfig(GnssConfigFlagsMask config);
+ inline LocationControlAPI* getControlAPI() { return mLocationControlAPI; }
// callbacks
void onCtrlResponseCb(LocationError error, uint32_t id);
@@ -130,6 +141,8 @@ public:
inline virtual void onDisableCb(LocationError /*error*/) {}
inline virtual void onGnssUpdateConfigCb(
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
+ inline virtual void onGnssGetConfigCb(
+ size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
class GnssDeleteAidingDataRequest : public LocationAPIRequest {
public:
@@ -167,6 +180,15 @@ public:
LocationAPIControlClient& mAPI;
};
+ class GnssGetConfigRequest : public LocationAPIRequest {
+ public:
+ GnssGetConfigRequest(LocationAPIControlClient& API) : mAPI(API) {}
+ inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) {
+ mAPI.onGnssGetConfigCb(count, errors, ids);
+ }
+ LocationAPIControlClient& mAPI;
+ };
+
private:
pthread_mutex_t mMutex;
LocationControlAPI* mLocationControlAPI;
@@ -187,16 +209,16 @@ public:
LocationAPIRequest* getRequestBySession(uint32_t session);
// LocationAPI
- uint32_t locAPIStartTracking(LocationOptions& options);
+ uint32_t locAPIStartTracking(TrackingOptions& trackingOptions);
void locAPIStopTracking();
- void locAPIUpdateTrackingOptions(LocationOptions& options);
+ void locAPIUpdateTrackingOptions(TrackingOptions& trackingOptions);
int32_t locAPIGetBatchSize();
- uint32_t locAPIStartSession(uint32_t id, uint32_t sessionMode,
- LocationOptions& options);
+ uint32_t locAPIStartSession(
+ uint32_t id, uint32_t sessionMode, TrackingOptions&& trackingOptions);
uint32_t locAPIStopSession(uint32_t id);
- uint32_t locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode,
- LocationOptions& options);
+ uint32_t locAPIUpdateSessionOptions(
+ uint32_t id, uint32_t sessionMode, TrackingOptions&& trackingOptions);
uint32_t locAPIGetBatchedLocations(uint32_t id, size_t count);
uint32_t locAPIAddGeofences(size_t count, uint32_t* ids,
@@ -217,6 +239,7 @@ public:
inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {}
inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {}
+ inline virtual void onGnssDataCb(GnssDataNotification /*gnssDataNotification*/) {}
inline virtual void onGnssMeasurementsCb(
GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {}
@@ -258,6 +281,8 @@ public:
inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {}
inline virtual void onGnssNiResponseCb(LocationError /*error*/) {}
+ inline virtual void onLocationSystemInfoCb(LocationSystemInfo /*locationSystemInfo*/) {}
+
private:
// private inner classes
typedef struct {
@@ -463,6 +488,7 @@ private:
for (size_t i = 0; i < count; i++) {
ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
}
+ LOC_LOGD("%s:]Returned geofence-id: %d in add geofence", __FUNCTION__, *ids);
mAPI.onAddGeofencesCb(count, errors, ids);
free(ids);
}
@@ -480,6 +506,7 @@ private:
for (size_t i = 0; i < count; i++) {
ids[i] = mRemovedGeofenceBiDict->getId(sessions[i]);
}
+ LOC_LOGD("%s:]Returned geofence-id: %d in remove geofence", __FUNCTION__, *ids);
mAPI.onRemoveGeofencesCb(count, errors, ids);
free(ids);
delete(mRemovedGeofenceBiDict);
diff --git a/gps/location/LocationDataTypes.h b/gps/location/LocationDataTypes.h
new file mode 100644
index 0000000..17094ab
--- /dev/null
+++ b/gps/location/LocationDataTypes.h
@@ -0,0 +1,1465 @@
+/* Copyright (c) 2018-2019 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 LOCATIONDATATYPES_H
+#define LOCATIONDATATYPES_H
+
+#include <vector>
+#include <stdint.h>
+#include <functional>
+#include <list>
+#include <string.h>
+
+#define GNSS_NI_REQUESTOR_MAX (256)
+#define GNSS_NI_MESSAGE_ID_MAX (2048)
+#define GNSS_SV_MAX (176)
+#define GNSS_MEASUREMENTS_MAX (128)
+#define GNSS_UTC_TIME_OFFSET (3657)
+
+#define GNSS_BUGREPORT_GPS_MIN (1)
+#define GNSS_BUGREPORT_SBAS_MIN (120)
+#define GNSS_BUGREPORT_GLO_MIN (1)
+#define GNSS_BUGREPORT_QZSS_MIN (193)
+#define GNSS_BUGREPORT_BDS_MIN (1)
+#define GNSS_BUGREPORT_GAL_MIN (1)
+#define GNSS_BUGREPORT_NAVIC_MIN (1)
+
+#define GNSS_MAX_NAME_LENGTH (8)
+
+typedef enum {
+ LOCATION_ERROR_SUCCESS = 0,
+ LOCATION_ERROR_GENERAL_FAILURE,
+ LOCATION_ERROR_CALLBACK_MISSING,
+ LOCATION_ERROR_INVALID_PARAMETER,
+ LOCATION_ERROR_ID_EXISTS,
+ LOCATION_ERROR_ID_UNKNOWN,
+ LOCATION_ERROR_ALREADY_STARTED,
+ LOCATION_ERROR_GEOFENCES_AT_MAX,
+ LOCATION_ERROR_NOT_SUPPORTED
+} LocationError;
+
+// Flags to indicate which values are valid in a Location
+typedef uint16_t LocationFlagsMask;
+typedef enum {
+ LOCATION_HAS_LAT_LONG_BIT = (1<<0), // location has valid latitude and longitude
+ LOCATION_HAS_ALTITUDE_BIT = (1<<1), // location has valid altitude
+ LOCATION_HAS_SPEED_BIT = (1<<2), // location has valid speed
+ LOCATION_HAS_BEARING_BIT = (1<<3), // location has valid bearing
+ LOCATION_HAS_ACCURACY_BIT = (1<<4), // location has valid accuracy
+ LOCATION_HAS_VERTICAL_ACCURACY_BIT = (1<<5), // location has valid vertical accuracy
+ LOCATION_HAS_SPEED_ACCURACY_BIT = (1<<6), // location has valid speed accuracy
+ LOCATION_HAS_BEARING_ACCURACY_BIT = (1<<7), // location has valid bearing accuracy
+ LOCATION_HAS_SPOOF_MASK = (1<<8), // location has valid spoof mask
+} LocationFlagsBits;
+
+typedef uint16_t LocationTechnologyMask;
+typedef enum {
+ LOCATION_TECHNOLOGY_GNSS_BIT = (1<<0), // location was calculated using GNSS
+ LOCATION_TECHNOLOGY_CELL_BIT = (1<<1), // location was calculated using Cell
+ LOCATION_TECHNOLOGY_WIFI_BIT = (1<<2), // location was calculated using WiFi
+ LOCATION_TECHNOLOGY_SENSORS_BIT = (1<<3), // location was calculated using Sensors
+} LocationTechnologyBits;
+
+typedef uint32_t LocationSpoofMask;
+typedef enum {
+ LOCATION_POSTION_SPOOFED = (1<<0), // location position spoofed
+ LOCATION_TIME_SPOOFED = (1<<1), // location time spoofed
+ LOCATION_NAVIGATION_DATA_SPOOFED = (1<<2), // location navigation data spoofed
+} LocationSpoofBits;
+
+typedef enum {
+ LOCATION_RELIABILITY_NOT_SET = 0,
+ LOCATION_RELIABILITY_VERY_LOW,
+ LOCATION_RELIABILITY_LOW,
+ LOCATION_RELIABILITY_MEDIUM,
+ LOCATION_RELIABILITY_HIGH,
+} LocationReliability;
+
+typedef uint32_t GnssLocationNavSolutionMask;
+typedef enum {
+ LOCATION_SBAS_CORRECTION_IONO_BIT = (1<<0), // SBAS ionospheric correction is used
+ LOCATION_SBAS_CORRECTION_FAST_BIT = (1<<1), // SBAS fast correction is used
+ LOCATION_SBAS_CORRECTION_LONG_BIT = (1<<2), // SBAS long-tem correction is used
+ LOCATION_SBAS_INTEGRITY_BIT = (1<<3), // SBAS integrity information is used
+ LOCATION_NAV_CORRECTION_DGNSS_BIT = (1<<4), // Position Report is DGNSS corrected
+ LOCATION_NAV_CORRECTION_RTK_BIT = (1<<5), // Position Report is RTK corrected
+ LOCATION_NAV_CORRECTION_PPP_BIT = (1<<6) // Position Report is PPP corrected
+} GnssLocationNavSolutionBits;
+
+typedef uint32_t GnssLocationPosTechMask;
+typedef enum {
+ LOCATION_POS_TECH_DEFAULT_BIT = 0,
+ LOCATION_POS_TECH_SATELLITE_BIT = (1<<0),
+ LOCATION_POS_TECH_CELLID_BIT = (1<<1),
+ LOCATION_POS_TECH_WIFI_BIT = (1<<2),
+ LOCATION_POS_TECH_SENSORS_BIT = (1<<3),
+ LOCATION_POS_TECH_REFERENCE_LOCATION_BIT = (1<<4),
+ LOCATION_POS_TECH_INJECTED_COARSE_POSITION_BIT = (1<<5),
+ LOCATION_POS_TECH_AFLT_BIT = (1<<6),
+ LOCATION_POS_TECH_HYBRID_BIT = (1<<7),
+ LOCATION_POS_TECH_PPE_BIT = (1<<8)
+} GnssLocationPosTechBits;
+
+typedef uint32_t GnssLocationPosDataMask;
+typedef enum {
+ LOCATION_NAV_DATA_HAS_LONG_ACCEL_BIT = (1<<0), // Navigation data has Forward Acceleration
+ LOCATION_NAV_DATA_HAS_LAT_ACCEL_BIT = (1<<1), // Navigation data has Sideward Acceleration
+ LOCATION_NAV_DATA_HAS_VERT_ACCEL_BIT = (1<<2), // Navigation data has Vertical Acceleration
+ LOCATION_NAV_DATA_HAS_YAW_RATE_BIT = (1<<3), // Navigation data has Heading Rate
+ LOCATION_NAV_DATA_HAS_PITCH_BIT = (1<<4), // Navigation data has Body pitch
+ // Navigation data has Forward Acceleration uncertainty
+ LOCATION_NAV_DATA_HAS_LONG_ACCEL_UNC_BIT = (1<<5),
+ // Navigation data has Sideward Acceleration uncertainty
+ LOCATION_NAV_DATA_HAS_LAT_ACCEL_UNC_BIT = (1<<6),
+ // Navigation data has Vertical Acceleration uncertainty
+ LOCATION_NAV_DATA_HAS_VERT_ACCEL_UNC_BIT = (1<<7),
+ // Navigation data has Heading Rate uncertainty
+ LOCATION_NAV_DATA_HAS_YAW_RATE_UNC_BIT = (1<<8),
+ // Navigation data has Body pitch uncertainty
+ LOCATION_NAV_DATA_HAS_PITCH_UNC_BIT = (1<<9)
+} GnssLocationPosDataBits;
+
+typedef uint32_t GnssLocationInfoFlagMask;
+typedef enum {
+ GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT = (1<<0), // valid altitude mean sea level
+ GNSS_LOCATION_INFO_DOP_BIT = (1<<1), // valid pdop, hdop, and vdop
+ GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT = (1<<2), // valid magnetic deviation
+ GNSS_LOCATION_INFO_HOR_RELIABILITY_BIT = (1<<3), // valid horizontal reliability
+ GNSS_LOCATION_INFO_VER_RELIABILITY_BIT = (1<<4), // valid vertical reliability
+ GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT = (1<<5), // valid elipsode semi major
+ GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT = (1<<6), // valid elipsode semi minor
+ GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT = (1<<7), // valid accuracy elipsode azimuth
+ GNSS_LOCATION_INFO_GNSS_SV_USED_DATA_BIT = (1<<8), // valid svUsedInPosition,
+ // numOfMeasReceived
+ // and measUsageInfo
+ GNSS_LOCATION_INFO_NAV_SOLUTION_MASK_BIT = (1<<9), // valid navSolutionMask
+ GNSS_LOCATION_INFO_POS_TECH_MASK_BIT = (1<<10),// valid LocPosTechMask
+ GNSS_LOCATION_INFO_SV_SOURCE_INFO_BIT = (1<<11),// valid LocSvInfoSource
+ GNSS_LOCATION_INFO_POS_DYNAMICS_DATA_BIT = (1<<12),// valid position dynamics data
+ GNSS_LOCATION_INFO_EXT_DOP_BIT = (1<<13),// valid gdop, tdop
+ GNSS_LOCATION_INFO_NORTH_STD_DEV_BIT = (1<<14),// valid North standard deviation
+ GNSS_LOCATION_INFO_EAST_STD_DEV_BIT = (1<<15),// valid East standard deviation
+ GNSS_LOCATION_INFO_NORTH_VEL_BIT = (1<<16),// valid North Velocity
+ GNSS_LOCATION_INFO_EAST_VEL_BIT = (1<<17),// valid East Velocity
+ GNSS_LOCATION_INFO_UP_VEL_BIT = (1<<18),// valid Up Velocity
+ GNSS_LOCATION_INFO_NORTH_VEL_UNC_BIT = (1<<19),// valid North Velocity Uncertainty
+ GNSS_LOCATION_INFO_EAST_VEL_UNC_BIT = (1<<20),// valid East Velocity Uncertainty
+ GNSS_LOCATION_INFO_UP_VEL_UNC_BIT = (1<<21),// valid Up Velocity Uncertainty
+ GNSS_LOCATION_INFO_LEAP_SECONDS_BIT = (1<<22),// valid leap seconds
+ GNSS_LOCATION_INFO_TIME_UNC_BIT = (1<<23),// valid time uncertainty
+ GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT = (1<<24), // number of SV used in position
+ GNSS_LOCATION_INFO_CALIBRATION_CONFIDENCE_BIT = (1<<25), // valid sensor cal confidence
+ GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT = (1<<26), // valid sensor cal status
+ GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT = (1<<27), // valid output engine type
+ GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT = (1<<28), // valid output engine mask
+} GnssLocationInfoFlagBits;
+
+typedef enum {
+ GEOFENCE_BREACH_ENTER = 0,
+ GEOFENCE_BREACH_EXIT,
+ GEOFENCE_BREACH_DWELL_IN,
+ GEOFENCE_BREACH_DWELL_OUT,
+ GEOFENCE_BREACH_UNKNOWN,
+} GeofenceBreachType;
+
+typedef uint16_t GeofenceBreachTypeMask;
+typedef enum {
+ GEOFENCE_BREACH_ENTER_BIT = (1<<0),
+ GEOFENCE_BREACH_EXIT_BIT = (1<<1),
+ GEOFENCE_BREACH_DWELL_IN_BIT = (1<<2),
+ GEOFENCE_BREACH_DWELL_OUT_BIT = (1<<3),
+} GeofenceBreachTypeBits;
+
+typedef enum {
+ GEOFENCE_STATUS_AVAILABILE_NO = 0,
+ GEOFENCE_STATUS_AVAILABILE_YES,
+} GeofenceStatusAvailable;
+
+typedef uint32_t LocationCapabilitiesMask;
+typedef enum {
+ // supports startTracking API with minInterval param
+ LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT = (1<<0),
+ // supports startBatching API with minInterval param
+ LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT = (1<<1),
+ // supports startTracking API with minDistance param
+ LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT = (1<<2),
+ // supports startBatching API with minDistance param
+ LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT = (1<<3),
+ // supports addGeofences API
+ LOCATION_CAPABILITIES_GEOFENCE_BIT = (1<<4),
+ // supports GnssMeasurementsCallback
+ LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT = (1<<5),
+ // supports startTracking/startBatching API with LocationOptions.mode of MSB (Ms Based)
+ LOCATION_CAPABILITIES_GNSS_MSB_BIT = (1<<6),
+ // supports startTracking/startBatching API with LocationOptions.mode of MSA (MS Assisted)
+ LOCATION_CAPABILITIES_GNSS_MSA_BIT = (1<<7),
+ // supports debug nmea sentences in the debugNmeaCallback
+ LOCATION_CAPABILITIES_DEBUG_NMEA_BIT = (1<<8),
+ // support outdoor trip batching
+ LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT = (1<<9),
+ // support constellation enablement
+ LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT = (1<<10),
+ // support agpm
+ LOCATION_CAPABILITIES_AGPM_BIT = (1<<11),
+ // support location privacy
+ LOCATION_CAPABILITIES_PRIVACY_BIT = (1<<12),
+} LocationCapabilitiesBits;
+
+typedef enum {
+ LOCATION_TECHNOLOGY_TYPE_GNSS = 0,
+} LocationTechnologyType;
+
+// Configures how GPS is locked when GPS is disabled (through GnssDisable)
+enum {
+ GNSS_CONFIG_GPS_LOCK_NONE = 0, // gps is not locked when GPS is disabled (GnssDisable)
+ GNSS_CONFIG_GPS_LOCK_MO, // gps mobile originated (MO) is locked when GPS is disabled
+ GNSS_CONFIG_GPS_LOCK_NI, // gps network initiated (NI) is locked when GPS is disabled
+ GNSS_CONFIG_GPS_LOCK_MO_AND_NI,// gps MO and NI is locked when GPS is disabled
+};
+typedef int32_t GnssConfigGpsLock;
+
+// SUPL version
+typedef enum {
+ GNSS_CONFIG_SUPL_VERSION_1_0_0 = 1,
+ GNSS_CONFIG_SUPL_VERSION_2_0_0,
+ GNSS_CONFIG_SUPL_VERSION_2_0_2,
+} GnssConfigSuplVersion;
+
+// LTE Positioning Profile
+typedef enum {
+ GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE = 0, // RRLP on LTE (Default)
+ GNSS_CONFIG_LPP_PROFILE_USER_PLANE, // LPP User Plane (UP) on LTE
+ GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE, // LPP_Control_Plane (CP)
+ GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE, // Both LPP UP and CP
+} GnssConfigLppProfile;
+
+// Technology for LPPe Control Plane
+typedef uint16_t GnssConfigLppeControlPlaneMask;
+typedef enum {
+ GNSS_CONFIG_LPPE_CONTROL_PLANE_DBH_BIT = (1<<0), // DBH
+ GNSS_CONFIG_LPPE_CONTROL_PLANE_WLAN_AP_MEASUREMENTS_BIT = (1<<1), // WLAN_AP_MEASUREMENTS
+ GNSS_CONFIG_LPPE_CONTROL_PLANE_SRN_AP_MEASUREMENTS_BIT = (1<<2), // SRN_AP_MEASUREMENTS
+ GNSS_CONFIG_LPPE_CONTROL_PLANE_SENSOR_BARO_MEASUREMENTS_BIT = (1<<3),
+ // SENSOR_BARO_MEASUREMENTS
+} GnssConfigLppeControlPlaneBits;
+
+// Technology for LPPe User Plane
+typedef uint16_t GnssConfigLppeUserPlaneMask;
+typedef enum {
+ GNSS_CONFIG_LPPE_USER_PLANE_DBH_BIT = (1<<0), // DBH
+ GNSS_CONFIG_LPPE_USER_PLANE_WLAN_AP_MEASUREMENTS_BIT = (1<<1), // WLAN_AP_MEASUREMENTS
+ GNSS_CONFIG_LPPE_USER_PLANE_SRN_AP_MEASUREMENTS_BIT = (1<<2), // SRN_AP_MEASUREMENTS
+ GNSS_CONFIG_LPPE_USER_PLANE_SENSOR_BARO_MEASUREMENTS_BIT = (1<<3),
+ // SENSOR_BARO_MEASUREMENTS
+} GnssConfigLppeUserPlaneBits;
+
+// Positioning Protocol on A-GLONASS system
+typedef uint16_t GnssConfigAGlonassPositionProtocolMask;
+typedef enum {
+ GNSS_CONFIG_RRC_CONTROL_PLANE_BIT = (1<<0), // RRC Control Plane
+ GNSS_CONFIG_RRLP_USER_PLANE_BIT = (1<<1), // RRLP User Plane
+ GNSS_CONFIG_LLP_USER_PLANE_BIT = (1<<2), // LPP User Plane
+ GNSS_CONFIG_LLP_CONTROL_PLANE_BIT = (1<<3), // LPP Control Plane
+} GnssConfigAGlonassPositionProtocolBits;
+
+typedef enum {
+ GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO = 0,
+ GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES,
+} GnssConfigEmergencyPdnForEmergencySupl;
+
+typedef enum {
+ GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO = 0,
+ GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_YES,
+} GnssConfigSuplEmergencyServices;
+
+typedef uint16_t GnssConfigSuplModeMask;
+typedef enum {
+ GNSS_CONFIG_SUPL_MODE_MSB_BIT = (1<<0),
+ GNSS_CONFIG_SUPL_MODE_MSA_BIT = (1<<1),
+} GnssConfigSuplModeBits;
+
+typedef uint32_t GnssConfigFlagsMask;
+typedef enum {
+ GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT = (1<<0),
+ GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT = (1<<1),
+ GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT = (1<<2),
+ GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT = (1<<3),
+ GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT = (1<<4),
+ GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT = (1<<5),
+ GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT = (1<<6),
+ GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT = (1<<7),
+ GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT = (1<<8),
+ GNSS_CONFIG_FLAGS_SUPL_MODE_BIT = (1<<9),
+ GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT = (1<<10),
+ GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT = (1<<11),
+} GnssConfigFlagsBits;
+
+typedef enum {
+ GNSS_NI_ENCODING_TYPE_NONE = 0,
+ GNSS_NI_ENCODING_TYPE_GSM_DEFAULT,
+ GNSS_NI_ENCODING_TYPE_UTF8,
+ GNSS_NI_ENCODING_TYPE_UCS2,
+} GnssNiEncodingType;
+
+typedef enum {
+ GNSS_NI_TYPE_VOICE = 0,
+ GNSS_NI_TYPE_SUPL,
+ GNSS_NI_TYPE_CONTROL_PLANE,
+ GNSS_NI_TYPE_EMERGENCY_SUPL
+} GnssNiType;
+
+typedef uint16_t GnssNiOptionsMask;
+typedef enum {
+ GNSS_NI_OPTIONS_NOTIFICATION_BIT = (1<<0),
+ GNSS_NI_OPTIONS_VERIFICATION_BIT = (1<<1),
+ GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT = (1<<2),
+} GnssNiOptionsBits;
+
+typedef enum {
+ GNSS_NI_RESPONSE_ACCEPT = 1,
+ GNSS_NI_RESPONSE_DENY,
+ GNSS_NI_RESPONSE_NO_RESPONSE,
+ GNSS_NI_RESPONSE_IGNORE,
+} GnssNiResponse;
+
+typedef enum {
+ GNSS_SV_TYPE_UNKNOWN = 0,
+ GNSS_SV_TYPE_GPS,
+ GNSS_SV_TYPE_SBAS,
+ GNSS_SV_TYPE_GLONASS,
+ GNSS_SV_TYPE_QZSS,
+ GNSS_SV_TYPE_BEIDOU,
+ GNSS_SV_TYPE_GALILEO,
+ GNSS_SV_TYPE_NAVIC,
+} GnssSvType;
+
+typedef enum {
+ GNSS_EPH_TYPE_UNKNOWN = 0,
+ GNSS_EPH_TYPE_EPHEMERIS,
+ GNSS_EPH_TYPE_ALMANAC,
+} GnssEphemerisType;
+
+typedef enum {
+ GNSS_EPH_SOURCE_UNKNOWN = 0,
+ GNSS_EPH_SOURCE_DEMODULATED,
+ GNSS_EPH_SOURCE_SUPL_PROVIDED,
+ GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED,
+ GNSS_EPH_SOURCE_LOCAL,
+} GnssEphemerisSource;
+
+typedef enum {
+ GNSS_EPH_HEALTH_UNKNOWN = 0,
+ GNSS_EPH_HEALTH_GOOD,
+ GNSS_EPH_HEALTH_BAD,
+} GnssEphemerisHealth;
+
+typedef uint16_t GnssSvOptionsMask;
+typedef enum {
+ GNSS_SV_OPTIONS_HAS_EPHEMER_BIT = (1<<0),
+ GNSS_SV_OPTIONS_HAS_ALMANAC_BIT = (1<<1),
+ GNSS_SV_OPTIONS_USED_IN_FIX_BIT = (1<<2),
+ GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT = (1<<3),
+} GnssSvOptionsBits;
+
+typedef enum {
+ GNSS_ASSISTANCE_TYPE_SUPL = 0,
+ GNSS_ASSISTANCE_TYPE_C2K,
+ GNSS_ASSISTANCE_TYPE_SUPL_EIMS,
+ GNSS_ASSISTANCE_TYPE_SUPL_IMS,
+} GnssAssistanceType;
+
+typedef enum {
+ GNSS_SUPL_MODE_STANDALONE = 0,
+ GNSS_SUPL_MODE_MSB,
+ GNSS_SUPL_MODE_MSA,
+} GnssSuplMode;
+
+typedef enum {
+ BATCHING_MODE_ROUTINE = 0, // positions are reported when batched positions memory is full
+ BATCHING_MODE_TRIP, // positions are reported when a certain distance is covered
+ BATCHING_MODE_NO_AUTO_REPORT // no report of positions automatically, instead queried on demand
+} BatchingMode;
+
+typedef enum {
+ BATCHING_STATUS_TRIP_COMPLETED = 0,
+ BATCHING_STATUS_POSITION_AVAILABE,
+ BATCHING_STATUS_POSITION_UNAVAILABLE
+} BatchingStatus;
+
+typedef uint16_t GnssMeasurementsAdrStateMask;
+typedef enum {
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_UNKNOWN = 0,
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT = (1<<0),
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT = (1<<1),
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT = (1<<2),
+ GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT = (1<<3),
+} GnssMeasurementsAdrStateBits;
+
+typedef enum {
+ GNSS_MEASUREMENTS_CODE_TYPE_A = 0,
+ GNSS_MEASUREMENTS_CODE_TYPE_B = 1,
+ GNSS_MEASUREMENTS_CODE_TYPE_C = 2,
+ GNSS_MEASUREMENTS_CODE_TYPE_I = 3,
+ GNSS_MEASUREMENTS_CODE_TYPE_L = 4,
+ GNSS_MEASUREMENTS_CODE_TYPE_M = 5,
+ GNSS_MEASUREMENTS_CODE_TYPE_P = 6,
+ GNSS_MEASUREMENTS_CODE_TYPE_Q = 7,
+ GNSS_MEASUREMENTS_CODE_TYPE_S = 8,
+ GNSS_MEASUREMENTS_CODE_TYPE_W = 9,
+ GNSS_MEASUREMENTS_CODE_TYPE_X = 10,
+ GNSS_MEASUREMENTS_CODE_TYPE_Y = 11,
+ GNSS_MEASUREMENTS_CODE_TYPE_Z = 12,
+ GNSS_MEASUREMENTS_CODE_TYPE_N = 13,
+ GNSS_MEASUREMENTS_CODE_TYPE_OTHER = 255,
+} GnssMeasurementsCodeType;
+
+typedef uint32_t GnssMeasurementsDataFlagsMask;
+typedef enum {
+ GNSS_MEASUREMENTS_DATA_SV_ID_BIT = (1<<0),
+ GNSS_MEASUREMENTS_DATA_SV_TYPE_BIT = (1<<1),
+ GNSS_MEASUREMENTS_DATA_STATE_BIT = (1<<2),
+ GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_BIT = (1<<3),
+ GNSS_MEASUREMENTS_DATA_RECEIVED_SV_TIME_UNCERTAINTY_BIT = (1<<4),
+ GNSS_MEASUREMENTS_DATA_CARRIER_TO_NOISE_BIT = (1<<5),
+ GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_BIT = (1<<6),
+ GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_UNCERTAINTY_BIT = (1<<7),
+ GNSS_MEASUREMENTS_DATA_ADR_STATE_BIT = (1<<8),
+ GNSS_MEASUREMENTS_DATA_ADR_BIT = (1<<9),
+ GNSS_MEASUREMENTS_DATA_ADR_UNCERTAINTY_BIT = (1<<10),
+ GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT = (1<<11),
+ GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT = (1<<12),
+ GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT = (1<<13),
+ GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT = (1<<14),
+ GNSS_MEASUREMENTS_DATA_MULTIPATH_INDICATOR_BIT = (1<<15),
+ GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT = (1<<16),
+ GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT = (1<<17),
+} GnssMeasurementsDataFlagsBits;
+
+typedef uint32_t GnssMeasurementsStateMask;
+typedef enum {
+ GNSS_MEASUREMENTS_STATE_UNKNOWN_BIT = 0,
+ GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT = (1<<0),
+ GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT = (1<<1),
+ GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT = (1<<2),
+ GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT = (1<<3),
+ GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT = (1<<4),
+ GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT = (1<<5),
+ GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT = (1<<6),
+ GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT = (1<<7),
+ GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT = (1<<8),
+ GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT = (1<<9),
+ GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT = (1<<10),
+ GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT = (1<<11),
+ GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT = (1<<12),
+ GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT = (1<<13),
+ GNSS_MEASUREMENTS_STATE_TOW_KNOWN_BIT = (1<<14),
+ GNSS_MEASUREMENTS_STATE_GLO_TOD_KNOWN_BIT = (1<<15),
+ GNSS_MEASUREMENTS_STATE_2ND_CODE_LOCK_BIT = (1<<16),
+} GnssMeasurementsStateBits;
+
+typedef enum {
+ GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_UNKNOWN = 0,
+ GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT,
+ GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT,
+} GnssMeasurementsMultipathIndicator;
+
+typedef uint32_t GnssMeasurementsClockFlagsMask;
+typedef enum {
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT = (1<<0),
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_BIT = (1<<1),
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT = (1<<2),
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT = (1<<3),
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT = (1<<4),
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT = (1<<5),
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT = (1<<6),
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT = (1<<7),
+ GNSS_MEASUREMENTS_CLOCK_FLAGS_HW_CLOCK_DISCONTINUITY_COUNT_BIT = (1<<8),
+} GnssMeasurementsClockFlagsBits;
+
+typedef uint32_t GnssAidingDataSvMask;
+typedef enum {
+ GNSS_AIDING_DATA_SV_EPHEMERIS_BIT = (1<<0), // ephemeris
+ GNSS_AIDING_DATA_SV_ALMANAC_BIT = (1<<1), // almanac
+ GNSS_AIDING_DATA_SV_HEALTH_BIT = (1<<2), // health
+ GNSS_AIDING_DATA_SV_DIRECTION_BIT = (1<<3), // direction
+ GNSS_AIDING_DATA_SV_STEER_BIT = (1<<4), // steer
+ GNSS_AIDING_DATA_SV_ALMANAC_CORR_BIT = (1<<5), // almanac correction
+ GNSS_AIDING_DATA_SV_BLACKLIST_BIT = (1<<6), // blacklist SVs
+ GNSS_AIDING_DATA_SV_SA_DATA_BIT = (1<<7), // sensitivity assistance data
+ GNSS_AIDING_DATA_SV_NO_EXIST_BIT = (1<<8), // SV does not exist
+ GNSS_AIDING_DATA_SV_IONOSPHERE_BIT = (1<<9), // ionosphere correction
+ GNSS_AIDING_DATA_SV_TIME_BIT = (1<<10),// reset satellite time
+ GNSS_AIDING_DATA_SV_MB_DATA = (1<<11),// delete multiband data
+ GNSS_AIDING_DATA_SV_POLY_BIT = (1<<12),// poly
+} GnssAidingDataSvBits;
+
+typedef uint32_t GnssAidingDataSvTypeMask;
+typedef enum {
+ GNSS_AIDING_DATA_SV_TYPE_GPS_BIT = (1<<0),
+ GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT = (1<<1),
+ GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT = (1<<2),
+ GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT = (1<<3),
+ GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT = (1<<4),
+ GNSS_AIDING_DATA_SV_TYPE_NAVIC_BIT = (1<<5),
+} GnssAidingDataSvTypeBits;
+
+/* Gnss constellation type mask */
+typedef uint16_t GnssConstellationTypeMask;
+typedef enum {
+ GNSS_CONSTELLATION_TYPE_GPS_BIT = (1<<0),
+ GNSS_CONSTELLATION_TYPE_GLONASS_BIT = (1<<1),
+ GNSS_CONSTELLATION_TYPE_QZSS_BIT = (1<<2),
+ GNSS_CONSTELLATION_TYPE_BEIDOU_BIT = (1<<3),
+ GNSS_CONSTELLATION_TYPE_GALILEO_BIT = (1<<4),
+ GNSS_CONSTELLATION_TYPE_SBAS_BIT = (1<<5),
+ GNSS_CONSTELLATION_TYPE_NAVIC_BIT = (1<<6)
+} GnssConstellationTypeBits;
+
+#define GNSS_CONSTELLATION_TYPE_MASK_ALL\
+ (GNSS_CONSTELLATION_TYPE_GPS_BIT | GNSS_CONSTELLATION_TYPE_GLONASS_BIT |\
+ GNSS_CONSTELLATION_TYPE_QZSS_BIT | GNSS_CONSTELLATION_TYPE_BEIDOU_BIT |\
+ GNSS_CONSTELLATION_TYPE_GALILEO_BIT | GNSS_CONSTELLATION_TYPE_SBAS_BIT |\
+ GNSS_CONSTELLATION_TYPE_NAVIC_BIT)
+
+/** GNSS Signal Type and RF Band */
+typedef uint32_t GnssSignalTypeMask;
+typedef enum {
+ /** GPS L1CA Signal */
+ GNSS_SIGNAL_GPS_L1CA = (1<<0),
+ /** GPS L1C Signal */
+ GNSS_SIGNAL_GPS_L1C = (1<<1),
+ /** GPS L2 RF Band */
+ GNSS_SIGNAL_GPS_L2 = (1<<2),
+ /** GPS L5 RF Band */
+ GNSS_SIGNAL_GPS_L5 = (1<<3),
+ /** GLONASS G1 (L1OF) RF Band */
+ GNSS_SIGNAL_GLONASS_G1 = (1<<4),
+ /** GLONASS G2 (L2OF) RF Band */
+ GNSS_SIGNAL_GLONASS_G2 = (1<<5),
+ /** GALILEO E1 RF Band */
+ GNSS_SIGNAL_GALILEO_E1 = (1<<6),
+ /** GALILEO E5A RF Band */
+ GNSS_SIGNAL_GALILEO_E5A = (1<<7),
+ /** GALILEO E5B RF Band */
+ GNSS_SIGNAL_GALILEO_E5B = (1<<8),
+ /** BEIDOU B1_I RF Band */
+ GNSS_SIGNAL_BEIDOU_B1I = (1<<9),
+ /** BEIDOU B1C RF Band */
+ GNSS_SIGNAL_BEIDOU_B1C = (1<<10),
+ /** BEIDOU B2_I RF Band */
+ GNSS_SIGNAL_BEIDOU_B2I = (1<<11),
+ /** BEIDOU B2A_I RF Band */
+ GNSS_SIGNAL_BEIDOU_B2AI = (1<<12),
+ /** QZSS L1CA RF Band */
+ GNSS_SIGNAL_QZSS_L1CA = (1<<13),
+ /** QZSS L1S RF Band */
+ GNSS_SIGNAL_QZSS_L1S = (1<<14),
+ /** QZSS L2 RF Band */
+ GNSS_SIGNAL_QZSS_L2 = (1<<15),
+ /** QZSS L5 RF Band */
+ GNSS_SIGNAL_QZSS_L5 = (1<<16),
+ /** SBAS L1 RF Band */
+ GNSS_SIGNAL_SBAS_L1 = (1<<17),
+ /** NAVIC L5 RF Band */
+ GNSS_SIGNAL_NAVIC_L5 = (1<<18),
+ /** BEIDOU B2A_Q RF Band */
+ GNSS_SIGNAL_BEIDOU_B2AQ = (1<<19)
+} GnssSignalTypeBits;
+
+#define GNSS_SIGNAL_TYPE_MASK_ALL\
+ (GNSS_SIGNAL_GPS_L1CA | GNSS_SIGNAL_GPS_L1C | GNSS_SIGNAL_GPS_L2 |\
+ GNSS_SIGNAL_GPS_L5| GNSS_SIGNAL_GLONASS_G1 | GNSS_SIGNAL_GLONASS_G2 |\
+ GNSS_SIGNAL_GALILEO_E1 | GNSS_SIGNAL_GALILEO_E5A | GNSS_SIGNAL_GALILEO_E5B |\
+ GNSS_SIGNAL_BEIDOU_B1I | GNSS_SIGNAL_BEIDOU_B1C | GNSS_SIGNAL_BEIDOU_B2I|\
+ GNSS_SIGNAL_BEIDOU_B2AI | GNSS_SIGNAL_QZSS_L1CA | GNSS_SIGNAL_QZSS_L1S |\
+ GNSS_SIGNAL_QZSS_L2| GNSS_SIGNAL_QZSS_L5 | GNSS_SIGNAL_SBAS_L1 |\
+ GNSS_SIGNAL_NAVIC_L5 | GNSS_SIGNAL_BEIDOU_B2AQ)
+
+typedef enum
+{
+ GNSS_LOC_SV_SYSTEM_UNKNOWN = 0,
+ /** unknown sv system. */
+ GNSS_LOC_SV_SYSTEM_MIN = 1,
+ /**< Min enum of valid SV system. */
+ GNSS_LOC_SV_SYSTEM_GPS = 1,
+ /**< GPS satellite. */
+ GNSS_LOC_SV_SYSTEM_GALILEO = 2,
+ /**< GALILEO satellite. */
+ GNSS_LOC_SV_SYSTEM_SBAS = 3,
+ /**< SBAS satellite. */
+ GNSS_LOC_SV_SYSTEM_GLONASS = 4,
+ /**< GLONASS satellite. */
+ GNSS_LOC_SV_SYSTEM_BDS = 5,
+ /**< BDS satellite. */
+ GNSS_LOC_SV_SYSTEM_QZSS = 6,
+ /**< QZSS satellite. */
+ GNSS_LOC_SV_SYSTEM_NAVIC = 7,
+ /**< QZSS satellite. */
+ GNSS_LOC_SV_SYSTEM_MAX = 7,
+ /**< Max enum of valid SV system. */
+} Gnss_LocSvSystemEnumType;
+
+typedef enum {
+ GNSS_LOC_SIGNAL_TYPE_GPS_L1CA = 0, /**< GPS L1CA Signal */
+ GNSS_LOC_SIGNAL_TYPE_GPS_L1C = 1, /**< GPS L1C Signal */
+ GNSS_LOC_SIGNAL_TYPE_GPS_L2C_L = 2, /**< GPS L2C_L RF Band */
+ GNSS_LOC_SIGNAL_TYPE_GPS_L5_Q = 3, /**< GPS L5_Q RF Band */
+ GNSS_LOC_SIGNAL_TYPE_GLONASS_G1 = 4, /**< GLONASS G1 (L1OF) RF Band */
+ GNSS_LOC_SIGNAL_TYPE_GLONASS_G2 = 5, /**< GLONASS G2 (L2OF) RF Band */
+ GNSS_LOC_SIGNAL_TYPE_GALILEO_E1_C = 6, /**< GALILEO E1_C RF Band */
+ GNSS_LOC_SIGNAL_TYPE_GALILEO_E5A_Q = 7, /**< GALILEO E5A_Q RF Band */
+ GNSS_LOC_SIGNAL_TYPE_GALILEO_E5B_Q = 8, /**< GALILEO E5B_Q RF Band */
+ GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1_I = 9, /**< BEIDOU B1_I RF Band */
+ GNSS_LOC_SIGNAL_TYPE_BEIDOU_B1C = 10, /**< BEIDOU B1C RF Band */
+ GNSS_LOC_SIGNAL_TYPE_BEIDOU_B2_I = 11, /**< BEIDOU B2_I RF Band */
+ GNSS_LOC_SIGNAL_TYPE_BEIDOU_B2A_I = 12, /**< BEIDOU B2A_I RF Band */
+ GNSS_LOC_SIGNAL_TYPE_QZSS_L1CA = 13, /**< QZSS L1CA RF Band */
+ GNSS_LOC_SIGNAL_TYPE_QZSS_L1S = 14, /**< QZSS L1S RF Band */
+ GNSS_LOC_SIGNAL_TYPE_QZSS_L2C_L = 15, /**< QZSS L2C_L RF Band */
+ GNSS_LOC_SIGNAL_TYPE_QZSS_L5_Q = 16, /**< QZSS L5_Q RF Band */
+ GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA = 17, /**< SBAS L1_CA RF Band */
+ GNSS_LOC_SIGNAL_TYPE_NAVIC_L5 = 18, /**< NAVIC L5 RF Band */
+ GNSS_LOC_SIGNAL_TYPE_BEIDOU_B2A_Q = 19, /**< BEIDOU B2A_Q RF Band */
+ GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES = 20 /**< Maximum number of signal types */
+} Gnss_LocSignalEnumType;
+
+typedef uint32_t PositioningEngineMask;
+typedef enum {
+ STANDARD_POSITIONING_ENGINE = (1 << 0),
+ DEAD_RECKONING_ENGINE = (1 << 1),
+ PRECISE_POSITIONING_ENGINE = (1 << 2)
+} PositioningEngineBits;
+
+typedef uint64_t GnssDataMask;
+typedef enum {
+ // Jammer Indicator is available
+ GNSS_LOC_DATA_JAMMER_IND_BIT = (1ULL << 0),
+ // AGC is available
+ GNSS_LOC_DATA_AGC_BIT = (1ULL << 1)
+} GnssDataBits;
+
+typedef uint32_t GnssSystemTimeStructTypeFlags;
+typedef enum {
+ GNSS_SYSTEM_TIME_WEEK_VALID = (1 << 0),
+ GNSS_SYSTEM_TIME_WEEK_MS_VALID = (1 << 1),
+ GNSS_SYSTEM_CLK_TIME_BIAS_VALID = (1 << 2),
+ GNSS_SYSTEM_CLK_TIME_BIAS_UNC_VALID = (1 << 3),
+ GNSS_SYSTEM_REF_FCOUNT_VALID = (1 << 4),
+ GNSS_SYSTEM_NUM_CLOCK_RESETS_VALID = (1 << 5)
+} GnssSystemTimeTypeBits;
+
+typedef uint32_t GnssGloTimeStructTypeFlags;
+typedef enum {
+ GNSS_CLO_DAYS_VALID = (1 << 0),
+ GNSS_GLO_MSEC_VALID = (1 << 1),
+ GNSS_GLO_CLK_TIME_BIAS_VALID = (1 << 2),
+ GNSS_GLO_CLK_TIME_BIAS_UNC_VALID = (1 << 3),
+ GNSS_GLO_REF_FCOUNT_VALID = (1 << 4),
+ GNSS_GLO_NUM_CLOCK_RESETS_VALID = (1 << 5),
+ GNSS_GLO_FOUR_YEAR_VALID = (1 << 6)
+} GnssGloTimeTypeBits;
+
+typedef struct {
+ GnssAidingDataSvMask svMask; // bitwise OR of GnssAidingDataSvBits
+ GnssAidingDataSvTypeMask svTypeMask; // bitwise OR of GnssAidingDataSvTypeBits
+} GnssAidingDataSv;
+
+typedef uint32_t GnssAidingDataCommonMask;
+typedef enum {
+ GNSS_AIDING_DATA_COMMON_POSITION_BIT = (1<<0), // position estimate
+ GNSS_AIDING_DATA_COMMON_TIME_BIT = (1<<1), // reset all clock values
+ GNSS_AIDING_DATA_COMMON_UTC_BIT = (1<<2), // UTC estimate
+ GNSS_AIDING_DATA_COMMON_RTI_BIT = (1<<3), // RTI
+ GNSS_AIDING_DATA_COMMON_FREQ_BIAS_EST_BIT = (1<<4), // frequency bias estimate
+ GNSS_AIDING_DATA_COMMON_CELLDB_BIT = (1<<5), // all celldb info
+} GnssAidingDataCommonBits;
+
+typedef struct {
+ GnssAidingDataCommonMask mask; // bitwise OR of GnssAidingDataCommonBits
+} GnssAidingDataCommon;
+
+typedef struct {
+ bool deleteAll; // if true, delete all aiding data and ignore other params
+ GnssAidingDataSv sv; // SV specific aiding data
+ GnssAidingDataCommon common; // common aiding data
+ PositioningEngineMask posEngineMask; // engines to perform the delete operation on.
+} GnssAidingData;
+
+typedef uint16_t DrCalibrationStatusMask;
+typedef enum {
+ // Indicate that roll calibration is needed. Need to take more turns on level ground
+ DR_ROLL_CALIBRATION_NEEDED = (1<<0),
+ // Indicate that pitch calibration is needed. Need to take more turns on level ground
+ DR_PITCH_CALIBRATION_NEEDED = (1<<1),
+ // Indicate that yaw calibration is needed. Need to accelerate in a straight line
+ DR_YAW_CALIBRATION_NEEDED = (1<<2),
+ // Indicate that odo calibration is needed. Need to accelerate in a straight line
+ DR_ODO_CALIBRATION_NEEDED = (1<<3),
+ // Indicate that gyro calibration is needed. Need to take more turns on level ground
+ DR_GYRO_CALIBRATION_NEEDED = (1<<4)
+} DrCalibrationStatusBits;
+
+typedef struct {
+ uint32_t size; // set to sizeof(Location)
+ LocationFlagsMask flags; // bitwise OR of LocationFlagsBits to mark which params are valid
+ uint64_t timestamp; // UTC timestamp for location fix, milliseconds since January 1, 1970
+ double latitude; // in degrees
+ double longitude; // in degrees
+ double altitude; // in meters above the WGS 84 reference ellipsoid
+ float speed; // in meters per second
+ float bearing; // in degrees; range [0, 360)
+ float accuracy; // in meters
+ float verticalAccuracy; // in meters
+ float speedAccuracy; // in meters/second
+ float bearingAccuracy; // in degrees (0 to 359.999)
+ LocationTechnologyMask techMask;
+ LocationSpoofMask spoofMask;
+} Location;
+
+typedef enum {
+ LOC_REQ_ENGINE_FUSED_BIT = (1<<0),
+ LOC_REQ_ENGINE_SPE_BIT = (1<<1),
+ LOC_REQ_ENGINE_PPE_BIT = (1<<2),
+} LocReqEngineTypeMask;
+
+typedef enum {
+ LOC_OUTPUT_ENGINE_FUSED = 0,
+ /** This is the GNSS fix from modem */
+ LOC_OUTPUT_ENGINE_SPE = 1,
+ /** This is the GNSS fix with correction PPP/RTK correction */
+ LOC_OUTPUT_ENGINE_PPE = 2,
+ LOC_OUTPUT_ENGINE_COUNT,
+} LocOutputEngineType;
+
+struct LocationOptions {
+ uint32_t size; // set to sizeof(LocationOptions)
+ uint32_t minInterval; // in milliseconds
+ uint32_t minDistance; // in meters. if minDistance > 0, gnssSvCallback/gnssNmeaCallback/
+ // gnssMeasurementsCallback may not be called
+ GnssSuplMode mode; // Standalone/MS-Based/MS-Assisted
+ // behavior when this field is 0:
+ // if engine hub is running, this will be fused fix,
+ // if engine hub is not running, this will be SPE fix
+ LocReqEngineTypeMask locReqEngTypeMask;
+
+ inline LocationOptions() :
+ size(0), minInterval(0), minDistance(0), mode(GNSS_SUPL_MODE_STANDALONE),
+ locReqEngTypeMask((LocReqEngineTypeMask)0) {}
+};
+
+typedef enum {
+ GNSS_POWER_MODE_INVALID = 0,
+ GNSS_POWER_MODE_M1, /* Improved Accuracy Mode */
+ GNSS_POWER_MODE_M2, /* Normal Mode */
+ GNSS_POWER_MODE_M3, /* Background Mode */
+ GNSS_POWER_MODE_M4, /* Background Mode */
+ GNSS_POWER_MODE_M5 /* Background Mode */
+} GnssPowerMode;
+
+struct TrackingOptions : LocationOptions {
+ GnssPowerMode powerMode; /* Power Mode to be used for time based tracking
+ sessions */
+ uint32_t tbm; /* Time interval between measurements specified in millis.
+ Applicable to background power modes */
+
+ inline TrackingOptions() :
+ LocationOptions(), powerMode(GNSS_POWER_MODE_INVALID), tbm(0) {}
+ inline TrackingOptions(uint32_t s, GnssPowerMode m, uint32_t t) :
+ LocationOptions(), powerMode(m), tbm(t) { LocationOptions::size = s; }
+ inline TrackingOptions(const LocationOptions& options) :
+ LocationOptions(options), powerMode(GNSS_POWER_MODE_INVALID), tbm(0) {}
+ inline void setLocationOptions(const LocationOptions& options) {
+ size = sizeof(TrackingOptions);
+ minInterval = options.minInterval;
+ minDistance = options.minDistance;
+ mode = options.mode;
+ locReqEngTypeMask = options.locReqEngTypeMask;
+ }
+ inline LocationOptions getLocationOptions() {
+ LocationOptions locOption;
+ locOption.size = sizeof(locOption);
+ locOption.minDistance = minDistance;
+ locOption.minInterval = minInterval;
+ locOption.mode = mode;
+ locOption.locReqEngTypeMask = locReqEngTypeMask;
+ return locOption;
+ }
+};
+
+struct BatchingOptions : LocationOptions {
+ BatchingMode batchingMode;
+
+ inline BatchingOptions() :
+ LocationOptions(), batchingMode(BATCHING_MODE_ROUTINE) {}
+ inline BatchingOptions(uint32_t s, BatchingMode m) :
+ LocationOptions(), batchingMode(m) { LocationOptions::size = s; }
+ inline BatchingOptions(const LocationOptions& options) :
+ LocationOptions(options), batchingMode(BATCHING_MODE_ROUTINE) {}
+ inline void setLocationOptions(const LocationOptions& options) {
+ minInterval = options.minInterval;
+ minDistance = options.minDistance;
+ mode = options.mode;
+ }
+};
+
+typedef struct {
+ uint32_t size;
+ BatchingStatus batchingStatus;
+} BatchingStatusInfo;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GeofenceOption)
+ GeofenceBreachTypeMask breachTypeMask; // bitwise OR of GeofenceBreachTypeBits
+ uint32_t responsiveness; // in milliseconds
+ uint32_t dwellTime; // in seconds
+} GeofenceOption;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GeofenceInfo)
+ double latitude; // in degrees
+ double longitude; // in degrees
+ double radius; // in meters
+} GeofenceInfo;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GeofenceBreachNotification)
+ uint32_t count; // number of ids in array
+ uint32_t* ids; // array of ids that have breached
+ Location location; // location associated with breach
+ GeofenceBreachType type; // type of breach
+ uint64_t timestamp; // timestamp of breach
+} GeofenceBreachNotification;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GeofenceBreachNotification)
+ GeofenceStatusAvailable available; // GEOFENCE_STATUS_AVAILABILE_NO/_YES
+ LocationTechnologyType techType; // GNSS
+} GeofenceStatusNotification;
+
+typedef struct {
+ uint64_t gpsSvUsedIdsMask;
+ uint64_t gloSvUsedIdsMask;
+ uint64_t galSvUsedIdsMask;
+ uint64_t bdsSvUsedIdsMask;
+ uint64_t qzssSvUsedIdsMask;
+ uint64_t navicSvUsedIdsMask;
+} GnssLocationSvUsedInPosition;
+
+typedef struct {
+ /** GnssSignalType mask */
+ GnssSignalTypeMask gnssSignalType;
+ /** Specifies GNSS Constellation Type */
+ Gnss_LocSvSystemEnumType gnssConstellation;
+ /** GNSS SV ID.
+ For GPS: 1 to 32
+ For GLONASS: 65 to 96. When slot-number to SV ID mapping is unknown, set as 255.
+ For SBAS: 120 to 151
+ For QZSS-L1CA:193 to 197
+ For BDS: 201 to 237
+ For GAL: 301 to 336
+ For NAVIC: 401 to 414 */
+ uint16_t gnssSvId;
+} GnssMeasUsageInfo;
+
+/** @struct
+ Body Frame parameters
+*/
+typedef struct {
+ GnssLocationPosDataMask bodyFrameDataMask; // Contains Body frame LocPosDataMask bits
+ float longAccel; // Forward Acceleration in body frame (m/s2)
+ float latAccel; // Sideward Acceleration in body frame (m/s2)
+ float vertAccel; // Vertical Acceleration in body frame (m/s2)
+ float yawRate; // Heading Rate (Radians/second)
+ float pitch; // Body pitch (Radians)
+ float longAccelUnc; // Uncertainty of Forward Acceleration in body frame
+ float latAccelUnc; // Uncertainty of Side-ward Acceleration in body frame
+ float vertAccelUnc; // Uncertainty of Vertical Acceleration in body frame
+ float yawRateUnc; // Uncertainty of Heading Rate
+ float pitchUnc; // Uncertainty of Body pitch
+} GnssLocationPositionDynamics;
+
+typedef struct {
+ /** Validity mask for below fields */
+ GnssSystemTimeStructTypeFlags validityMask;
+ /** Extended week number at reference tick.
+ Unit: Week.
+ Set to 65535 if week number is unknown.
+ For GPS:
+ Calculated from midnight, Jan. 6, 1980.
+ OTA decoded 10 bit GPS week is extended to map between:
+ [NV6264 to (NV6264 + 1023)].
+ NV6264: Minimum GPS week number configuration.
+ Default value of NV6264: 1738
+ For BDS:
+ Calculated from 00:00:00 on January 1, 2006 of Coordinated Universal Time (UTC).
+ For GAL:
+ Calculated from 00:00 UT on Sunday August 22, 1999 (midnight between August 21 and August 22).
+ */
+ uint16_t systemWeek;
+ /** Time in to the current week at reference tick.
+ Unit: Millisecond. Range: 0 to 604799999.
+ Check for systemClkTimeUncMs before use */
+ uint32_t systemMsec;
+ /** System clock time bias (sub-millisecond)
+ Units: Millisecond
+ Note: System time (TOW Millisecond) = systemMsec - systemClkTimeBias.
+ Check for systemClkTimeUncMs before use. */
+ float systemClkTimeBias;
+ /** Single sided maximum time bias uncertainty
+ Units: Millisecond */
+ float systemClkTimeUncMs;
+ /** FCount (free running HW timer) value. Don't use for relative time purpose
+ due to possible discontinuities.
+ Unit: Millisecond */
+ uint32_t refFCount;
+ /** Number of clock resets/discontinuities detected, affecting the local hardware counter value. */
+ uint32_t numClockResets;
+} GnssSystemTimeStructType;
+
+typedef struct {
+ /** GLONASS day number in four years. Refer to GLONASS ICD.
+ Applicable only for GLONASS and shall be ignored for other constellations.
+ If unknown shall be set to 65535 */
+ uint16_t gloDays;
+ /** Validity mask for below fields */
+ GnssGloTimeStructTypeFlags validityMask;
+ /** GLONASS time of day in Millisecond. Refer to GLONASS ICD.
+ Units: Millisecond
+ Check for gloClkTimeUncMs before use */
+ uint32_t gloMsec;
+ /** GLONASS clock time bias (sub-millisecond)
+ Units: Millisecond
+ Note: GLO time (TOD Millisecond) = gloMsec - gloClkTimeBias.
+ Check for gloClkTimeUncMs before use. */
+ float gloClkTimeBias;
+ /** Single sided maximum time bias uncertainty
+ Units: Millisecond */
+ float gloClkTimeUncMs;
+ /** FCount (free running HW timer) value. Don't use for relative time purpose
+ due to possible discontinuities.
+ Unit: Millisecond */
+ uint32_t refFCount;
+ /** Number of clock resets/discontinuities detected, affecting the local hardware counter value. */
+ uint32_t numClockResets;
+ /** GLONASS four year number from 1996. Refer to GLONASS ICD.
+ Applicable only for GLONASS and shall be ignored for other constellations.
+ If unknown shall be set to 255 */
+ uint8_t gloFourYear;
+} GnssGloTimeStructType;
+
+typedef union {
+ GnssSystemTimeStructType gpsSystemTime;
+ GnssSystemTimeStructType galSystemTime;
+ GnssSystemTimeStructType bdsSystemTime;
+ GnssSystemTimeStructType qzssSystemTime;
+ GnssGloTimeStructType gloSystemTime;
+ GnssSystemTimeStructType navicSystemTime;
+} SystemTimeStructUnion;
+ /** Time applicability of PVT report */
+typedef struct {
+ /** Specifies GNSS system time reported. Mandatory field */
+ Gnss_LocSvSystemEnumType gnssSystemTimeSrc;
+ /** Reporting of GPS system time is recommended.
+ If GPS time is unknown & other satellite system time is known,
+ it should be reported.
+ Mandatory field
+ */
+ SystemTimeStructUnion u;
+} GnssSystemTime;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssLocationInfo)
+ Location location; // basic locaiton info, latitude, longitude, and etc
+ GnssLocationInfoFlagMask flags; // bitwise OR of GnssLocationInfoBits for param validity
+ float altitudeMeanSeaLevel; // altitude wrt mean sea level
+ float pdop; // position dilusion of precision
+ float hdop; // horizontal dilusion of precision
+ float vdop; // vertical dilusion of precision
+ float gdop; // geometric dilution of precision
+ float tdop; // time dilution of precision
+ float magneticDeviation; // magnetic deviation
+ LocationReliability horReliability; // horizontal reliability
+ LocationReliability verReliability; // vertical reliability
+ float horUncEllipseSemiMajor; // horizontal elliptical accuracy semi-major axis
+ float horUncEllipseSemiMinor; // horizontal elliptical accuracy semi-minor axis
+ float horUncEllipseOrientAzimuth; // horizontal elliptical accuracy azimuth
+ float northStdDeviation; // North standard deviation Unit: Meters
+ float eastStdDeviation; // East standard deviation. Unit: Meters
+ float northVelocity; // North Velocity.Unit: Meters/sec
+ float eastVelocity; // East Velocity Unit Meters/sec
+ float upVelocity; // Up Velocity. Unit Meters/sec
+ float northVelocityStdDeviation;
+ float eastVelocityStdDeviation;
+ float upVelocityStdDeviation;
+ uint16_t numSvUsedInPosition;
+ GnssLocationSvUsedInPosition svUsedInPosition;// Gnss sv used in position data
+ GnssLocationNavSolutionMask navSolutionMask; // Nav solution mask to indicate sbas corrections
+ GnssLocationPosTechMask posTechMask; // Position technology used in computing this fix
+ GnssLocationPositionDynamics bodyFrameData; // Body Frame Dynamics: 4wayAcceleration and
+ // pitch set with validity
+ GnssSystemTime gnssSystemTime; // GNSS System Time
+ uint8_t numOfMeasReceived; // Number of measurements received for use in fix.
+ GnssMeasUsageInfo measUsageInfo[GNSS_SV_MAX]; // GNSS Measurement Usage info
+ uint8_t leapSeconds; // leap second
+ float timeUncMs; // Time uncertainty in milliseconds
+ uint8_t calibrationConfidence; // Sensor calibration confidence percent,
+ // in range of [0, 100]
+ DrCalibrationStatusMask calibrationStatus; // Sensor calibration status
+ // location engine type. When the fix. when the type is set to
+ // LOC_ENGINE_SRC_FUSED, the fix is the propagated/aggregated
+ // reports from all engines running on the system (e.g.:
+ // DR/SPE/PPE). To check which location engine contributes to
+ // the fused output, check for locOutputEngMask.
+ LocOutputEngineType locOutputEngType;
+ // when loc output eng type is set to fused, this field
+ // indicates the set of engines contribute to the fix.
+ PositioningEngineMask locOutputEngMask;
+} GnssLocationInfoNotification;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssNiNotification)
+ GnssNiType type; // type of NI (Voice, SUPL, Control Plane)
+ GnssNiOptionsMask options; // bitwise OR of GnssNiOptionsBits
+ uint32_t timeout; // time (seconds) to wait for user input
+ GnssNiResponse timeoutResponse; // the response that should be sent when timeout expires
+ char requestor[GNSS_NI_REQUESTOR_MAX]; // the requestor that is making the request
+ GnssNiEncodingType requestorEncoding; // the encoding type for requestor
+ char message[GNSS_NI_MESSAGE_ID_MAX]; // the message to show user
+ GnssNiEncodingType messageEncoding; // the encoding type for message
+ char extras[GNSS_NI_MESSAGE_ID_MAX];
+} GnssNiNotification;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssSv)
+ uint16_t svId; // Unique Identifier
+ GnssSvType type; // type of SV (GPS, SBAS, GLONASS, QZSS, BEIDOU, GALILEO)
+ float cN0Dbhz; // signal strength
+ float elevation; // elevation of SV (in degrees)
+ float azimuth; // azimuth of SV (in degrees)
+ GnssSvOptionsMask gnssSvOptionsMask; // Bitwise OR of GnssSvOptionsBits
+ float carrierFrequencyHz; // carrier frequency of the signal tracked
+ GnssSignalTypeMask gnssSignalTypeMask; // Specifies GNSS signal type
+} GnssSv;
+
+struct GnssConfigSetAssistanceServer {
+ uint32_t size; // set to sizeof(GnssConfigSetAssistanceServer)
+ GnssAssistanceType type; // SUPL or C2K
+ const char* hostName; // null terminated string
+ uint32_t port; // port of server
+
+ inline bool equals(const GnssConfigSetAssistanceServer& config) {
+ if (config.type == type && config.port == port &&
+ ((NULL == config.hostName && NULL == hostName) ||
+ (NULL != config.hostName && NULL != hostName &&
+ 0 == strcmp(config.hostName, hostName)))) {
+ return true;
+ }
+ return false;
+ }
+};
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssMeasurementsData)
+ GnssMeasurementsDataFlagsMask flags; // bitwise OR of GnssMeasurementsDataFlagsBits
+ int16_t svId;
+ GnssSvType svType;
+ double timeOffsetNs;
+ GnssMeasurementsStateMask stateMask; // bitwise OR of GnssMeasurementsStateBits
+ int64_t receivedSvTimeNs;
+ int64_t receivedSvTimeUncertaintyNs;
+ double carrierToNoiseDbHz;
+ double pseudorangeRateMps;
+ double pseudorangeRateUncertaintyMps;
+ GnssMeasurementsAdrStateMask adrStateMask; // bitwise OR of GnssMeasurementsAdrStateBits
+ double adrMeters;
+ double adrUncertaintyMeters;
+ float carrierFrequencyHz;
+ int64_t carrierCycles;
+ double carrierPhase;
+ double carrierPhaseUncertainty;
+ GnssMeasurementsMultipathIndicator multipathIndicator;
+ double signalToNoiseRatioDb;
+ double agcLevelDb;
+ GnssMeasurementsCodeType codeType;
+ char otherCodeTypeName[GNSS_MAX_NAME_LENGTH];
+} GnssMeasurementsData;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssMeasurementsClock)
+ GnssMeasurementsClockFlagsMask flags; // bitwise OR of GnssMeasurementsClockFlagsBits
+ int16_t leapSecond;
+ int64_t timeNs;
+ double timeUncertaintyNs;
+ int64_t fullBiasNs;
+ double biasNs;
+ double biasUncertaintyNs;
+ double driftNsps;
+ double driftUncertaintyNsps;
+ uint32_t hwClockDiscontinuityCount;
+} GnssMeasurementsClock;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssSvNotification)
+ uint32_t count; // number of SVs in the GnssSv array
+ bool gnssSignalTypeMaskValid;
+ GnssSv gnssSvs[GNSS_SV_MAX]; // information on a number of SVs
+} GnssSvNotification;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssNmeaNotification)
+ uint64_t timestamp; // timestamp
+ const char* nmea; // nmea text
+ uint32_t length; // length of the nmea text
+} GnssNmeaNotification;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssDataNotification)
+ GnssDataMask gnssDataMask[GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES]; // bitwise OR of GnssDataBits
+ double jammerInd[GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES]; // Jammer Indication
+ double agc[GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES]; // Automatic gain control
+} GnssDataNotification;
+
+typedef struct {
+ uint32_t size; // set to sizeof(GnssMeasurementsNotification)
+ uint32_t count; // number of items in GnssMeasurements array
+ GnssMeasurementsData measurements[GNSS_MEASUREMENTS_MAX];
+ GnssMeasurementsClock clock; // clock
+} GnssMeasurementsNotification;
+
+typedef uint32_t GnssSvId;
+
+struct GnssSvIdSource{
+ uint32_t size; // set to sizeof(GnssSvIdSource)
+ GnssSvType constellation; // constellation for the sv to blacklist
+ GnssSvId svId; // sv id to blacklist
+};
+inline bool operator ==(GnssSvIdSource const& left, GnssSvIdSource const& right) {
+ return left.size == right.size &&
+ left.constellation == right.constellation && left.svId == right.svId;
+}
+
+#define GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK ((uint64_t)0xFFFFFFFFFFFFFFFF)
+typedef struct {
+ uint32_t size; // set to sizeof(GnssSvIdConfig)
+
+ // GLONASS - SV 65 maps to bit 0
+#define GNSS_SV_CONFIG_GLO_INITIAL_SV_ID 65
+ uint64_t gloBlacklistSvMask;
+
+ // BEIDOU - SV 201 maps to bit 0
+#define GNSS_SV_CONFIG_BDS_INITIAL_SV_ID 201
+ uint64_t bdsBlacklistSvMask;
+
+ // QZSS - SV 193 maps to bit 0
+#define GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID 193
+ uint64_t qzssBlacklistSvMask;
+
+ // GAL - SV 301 maps to bit 0
+#define GNSS_SV_CONFIG_GAL_INITIAL_SV_ID 301
+ uint64_t galBlacklistSvMask;
+} GnssSvIdConfig;
+
+struct GnssConfig{
+ uint32_t size; // set to sizeof(GnssConfig)
+ GnssConfigFlagsMask flags; // bitwise OR of GnssConfigFlagsBits to mark which params are valid
+ GnssConfigGpsLock gpsLock;
+ GnssConfigSuplVersion suplVersion;
+ GnssConfigSetAssistanceServer assistanceServer;
+ GnssConfigLppProfile lppProfile;
+ GnssConfigLppeControlPlaneMask lppeControlPlaneMask;
+ GnssConfigLppeUserPlaneMask lppeUserPlaneMask;
+ GnssConfigAGlonassPositionProtocolMask aGlonassPositionProtocolMask;
+ GnssConfigEmergencyPdnForEmergencySupl emergencyPdnForEmergencySupl;
+ GnssConfigSuplEmergencyServices suplEmergencyServices;
+ GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits
+ std::vector<GnssSvIdSource> blacklistedSvIds;
+ uint32_t emergencyExtensionSeconds;
+
+ inline bool equals(const GnssConfig& config) {
+ if (flags == config.flags &&
+ gpsLock == config.gpsLock &&
+ suplVersion == config.suplVersion &&
+ assistanceServer.equals(config.assistanceServer) &&
+ lppProfile == config.lppProfile &&
+ lppeControlPlaneMask == config.lppeControlPlaneMask &&
+ lppeUserPlaneMask == config.lppeUserPlaneMask &&
+ aGlonassPositionProtocolMask == config.aGlonassPositionProtocolMask &&
+ emergencyPdnForEmergencySupl == config.emergencyPdnForEmergencySupl &&
+ suplEmergencyServices == config.suplEmergencyServices &&
+ suplModeMask == config.suplModeMask &&
+ blacklistedSvIds == config.blacklistedSvIds &&
+ emergencyExtensionSeconds == config.emergencyExtensionSeconds) {
+ return true;
+ }
+ return false;
+ }
+};
+
+typedef struct {
+ uint32_t size; // set to sizeof
+ bool mValid;
+ Location mLocation;
+ double verticalAccuracyMeters;
+ double speedAccuracyMetersPerSecond;
+ double bearingAccuracyDegrees;
+ timespec mUtcReported;
+} GnssDebugLocation;
+
+typedef struct {
+ uint32_t size; // set to sizeof
+ bool mValid;
+ int64_t timeEstimate;
+ float timeUncertaintyNs;
+ float frequencyUncertaintyNsPerSec;
+} GnssDebugTime;
+
+typedef struct {
+ uint32_t size; // set to sizeof
+ uint32_t svid;
+ GnssSvType constellation;
+ GnssEphemerisType mEphemerisType;
+ GnssEphemerisSource mEphemerisSource;
+ GnssEphemerisHealth mEphemerisHealth;
+ float ephemerisAgeSeconds;
+ bool serverPredictionIsAvailable;
+ float serverPredictionAgeSeconds;
+} GnssDebugSatelliteInfo;
+
+typedef struct {
+ uint32_t size; // set to sizeof
+ GnssDebugLocation mLocation;
+ GnssDebugTime mTime;
+ std::vector<GnssDebugSatelliteInfo> mSatelliteInfo;
+} GnssDebugReport;
+
+typedef uint32_t LeapSecondSysInfoMask;
+typedef enum {
+ // current leap second info is available. This info will only
+ // be available if the leap second change info is not available.
+ //
+ // If leap second change info is avaiable, to figure out
+ // the current leap second info, compare current gps time with
+ // the gps timestamp of leap second change to know whether to choose
+ // leapSecondBefore or leapSecondAfter as current leap second.
+ LEAP_SECOND_SYS_INFO_CURRENT_LEAP_SECONDS_BIT = (1ULL << 0),
+ // the last known leap change event is available.
+ // The info can be available on two scenario:
+ // 1: this leap second change event has been scheduled and yet to happen
+ // 2: this leap second change event has already happened and next
+ // leap second change event has not yet been scheduled.
+ LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT = (1ULL << 1),
+} LeapSecondSysInfoDataBits;
+
+struct LeapSecondChangeInfo {
+ // GPS timestamp that corrresponds to the last known
+ // leap second change event.
+ //
+ // The info can be available on two scenario:
+ // 1: this leap second change event has been scheduled and yet to happen
+ // 2: this leap second change event has already happened and next
+ // leap second change event has not yet been scheduled.
+ GnssSystemTimeStructType gpsTimestampLsChange;
+ // Number of leap seconds prior to the leap second change event
+ // that corresponds to the timestamp at gpsTimestampLsChange.
+ uint8_t leapSecondsBeforeChange;
+ // Number of leap seconds after the leap second change event
+ // that corresponds to the timestamp at gpsTimestampLsChange.
+ uint8_t leapSecondsAfterChange;
+};
+
+struct LeapSecondSystemInfo {
+ LeapSecondSysInfoMask leapSecondInfoMask;
+ uint8_t leapSecondCurrent;
+ LeapSecondChangeInfo leapSecondChangeInfo;
+};
+
+typedef uint32_t LocationSystemInfoMask;
+typedef enum {
+ // contains current leap second or leap second change info
+ LOCATION_SYS_INFO_LEAP_SECOND = (1ULL << 0),
+} LocationSystemInfoDataBits;
+
+struct LocationSystemInfo {
+ LocationSystemInfoMask systemInfoMask;
+ LeapSecondSystemInfo leapSecondSysInfo;
+};
+
+/* Provides the capabilities of the system
+ capabilities callback is called once soon after createInstance is called */
+typedef std::function<void(
+ LocationCapabilitiesMask capabilitiesMask // bitwise OR of LocationCapabilitiesBits
+)> capabilitiesCallback;
+
+/* Used by tracking, batching, and miscellanous APIs
+ responseCallback is called for every Tracking, Batching API, and Miscellanous API */
+typedef std::function<void(
+ LocationError err, // if not SUCCESS, then id is not valid
+ uint32_t id // id to be associated to the request
+)> responseCallback;
+
+/* Used by APIs that gets more than one LocationError in it's response
+ collectiveResponseCallback is called for every geofence API call.
+ ids array and LocationError array are only valid until collectiveResponseCallback returns. */
+typedef std::function<void(
+ uint32_t count, // number of locations in arrays
+ LocationError* errs, // array of LocationError associated to the request
+ uint32_t* ids // array of ids to be associated to the request
+)> collectiveResponseCallback;
+
+/* Used for startTracking API, optional can be NULL
+ trackingCallback is called when delivering a location in a tracking session
+ broadcasted to all clients, no matter if a session has started by client */
+typedef std::function<void(
+ Location location
+)> trackingCallback;
+
+/* Used for startBatching API, optional can be NULL
+ batchingCallback is called when delivering locations in a batching session.
+ broadcasted to all clients, no matter if a session has started by client */
+typedef std::function<void(
+ uint32_t count, // number of locations in array
+ Location* location, // array of locations
+ BatchingOptions batchingOptions // Batching options
+)> batchingCallback;
+
+typedef std::function<void(
+ BatchingStatusInfo batchingStatus, // batch status
+ std::list<uint32_t> & listOfCompletedTrips
+)> batchingStatusCallback;
+
+/* Gives GNSS Location information, optional can be NULL
+ gnssLocationInfoCallback is called only during a tracking session
+ broadcasted to all clients, no matter if a session has started by client */
+typedef std::function<void(
+ GnssLocationInfoNotification gnssLocationInfoNotification
+)> gnssLocationInfoCallback;
+
+/* Gives default combined location information from all engines and
+ location information individually from selected engines.
+ This callback is only used when there are multiple engines
+ running in the system.
+
+ optional can be NULL
+
+ engineLocationsInfoCallback is called only during a tracking session
+ broadcasted to all clients, no matter if a session has started by client */
+typedef std::function<void(
+ uint32_t count,
+ GnssLocationInfoNotification* engineLocationInfoNotification
+)> engineLocationsInfoCallback;
+
+/* Used for addGeofences API, optional can be NULL
+ geofenceBreachCallback is called when any number of geofences have a state change */
+typedef std::function<void(
+ GeofenceBreachNotification geofenceBreachNotification
+)> geofenceBreachCallback;
+
+/* Used for addGeofences API, optional can be NULL
+ geofenceStatusCallback is called when any number of geofences have a status change */
+typedef std::function<void(
+ GeofenceStatusNotification geofenceStatusNotification
+)> geofenceStatusCallback;
+
+/* Network Initiated request, optional can be NULL
+ This callback should be responded to by calling gnssNiResponse */
+typedef std::function<void(
+ uint32_t id, // id that should be used to respond by calling gnssNiResponse
+ GnssNiNotification gnssNiNotification
+)> gnssNiCallback;
+
+/* Gives GNSS SV information, optional can be NULL
+ gnssSvCallback is called only during a tracking session
+ broadcasted to all clients, no matter if a session has started by client */
+typedef std::function<void(
+ GnssSvNotification gnssSvNotification
+)> gnssSvCallback;
+
+/* Gives GNSS NMEA data, optional can be NULL
+ gnssNmeaCallback is called only during a tracking session
+ broadcasted to all clients, no matter if a session has started by client */
+typedef std::function<void(
+ GnssNmeaNotification gnssNmeaNotification
+)> gnssNmeaCallback;
+
+/* Gives GNSS data, optional can be NULL
+ gnssDataCallback is called only during a tracking session
+ broadcasted to all clients, no matter if a session has started by client */
+typedef std::function<void(
+ GnssDataNotification gnssDataNotification
+)> gnssDataCallback;
+
+/* Gives GNSS Measurements information, optional can be NULL
+ gnssMeasurementsCallback is called only during a tracking session
+ broadcasted to all clients, no matter if a session has started by client */
+typedef std::function<void(
+ GnssMeasurementsNotification gnssMeasurementsNotification
+)> gnssMeasurementsCallback;
+
+/* Provides the current GNSS configuration to the client */
+typedef std::function<void(
+ GnssConfig& config
+)> gnssConfigCallback;
+
+/* LocationSystemInfoCb is for receiving rare occuring location
+ system information update. optional, can be NULL.
+*/
+typedef std::function<void(
+ LocationSystemInfo locationSystemInfo
+)> locationSystemInfoCallback;
+
+typedef std::function<void(
+)> locationApiDestroyCompleteCallback;
+
+typedef uint16_t LocationAdapterTypeMask;
+typedef enum {
+ LOCATION_ADAPTER_GNSS_TYPE_BIT = (1<<0), // adapter type is GNSS
+ LOCATION_ADAPTER_BATCHING_TYPE_BIT = (1<<1), // adapter type is BATCHING
+ LOCATION_ADAPTER_GEOFENCE_TYPE_BIT = (1<<2) // adapter type is geo fence
+} LocationAdapterTypeBits;
+
+typedef struct {
+ uint32_t size; // set to sizeof(LocationCallbacks)
+ capabilitiesCallback capabilitiesCb; // mandatory
+ responseCallback responseCb; // mandatory
+ collectiveResponseCallback collectiveResponseCb; // mandatory
+ trackingCallback trackingCb; // optional
+ batchingCallback batchingCb; // optional
+ geofenceBreachCallback geofenceBreachCb; // optional
+ geofenceStatusCallback geofenceStatusCb; // optional
+ gnssLocationInfoCallback gnssLocationInfoCb; // optional
+ gnssNiCallback gnssNiCb; // optional
+ gnssSvCallback gnssSvCb; // optional
+ gnssNmeaCallback gnssNmeaCb; // optional
+ gnssDataCallback gnssDataCb; // optional
+ gnssMeasurementsCallback gnssMeasurementsCb; // optional
+ batchingStatusCallback batchingStatusCb; // optional
+ locationSystemInfoCallback locationSystemInfoCb; // optional
+ engineLocationsInfoCallback engineLocationsInfoCb; // optional
+} LocationCallbacks;
+
+#endif /* LOCATIONDATATYPES_H */
diff --git a/gps/location/Makefile.am b/gps/location/Makefile.am
deleted file mode 100644
index 3688cc8..0000000
--- a/gps/location/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-ACLOCAL_AMFLAGS = -I m4
-
-AM_CFLAGS = \
- -I./ \
- -I../utils \
- $(LOCPLA_CFLAGS) \
- $(GPSUTILS_CFLAGS) \
- -std=c++11
-
-liblocation_api_la_SOURCES = \
- LocationAPI.cpp \
- LocationAPIClientBase.cpp
-
-if USE_GLIB
-liblocation_api_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
-liblocation_api_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
-liblocation_api_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
-else
-liblocation_api_la_CFLAGS = $(AM_CFLAGS)
-liblocation_api_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
-liblocation_api_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
-endif
-
-liblocation_api_la_LIBADD = -lstdc++ -ldl $(GPSUTILS_LIBS)
-
-library_include_HEADERS = \
- LocationAPI.h \
- LocationAPIClientBase.h \
- location_interface.h
-
-#Create and Install libraries
-lib_LTLIBRARIES = liblocation_api.la
-
-library_includedir = $(pkgincludedir)
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = location-api.pc
-EXTRA_DIST = $(pkgconfig_DATA)
diff --git a/gps/location/configure.ac b/gps/location/configure.ac
deleted file mode 100644
index 6391d65..0000000
--- a/gps/location/configure.ac
+++ /dev/null
@@ -1,82 +0,0 @@
-# configure.ac -- Autoconf script for gps location-api-iface
-#
-# Process this file with autoconf to produce a configure script
-
-# Requires autoconf tool later than 2.61
-AC_PREREQ(2.61)
-# Initialize the gps location-api-iface package version 1.0.0
-AC_INIT([location-api-iface],1.0.0)
-# Does not strictly follow GNU Coding standards
-AM_INIT_AUTOMAKE([foreign])
-# Disables auto rebuilding of configure, Makefile.ins
-AM_MAINTAINER_MODE
-# Verifies the --srcdir is correct by checking for the path
-AC_CONFIG_SRCDIR([location-api.pc.in])
-# defines some macros variable to be included by source
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_MACRO_DIR([m4])
-
-# Checks for programs.
-AC_PROG_LIBTOOL
-AC_PROG_CXX
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_AWK
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-PKG_PROG_PKG_CONFIG
-
-# Checks for libraries.
-PKG_CHECK_MODULES([GPSUTILS], [gps-utils])
-AC_SUBST([GPSUTILS_CFLAGS])
-AC_SUBST([GPSUTILS_LIBS])
-
-AC_ARG_WITH([core_includes],
- AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
- [Specify the location of the core headers]),
- [core_incdir=$withval],
- with_core_includes=no)
-
-if test "x$with_core_includes" != "xno"; then
- CPPFLAGS="${CPPFLAGS} -I${core_incdir}"
-fi
-
-AC_ARG_WITH([locpla_includes],
- AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@],
- [Specify the path to locpla-includes in loc-pla_git.bb]),
- [locpla_incdir=$withval],
- with_locpla_includes=no)
-
-if test "x${with_locpla_includes}" != "xno"; then
- AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}")
-fi
-
-AC_SUBST([CPPFLAGS])
-
-AC_ARG_WITH([glib],
- AC_HELP_STRING([--with-glib],
- [enable glib, building HLOS systems which use glib]))
-
-if (test "x${with_glib}" = "xyes"); then
- AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
- PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GThread >= 2.16 is required))
- PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GLib >= 2.16 is required))
- GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
- GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
-
- AC_SUBST(GLIB_CFLAGS)
- AC_SUBST(GLIB_LIBS)
-fi
-
-AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
-
-AC_CONFIG_FILES([ \
- Makefile \
- location-api.pc \
- ])
-
-AC_OUTPUT
diff --git a/gps/location/location-api.pc.in b/gps/location/location-api.pc.in
deleted file mode 100644
index c7b146a..0000000
--- a/gps/location/location-api.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: location-api
-Description: Location API
-Version: @VERSION
-Libs: -L${libdir} -llocation_api
-Cflags: -I${includedir}/location-api
diff --git a/gps/location/location_interface.h b/gps/location/location_interface.h
index 9229052..fb15bea 100644
--- a/gps/location/location_interface.h
+++ b/gps/location/location_interface.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019 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
@@ -32,21 +32,41 @@
#include <LocationAPI.h>
#include <gps_extended_c.h>
+/* Used for callback to deliver GNSS energy consumed */
+/** @fn
+ @brief Used by query API that retrieves energy consumed by
+ modem GNSS engine.
+
+ @param gnssEnergyConsumedFromFirstBoot:
+ Energy consumed by the GNSS engine since the first bootup
+ in units of 0.1 milli watt seconds.
+ A value of 0xffffffffffffffff indicates an invalid reading.
+*/
+typedef std::function<void(
+ uint64_t gnssEnergyConsumedFromFirstBoot
+)> GnssEnergyConsumedCallback;
+
+typedef void (*removeClientCompleteCallback)(LocationAPI* client);
+
struct GnssInterface {
size_t size;
void (*initialize)(void);
void (*deinitialize)(void);
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
- void (*removeClient)(LocationAPI* client);
+ void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
void (*requestCapabilities)(LocationAPI* client);
- uint32_t (*startTracking)(LocationAPI* client, LocationOptions& options);
- void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, LocationOptions& options);
+ uint32_t (*startTracking)(LocationAPI* client, TrackingOptions&);
+ void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, TrackingOptions&);
void (*stopTracking)(LocationAPI* client, uint32_t id);
void (*gnssNiResponse)(LocationAPI* client, uint32_t id, GnssNiResponse response);
void (*setControlCallbacks)(LocationControlCallbacks& controlCallbacks);
uint32_t (*enable)(LocationTechnologyType techType);
void (*disable)(uint32_t id);
uint32_t* (*gnssUpdateConfig)(GnssConfig config);
+ uint32_t* (*gnssGetConfig)(GnssConfigFlagsMask config);
+ void (*gnssUpdateSvTypeConfig)(GnssSvTypeConfig& config);
+ void (*gnssGetSvTypeConfig)(GnssSvTypeConfigCallback& callback);
+ void (*gnssResetSvTypeConfig)();
uint32_t (*gnssDeleteAidingData)(GnssAidingData& data);
void (*gnssUpdateXtraThrottle)(const bool enabled);
void (*injectLocation)(double latitude, double longitude, float accuracy);
@@ -56,27 +76,31 @@ struct GnssInterface {
void (*agpsDataConnClosed)(AGpsExtType agpsType);
void (*agpsDataConnFailed)(AGpsExtType agpsType);
void (*getDebugReport)(GnssDebugReport& report);
- void (*updateConnectionStatus)(bool connected, int8_t type);
+ void (*updateConnectionStatus)(bool connected, int8_t type, bool roaming,
+ NetworkHandle networkHandle);
void (*odcpiInit)(const OdcpiRequestCallback& callback);
void (*odcpiInject)(const Location& location);
+ void (*blockCPI)(double latitude, double longitude, float accuracy,
+ int blockDurationMsec, double latLonDiffThreshold);
+ void (*getGnssEnergyConsumed)(GnssEnergyConsumedCallback energyConsumedCb);
+ void (*enableNfwLocationAccess)(bool enable);
+ void (*nfwInit)(const NfwCbInfo& cbInfo);
+ void (*getPowerStateChanges)(void* powerStateCb);
+ void (*injectLocationExt)(const GnssLocationInfoNotification &locationInfo);
+ void (*updateBatteryStatus)(bool charging);
};
-struct FlpInterface {
+struct BatchingInterface {
size_t size;
void (*initialize)(void);
void (*deinitialize)(void);
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
- void (*removeClient)(LocationAPI* client);
+ void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
void (*requestCapabilities)(LocationAPI* client);
- uint32_t (*startTracking)(LocationAPI* client, LocationOptions& options);
- void (*updateTrackingOptions)(LocationAPI* client, uint32_t id, LocationOptions& options);
- void (*stopTracking)(LocationAPI* client, uint32_t id);
- uint32_t (*startBatching)(LocationAPI* client, LocationOptions&, BatchingOptions&);
+ uint32_t (*startBatching)(LocationAPI* client, BatchingOptions&);
void (*stopBatching)(LocationAPI* client, uint32_t id);
- void (*updateBatchingOptions)(LocationAPI* client, uint32_t id, LocationOptions&,
- BatchingOptions&);
+ void (*updateBatchingOptions)(LocationAPI* client, uint32_t id, BatchingOptions&);
void (*getBatchedLocations)(LocationAPI* client, uint32_t id, size_t count);
- void (*getPowerStateChanges)(void* powerStateCb);
};
struct GeofenceInterface {
@@ -84,7 +108,7 @@ struct GeofenceInterface {
void (*initialize)(void);
void (*deinitialize)(void);
void (*addClient)(LocationAPI* client, const LocationCallbacks& callbacks);
- void (*removeClient)(LocationAPI* client);
+ void (*removeClient)(LocationAPI* client, removeClientCompleteCallback rmClientCb);
void (*requestCapabilities)(LocationAPI* client);
uint32_t* (*addGeofences)(LocationAPI* client, size_t count, GeofenceOption*, GeofenceInfo*);
void (*removeGeofences)(LocationAPI* client, size_t count, uint32_t* ids);
diff --git a/gps/pla/Android.mk b/gps/pla/Android.mk
index 5d6bb97..a57861d 100644
--- a/gps/pla/Android.mk
+++ b/gps/pla/Android.mk
@@ -1,6 +1,19 @@
GNSS_CFLAGS := \
-Werror \
- -Wno-undefined-bool-conversion
+ -Wno-error=unused-parameter \
+ -Wno-error=macro-redefined \
+ -Wno-error=reorder \
+ -Wno-error=missing-braces \
+ -Wno-error=self-assign \
+ -Wno-error=enum-conversion \
+ -Wno-error=logical-op-parentheses \
+ -Wno-error=null-arithmetic \
+ -Wno-error=null-conversion \
+ -Wno-error=parentheses-equality \
+ -Wno-error=undefined-bool-conversion \
+ -Wno-error=tautological-compare \
+ -Wno-error=switch \
+ -Wno-error=date-time
ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
ifneq ($(BUILD_TINY_ANDROID),true)
diff --git a/gps/pla/android/loc_pla.h b/gps/pla/android/loc_pla.h
index 74bc2f2..ab8c75e 100644
--- a/gps/pla/android/loc_pla.h
+++ b/gps/pla/android/loc_pla.h
@@ -40,6 +40,14 @@ extern "C" {
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
+#include <cutils/android_filesystem_config.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define UID_GPS (AID_GPS)
+#define GID_GPS (AID_GPS)
+#define UID_LOCCLIENT (4021)
+#define GID_LOCCLIENT (4021)
#define LOC_PATH_GPS_CONF_STR "/vendor/etc/gps.conf"
#define LOC_PATH_IZAT_CONF_STR "/vendor/etc/izat.conf"
diff --git a/gps/pla/oe/loc_pla.h b/gps/pla/oe/loc_pla.h
index 6c6dde9..1e3d6c5 100644
--- a/gps/pla/oe/loc_pla.h
+++ b/gps/pla/oe/loc_pla.h
@@ -30,15 +30,33 @@
#define __LOC_PLA__
#ifdef __cplusplus
+#ifndef FEATURE_EXTERNAL_AP
#include <utils/SystemClock.h>
-#define uptimeMillis android::uptimeMillis
+#endif /* FEATURE_EXTERNAL_AP */
+#include <inttypes.h>
+#include <sys/time.h>
+#include <time.h>
+
+inline int64_t uptimeMillis()
+{
+ struct timespec ts;
+ int64_t time_ms = 0;
+ clock_gettime(CLOCK_BOOTTIME, &ts);
+ time_ms += (ts.tv_sec * 1000000000LL);
+ time_ms += ts.tv_nsec + 500000LL;
+ return time_ms / 1000000LL;
+}
extern "C" {
#endif
+#ifndef FEATURE_EXTERNAL_AP
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
+#endif /* FEATURE_EXTERNAL_AP */
+#include <pthread.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#ifndef OFF_TARGET
@@ -50,6 +68,11 @@ extern "C" {
#define strlcpy strncpy
#endif
+#define UID_GPS (1021)
+#define GID_GPS (1021)
+#define UID_LOCCLIENT (4021)
+#define GID_LOCCLIENT (4021)
+
#define LOC_PATH_GPS_CONF_STR "/etc/gps.conf"
#define LOC_PATH_IZAT_CONF_STR "/etc/izat.conf"
#define LOC_PATH_FLP_CONF_STR "/etc/flp.conf"
@@ -59,6 +82,16 @@ extern "C" {
#define LOC_PATH_XTWIFI_CONF_STR "/etc/xtwifi.conf"
#define LOC_PATH_QUIPC_CONF_STR "/etc/quipc.conf"
+#ifdef FEATURE_EXTERNAL_AP
+#define PROPERTY_VALUE_MAX 92
+
+inline int property_get(const char* key, char* value, const char* default_value)
+{
+ strlcpy(value, default_value, PROPERTY_VALUE_MAX - 1);
+ return strlen(value);
+}
+#endif /* FEATURE_EXTERNAL_AP */
+
#ifdef __cplusplus
}
#endif /*__cplusplus */
diff --git a/gps/utils/Android.mk b/gps/utils/Android.mk
index ec6bf05..88ad487 100644
--- a/gps/utils/Android.mk
+++ b/gps/utils/Android.mk
@@ -9,6 +9,7 @@ include $(CLEAR_VARS)
## Libs
LOCAL_SHARED_LIBRARIES := \
+ libdl \
libutils \
libcutils \
liblog \
@@ -46,6 +47,9 @@ LOCAL_HEADER_LIBRARIES := \
liblocation_api_headers
LOCAL_MODULE := libgps.utils
+LOCAL_SANITIZE += $(GNSS_SANITIZE)
+# activate the following line for debug purposes only, comment out for production
+#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG)
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
diff --git a/gps/utils/LocIpc.cpp b/gps/utils/LocIpc.cpp
index 675664a..64d27cb 100644
--- a/gps/utils/LocIpc.cpp
+++ b/gps/utils/LocIpc.cpp
@@ -30,8 +30,14 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <loc_misc_utils.h>
#include <log_util.h>
-#include "LocIpc.h"
+#include <LocIpc.h>
+#include <algorithm>
+
+using namespace std;
namespace loc_util {
@@ -40,198 +46,369 @@ namespace loc_util {
#endif
#define LOG_TAG "LocSvc_LocIpc"
-#define LOC_MSG_BUF_LEN 8192
-#define LOC_MSG_HEAD "$MSGLEN$"
-#define LOC_MSG_ABORT "LocIpcMsg::ABORT"
+#define SOCK_OP_AND_LOG(buf, length, opable, rtv, exe) \
+ if (nullptr == (buf) || 0 == (length)) { \
+ LOC_LOGe("Invalid inputs: buf - %p, length - %u", (buf), (length)); \
+ } else if (!(opable)) { \
+ LOC_LOGe("Invalid object: operable - %d", (opable)); \
+ } else { \
+ rtv = (exe); \
+ if (-1 == rtv) { \
+ LOC_LOGw("failed reason: %s", strerror(errno)); \
+ } \
+ }
-class LocIpcRunnable : public LocRunnable {
-friend LocIpc;
-public:
- LocIpcRunnable(LocIpc& locIpc, const std::string& ipcName)
- : mLocIpc(locIpc), mIpcName(ipcName) {}
- bool run() override {
- if (!mLocIpc.startListeningBlocking(mIpcName)) {
- LOC_LOGe("listen to socket failed");
+const char Sock::MSG_ABORT[] = "LocIpc::Sock::ABORT";
+const char Sock::LOC_IPC_HEAD[] = "$MSGLEN$";
+ssize_t Sock::send(const void *buf, uint32_t len, int flags, const struct sockaddr *destAddr,
+ socklen_t addrlen) const {
+ ssize_t rtv = -1;
+ SOCK_OP_AND_LOG(buf, len, isValid(), rtv, sendto(buf, len, flags, destAddr, addrlen));
+ return rtv;
+}
+ssize_t Sock::recv(const LocIpcRecver& recver, const shared_ptr<ILocIpcListener>& dataCb, int flags,
+ struct sockaddr *srcAddr, socklen_t *addrlen, int sid) const {
+ ssize_t rtv = -1;
+ if (-1 == sid) {
+ sid = mSid;
+ } // else it sid would be connection based socket id for recv
+ SOCK_OP_AND_LOG(dataCb.get(), mMaxTxSize, isValid(), rtv,
+ recvfrom(recver, dataCb, sid, flags, srcAddr, addrlen));
+ return rtv;
+}
+ssize_t Sock::sendto(const void *buf, size_t len, int flags, const struct sockaddr *destAddr,
+ socklen_t addrlen) const {
+ ssize_t rtv = -1;
+ if (len <= mMaxTxSize) {
+ rtv = ::sendto(mSid, buf, len, flags, destAddr, addrlen);
+ } else {
+ std::string head(LOC_IPC_HEAD + to_string(len));
+ rtv = ::sendto(mSid, head.c_str(), head.length(), flags, destAddr, addrlen);
+ if (rtv > 0) {
+ for (size_t offset = 0; offset < len && rtv > 0; offset += rtv) {
+ rtv = ::sendto(mSid, (char*)buf + offset, min(len - offset, (size_t)mMaxTxSize),
+ flags, destAddr, addrlen);
+ }
+ rtv = (rtv > 0) ? (head.length() + len) : -1;
}
-
- return false;
}
-private:
- LocIpc& mLocIpc;
- const std::string mIpcName;
-};
-
-bool LocIpc::startListeningNonBlocking(const std::string& name) {
- mRunnable = new LocIpcRunnable(*this, name);
- std::string threadName("LocIpc-");
- threadName.append(name);
- return mThread.start(threadName.c_str(), mRunnable);
+ return rtv;
}
+ssize_t Sock::recvfrom(const LocIpcRecver& recver, const shared_ptr<ILocIpcListener>& dataCb,
+ int sid, int flags, struct sockaddr *srcAddr, socklen_t *addrlen) const {
+ std::string msg(mMaxTxSize, 0);
+ ssize_t nBytes = ::recvfrom(sid, (void*)msg.data(), msg.size(), flags, srcAddr, addrlen);
+ if (nBytes > 0) {
+ if (strncmp(msg.data(), MSG_ABORT, sizeof(MSG_ABORT)) == 0) {
+ LOC_LOGi("recvd abort msg.data %s", msg.data());
+ nBytes = 0;
+ } else if (strncmp(msg.data(), LOC_IPC_HEAD, sizeof(LOC_IPC_HEAD) - 1)) {
+ // short message
+ msg.resize(nBytes);
+ dataCb->onReceive(msg.data(), nBytes, &recver);
+ } else {
+ // long message
+ size_t msgLen = 0;
+ sscanf(msg.data() + sizeof(LOC_IPC_HEAD) - 1, "%zu", &msgLen);
+ msg.resize(msgLen);
+ for (size_t msgLenReceived = 0; (msgLenReceived < msgLen) && (nBytes > 0);
+ msgLenReceived += nBytes) {
+ nBytes = ::recvfrom(sid, &(msg[msgLenReceived]), msg.size() - msgLenReceived,
+ flags, srcAddr, addrlen);
+ }
+ if (nBytes > 0) {
+ nBytes = msgLen;
+ dataCb->onReceive(msg.data(), nBytes, &recver);
+ }
+ }
+ }
-bool LocIpc::startListeningBlocking(const std::string& name) {
+ return nBytes;
+}
+ssize_t Sock::sendAbort(int flags, const struct sockaddr *destAddr, socklen_t addrlen) {
+ return send(MSG_ABORT, sizeof(MSG_ABORT), flags, destAddr, addrlen);
+}
- int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
- if (fd < 0) {
- LOC_LOGe("create socket error. reason:%s", strerror(errno));
- return false;
+class LocIpcLocalSender : public LocIpcSender {
+protected:
+ shared_ptr<Sock> mSock;
+ struct sockaddr_un mAddr;
+ inline virtual bool isOperable() const override { return mSock != nullptr && mSock->isValid(); }
+ inline virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const {
+ return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr));
}
+public:
+ inline LocIpcLocalSender(const char* name) : LocIpcSender(),
+ mSock(make_shared<Sock>((nullptr == name) ? -1 : (::socket(AF_UNIX, SOCK_DGRAM, 0)))),
+ mAddr({.sun_family = AF_UNIX, {}}) {
+ if (mSock != nullptr && mSock->isValid()) {
+ snprintf(mAddr.sun_path, sizeof(mAddr.sun_path), "%s", name);
+ }
+ }
+};
- if ((unlink(name.c_str()) < 0) && (errno != ENOENT)) {
- LOC_LOGw("unlink socket error. reason:%s", strerror(errno));
+class LocIpcLocalRecver : public LocIpcLocalSender, public LocIpcRecver {
+protected:
+ inline virtual ssize_t recv() const override {
+ socklen_t size = sizeof(mAddr);
+ return mSock->recv(*this, mDataCb, 0, (struct sockaddr*)&mAddr, &size);
}
+public:
+ inline LocIpcLocalRecver(const shared_ptr<ILocIpcListener>& listener, const char* name) :
+ LocIpcLocalSender(name), LocIpcRecver(listener, *this) {
- struct sockaddr_un addr = { .sun_family = AF_UNIX };
- snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", name.c_str());
+ if ((unlink(mAddr.sun_path) < 0) && (errno != ENOENT)) {
+ LOC_LOGw("unlink socket error. reason:%s", strerror(errno));
+ }
- umask(0157);
+ umask(0157);
+ if (mSock->isValid() && ::bind(mSock->mSid, (struct sockaddr*)&mAddr, sizeof(mAddr)) < 0) {
+ LOC_LOGe("bind socket error. sock fd: %d: %s, reason: %s", mSock->mSid,
+ mAddr.sun_path, strerror(errno));
+ mSock->close();
+ }
+ }
+ inline virtual ~LocIpcLocalRecver() { unlink(mAddr.sun_path); }
+ inline virtual const char* getName() const override { return mAddr.sun_path; };
+ inline virtual void abort() const override {
+ if (isSendable()) {
+ mSock->sendAbort(0, (struct sockaddr*)&mAddr, sizeof(mAddr));
+ }
+ }
+};
- if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
- LOC_LOGe("bind socket error. reason:%s", strerror(errno));
- ::close(fd);
- fd = -1;
- return false;
+class LocIpcInetSender : public LocIpcSender {
+protected:
+ int mSockType;
+ shared_ptr<Sock> mSock;
+ const string mName;
+ sockaddr_in mAddr;
+ inline virtual bool isOperable() const override { return mSock != nullptr && mSock->isValid(); }
+ virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const {
+ return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr));
+ }
+public:
+ inline LocIpcInetSender(const LocIpcInetSender& sender) :
+ mSockType(sender.mSockType), mSock(sender.mSock),
+ mName(sender.mName), mAddr(sender.mAddr) {
+ }
+ inline LocIpcInetSender(const char* name, int32_t port, int sockType) : LocIpcSender(),
+ mSockType(sockType),
+ mSock(make_shared<Sock>((nullptr == name) ? -1 : (::socket(AF_INET, mSockType, 0)))),
+ mName((nullptr == name) ? "" : name),
+ mAddr({.sin_family = AF_INET, .sin_port = htons(port),
+ .sin_addr = {htonl(INADDR_ANY)}}) {
+ if (mSock != nullptr && mSock->isValid() && nullptr != name) {
+ struct hostent* hp = gethostbyname(name);
+ if (nullptr != hp) {
+ memcpy((char*)&(mAddr.sin_addr.s_addr), hp->h_addr_list[0], hp->h_length);
+ }
+ }
}
- mIpcFd = fd;
+ unique_ptr<LocIpcRecver> getRecver(const shared_ptr<ILocIpcListener>& listener) override {
+ return make_unique<SockRecver>(listener, *this, mSock);
+ }
+};
- // inform that the socket is ready to receive message
- onListenerReady();
+class LocIpcInetTcpSender : public LocIpcInetSender {
+protected:
+ mutable bool mFirstTime;
- ssize_t nBytes = 0;
- std::string msg = "";
- std::string abort = LOC_MSG_ABORT;
- while (1) {
- msg.resize(LOC_MSG_BUF_LEN);
- nBytes = ::recvfrom(mIpcFd, (void*)(msg.data()), msg.size(), 0, NULL, NULL);
- if (nBytes < 0) {
- break;
- } else if (nBytes == 0) {
- continue;
+ virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const {
+ if (mFirstTime) {
+ mFirstTime = false;
+ ::connect(mSock->mSid, (const struct sockaddr*)&mAddr, sizeof(mAddr));
}
+ return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr));
+ }
- if (strncmp(msg.data(), abort.c_str(), abort.length()) == 0) {
- LOC_LOGi("recvd abort msg.data %s", msg.data());
- break;
+public:
+ inline LocIpcInetTcpSender(const char* name, int32_t port) :
+ LocIpcInetSender(name, port, SOCK_STREAM),
+ mFirstTime(true) {}
+};
+
+class LocIpcInetRecver : public LocIpcInetSender, public LocIpcRecver {
+ int32_t mPort;
+protected:
+ virtual ssize_t recv() const = 0;
+public:
+ inline LocIpcInetRecver(const shared_ptr<ILocIpcListener>& listener, const char* name,
+ int32_t port, int sockType) :
+ LocIpcInetSender(name, port, sockType), LocIpcRecver(listener, *this),
+ mPort(port) {
+ if (mSock->isValid() && ::bind(mSock->mSid, (struct sockaddr*)&mAddr, sizeof(mAddr)) < 0) {
+ LOC_LOGe("bind socket error. sock fd: %d, reason: %s", mSock->mSid, strerror(errno));
+ mSock->close();
+ }
+ }
+ inline virtual ~LocIpcInetRecver() {}
+ inline virtual const char* getName() const override { return mName.data(); };
+ inline virtual void abort() const override {
+ if (isSendable()) {
+ sockaddr_in loopBackAddr = {.sin_family = AF_INET, .sin_port = htons(mPort),
+ .sin_addr = {htonl(INADDR_LOOPBACK)}};
+ mSock->sendAbort(0, (struct sockaddr*)&loopBackAddr, sizeof(loopBackAddr));
}
+ }
+ inline virtual unique_ptr<LocIpcSender> getLastSender() const override {
+ return make_unique<LocIpcInetSender>(static_cast<const LocIpcInetSender&>(*this));
+ }
+};
- if (strncmp(msg.data(), LOC_MSG_HEAD, sizeof(LOC_MSG_HEAD) - 1)) {
- // short message
- msg.resize(nBytes);
- onReceive(msg);
- } else {
- // long message
- size_t msgLen = 0;
- sscanf(msg.data(), LOC_MSG_HEAD"%zu", &msgLen);
- msg.resize(msgLen);
- size_t msgLenReceived = 0;
- while ((msgLenReceived < msgLen) && (nBytes > 0)) {
- nBytes = recvfrom(mIpcFd, (void*)&(msg[msgLenReceived]),
- msg.size() - msgLenReceived, 0, NULL, NULL);
- msgLenReceived += nBytes;
- }
- if (nBytes > 0) {
- onReceive(msg);
- } else {
- break;
+class LocIpcInetTcpRecver : public LocIpcInetRecver {
+ mutable int32_t mConnFd;
+protected:
+ inline virtual ssize_t recv() const override {
+ socklen_t size = sizeof(mAddr);
+ if (-1 == mConnFd && mSock->isValid()) {
+ if (::listen(mSock->mSid, 3) < 0 ||
+ (mConnFd = accept(mSock->mSid, (struct sockaddr*)&mAddr, &size)) < 0) {
+ mSock->close();
+ mConnFd = -1;
}
}
+ return mSock->recv(*this, mDataCb, 0, (struct sockaddr*)&mAddr, &size, mConnFd);
}
+public:
+ inline LocIpcInetTcpRecver(const shared_ptr<ILocIpcListener>& listener, const char* name,
+ int32_t port) :
+ LocIpcInetRecver(listener, name, port, SOCK_STREAM), mConnFd(-1) {}
+ inline virtual ~LocIpcInetTcpRecver() { if (-1 != mConnFd) ::close(mConnFd);}
+};
- if (mStopRequested) {
- mStopRequested = false;
- return true;
- } else {
- LOC_LOGe("cannot read socket. reason:%s", strerror(errno));
- (void)::close(mIpcFd);
- mIpcFd = -1;
- return false;
+class LocIpcInetUdpRecver : public LocIpcInetRecver {
+protected:
+ inline virtual ssize_t recv() const override {
+ socklen_t size = sizeof(mAddr);
+ return mSock->recv(*this, mDataCb, 0, (struct sockaddr*)&mAddr, &size);
}
-}
-
-void LocIpc::stopListening() {
+public:
+ inline LocIpcInetUdpRecver(const shared_ptr<ILocIpcListener>& listener, const char* name,
+ int32_t port) :
+ LocIpcInetRecver(listener, name, port, SOCK_DGRAM) {}
- const char *socketName = nullptr;
- mStopRequested = true;
+ inline virtual ~LocIpcInetUdpRecver() {}
+};
- if (mRunnable) {
- std::string abort = LOC_MSG_ABORT;
- socketName = (reinterpret_cast<LocIpcRunnable *>(mRunnable))->mIpcName.c_str();
- send(socketName, abort);
- mRunnable = nullptr;
+class LocIpcRunnable : public LocRunnable {
+ bool mAbortCalled;
+ LocIpc& mLocIpc;
+ unique_ptr<LocIpcRecver> mIpcRecver;
+public:
+ inline LocIpcRunnable(LocIpc& locIpc, unique_ptr<LocIpcRecver>& ipcRecver) :
+ mAbortCalled(false),
+ mLocIpc(locIpc),
+ mIpcRecver(std::move(ipcRecver)) {}
+ inline bool run() override {
+ if (mIpcRecver != nullptr) {
+ mLocIpc.startBlockingListening(*(mIpcRecver.get()));
+ if (!mAbortCalled) {
+ LOC_LOGw("startListeningBlocking() returned w/o stopBlockingListening() called");
+ }
+ }
+ // return false so the calling thread exits while loop
+ return false;
}
-
- if (mIpcFd >= 0) {
- if (::close(mIpcFd)) {
- LOC_LOGe("cannot close socket:%s", strerror(errno));
+ inline void abort() {
+ mAbortCalled = true;
+ if (mIpcRecver != nullptr) {
+ mIpcRecver->abort();
}
- mIpcFd = -1;
}
+};
- //delete from the file system at the end
- if (socketName) {
- unlink(socketName);
+bool LocIpc::startNonBlockingListening(unique_ptr<LocIpcRecver>& ipcRecver) {
+ if (ipcRecver != nullptr && ipcRecver->isRecvable()) {
+ std::string threadName("LocIpc-");
+ threadName.append(ipcRecver->getName());
+ mRunnable = new LocIpcRunnable(*this, ipcRecver);
+ return mThread.start(threadName.c_str(), mRunnable);
+ } else {
+ LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle");
+ return false;
}
}
-bool LocIpc::send(const char name[], const std::string& data) {
- return send(name, (const uint8_t*)data.c_str(), data.length());
-}
-
-bool LocIpc::send(const char name[], const uint8_t data[], uint32_t length) {
-
- bool result = true;
- int fd = ::socket(AF_UNIX, SOCK_DGRAM, 0);
- if (fd < 0) {
- LOC_LOGe("create socket error. reason:%s", strerror(errno));
+bool LocIpc::startBlockingListening(LocIpcRecver& ipcRecver) {
+ if (ipcRecver.isRecvable()) {
+ // inform that the socket is ready to receive message
+ ipcRecver.onListenerReady();
+ while (ipcRecver.recvData());
+ return true;
+ } else {
+ LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle");
return false;
}
-
- struct sockaddr_un addr = { .sun_family = AF_UNIX };
- snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", name);
-
- result = sendData(fd, addr, data, length);
-
- (void)::close(fd);
- return result;
}
+void LocIpc::stopNonBlockingListening() {
+ if (mRunnable) {
+ mRunnable->abort();
+ mRunnable = nullptr;
+ }
+}
-bool LocIpc::sendData(int fd, const sockaddr_un &addr, const uint8_t data[], uint32_t length) {
+void LocIpc::stopBlockingListening(LocIpcRecver& ipcRecver) {
+ if (ipcRecver.isRecvable()) {
+ ipcRecver.abort();
+ }
+}
- bool result = true;
+bool LocIpc::send(LocIpcSender& sender, const uint8_t data[], uint32_t length, int32_t msgId) {
+ return sender.sendData(data, length, msgId);
+}
- if (length <= LOC_MSG_BUF_LEN) {
- if (::sendto(fd, data, length, 0,
- (struct sockaddr*)&addr, sizeof(addr)) < 0) {
- LOC_LOGe("cannot send to socket. reason:%s", strerror(errno));
- result = false;
- }
- } else {
- std::string head = LOC_MSG_HEAD;
- head.append(std::to_string(length));
- if (::sendto(fd, head.c_str(), head.length(), 0,
- (struct sockaddr*)&addr, sizeof(addr)) < 0) {
- LOC_LOGe("cannot send to socket. reason:%s", strerror(errno));
- result = false;
- } else {
- size_t sentBytes = 0;
- while(sentBytes < length) {
- size_t partLen = length - sentBytes;
- if (partLen > LOC_MSG_BUF_LEN) {
- partLen = LOC_MSG_BUF_LEN;
- }
- ssize_t rv = ::sendto(fd, data + sentBytes, partLen, 0,
- (struct sockaddr*)&addr, sizeof(addr));
- if (rv < 0) {
- LOC_LOGe("cannot send to socket. reason:%s", strerror(errno));
- result = false;
- break;
- }
- sentBytes += rv;
- }
- }
- }
- return result;
+shared_ptr<LocIpcSender> LocIpc::getLocIpcLocalSender(const char* localSockName) {
+ return make_shared<LocIpcLocalSender>(localSockName);
+}
+unique_ptr<LocIpcRecver> LocIpc::getLocIpcLocalRecver(const shared_ptr<ILocIpcListener>& listener,
+ const char* localSockName) {
+ return make_unique<LocIpcLocalRecver>(listener, localSockName);
+}
+static void* sLibQrtrHandle = nullptr;
+static const char* sLibQrtrName = "libloc_socket.so";
+shared_ptr<LocIpcSender> LocIpc::getLocIpcQrtrSender(int service, int instance) {
+ typedef shared_ptr<LocIpcSender> (*creator_t) (int, int);
+ static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName,
+ "_ZN8loc_util22createLocIpcQrtrSenderEii");
+ return (nullptr == creator) ? nullptr : creator(service, instance);
+}
+unique_ptr<LocIpcRecver> LocIpc::getLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener,
+ int service, int instance) {
+ typedef unique_ptr<LocIpcRecver> (*creator_t)(const shared_ptr<ILocIpcListener>&, int, int);
+ static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName,
+#ifdef USE_GLIB
+ "_ZN8loc_util22createLocIpcQrtrRecverERKSt10shared_ptrINS_15ILocIpcListenerEEii");
+#else
+ "_ZN8loc_util22createLocIpcQrtrRecverERKNSt3__110shared_ptrINS_15ILocIpcListenerEEEii");
+#endif
+ return (nullptr == creator) ? nullptr : creator(listener, service, instance);
+}
+shared_ptr<LocIpcSender> LocIpc::getLocIpcInetTcpSender(const char* serverName, int32_t port) {
+ return make_shared<LocIpcInetTcpSender>(serverName, port);
+}
+unique_ptr<LocIpcRecver> LocIpc::getLocIpcInetTcpRecver(const shared_ptr<ILocIpcListener>& listener,
+ const char* serverName, int32_t port) {
+ return make_unique<LocIpcInetTcpRecver>(listener, serverName, port);
+}
+shared_ptr<LocIpcSender> LocIpc::getLocIpcInetUdpSender(const char* serverName, int32_t port) {
+ return make_shared<LocIpcInetSender>(serverName, port, SOCK_DGRAM);
+}
+unique_ptr<LocIpcRecver> LocIpc::getLocIpcInetUdpRecver(const shared_ptr<ILocIpcListener>& listener,
+ const char* serverName, int32_t port) {
+ return make_unique<LocIpcInetUdpRecver>(listener, serverName, port);
+}
+pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>>
+ LocIpc::getLocIpcQmiLocServiceSenderRecverPair(const shared_ptr<ILocIpcListener>& listener, int instance) {
+ typedef pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>> (*creator_t)(const shared_ptr<ILocIpcListener>&, int);
+ static void* sLibEmuHandle = nullptr;
+ static creator_t creator = (creator_t)dlGetSymFromLib(sLibEmuHandle, "libloc_emu.so",
+ "_ZN13QmiLocService41createLocIpcQmiLocServiceSenderRecverPairERKNSt3__110shared_ptrIN8loc_util15ILocIpcListenerEEEi");
+ return (nullptr == creator) ?
+ make_pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>>(nullptr, nullptr) :
+ creator(listener, instance);
}
}
diff --git a/gps/utils/LocIpc.h b/gps/utils/LocIpc.h
index 364093b..d6f8d1d 100644
--- a/gps/utils/LocIpc.h
+++ b/gps/utils/LocIpc.h
@@ -27,8 +27,8 @@
*
*/
-#ifndef __LOC_SOCKET__
-#define __LOC_SOCKET__
+#ifndef __LOC_IPC__
+#define __LOC_IPC__
#include <string>
#include <memory>
@@ -37,33 +37,71 @@
#include <sys/un.h>
#include <LocThread.h>
+using namespace std;
+
namespace loc_util {
+
+class LocIpcRecver;
class LocIpcSender;
+class LocIpcRunnable;
+
+class ILocIpcListener {
+protected:
+ inline virtual ~ILocIpcListener() {}
+public:
+ // LocIpc client can overwrite this function to get notification
+ // when the socket for LocIpc is ready to receive messages.
+ inline virtual void onListenerReady() {}
+ virtual void onReceive(const char* data, uint32_t len, const LocIpcRecver* recver) = 0;
+};
+
class LocIpc {
-friend LocIpcSender;
public:
- inline LocIpc() : mIpcFd(-1), mStopRequested(false), mRunnable(nullptr) {}
- inline virtual ~LocIpc() { stopListening(); }
+ inline LocIpc() : mRunnable(nullptr) {}
+ inline virtual ~LocIpc() {
+ stopNonBlockingListening();
+ }
+
+ static shared_ptr<LocIpcSender>
+ getLocIpcLocalSender(const char* localSockName);
+ static shared_ptr<LocIpcSender>
+ getLocIpcInetUdpSender(const char* serverName, int32_t port);
+ static shared_ptr<LocIpcSender>
+ getLocIpcInetTcpSender(const char* serverName, int32_t port);
+ static shared_ptr<LocIpcSender>
+ getLocIpcQrtrSender(int service, int instance);
+
+ static unique_ptr<LocIpcRecver>
+ getLocIpcLocalRecver(const shared_ptr<ILocIpcListener>& listener,
+ const char* localSockName);
+ static unique_ptr<LocIpcRecver>
+ getLocIpcInetUdpRecver(const shared_ptr<ILocIpcListener>& listener,
+ const char* serverName, int32_t port);
+ static unique_ptr<LocIpcRecver>
+ getLocIpcInetTcpRecver(const shared_ptr<ILocIpcListener>& listener,
+ const char* serverName, int32_t port);
+ static unique_ptr<LocIpcRecver>
+ getLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener,
+ int service, int instance);
+
+ static pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>>
+ getLocIpcQmiLocServiceSenderRecverPair(const shared_ptr<ILocIpcListener>& listener,
+ int instance);
// Listen for new messages in current thread. Calling this funciton will
- // block current thread. The listening can be stopped by calling stopListening().
- //
- // Argument name is the path of the unix local socket to be listened.
- // The function will return true on success, and false on failure.
- bool startListeningBlocking(const std::string& name);
+ // block current thread.
+ // The listening can be stopped by calling stopBlockingListening() passing
+ // in the same ipcRecver obj handle.
+ static bool startBlockingListening(LocIpcRecver& ipcRecver);
+ static void stopBlockingListening(LocIpcRecver& ipcRecver);
// Create a new LocThread and listen for new messages in it.
// Calling this function will return immediately and won't block current thread.
- // The listening can be stopped by calling stopListening().
- //
- // Argument name is the path of the unix local socket to be be listened.
- // The function will return true on success, and false on failure.
- bool startListeningNonBlocking(const std::string& name);
-
- // Stop listening to new messages.
- void stopListening();
+ // The listening can be stopped by calling stopNonBlockingListening().
+ bool startNonBlockingListening(unique_ptr<LocIpcRecver>& ipcRecver);
+ void stopNonBlockingListening();
// Send out a message.
// Call this function to send a message in argument data to socket in argument name.
@@ -71,83 +109,98 @@ public:
// Argument name contains the name of the target unix socket. data contains the
// message to be sent out. Convert your message to a string before calling this function.
// The function will return true on success, and false on failure.
- static bool send(const char name[], const std::string& data);
- static bool send(const char name[], const uint8_t data[], uint32_t length);
-
-protected:
- // Callback function for receiving incoming messages.
- // Override this function in your derived class to process incoming messages.
- // For each received message, this callback function will be called once.
- // This callback function will be called in the calling thread of startListeningBlocking
- // or in the new LocThread created by startListeningNonBlocking.
- //
- // Argument data contains the received message. You need to parse it.
- inline virtual void onReceive(const std::string& /*data*/) {}
-
- // LocIpc client can overwrite this function to get notification
- // when the socket for LocIpc is ready to receive messages.
- inline virtual void onListenerReady() {}
+ static bool send(LocIpcSender& sender, const uint8_t data[],
+ uint32_t length, int32_t msgId = -1);
private:
- static bool sendData(int fd, const sockaddr_un& addr,
- const uint8_t data[], uint32_t length);
-
- int mIpcFd;
- bool mStopRequested;
LocThread mThread;
- LocRunnable *mRunnable;
+ LocIpcRunnable *mRunnable;
};
+/* this is only when client needs to implement Sender / Recver that are not already provided by
+ the factor methods prvoided by LocIpc. */
+
class LocIpcSender {
+protected:
+ LocIpcSender() = default;
+ virtual bool isOperable() const = 0;
+ virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t msgId) const = 0;
public:
- // Constructor of LocIpcSender class
- //
- // Argument destSocket contains the full path name of destination socket.
- // This class hides generated fd and destination address object from user.
- inline LocIpcSender(const char* destSocket):
- LocIpcSender(std::make_shared<int>(::socket(AF_UNIX, SOCK_DGRAM, 0)), destSocket) {
- if (-1 == *mSocket) {
- mSocket = nullptr;
- }
+ virtual ~LocIpcSender() = default;
+ virtual void informRecverRestarted() {}
+ inline bool isSendable() const { return isOperable(); }
+ inline bool sendData(const uint8_t data[], uint32_t length, int32_t msgId) const {
+ return isSendable() && (send(data, length, msgId) > 0);
}
-
- // Replicate a new LocIpcSender object with new destination socket.
- inline LocIpcSender* replicate(const char* destSocket) {
- return (nullptr == mSocket) ? nullptr : new LocIpcSender(mSocket, destSocket);
+ virtual unique_ptr<LocIpcRecver> getRecver(const shared_ptr<ILocIpcListener>& listener) {
+ return nullptr;
}
+};
- inline ~LocIpcSender() {
- if (nullptr != mSocket && mSocket.unique()) {
- ::close(*mSocket);
- }
+class LocIpcRecver {
+ LocIpcSender& mIpcSender;
+protected:
+ const shared_ptr<ILocIpcListener> mDataCb;
+ inline LocIpcRecver(const shared_ptr<ILocIpcListener>& listener, LocIpcSender& sender) :
+ mIpcSender(sender), mDataCb(listener) {}
+ LocIpcRecver(LocIpcRecver const& recver) = delete;
+ LocIpcRecver& operator=(LocIpcRecver const& recver) = delete;
+ virtual ssize_t recv() const = 0;
+public:
+ virtual ~LocIpcRecver() = default;
+ inline bool recvData() const { return isRecvable() && (recv() > 0); }
+ inline bool isRecvable() const { return mDataCb != nullptr && mIpcSender.isSendable(); }
+ virtual void onListenerReady() { if (mDataCb != nullptr) mDataCb->onListenerReady(); }
+ inline virtual unique_ptr<LocIpcSender> getLastSender() const {
+ return nullptr;
}
+ virtual void abort() const = 0;
+ virtual const char* getName() const = 0;
+};
- // Send out a message.
- // Call this function to send a message
- //
- // Argument data and length contains the message to be sent out.
- // Return true when succeeded
- inline bool send(const uint8_t data[], uint32_t length) {
- bool rtv = false;
- if (nullptr != mSocket && nullptr != data) {
- rtv = LocIpc::sendData(*mSocket, mDestAddr, data, length);
+class Sock {
+ static const char MSG_ABORT[];
+ static const char LOC_IPC_HEAD[];
+ const uint32_t mMaxTxSize;
+ ssize_t sendto(const void *buf, size_t len, int flags, const struct sockaddr *destAddr,
+ socklen_t addrlen) const;
+ ssize_t recvfrom(const LocIpcRecver& recver, const shared_ptr<ILocIpcListener>& dataCb,
+ int sid, int flags, struct sockaddr *srcAddr, socklen_t *addrlen) const;
+public:
+ int mSid;
+ inline Sock(int sid, const uint32_t maxTxSize = 8192) : mMaxTxSize(maxTxSize), mSid(sid) {}
+ inline ~Sock() { close(); }
+ inline bool isValid() const { return -1 != mSid; }
+ ssize_t send(const void *buf, uint32_t len, int flags, const struct sockaddr *destAddr,
+ socklen_t addrlen) const;
+ ssize_t recv(const LocIpcRecver& recver, const shared_ptr<ILocIpcListener>& dataCb, int flags,
+ struct sockaddr *srcAddr, socklen_t *addrlen, int sid = -1) const;
+ ssize_t sendAbort(int flags, const struct sockaddr *destAddr, socklen_t addrlen);
+ inline void close() {
+ if (isValid()) {
+ ::close(mSid);
+ mSid = -1;
}
- return rtv;
}
+};
-private:
- std::shared_ptr<int> mSocket;
- struct sockaddr_un mDestAddr;
-
- inline LocIpcSender(
- const std::shared_ptr<int>& mySocket, const char* destSocket) : mSocket(mySocket) {
- if ((nullptr != mSocket) && (-1 != *mSocket) && (nullptr != destSocket)) {
- mDestAddr.sun_family = AF_UNIX;
- snprintf(mDestAddr.sun_path, sizeof(mDestAddr.sun_path), "%s", destSocket);
- }
+class SockRecver : public LocIpcRecver {
+ shared_ptr<Sock> mSock;
+protected:
+ inline virtual ssize_t recv() const override {
+ return mSock->recv(*this, mDataCb, 0, nullptr, nullptr);
+ }
+public:
+ inline SockRecver(const shared_ptr<ILocIpcListener>& listener,
+ LocIpcSender& sender, shared_ptr<Sock> sock) :
+ LocIpcRecver(listener, sender), mSock(sock) {
+ }
+ inline virtual const char* getName() const override {
+ return "SockRecver";
}
+ inline virtual void abort() const override {}
};
}
-#endif //__LOC_SOCKET__
+#endif //__LOC_IPC__
diff --git a/gps/utils/LocSharedLock.h b/gps/utils/LocSharedLock.h
index 7fe6237..a7af35e 100644
--- a/gps/utils/LocSharedLock.h
+++ b/gps/utils/LocSharedLock.h
@@ -30,10 +30,28 @@
#define __LOC_SHARED_LOCK__
#include <stddef.h>
+#ifndef FEATURE_EXTERNAL_AP
#include <cutils/atomic.h>
+#endif /* FEATURE_EXTERNAL_AP */
#include <pthread.h>
-// This is a utility created for use cases such that there are more than
+#ifdef FEATURE_EXTERNAL_AP
+#include <atomic>
+
+inline int32_t android_atomic_inc(volatile int32_t *addr)
+{
+ volatile std::atomic_int_least32_t* a = (volatile std::atomic_int_least32_t*)addr;
+ return std::atomic_fetch_add_explicit(a, 1, std::memory_order_release);
+}
+
+inline int32_t android_atomic_dec(volatile int32_t *addr)
+{
+ volatile std::atomic_int_least32_t* a = (volatile std::atomic_int_least32_t*)addr;
+ return std::atomic_fetch_sub_explicit(a, 1, std::memory_order_release);
+}
+
+#endif /* FEATURE_EXTERNAL_AP */
+ // This is a utility created for use cases such that there are more than
// one client who need to share the same lock, but it is not predictable
// which of these clients is to last to go away. This shared lock deletes
// itself when the last client calls its drop() method. To add a cient,
diff --git a/gps/utils/LocThread.cpp b/gps/utils/LocThread.cpp
index c1052cb..568a6bb 100644
--- a/gps/utils/LocThread.cpp
+++ b/gps/utils/LocThread.cpp
@@ -85,8 +85,8 @@ LocThreadDelegate::LocThreadDelegate(LocThread::tCreate creator,
if (mThandle) {
// set thread name
char lname[16];
- int len = (sizeof(lname)>sizeof(threadName)) ?
- (sizeof(threadName) -1):(sizeof(lname) - 1);
+ int len = (sizeof(lname) > (strlen(threadName) + 1)) ?
+ (strlen(threadName)):(sizeof(lname) - 1);
memcpy(lname, threadName, len);
lname[len] = 0;
// set the thread name here
diff --git a/gps/utils/Makefile.am b/gps/utils/Makefile.am
deleted file mode 100644
index 3801fdd..0000000
--- a/gps/utils/Makefile.am
+++ /dev/null
@@ -1,70 +0,0 @@
-ACLOCAL_AMFLAGS = -I m4
-
-AM_CFLAGS = -Wundef \
- -MD \
- -Wno-trigraphs \
- -g -O0 \
- -fno-inline \
- -fno-short-enums \
- -fpic \
- -I./ \
- -std=c++11 \
- $(LOCPLA_CFLAGS)
-
-libgps_utils_la_h_sources = \
- msg_q.h \
- linked_list.h \
- loc_cfg.h \
- loc_log.h \
- loc_target.h \
- loc_timer.h \
- MsgTask.h \
- LocHeap.h \
- LocThread.h \
- LocTimer.h \
- LocIpc.h \
- loc_misc_utils.h \
- loc_nmea.h \
- gps_extended_c.h \
- gps_extended.h \
- loc_gps.h \
- log_util.h
-
-libgps_utils_la_c_sources = \
- linked_list.c \
- msg_q.c \
- loc_cfg.cpp \
- loc_log.cpp \
- loc_target.cpp \
- LocHeap.cpp \
- LocTimer.cpp \
- LocThread.cpp \
- LocIpc.cpp \
- MsgTask.cpp \
- loc_misc_utils.cpp \
- loc_nmea.cpp
-
-library_includedir = $(pkgincludedir)
-
-library_include_HEADERS = $(libgps_utils_la_h_sources)
-
-libgps_utils_la_SOURCES = $(libgps_utils_la_c_sources)
-
-if USE_GLIB
-libgps_utils_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@
-libgps_utils_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
-libgps_utils_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
-else
-libgps_utils_la_CFLAGS = $(AM_CFLAGS)
-libgps_utils_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0
-libgps_utils_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS)
-endif
-
-libgps_utils_la_LIBADD = $(CUTILS_LIBS)
-
-#Create and Install libraries
-lib_LTLIBRARIES = libgps_utils.la
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = gps-utils.pc
-EXTRA_DIST = $(pkgconfig_DATA)
diff --git a/gps/utils/MsgTask.cpp b/gps/utils/MsgTask.cpp
index eaead5c..73a77fd 100644
--- a/gps/utils/MsgTask.cpp
+++ b/gps/utils/MsgTask.cpp
@@ -74,16 +74,19 @@ void MsgTask::destroy() {
}
void MsgTask::sendMsg(const LocMsg* msg) const {
- if (msg) {
+ if (msg && this) {
msg_q_snd((void*)mQ, (void*)msg, LocMsgDestroy);
} else {
- LOC_LOGE("%s: msg is NULL", __func__);
+ LOC_LOGE("%s: msg is %p and this is %p",
+ __func__, msg, this);
}
}
void MsgTask::prerun() {
+#ifndef FEATURE_EXTERNAL_AP
// make sure we do not run in background scheduling group
set_sched_policy(gettid(), SP_FOREGROUND);
+#endif /* FEATURE_EXTERNAL_AP */
}
bool MsgTask::run() {
diff --git a/gps/utils/configure.ac b/gps/utils/configure.ac
deleted file mode 100644
index 639f8c4..0000000
--- a/gps/utils/configure.ac
+++ /dev/null
@@ -1,82 +0,0 @@
-# configure.ac -- Autoconf script for gps gps-utils
-#
-# Process this file with autoconf to produce a configure script
-
-# Requires autoconf tool later than 2.61
-AC_PREREQ(2.61)
-# Initialize the gps gps-utils package version 1.0.0
-AC_INIT([gps-utils],1.0.0)
-# Does not strictly follow GNU Coding standards
-AM_INIT_AUTOMAKE([foreign])
-# Disables auto rebuilding of configure, Makefile.ins
-AM_MAINTAINER_MODE
-# Verifies the --srcdir is correct by checking for the path
-AC_CONFIG_SRCDIR([Makefile.am])
-# defines some macros variable to be included by source
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_MACRO_DIR([m4])
-
-# Checks for programs.
-AC_PROG_LIBTOOL
-AC_PROG_CXX
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_AWK
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-PKG_PROG_PKG_CONFIG
-
-# Checks for libraries.
-PKG_CHECK_MODULES([CUTILS], [libcutils])
-AC_SUBST([CUTILS_CFLAGS])
-AC_SUBST([CUTILS_LIBS])
-
-AC_ARG_WITH([core_includes],
- AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
- [Specify the location of the core headers]),
- [core_incdir=$withval],
- with_core_includes=no)
-
-if test "x$with_core_includes" != "xno"; then
- CPPFLAGS="${CPPFLAGS} -I${core_incdir}"
-fi
-
-AC_ARG_WITH([locpla_includes],
- AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@],
- [specify the path to locpla-includes in loc-pla_git.bb]),
- [locpla_incdir=$withval],
- with_locpla_includes=no)
-
-if test "x$with_locpla_includes" != "xno"; then
- AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}")
-fi
-
-AC_SUBST([CPPFLAGS])
-
-AC_ARG_WITH([glib],
- AC_HELP_STRING([--with-glib],
- [enable glib, building HLOS systems which use glib]))
-
-if (test "x${with_glib}" = "xyes"); then
- AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib])
- PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GThread >= 2.16 is required))
- PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
- AC_MSG_ERROR(GLib >= 2.16 is required))
- GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
- GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
-
- AC_SUBST(GLIB_CFLAGS)
- AC_SUBST(GLIB_LIBS)
-fi
-
-AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
-
-AC_CONFIG_FILES([ \
- Makefile \
- gps-utils.pc
- ])
-
-AC_OUTPUT
diff --git a/gps/utils/gps-utils.pc.in b/gps/utils/gps-utils.pc.in
deleted file mode 100644
index a988731..0000000
--- a/gps/utils/gps-utils.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: gps-utils
-Description: QTI GPS Location utils
-Version: @VERSION
-Libs: -L${libdir} -lgps_utils
-Cflags: -I${includedir}/gps-utils
diff --git a/gps/utils/gps_extended.h b/gps/utils/gps_extended.h
index dc6ad1e..2455629 100644
--- a/gps/utils/gps_extended.h
+++ b/gps/utils/gps_extended.h
@@ -55,14 +55,19 @@ struct LocPosMode
bool share_position;
char credentials[14];
char provider[8];
+ GnssPowerMode powerMode;
+ uint32_t timeBetweenMeasurements;
LocPosMode(LocPositionMode m, LocGpsPositionRecurrence recr,
uint32_t gap, uint32_t accu, uint32_t time,
- bool sp, const char* cred, const char* prov) :
+ bool sp, const char* cred, const char* prov,
+ GnssPowerMode pMode = GNSS_POWER_MODE_INVALID,
+ uint32_t tbm = 0) :
mode(m), recurrence(recr),
min_interval(gap < GPS_MIN_POSSIBLE_FIX_INTERVAL_MS ?
GPS_MIN_POSSIBLE_FIX_INTERVAL_MS : gap),
preferred_accuracy(accu), preferred_time(time),
- share_position(sp) {
+ share_position(sp), powerMode(pMode),
+ timeBetweenMeasurements(tbm) {
memset(credentials, 0, sizeof(credentials));
memset(provider, 0, sizeof(provider));
if (NULL != cred) {
@@ -78,7 +83,8 @@ struct LocPosMode
recurrence(LOC_GPS_POSITION_RECURRENCE_PERIODIC),
min_interval(GPS_DEFAULT_FIX_INTERVAL_MS),
preferred_accuracy(50), preferred_time(120000),
- share_position(true) {
+ share_position(true), powerMode(GNSS_POWER_MODE_INVALID),
+ timeBetweenMeasurements(GPS_DEFAULT_FIX_INTERVAL_MS) {
memset(credentials, 0, sizeof(credentials));
memset(provider, 0, sizeof(provider));
}
@@ -90,6 +96,8 @@ struct LocPosMode
anotherMode.min_interval == min_interval &&
anotherMode.preferred_accuracy == preferred_accuracy &&
anotherMode.preferred_time == preferred_time &&
+ anotherMode.powerMode == powerMode &&
+ anotherMode.timeBetweenMeasurements == timeBetweenMeasurements &&
!strncmp(anotherMode.credentials, credentials, sizeof(credentials)-1) &&
!strncmp(anotherMode.provider, provider, sizeof(provider)-1);
}
diff --git a/gps/utils/gps_extended_c.h b/gps/utils/gps_extended_c.h
index 5479bec..69a659e 100644
--- a/gps/utils/gps_extended_c.h
+++ b/gps/utils/gps_extended_c.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2019 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
@@ -35,7 +35,12 @@
#include <string.h>
#include <loc_gps.h>
#include <LocationAPI.h>
-#include <time.h>
+
+struct timespec32_t {
+ uint32_t tv_sec; /* seconds */
+ uint32_t tv_nsec; /* and nanoseconds */
+};
+
/**
* @file
@@ -57,6 +62,8 @@ extern "C" {
/** LocGpsLocation has valid map index */
#define LOC_GPS_LOCATION_HAS_MAP_INDEX 0x0200
+#define GNSS_INVALID_JAMMER_IND 0x7FFFFFFF
+
/** Sizes for indoor fields */
#define GPS_LOCATION_MAP_URL_SIZE 400
#define GPS_LOCATION_MAP_INDEX_SIZE 16
@@ -65,20 +72,16 @@ extern "C" {
#define ULP_LOCATION_IS_FROM_HYBRID 0x0001
/** Position source is GNSS only */
#define ULP_LOCATION_IS_FROM_GNSS 0x0002
-/** Position source is ZPP only */
-#define ULP_LOCATION_IS_FROM_ZPP 0x0004
/** Position is from a Geofence Breach Event */
-#define ULP_LOCATION_IS_FROM_GEOFENCE 0X0008
+#define ULP_LOCATION_IS_FROM_GEOFENCE 0X0004
/** Position is from Hardware FLP */
-#define ULP_LOCATION_IS_FROM_HW_FLP 0x0010
+#define ULP_LOCATION_IS_FROM_HW_FLP 0x0008
/** Position is from NLP */
-#define ULP_LOCATION_IS_FROM_NLP 0x0020
-/** Position is from PIP */
-#define ULP_LOCATION_IS_FROM_PIP 0x0040
+#define ULP_LOCATION_IS_FROM_NLP 0x0010
/** Position is from external DR solution*/
-#define ULP_LOCATION_IS_FROM_EXT_DR 0X0080
+#define ULP_LOCATION_IS_FROM_EXT_DR 0X0020
/** Raw GNSS position fixes */
-#define ULP_LOCATION_IS_FROM_GNSS_RAW 0X0100
+#define ULP_LOCATION_IS_FROM_GNSS_RAW 0X0040
typedef uint32_t LocSvInfoSource;
/** SVinfo source is GNSS/DR */
@@ -95,6 +98,12 @@ typedef uint32_t LocSvInfoSource;
#define LOC_AGPS_CERTIFICATE_MAX_LENGTH 2000
#define LOC_AGPS_CERTIFICATE_MAX_SLOTS 10
+/* TBM Threshold for tracking in background power mode : in millis */
+#define TRACKING_TBM_THRESHOLD_MILLIS 480000
+
+/** Maximum number of satellites in an ephemeris report. */
+#define GNSS_EPHEMERIS_LIST_MAX_SIZE_V02 32
+
typedef uint32_t LocPosTechMask;
#define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000)
#define LOC_POS_TECH_MASK_SATELLITE ((LocPosTechMask)0x00000001)
@@ -105,6 +114,7 @@ typedef uint32_t LocPosTechMask;
#define LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION ((LocPosTechMask)0x00000020)
#define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040)
#define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080)
+#define LOC_POS_TECH_MASK_PPE ((LocPosTechMask)0x00000100)
enum loc_registration_mask_status {
LOC_REGISTRATION_MASK_ENABLED,
@@ -117,28 +127,27 @@ typedef enum {
LOC_SUPPORTED_FEATURE_WIFI_AP_DATA_INJECT_2_V02, /**< Support Wifi AP data inject version 2 feature */
LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02, /**< Support debug NMEA feature */
LOC_SUPPORTED_FEATURE_GNSS_ONLY_POSITION_REPORT, /**< Support GNSS Only position reports */
- LOC_SUPPORTED_FEATURE_FDCL /**< Support FDCL */
+ LOC_SUPPORTED_FEATURE_FDCL, /**< Support FDCL */
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02, /**< Support constellation enablement */
+ LOC_SUPPORTED_FEATURE_AGPM_V02, /**< Support AGPM feature */
+ LOC_SUPPORTED_FEATURE_XTRA_INTEGRITY, /**< Support XTRA integrity */
+ LOC_SUPPORTED_FEATURE_FDCL_2, /**< Support FDCL V2 */
+ LOC_SUPPORTED_FEATURE_LOCATION_PRIVACY /**< Support location privacy */
} loc_supported_feature_enum;
typedef struct {
/** set to sizeof(UlpLocation) */
- size_t size;
+ uint32_t size;
LocGpsLocation gpsLocation;
/* Provider indicator for HYBRID or GPS */
uint16_t position_source;
LocPosTechMask tech_mask;
- /*allows HAL to pass additional information related to the location */
- int rawDataSize; /* in # of bytes */
- void * rawData;
- bool is_indoor;
- float floor_number;
- char map_url[GPS_LOCATION_MAP_URL_SIZE];
- unsigned char map_index[GPS_LOCATION_MAP_INDEX_SIZE];
+ bool unpropagatedPosition;
} UlpLocation;
typedef struct {
/** set to sizeof(UlpNmea) */
- size_t size;
+ uint32_t size;
char nmea_str[ULP_MAX_NMEA_STRING_SIZE];
unsigned int len;
} UlpNmea;
@@ -163,21 +172,47 @@ typedef int16_t AGpsBearerType;
#define AGPS_APN_BEARER_IPV6 2
#define AGPS_APN_BEARER_IPV4V6 3
-typedef enum {
- AGPS_CB_PRIORITY_LOW = 1,
- AGPS_CB_PRIORITY_MED = 2,
- AGPS_CB_PRIORITY_HIGH = 3
-} AgpsCbPriority;
+typedef uint32_t LocApnTypeMask;
+/**< Denotes APN type for Default/Internet traffic */
+#define LOC_APN_TYPE_MASK_DEFAULT ((LocApnTypeMask)0x00000001)
+/**< Denotes APN type for IP Multimedia Subsystem */
+#define LOC_APN_TYPE_MASK_IMS ((LocApnTypeMask)0x00000002)
+/**< Denotes APN type for Multimedia Messaging Service */
+#define LOC_APN_TYPE_MASK_MMS ((LocApnTypeMask)0x00000004)
+/**< Denotes APN type for Dial Up Network */
+#define LOC_APN_TYPE_MASK_DUN ((LocApnTypeMask)0x00000008)
+/**< Denotes APN type for Secure User Plane Location */
+#define LOC_APN_TYPE_MASK_SUPL ((LocApnTypeMask)0x00000010)
+/**< Denotes APN type for High Priority Mobile Data */
+#define LOC_APN_TYPE_MASK_HIPRI ((LocApnTypeMask)0x00000020)
+/**< Denotes APN type for over the air administration */
+#define LOC_APN_TYPE_MASK_FOTA ((LocApnTypeMask)0x00000040)
+/**< Denotes APN type for Carrier Branded Services */
+#define LOC_APN_TYPE_MASK_CBS ((LocApnTypeMask)0x00000080)
+/**< Denotes APN type for Initial Attach */
+#define LOC_APN_TYPE_MASK_IA ((LocApnTypeMask)0x00000100)
+/**< Denotes APN type for emergency */
+#define LOC_APN_TYPE_MASK_EMERGENCY ((LocApnTypeMask)0x00000200)
+
+typedef uint32_t AGpsTypeMask;
+#define AGPS_ATL_TYPE_SUPL ((AGpsTypeMask)0x00000001)
+#define AGPS_ATL_TYPE_SUPL_ES ((AGpsTypeMask)0x00000002)
+#define AGPS_ATL_TYPE_WWAN ((AGpsTypeMask)0x00000004)
typedef struct {
void* statusV4Cb;
- AgpsCbPriority cbPriority;
+ AGpsTypeMask atlType;
} AgpsCbInfo;
+typedef struct {
+ void* visibilityControlCb;
+ void* isInEmergencySession;
+} NfwCbInfo;
+
/** GPS extended callback structure. */
typedef struct {
/** set to sizeof(LocGpsCallbacks) */
- size_t size;
+ uint32_t size;
loc_gps_set_capabilities set_capabilities_cb;
loc_gps_acquire_wakelock acquire_wakelock_cb;
loc_gps_release_wakelock release_wakelock_cb;
@@ -201,7 +236,7 @@ typedef struct {
/** Represents the status of AGPS. */
typedef struct {
/** set to sizeof(AGpsExtStatus) */
- size_t size;
+ uint32_t size;
AGpsExtType type;
LocAGpsStatusValue status;
@@ -237,7 +272,8 @@ typedef enum loc_server_type {
LOC_AGPS_CDMA_PDE_SERVER,
LOC_AGPS_CUSTOM_PDE_SERVER,
LOC_AGPS_MPC_SERVER,
- LOC_AGPS_SUPL_SERVER
+ LOC_AGPS_SUPL_SERVER,
+ LOC_AGPS_MO_SUPL_SERVER
} LocServerType;
typedef enum loc_position_mode_type {
@@ -273,7 +309,7 @@ typedef enum loc_position_mode_type {
#define GPS_DEFAULT_FIX_INTERVAL_MS 1000
/** Flags to indicate which values are valid in a GpsLocationExtended. */
-typedef uint32_t GpsLocationExtendedFlags;
+typedef uint64_t GpsLocationExtendedFlags;
/** GpsLocationExtended has valid pdop, hdop, vdop. */
#define GPS_LOCATION_EXTENDED_HAS_DOP 0x0001
/** GpsLocationExtended has valid altitude mean sea level. */
@@ -312,8 +348,49 @@ typedef uint32_t GpsLocationExtendedFlags;
#define GPS_LOCATION_EXTENDED_HAS_GPS_TIME 0x20000
/** GpsLocationExtended has Extended Dilution of Precision */
#define GPS_LOCATION_EXTENDED_HAS_EXT_DOP 0x40000
-/** GpsLocationExtended has Elapsed Time */
-#define GPS_LOCATION_EXTENDED_HAS_ELAPSED_TIME 0x80000
+/** GpsLocationExtended has North standard deviation */
+#define GPS_LOCATION_EXTENDED_HAS_NORTH_STD_DEV 0x80000
+/** GpsLocationExtended has East standard deviation*/
+#define GPS_LOCATION_EXTENDED_HAS_EAST_STD_DEV 0x100000
+/** GpsLocationExtended has North Velocity */
+#define GPS_LOCATION_EXTENDED_HAS_NORTH_VEL 0x200000
+/** GpsLocationExtended has East Velocity */
+#define GPS_LOCATION_EXTENDED_HAS_EAST_VEL 0x400000
+/** GpsLocationExtended has up Velocity */
+#define GPS_LOCATION_EXTENDED_HAS_UP_VEL 0x800000
+/** GpsLocationExtended has North Velocity Uncertainty */
+#define GPS_LOCATION_EXTENDED_HAS_NORTH_VEL_UNC 0x1000000
+/** GpsLocationExtended has East Velocity Uncertainty */
+#define GPS_LOCATION_EXTENDED_HAS_EAST_VEL_UNC 0x2000000
+/** GpsLocationExtended has up Velocity Uncertainty */
+#define GPS_LOCATION_EXTENDED_HAS_UP_VEL_UNC 0x4000000
+/** GpsLocationExtended has Clock Bias */
+#define GPS_LOCATION_EXTENDED_HAS_CLOCK_BIAS 0x8000000
+/** GpsLocationExtended has Clock Bias std deviation*/
+#define GPS_LOCATION_EXTENDED_HAS_CLOCK_BIAS_STD_DEV 0x10000000
+/** GpsLocationExtended has Clock drift*/
+#define GPS_LOCATION_EXTENDED_HAS_CLOCK_DRIFT 0x20000000
+/** GpsLocationExtended has Clock drift std deviation**/
+#define GPS_LOCATION_EXTENDED_HAS_CLOCK_DRIFT_STD_DEV 0x40000000
+/** GpsLocationExtended has leap seconds **/
+#define GPS_LOCATION_EXTENDED_HAS_LEAP_SECONDS 0x80000000
+/** GpsLocationExtended has time uncertainty **/
+#define GPS_LOCATION_EXTENDED_HAS_TIME_UNC 0x100000000
+/** GpsLocationExtended has heading rate **/
+#define GPS_LOCATION_EXTENDED_HAS_HEADING_RATE 0x200000000
+/** GpsLocationExtended has multiband signals **/
+#define GPS_LOCATION_EXTENDED_HAS_MULTIBAND 0x400000000
+/** GpsLocationExtended has sensor calibration confidence */
+#define GPS_LOCATION_EXTENDED_HAS_CALIBRATION_CONFIDENCE 0x800000000
+/** GpsLocationExtended has sensor calibration status */
+#define GPS_LOCATION_EXTENDED_HAS_CALIBRATION_STATUS 0x1000000000
+/** GpsLocationExtended has the engine type that produced this
+ * position, the bit mask will only be set when there are two
+ * or more position engines running in the system */
+#define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE 0x2000000000
+ /** GpsLocationExtended has the engine mask that indicates the
+ * set of engines contribute to the fix. */
+#define GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK 0x4000000000
typedef uint32_t LocNavSolutionMask;
/* Bitmask to specify whether SBAS ionospheric correction is used */
@@ -324,6 +401,14 @@ typedef uint32_t LocNavSolutionMask;
#define LOC_NAV_MASK_SBAS_CORRECTION_LONG ((LocNavSolutionMask)0x0004)
/**< Bitmask to specify whether SBAS integrity information is used */
#define LOC_NAV_MASK_SBAS_INTEGRITY ((LocNavSolutionMask)0x0008)
+/**< Bitmask to specify whether Position Report is DGNSS corrected */
+#define LOC_NAV_MASK_DGNSS_CORRECTION ((LocNavSolutionMask)0x0010)
+/**< Bitmask to specify whether Position Report is RTK corrected */
+#define LOC_NAV_MASK_RTK_CORRECTION ((LocNavSolutionMask)0x0020)
+/**< Bitmask to specify whether Position Report is PPP corrected */
+#define LOC_NAV_MASK_PPP_CORRECTION ((LocNavSolutionMask)0x0040)
+/**< Bitmask to specify whether Position Report is RTK fixed corrected */
+#define LOC_NAV_MASK_RTK_FIXED_CORRECTION ((LocNavSolutionMask)0x0080)
typedef uint32_t LocPosDataMask;
/* Bitmask to specify whether Navigation data has Forward Acceleration */
@@ -336,10 +421,29 @@ typedef uint32_t LocPosDataMask;
#define LOC_NAV_DATA_HAS_YAW_RATE ((LocPosDataMask)0x0008)
/* Bitmask to specify whether Navigation data has Body pitch */
#define LOC_NAV_DATA_HAS_PITCH ((LocPosDataMask)0x0010)
+/* Bitmask to specify whether Navigation data has Forward Acceleration Unc */
+#define LOC_NAV_DATA_HAS_LONG_ACCEL_UNC ((LocPosDataMask)0x0020)
+/* Bitmask to specify whether Navigation data has Sideward Acceleration Unc*/
+#define LOC_NAV_DATA_HAS_LAT_ACCEL_UNC ((LocPosDataMask)0x0040)
+/* Bitmask to specify whether Navigation data has Vertical Acceleration Unc*/
+#define LOC_NAV_DATA_HAS_VERT_ACCEL_UNC ((LocPosDataMask)0x0080)
+/* Bitmask to specify whether Navigation data has Heading Rate Unc*/
+#define LOC_NAV_DATA_HAS_YAW_RATE_UNC ((LocPosDataMask)0x0100)
+/* Bitmask to specify whether Navigation data has Body pitch Unc*/
+#define LOC_NAV_DATA_HAS_PITCH_UNC ((LocPosDataMask)0x0200)
+
+typedef uint32_t GnssAdditionalSystemInfoMask;
+/* Bitmask to specify whether Tauc is valid */
+#define GNSS_ADDITIONAL_SYSTEMINFO_HAS_TAUC ((GnssAdditionalSystemInfoMask)0x0001)
+/* Bitmask to specify whether leapSec is valid */
+#define GNSS_ADDITIONAL_SYSTEMINFO_HAS_LEAP_SEC ((GnssAdditionalSystemInfoMask)0x0002)
+
/** GPS PRN Range */
#define GPS_SV_PRN_MIN 1
#define GPS_SV_PRN_MAX 32
+#define SBAS_SV_PRN_MIN 33
+#define SBAS_SV_PRN_MAX 64
#define GLO_SV_PRN_MIN 65
#define GLO_SV_PRN_MAX 96
#define QZSS_SV_PRN_MIN 193
@@ -348,17 +452,8 @@ typedef uint32_t LocPosDataMask;
#define BDS_SV_PRN_MAX 235
#define GAL_SV_PRN_MIN 301
#define GAL_SV_PRN_MAX 336
-
-typedef uint32_t LocPosTechMask;
-#define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000)
-#define LOC_POS_TECH_MASK_SATELLITE ((LocPosTechMask)0x00000001)
-#define LOC_POS_TECH_MASK_CELLID ((LocPosTechMask)0x00000002)
-#define LOC_POS_TECH_MASK_WIFI ((LocPosTechMask)0x00000004)
-#define LOC_POS_TECH_MASK_SENSORS ((LocPosTechMask)0x00000008)
-#define LOC_POS_TECH_MASK_REFERENCE_LOCATION ((LocPosTechMask)0x00000010)
-#define LOC_POS_TECH_MASK_INJECTED_COARSE_POSITION ((LocPosTechMask)0x00000020)
-#define LOC_POS_TECH_MASK_AFLT ((LocPosTechMask)0x00000040)
-#define LOC_POS_TECH_MASK_HYBRID ((LocPosTechMask)0x00000080)
+#define NAVIC_SV_PRN_MIN 401
+#define NAVIC_SV_PRN_MAX 414
typedef enum {
LOC_RELIABILITY_NOT_SET = 0,
@@ -368,8 +463,14 @@ typedef enum {
LOC_RELIABILITY_HIGH = 4
}LocReliability;
+typedef enum {
+ LOC_IN_EMERGENCY_UNKNOWN = 0,
+ LOC_IN_EMERGENCY_SET = 1,
+ LOC_IN_EMERGENCY_NOT_SET = 2
+}LocInEmergency;
+
typedef struct {
- struct timespec apTimeStamp;
+ struct timespec32_t apTimeStamp;
/*boottime received from pps-ktimer*/
float apTimeStampUncertaintyMs;
/* timestamp uncertainty in milli seconds */
@@ -381,22 +482,55 @@ typedef struct {
uint64_t gal_sv_used_ids_mask;
uint64_t bds_sv_used_ids_mask;
uint64_t qzss_sv_used_ids_mask;
+ uint64_t navic_sv_used_ids_mask;
} GnssSvUsedInPosition;
+typedef struct {
+ uint64_t gps_l1ca_sv_used_ids_mask; // GPS L1CA
+ uint64_t gps_l1c_sv_used_ids_mask; // GPS L1C
+ uint64_t gps_l2_sv_used_ids_mask; // GPS L2
+ uint64_t gps_l5_sv_used_ids_mask; // GPS L5
+ uint64_t glo_g1_sv_used_ids_mask; // GLO G1
+ uint64_t glo_g2_sv_used_ids_mask; // GLO G2
+ uint64_t gal_e1_sv_used_ids_mask; // GAL E1
+ uint64_t gal_e5a_sv_used_ids_mask; // GAL E5A
+ uint64_t gal_e5b_sv_used_ids_mask; // GAL E5B
+ uint64_t bds_b1i_sv_used_ids_mask; // BDS B1I
+ uint64_t bds_b1c_sv_used_ids_mask; // BDS B1C
+ uint64_t bds_b2i_sv_used_ids_mask; // BDS B2I
+ uint64_t bds_b2ai_sv_used_ids_mask; // BDS B2AI
+ uint64_t qzss_l1ca_sv_used_ids_mask; // QZSS L1CA
+ uint64_t qzss_l1s_sv_used_ids_mask; // QZSS L1S
+ uint64_t qzss_l2_sv_used_ids_mask; // QZSS L2
+ uint64_t qzss_l5_sv_used_ids_mask; // QZSS L5
+ uint64_t sbas_l1_sv_used_ids_mask; // SBAS L1
+ uint64_t bds_b2aq_sv_used_ids_mask; // BDS B2AQ
+} GnssSvMbUsedInPosition;
+
/* Body Frame parameters */
typedef struct {
/** Contains Body frame LocPosDataMask bits. */
uint32_t bodyFrameDatamask;
/* Forward Acceleration in body frame (m/s2)*/
float longAccel;
+ /** Uncertainty of Forward Acceleration in body frame */
+ float longAccelUnc;
/* Sideward Acceleration in body frame (m/s2)*/
float latAccel;
+ /** Uncertainty of Side-ward Acceleration in body frame */
+ float latAccelUnc;
/* Vertical Acceleration in body frame (m/s2)*/
float vertAccel;
+ /** Uncertainty of Vertical Acceleration in body frame */
+ float vertAccelUnc;
/* Heading Rate (Radians/second) */
float yawRate;
+ /** Uncertainty of Heading Rate */
+ float yawRateUnc;
/* Body pitch (Radians) */
float pitch;
+ /** Uncertainty of Body pitch */
+ float pitchRadUnc;
}LocPositionDynamics;
typedef struct {
@@ -434,12 +568,143 @@ typedef struct {
uint32_t gpsTimeOfWeekMs;
}GPSTimeStruct;
+typedef uint8_t CarrierPhaseAmbiguityType;
+#define CARRIER_PHASE_AMBIGUITY_RESOLUTION_NONE ((CarrierPhaseAmbiguityType)0)
+#define CARRIER_PHASE_AMBIGUITY_RESOLUTION_FLOAT ((CarrierPhaseAmbiguityType)1)
+#define CARRIER_PHASE_AMBIGUITY_RESOLUTION_FIXED ((CarrierPhaseAmbiguityType)2)
+
+/** GNSS Signal Type and RF Band */
+typedef uint32_t GnssSignalTypeMask;
+/** GPS L1CA Signal */
+#define GNSS_SIGNAL_GPS_L1CA ((GnssSignalTypeMask)0x00000001ul)
+/** GPS L1C Signal */
+#define GNSS_SIGNAL_GPS_L1C ((GnssSignalTypeMask)0x00000002ul)
+/** GPS L2 RF Band */
+#define GNSS_SIGNAL_GPS_L2 ((GnssSignalTypeMask)0x00000004ul)
+/** GPS L5 RF Band */
+#define GNSS_SIGNAL_GPS_L5 ((GnssSignalTypeMask)0x00000008ul)
+/** GLONASS G1 (L1OF) RF Band */
+#define GNSS_SIGNAL_GLONASS_G1 ((GnssSignalTypeMask)0x00000010ul)
+/** GLONASS G2 (L2OF) RF Band */
+#define GNSS_SIGNAL_GLONASS_G2 ((GnssSignalTypeMask)0x00000020ul)
+/** GALILEO E1 RF Band */
+#define GNSS_SIGNAL_GALILEO_E1 ((GnssSignalTypeMask)0x00000040ul)
+/** GALILEO E5A RF Band */
+#define GNSS_SIGNAL_GALILEO_E5A ((GnssSignalTypeMask)0x00000080ul)
+/** GALILEO E5B RF Band */
+#define GNSS_SIGNAL_GALILIEO_E5B ((GnssSignalTypeMask)0x00000100ul)
+/** BEIDOU B1_I RF Band */
+#define GNSS_SIGNAL_BEIDOU_B1I ((GnssSignalTypeMask)0x00000200ul)
+/** BEIDOU B1C RF Band */
+#define GNSS_SIGNAL_BEIDOU_B1C ((GnssSignalTypeMask)0x00000400ul)
+/** BEIDOU B2_I RF Band */
+#define GNSS_SIGNAL_BEIDOU_B2I ((GnssSignalTypeMask)0x00000800ul)
+/** BEIDOU B2A_I RF Band */
+#define GNSS_SIGNAL_BEIDOU_B2AI ((GnssSignalTypeMask)0x00001000ul)
+/** QZSS L1CA RF Band */
+#define GNSS_SIGNAL_QZSS_L1CA ((GnssSignalTypeMask)0x00002000ul)
+/** QZSS L1S RF Band */
+#define GNSS_SIGNAL_QZSS_L1S ((GnssSignalTypeMask)0x00004000ul)
+/** QZSS L2 RF Band */
+#define GNSS_SIGNAL_QZSS_L2 ((GnssSignalTypeMask)0x00008000ul)
+/** QZSS L5 RF Band */
+#define GNSS_SIGNAL_QZSS_L5 ((GnssSignalTypeMask)0x00010000ul)
+/** SBAS L1 RF Band */
+#define GNSS_SIGNAL_SBAS_L1 ((GnssSignalTypeMask)0x00020000ul)
+/** NAVIC L5 RF Band */
+#define GNSS_SIGNAL_NAVIC_L5 ((GnssSignalTypeMask)0x00040000ul)
+/** BEIDOU B2A_Q RF Band */
+#define GNSS_SIGNAL_BEIDOU_B2AQ ((GnssSignalTypeMask)0x00080000ul)
+
+typedef uint16_t GnssMeasUsageStatusBitMask;
+/** Used in fix */
+#define GNSS_MEAS_USED_IN_PVT ((GnssMeasUsageStatusBitMask)0x00000001ul)
+/** Measurement is Bad */
+#define GNSS_MEAS_USAGE_STATUS_BAD_MEAS ((GnssMeasUsageStatusBitMask)0x00000002ul)
+/** Measurement has too low C/N */
+#define GNSS_MEAS_USAGE_STATUS_CNO_TOO_LOW ((GnssMeasUsageStatusBitMask)0x00000004ul)
+/** Measurement has too low elevation */
+#define GNSS_MEAS_USAGE_STATUS_ELEVATION_TOO_LOW ((GnssMeasUsageStatusBitMask)0x00000008ul)
+/** No ephemeris available for this measurement */
+#define GNSS_MEAS_USAGE_STATUS_NO_EPHEMERIS ((GnssMeasUsageStatusBitMask)0x00000010ul)
+/** No corrections available for the measurement */
+#define GNSS_MEAS_USAGE_STATUS_NO_CORRECTIONS ((GnssMeasUsageStatusBitMask)0x00000020ul)
+/** Corrections has timed out for the measurement */
+#define GNSS_MEAS_USAGE_STATUS_CORRECTION_TIMEOUT ((GnssMeasUsageStatusBitMask)0x00000040ul)
+/** Measurement is unhealthy */
+#define GNSS_MEAS_USAGE_STATUS_UNHEALTHY ((GnssMeasUsageStatusBitMask)0x00000080ul)
+/** Configuration is disabled for this measurement */
+#define GNSS_MEAS_USAGE_STATUS_CONFIG_DISABLED ((GnssMeasUsageStatusBitMask)0x00000100ul)
+/** Measurement not used for other reasons */
+#define GNSS_MEAS_USAGE_STATUS_OTHER ((GnssMeasUsageStatusBitMask)0x00000200ul)
+
+/** Flags to indicate valid fields in epMeasUsageInfo */
+typedef uint16_t GnssMeasUsageInfoValidityMask;
+#define GNSS_PSEUDO_RANGE_RESIDUAL_VALID ((GnssMeasUsageInfoValidityMask)0x00000001ul)
+#define GNSS_DOPPLER_RESIDUAL_VALID ((GnssMeasUsageInfoValidityMask)0x00000002ul)
+#define GNSS_CARRIER_PHASE_RESIDUAL_VALID ((GnssMeasUsageInfoValidityMask)0x00000004ul)
+#define GNSS_CARRIER_PHASE_AMBIGUITY_TYPE_VALID ((GnssMeasUsageInfoValidityMask)0x00000008ul)
+
+typedef uint16_t GnssSvPolyStatusMask;
+#define GNSS_SV_POLY_SRC_ALM_CORR_V02 ((GnssSvPolyStatusMask)0x01)
+#define GNSS_SV_POLY_GLO_STR4_V02 ((GnssSvPolyStatusMask)0x02)
+#define GNSS_SV_POLY_DELETE_V02 ((GnssSvPolyStatusMask)0x04)
+#define GNSS_SV_POLY_SRC_GAL_FNAV_OR_INAV_V02 ((GnssSvPolyStatusMask)0x08)
+typedef uint16_t GnssSvPolyStatusMaskValidity;
+#define GNSS_SV_POLY_SRC_ALM_CORR_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x01)
+#define GNSS_SV_POLY_GLO_STR4_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x02)
+#define GNSS_SV_POLY_DELETE_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x04)
+#define GNSS_SV_POLY_SRC_GAL_FNAV_OR_INAV_VALID_V02 ((GnssSvPolyStatusMaskValidity)0x08)
+
+
+typedef struct {
+ /** Specifies GNSS signal type
+ Mandatory Field*/
+ GnssSignalTypeMask gnssSignalType;
+ /** Specifies GNSS Constellation Type
+ Mandatory Field*/
+ Gnss_LocSvSystemEnumType gnssConstellation;
+ /** GNSS SV ID.
+ For GPS: 1 to 32
+ For GLONASS: 65 to 96. When slot-number to SV ID mapping is unknown, set as 255.
+ For SBAS: 120 to 151
+ For QZSS-L1CA:193 to 197
+ For BDS: 201 to 237
+ For GAL: 301 to 336 */
+ uint16_t gnssSvId;
+ /** GLONASS frequency number + 7.
+ Valid only for a GLONASS system and
+ is to be ignored for all other systems.
+ Range: 1 to 14 */
+ uint8_t gloFrequency;
+ /** Carrier phase ambiguity type. */
+ CarrierPhaseAmbiguityType carrierPhaseAmbiguityType;
+ /** Validity mask */
+ GnssMeasUsageStatusBitMask measUsageStatusMask;
+ /** Specifies measurement usage status
+ Mandatory Field*/
+ GnssMeasUsageInfoValidityMask validityMask;
+ /** Computed pseudorange residual.
+ Unit: Meters */
+ float pseudorangeResidual;
+ /** Computed doppler residual.
+ Unit: Meters/sec*/
+ float dopplerResidual;
+ /** Computed carrier phase residual.
+ Unit: Cycles*/
+ float carrierPhaseResidual;
+ /** Carrier phase ambiguity value.
+ Unit: Cycles*/
+ float carrierPhasAmbiguity;
+} GpsMeasUsageInfo;
+
+
/** Represents gps location extended. */
typedef struct {
/** set to sizeof(GpsLocationExtended) */
- size_t size;
+ uint32_t size;
/** Contains GpsLocationExtendedFlags bits. */
- uint32_t flags;
+ uint64_t flags;
/** Contains the Altitude wrt mean sea level */
float altitudeMeanSeaLevel;
/** Contains Position Dilusion of Precision. */
@@ -470,6 +735,8 @@ typedef struct {
Gnss_ApTimeStampStructType timeStamp;
/** Gnss sv used in position data */
GnssSvUsedInPosition gnss_sv_used_ids;
+ /** Gnss sv used in position data for multiband */
+ GnssSvMbUsedInPosition gnss_mb_sv_used_ids;
/** Nav solution mask to indicate sbas corrections */
LocNavSolutionMask navSolutionMask;
/** Position technology used in computing this fix */
@@ -477,13 +744,75 @@ typedef struct {
/** SV Info source used in computing this fix */
LocSvInfoSource sv_source;
/** Body Frame Dynamics: 4wayAcceleration and pitch set with validity */
- LocPositionDynamics bodyFrameData;
+ GnssLocationPositionDynamics bodyFrameData;
/** GPS Time */
GPSTimeStruct gpsTime;
- /** Elapsed Time */
- int64_t elapsedTime;
+ GnssSystemTime gnssSystemTime;
/** Dilution of precision associated with this position*/
LocExtDOP extDOP;
+ /** North standard deviation.
+ Unit: Meters */
+ float northStdDeviation;
+ /** East standard deviation.
+ Unit: Meters */
+ float eastStdDeviation;
+ /** North Velocity.
+ Unit: Meters/sec */
+ float northVelocity;
+ /** East Velocity.
+ Unit: Meters/sec */
+ float eastVelocity;
+ /** Up Velocity.
+ Unit: Meters/sec */
+ float upVelocity;
+ /** North Velocity standard deviation.
+ Unit: Meters/sec */
+ float northVelocityStdDeviation;
+ /** East Velocity standard deviation.
+ Unit: Meters/sec */
+ float eastVelocityStdDeviation;
+ /** Up Velocity standard deviation
+ Unit: Meters/sec */
+ float upVelocityStdDeviation;
+ /** Estimated clock bias. Unit: Nano seconds */
+ float clockbiasMeter;
+ /** Estimated clock bias std deviation. Unit: Nano seconds */
+ float clockBiasStdDeviationMeter;
+ /** Estimated clock drift. Unit: Meters/sec */
+ float clockDrift;
+ /** Estimated clock drift std deviation. Unit: Meters/sec */
+ float clockDriftStdDeviation;
+ /** Number of valid reference stations. Range:[0-4] */
+ uint8_t numValidRefStations;
+ /** Reference station(s) number */
+ uint16_t referenceStation[4];
+ /** Number of measurements received for use in fix.
+ Shall be used as maximum index in-to svUsageInfo[].
+ Set to 0, if svUsageInfo reporting is not supported.
+ Range: 0-EP_GNSS_MAX_MEAS */
+ uint8_t numOfMeasReceived;
+ /** Measurement Usage Information */
+ GpsMeasUsageInfo measUsageInfo[GNSS_SV_MAX];
+ /** Leap Seconds */
+ uint8_t leapSeconds;
+ /** Time uncertainty in milliseconds */
+ float timeUncMs;
+ /** Heading Rate is in NED frame.
+ Range: 0 to 359.999. 946
+ Unit: Degrees per Seconds */
+ float headingRateDeg;
+ /** Sensor calibration confidence percent. Range: 0 - 100 */
+ uint8_t calibrationConfidence;
+ DrCalibrationStatusMask calibrationStatus;
+ /* location engine type. When the fix. when the type is set to
+ LOC_ENGINE_SRC_FUSED, the fix is the propagated/aggregated
+ reports from all engines running on the system (e.g.:
+ DR/SPE/PPE). To check which location engine contributes to
+ the fused output, check for locOutputEngMask. */
+ LocOutputEngineType locOutputEngType;
+ /* when loc output eng type is set to fused, this field
+ indicates the set of engines contribute to the fix. */
+ PositioningEngineMask locOutputEngMask;
} GpsLocationExtended;
enum loc_sess_status {
@@ -492,6 +821,13 @@ enum loc_sess_status {
LOC_SESS_FAILURE
};
+// struct that contains complete position info from engine
+typedef struct {
+ UlpLocation location;
+ GpsLocationExtended locationExtended;
+ enum loc_sess_status sessionStatus;
+} EngineLocationInfo;
+
// Nmea sentence types mask
typedef uint32_t NmeaSentenceTypesMask;
#define LOC_NMEA_MASK_GGA_V02 ((NmeaSentenceTypesMask)0x00000001) /**< Enable GGA type */
@@ -512,6 +848,20 @@ typedef uint32_t NmeaSentenceTypesMask;
#define LOC_NMEA_MASK_PQGSA_V02 ((NmeaSentenceTypesMask)0x00008000) /**< Enable PQGSA type */
#define LOC_NMEA_MASK_PQGSV_V02 ((NmeaSentenceTypesMask)0x00010000) /**< Enable PQGSV type */
#define LOC_NMEA_MASK_DEBUG_V02 ((NmeaSentenceTypesMask)0x00020000) /**< Enable DEBUG type */
+#define LOC_NMEA_MASK_GPDTM_V02 ((NmeaSentenceTypesMask)0x00040000) /**< Enable GPDTM type */
+#define LOC_NMEA_MASK_GNGGA_V02 ((NmeaSentenceTypesMask)0x00080000) /**< Enable GNGGA type */
+#define LOC_NMEA_MASK_GNRMC_V02 ((NmeaSentenceTypesMask)0x00100000) /**< Enable GNRMC type */
+#define LOC_NMEA_MASK_GNVTG_V02 ((NmeaSentenceTypesMask)0x00200000) /**< Enable GNVTG type */
+#define LOC_NMEA_MASK_GAGNS_V02 ((NmeaSentenceTypesMask)0x00400000) /**< Enable GAGNS type */
+#define LOC_NMEA_MASK_GBGGA_V02 ((NmeaSentenceTypesMask)0x00800000) /**< Enable GBGGA type */
+#define LOC_NMEA_MASK_GBGSA_V02 ((NmeaSentenceTypesMask)0x01000000) /**< Enable GBGSA type */
+#define LOC_NMEA_MASK_GBGSV_V02 ((NmeaSentenceTypesMask)0x02000000) /**< Enable GBGSV type */
+#define LOC_NMEA_MASK_GBRMC_V02 ((NmeaSentenceTypesMask)0x04000000) /**< Enable GBRMC type */
+#define LOC_NMEA_MASK_GBVTG_V02 ((NmeaSentenceTypesMask)0x08000000) /**< Enable GBVTG type */
+#define LOC_NMEA_MASK_GQGSV_V02 ((NmeaSentenceTypesMask)0x10000000) /**< Enable GQGSV type */
+#define LOC_NMEA_MASK_GIGSV_V02 ((NmeaSentenceTypesMask)0x20000000) /**< Enable GIGSV type */
+#define LOC_NMEA_MASK_GNDTM_V02 ((NmeaSentenceTypesMask)0x40000000) /**< Enable GNDTM type */
+
// all bitmasks of general supported NMEA sentenses - debug is not part of this
#define LOC_NMEA_ALL_GENERAL_SUPPORTED_MASK (LOC_NMEA_MASK_GGA_V02 | LOC_NMEA_MASK_RMC_V02 | \
@@ -519,7 +869,12 @@ typedef uint32_t NmeaSentenceTypesMask;
LOC_NMEA_MASK_PQXFI_V02 | LOC_NMEA_MASK_PSTIS_V02 | LOC_NMEA_MASK_GLGSV_V02 | \
LOC_NMEA_MASK_GNGSA_V02 | LOC_NMEA_MASK_GNGNS_V02 | LOC_NMEA_MASK_GARMC_V02 | \
LOC_NMEA_MASK_GAGSV_V02 | LOC_NMEA_MASK_GAGSA_V02 | LOC_NMEA_MASK_GAVTG_V02 | \
- LOC_NMEA_MASK_GAGGA_V02 | LOC_NMEA_MASK_PQGSA_V02 | LOC_NMEA_MASK_PQGSV_V02)
+ LOC_NMEA_MASK_GAGGA_V02 | LOC_NMEA_MASK_PQGSA_V02 | LOC_NMEA_MASK_PQGSV_V02 | \
+ LOC_NMEA_MASK_GPDTM_V02 | LOC_NMEA_MASK_GNGGA_V02 | LOC_NMEA_MASK_GNRMC_V02 | \
+ LOC_NMEA_MASK_GNVTG_V02 | LOC_NMEA_MASK_GAGNS_V02 | LOC_NMEA_MASK_GBGGA_V02 | \
+ LOC_NMEA_MASK_GBGSA_V02 | LOC_NMEA_MASK_GBGSV_V02 | LOC_NMEA_MASK_GBRMC_V02 | \
+ LOC_NMEA_MASK_GBVTG_V02 | LOC_NMEA_MASK_GQGSV_V02 | LOC_NMEA_MASK_GIGSV_V02 | \
+ LOC_NMEA_MASK_GNDTM_V02)
typedef enum {
LOC_ENG_IF_REQUEST_SENDER_ID_QUIPC = 0,
@@ -583,8 +938,8 @@ enum loc_api_adapter_event_index {
LOC_API_ADAPTER_BATCH_FULL, // Batching on full
LOC_API_ADAPTER_BATCHED_POSITION_REPORT, // Batching on fix
LOC_API_ADAPTER_BATCHED_GENFENCE_BREACH_REPORT, //
- LOC_API_ADAPTER_GNSS_MEASUREMENT_REPORT, //GNSS Measurement Report
- LOC_API_ADAPTER_GNSS_SV_POLYNOMIAL_REPORT, //GNSS SV Polynomial Report
+ LOC_API_ADAPTER_GNSS_MEASUREMENT_REPORT, // GNSS Measurement Report
+ LOC_API_ADAPTER_GNSS_SV_POLYNOMIAL_REPORT, // GNSS SV Polynomial Report
LOC_API_ADAPTER_GDT_UPLOAD_BEGIN_REQ, // GDT upload start request
LOC_API_ADAPTER_GDT_UPLOAD_END_REQ, // GDT upload end request
LOC_API_ADAPTER_GNSS_MEASUREMENT, // GNSS Measurement report
@@ -594,6 +949,12 @@ enum loc_api_adapter_event_index {
LOC_API_ADAPTER_REQUEST_POSITION_INJECTION, // Position injection request
LOC_API_ADAPTER_BATCH_STATUS, // batch status
LOC_API_ADAPTER_FDCL_SERVICE_REQ, // FDCL service request
+ LOC_API_ADAPTER_REPORT_UNPROPAGATED_POSITION, // Unpropagated Position report
+ LOC_API_ADAPTER_BS_OBS_DATA_SERVICE_REQ, // BS observation data request
+ LOC_API_ADAPTER_GNSS_SV_EPHEMERIS_REPORT, // GNSS SV Ephemeris Report
+ LOC_API_ADAPTER_LOC_SYSTEM_INFO, // Location system info event
+ LOC_API_ADAPTER_GNSS_NHZ_MEASUREMENT_REPORT, // GNSS SV nHz measurement report
+ LOC_API_ADAPTER_EVENT_REPORT_INFO, // Event report info
LOC_API_ADAPTER_EVENT_MAX
};
@@ -630,7 +991,12 @@ enum loc_api_adapter_event_index {
#define LOC_API_ADAPTER_BIT_POSITION_INJECTION_REQUEST (1<<LOC_API_ADAPTER_REQUEST_POSITION_INJECTION)
#define LOC_API_ADAPTER_BIT_BATCH_STATUS (1<<LOC_API_ADAPTER_BATCH_STATUS)
#define LOC_API_ADAPTER_BIT_FDCL_SERVICE_REQ (1ULL<<LOC_API_ADAPTER_FDCL_SERVICE_REQ)
-
+#define LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT (1ULL<<LOC_API_ADAPTER_REPORT_UNPROPAGATED_POSITION)
+#define LOC_API_ADAPTER_BIT_BS_OBS_DATA_SERVICE_REQ (1ULL<<LOC_API_ADAPTER_BS_OBS_DATA_SERVICE_REQ)
+#define LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT (1ULL<<LOC_API_ADAPTER_GNSS_SV_EPHEMERIS_REPORT)
+#define LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO (1ULL<<LOC_API_ADAPTER_LOC_SYSTEM_INFO)
+#define LOC_API_ADAPTER_BIT_GNSS_NHZ_MEASUREMENT (1ULL<<LOC_API_ADAPTER_GNSS_NHZ_MEASUREMENT_REPORT)
+#define LOC_API_ADAPTER_BIT_EVENT_REPORT_INFO (1ULL<<LOC_API_ADAPTER_EVENT_REPORT_INFO)
typedef uint64_t LOC_API_ADAPTER_EVENT_MASK_T;
@@ -663,7 +1029,8 @@ typedef uint32_t LOC_GPS_LOCK_MASK;
#define GNSS_SV_POLY_XYZ_0_TH_ORDER_COEFF_MAX_SIZE 3
#define GNSS_SV_POLY_XYZ_N_TH_ORDER_COEFF_MAX_SIZE 9
#define GNSS_SV_POLY_SV_CLKBIAS_COEFF_MAX_SIZE 4
-#define GNSS_LOC_SV_MEAS_LIST_MAX_SIZE 16
+/** Max number of GNSS SV measurement */
+#define GNSS_LOC_SV_MEAS_LIST_MAX_SIZE 128
enum ulp_gnss_sv_measurement_valid_flags{
@@ -708,9 +1075,19 @@ enum ulp_gnss_sv_poly_valid_flags{
ULP_GNSS_SV_POLY_ELEVATIONUNC,
ULP_GNSS_SV_POLY_VELO_COEFF,
ULP_GNSS_SV_POLY_ENHANCED_IOD,
-
- ULP_GNSS_SV_POLY_VALID_FLAGS
-
+ ULP_GNSS_SV_POLY_GPS_ISC_L1CA,
+ ULP_GNSS_SV_POLY_GPS_ISC_L2C,
+ ULP_GNSS_SV_POLY_GPS_ISC_L5I5,
+ ULP_GNSS_SV_POLY_GPS_ISC_L5Q5,
+ ULP_GNSS_SV_POLY_GPS_TGD,
+ ULP_GNSS_SV_POLY_GLO_TGD_G1G2,
+ ULP_GNSS_SV_POLY_BDS_TGD_B1,
+ ULP_GNSS_SV_POLY_BDS_TGD_B2,
+ ULP_GNSS_SV_POLY_BDS_TGD_B2A,
+ ULP_GNSS_SV_POLY_BDS_ISC_B2A,
+ ULP_GNSS_SV_POLY_GAL_BGD_E1E5A,
+ ULP_GNSS_SV_POLY_GAL_BGD_E1E5B,
+ ULP_GNSS_SV_POLY_NAVIC_TGD_L5
};
#define ULP_GNSS_SV_POLY_BIT_GLO_FREQ (1<<ULP_GNSS_SV_POLY_GLO_FREQ)
@@ -731,25 +1108,19 @@ enum ulp_gnss_sv_poly_valid_flags{
#define ULP_GNSS_SV_POLY_BIT_ELEVATIONUNC (1<<ULP_GNSS_SV_POLY_ELEVATIONUNC)
#define ULP_GNSS_SV_POLY_BIT_VELO_COEFF (1<<ULP_GNSS_SV_POLY_VELO_COEFF)
#define ULP_GNSS_SV_POLY_BIT_ENHANCED_IOD (1<<ULP_GNSS_SV_POLY_ENHANCED_IOD)
-
-
-typedef enum
-{
- GNSS_LOC_SV_SYSTEM_GPS = 1,
- /**< GPS satellite. */
- GNSS_LOC_SV_SYSTEM_GALILEO = 2,
- /**< GALILEO satellite. */
- GNSS_LOC_SV_SYSTEM_SBAS = 3,
- /**< SBAS satellite. */
- GNSS_LOC_SV_SYSTEM_COMPASS = 4,
- /**< COMPASS satellite. */
- GNSS_LOC_SV_SYSTEM_GLONASS = 5,
- /**< GLONASS satellite. */
- GNSS_LOC_SV_SYSTEM_BDS = 6,
- /**< BDS satellite. */
- GNSS_LOC_SV_SYSTEM_QZSS = 7
- /**< QZSS satellite. */
-} Gnss_LocSvSystemEnumType;
+#define ULP_GNSS_SV_POLY_BIT_GPS_ISC_L1CA (1<<ULP_GNSS_SV_POLY_GPS_ISC_L1CA)
+#define ULP_GNSS_SV_POLY_BIT_GPS_ISC_L2C (1<<ULP_GNSS_SV_POLY_GPS_ISC_L2C)
+#define ULP_GNSS_SV_POLY_BIT_GPS_ISC_L5I5 (1<<ULP_GNSS_SV_POLY_GPS_ISC_L5I5)
+#define ULP_GNSS_SV_POLY_BIT_GPS_ISC_L5Q5 (1<<ULP_GNSS_SV_POLY_GPS_ISC_L5Q5)
+#define ULP_GNSS_SV_POLY_BIT_GPS_TGD (1<<ULP_GNSS_SV_POLY_GPS_TGD)
+#define ULP_GNSS_SV_POLY_BIT_GLO_TGD_G1G2 (1<<ULP_GNSS_SV_POLY_GLO_TGD_G1G2)
+#define ULP_GNSS_SV_POLY_BIT_BDS_TGD_B1 (1<<ULP_GNSS_SV_POLY_BDS_TGD_B1)
+#define ULP_GNSS_SV_POLY_BIT_BDS_TGD_B2 (1<<ULP_GNSS_SV_POLY_BDS_TGD_B2)
+#define ULP_GNSS_SV_POLY_BIT_BDS_TGD_B2A (1<<ULP_GNSS_SV_POLY_BDS_TGD_B2A)
+#define ULP_GNSS_SV_POLY_BIT_BDS_ISC_B2A (1<<ULP_GNSS_SV_POLY_BDS_ISC_B2A)
+#define ULP_GNSS_SV_POLY_BIT_GAL_BGD_E1E5A (1<<ULP_GNSS_SV_POLY_GAL_BGD_E1E5A)
+#define ULP_GNSS_SV_POLY_BIT_GAL_BGD_E1E5B (1<<ULP_GNSS_SV_POLY_GAL_BGD_E1E5B)
+#define ULP_GNSS_SV_POLY_BIT_NAVIC_TGD_L5 (1<<ULP_GNSS_SV_POLY_NAVIC_TGD_L5)
typedef enum
{
@@ -765,7 +1136,7 @@ typedef enum
typedef struct
{
- size_t size;
+ uint32_t size;
float clockDrift;
/**< Receiver clock Drift \n
- Units: meter per sec \n
@@ -779,7 +1150,7 @@ typedef struct
typedef struct
{
- size_t size;
+ uint32_t size;
uint8_t leapSec;
/**< GPS time leap second delta to UTC time \n
- Units: sec \n
@@ -800,7 +1171,7 @@ typedef enum
typedef struct
{
- size_t size;
+ uint32_t size;
uint32_t validMask;
/* Validity mask as per Gnss_LocInterSystemBiasValidMaskType */
@@ -812,71 +1183,12 @@ typedef struct
/**< System-1 to System-2 Time Bias uncertainty \n
- Units: msec \n
*/
-}Gnss_InterSystemBiasStructType;
+} Gnss_InterSystemBiasStructType;
-typedef struct
-{
- size_t size;
- uint16_t systemWeek;
- /**< System week number for GPS, BDS and GAL satellite systems. \n
- Set to 65535 when invalid or not available. \n
- Not valid for GLONASS system. \n
- */
-
- uint32_t systemMsec;
- /**< System time msec. Time of Week for GPS, BDS, GAL and
- Time of Day for GLONASS.
- - Units: msec \n
- */
- float systemClkTimeBias;
- /**< System clock time bias \n
- - Units: msec \n
- System time = systemMsec - systemClkTimeBias \n
- */
- float systemClkTimeUncMs;
- /**< Single sided maximum time bias uncertainty \n
- - Units: msec \n
- */
-}Gnss_LocSystemTimeStructType;
-
typedef struct {
- size_t size;
- uint8_t gloFourYear;
- /**< GLONASS four year number from 1996. Refer to GLONASS ICD.\n
- Applicable only for GLONASS and shall be ignored for other constellations. \n
- If unknown shall be set to 255
- */
-
- uint16_t gloDays;
- /**< GLONASS day number in four years. Refer to GLONASS ICD.
- Applicable only for GLONASS and shall be ignored for other constellations. \n
- If unknown shall be set to 65535
- */
-
- uint32_t gloMsec;
- /**< GLONASS time of day in msec. Refer to GLONASS ICD.
- - Units: msec \n
- */
-
- float gloClkTimeBias;
- /**< System clock time bias (sub-millisecond) \n
- - Units: msec \n
- System time = systemMsec - systemClkTimeBias \n
- */
-
- float gloClkTimeUncMs;
- /**< Single sided maximum time bias uncertainty \n
- - Units: msec \n
- */
-}Gnss_LocGloTimeStructType; /* Type */
-
-typedef struct {
-
- size_t size;
- uint32_t refFCount;
- /**< Receiver frame counter value at reference tick */
+ uint32_t size;
uint8_t systemRtc_valid;
/**< Validity indicator for System RTC */
@@ -886,13 +1198,8 @@ typedef struct {
- Units: msec \n
*/
- uint32_t sourceOfTime;
- /**< Source of time information */
-
}Gnss_LocGnssTimeExtStructType;
-
-
typedef enum
{
GNSS_LOC_MEAS_STATUS_NULL = 0x00000000,
@@ -927,7 +1234,7 @@ typedef enum
typedef struct
{
- size_t size;
+ uint32_t size;
uint32_t svMs;
/**< Satellite time milisecond.\n
For GPS, BDS, GAL range of 0 thru (604800000-1) \n
@@ -985,10 +1292,12 @@ typedef enum
/**< SV is being tracked */
}Gnss_LocSvSearchStatusEnumT;
-
typedef struct
{
- size_t size;
+ uint32_t size;
+ Gnss_LocSvSystemEnumType gnssSystem;
+ // 0 signal type mask indicates invalid value
+ GnssSignalTypeMask gnssSignalTypeMask;
uint16_t gnssSvId;
/**< GNSS SV ID.
\begin{itemize1}
@@ -1110,70 +1419,112 @@ typedef struct
/**< Satellite Elevation
- Units: radians \n
*/
-} Gnss_SVMeasurementStructType;
-
-/**< Maximum number of satellites in measurement block for given system. */
-
-typedef struct
-{
- size_t size;
- Gnss_LocSvSystemEnumType system;
- /**< Specifies the Satellite System Type
- */
- bool isSystemTimeValid;
- /**< Indicates whether System Time is Valid:\n
- - 0x01 (TRUE) -- System Time is valid \n
- - 0x00 (FALSE) -- System Time is not valid
- */
- Gnss_LocSystemTimeStructType systemTime;
- /**< System Time Information \n
+ uint64_t validMeasStatusMask;
+ /**< Bitmask indicating SV measurement status Validity.
+ Valid bitmasks: \n
+ If any MSB bit in 0xFFC0000000000000 DONT_USE is set, the measurement
+ must not be used by the client.
+ @MASK()
*/
- bool isGloTime_valid;
- Gnss_LocGloTimeStructType gloTime;
+ bool carrierPhaseUncValid;
+ /**< Validity flag for SV direction */
- bool isSystemTimeExt_valid;
- Gnss_LocGnssTimeExtStructType systemTimeExt;
+ float carrierPhaseUnc;
- uint8_t numSvs;
- /* Number of SVs in this report block */
- Gnss_SVMeasurementStructType svMeasurement[GNSS_LOC_SV_MEAS_LIST_MAX_SIZE];
- /**< Satellite measurement Information \n
- */
-} Gnss_ClockMeasurementStructType;
+} Gnss_SVMeasurementStructType;
+
+typedef uint64_t GpsSvMeasHeaderFlags;
+#define GNSS_SV_MEAS_HEADER_HAS_LEAP_SECOND 0x00000001
+#define GNSS_SV_MEAS_HEADER_HAS_CLOCK_FREQ 0x00000002
+#define GNSS_SV_MEAS_HEADER_HAS_AP_TIMESTAMP 0x00000004
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_GLO_INTER_SYSTEM_BIAS 0x00000008
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_BDS_INTER_SYSTEM_BIAS 0x00000010
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_GAL_INTER_SYSTEM_BIAS 0x00000020
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_GLO_INTER_SYSTEM_BIAS 0x00000040
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_GLO_INTER_SYSTEM_BIAS 0x00000080
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_BDS_INTER_SYSTEM_BIAS 0x00000100
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME 0x00000200
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME 0x00000400
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME 0x00000800
+#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME 0x00001000
+#define GNSS_SV_MEAS_HEADER_HAS_GLO_SYSTEM_TIME 0x00002000
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME_EXT 0x00004000
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME_EXT 0x00008000
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME_EXT 0x00010000
+#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME_EXT 0x00020000
+#define GNSS_SV_MEAS_HEADER_HAS_GLO_SYSTEM_TIME_EXT 0x00040000
+#define GNSS_SV_MEAS_HEADER_HAS_GPSL1L5_TIME_BIAS 0x00080000
+#define GNSS_SV_MEAS_HEADER_HAS_GALE1E5A_TIME_BIAS 0x00100000
+#define GNSS_SV_MEAS_HEADER_HAS_GPS_NAVIC_INTER_SYSTEM_BIAS 0x00200000
+#define GNSS_SV_MEAS_HEADER_HAS_GAL_NAVIC_INTER_SYSTEM_BIAS 0x00400000
+#define GNSS_SV_MEAS_HEADER_HAS_GLO_NAVIC_INTER_SYSTEM_BIAS 0x00800000
+#define GNSS_SV_MEAS_HEADER_HAS_BDS_NAVIC_INTER_SYSTEM_BIAS 0x01000000
+#define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME 0x02000000
+#define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME_EXT 0x04000000
typedef struct
{
- size_t size;
- uint8_t seqNum;
- /**< Current message Number */
- uint8_t maxMessageNum;
- /**< Maximum number of message that will be sent for present time epoch. */
+ uint32_t size;
+ // see defines in GNSS_SV_MEAS_HEADER_HAS_XXX_XXX
+ uint64_t flags;
- bool leapSecValid;
Gnss_LeapSecondInfoStructType leapSec;
- Gnss_InterSystemBiasStructType gpsGloInterSystemBias;
+ Gnss_LocRcvrClockFrequencyInfoStructType clockFreq; /* Freq */
- Gnss_InterSystemBiasStructType gpsBdsInterSystemBias;
+ Gnss_ApTimeStampStructType apBootTimeStamp;
+ Gnss_InterSystemBiasStructType gpsGloInterSystemBias;
+ Gnss_InterSystemBiasStructType gpsBdsInterSystemBias;
Gnss_InterSystemBiasStructType gpsGalInterSystemBias;
-
Gnss_InterSystemBiasStructType bdsGloInterSystemBias;
-
Gnss_InterSystemBiasStructType galGloInterSystemBias;
-
Gnss_InterSystemBiasStructType galBdsInterSystemBias;
+ Gnss_InterSystemBiasStructType gpsNavicInterSystemBias;
+ Gnss_InterSystemBiasStructType galNavicInterSystemBias;
+ Gnss_InterSystemBiasStructType gloNavicInterSystemBias;
+ Gnss_InterSystemBiasStructType bdsNavicInterSystemBias;
+ Gnss_InterSystemBiasStructType gpsL1L5TimeBias;
+ Gnss_InterSystemBiasStructType galE1E5aTimeBias;
+
+ GnssSystemTimeStructType gpsSystemTime;
+ GnssSystemTimeStructType galSystemTime;
+ GnssSystemTimeStructType bdsSystemTime;
+ GnssSystemTimeStructType qzssSystemTime;
+ GnssSystemTimeStructType navicSystemTime;
+ GnssGloTimeStructType gloSystemTime;
+
+ /** GPS system RTC time information. */
+ Gnss_LocGnssTimeExtStructType gpsSystemTimeExt;
+ /** GAL system RTC time information. */
+ Gnss_LocGnssTimeExtStructType galSystemTimeExt;
+ /** BDS system RTC time information. */
+ Gnss_LocGnssTimeExtStructType bdsSystemTimeExt;
+ /** QZSS system RTC time information. */
+ Gnss_LocGnssTimeExtStructType qzssSystemTimeExt;
+ /** GLONASS system RTC time information. */
+ Gnss_LocGnssTimeExtStructType gloSystemTimeExt;
+ /** NAVIC system RTC time information. */
+ Gnss_LocGnssTimeExtStructType navicSystemTimeExt;
+} GnssSvMeasurementHeader;
- bool clockFreqValid;
- Gnss_LocRcvrClockFrequencyInfoStructType clockFreq; /* Freq */
- bool gnssMeasValid;
- Gnss_ClockMeasurementStructType gnssMeas;
- Gnss_ApTimeStampStructType timeStamp;
+typedef struct {
+ uint32_t size;
+ bool isNhz;
+ GnssSvMeasurementHeader svMeasSetHeader;
+ uint32_t svMeasCount;
+ Gnss_SVMeasurementStructType svMeas[GNSS_LOC_SV_MEAS_LIST_MAX_SIZE];
} GnssSvMeasurementSet;
+typedef struct {
+ uint32_t size; // set to sizeof(GnssMeasurements)
+ GnssSvMeasurementSet gnssSvMeasurementSet;
+ GnssMeasurementsNotification gnssMeasNotification;
+} GnssMeasurements;
+
typedef enum
{
GNSS_SV_POLY_COEFF_VALID = 0x01,
@@ -1200,7 +1551,7 @@ typedef enum
typedef struct
{
- size_t size;
+ uint32_t size;
uint16_t gnssSvId;
/* GPS: 1-32, GLO: 65-96, 0: Invalid,
SBAS: 120-151, BDS:201-237,GAL:301 to 336
@@ -1209,10 +1560,8 @@ typedef struct
int8_t freqNum;
/* Freq index, only valid if u_SysInd is GLO */
- uint8_t svPolyFlags;
- /* Indicate the validity of the elements
- as per Gnss_SvPolyStatusMaskType
- */
+ GnssSvPolyStatusMaskValidity svPolyStatusMaskValidity;
+ GnssSvPolyStatusMask svPolyStatusMask;
uint32_t is_valid;
@@ -1244,8 +1593,518 @@ typedef struct
double velCoef[GNSS_SV_POLY_VELOCITY_COEF_MAX_SIZE];
/* Coefficients of velocity poly */
uint32_t enhancedIOD; /* Enhanced Reference Time */
+ float gpsIscL1ca;
+ float gpsIscL2c;
+ float gpsIscL5I5;
+ float gpsIscL5Q5;
+ float gpsTgd;
+ float gloTgdG1G2;
+ float bdsTgdB1;
+ float bdsTgdB2;
+ float bdsTgdB2a;
+ float bdsIscB2a;
+ float galBgdE1E5a;
+ float galBgdE1E5b;
+ float navicTgdL5;
} GnssSvPolynomial;
+typedef enum {
+ GNSS_EPH_ACTION_UPDATE_SRC_UNKNOWN_V02 = 0, /**<Update ephemeris. Source of ephemeris is unknown */
+ GNSS_EPH_ACTION_UPDATE_SRC_OTA_V02 = 1, /**<Update ephemeris. Source of ephemeris is OTA */
+ GNSS_EPH_ACTION_UPDATE_SRC_NETWORK_V02 = 2, /**<Update ephemeris. Source of ephemeris is Network */
+ GNSS_EPH_ACTION_UPDATE_MAX_V02 = 999, /**<Max value for update ephemeris action. DO NOT USE */
+ GNSS_EPH_ACTION_DELETE_SRC_UNKNOWN_V02 = 1000, /**<Delete previous ephemeris from unknown source */
+ GNSS_EPH_ACTION_DELETE_SRC_NETWORK_V02 = 1001, /**<Delete previous ephemeris from network */
+ GNSS_EPH_ACTION_DELETE_SRC_OTA_V02 = 1002, /**<Delete previous ephemeris from OTA */
+ GNSS_EPH_ACTION_DELETE_MAX_V02 = 1999, /**<Max value for delete ephemeris action. DO NOT USE */
+} GnssEphAction;
+
+typedef enum {
+ GAL_EPH_SIGNAL_SRC_UNKNOWN_V02 = 0, /**< GALILEO signal is unknown */
+ GAL_EPH_SIGNAL_SRC_E1B_V02 = 1, /**< GALILEO signal is E1B */
+ GAL_EPH_SIGNAL_SRC_E5A_V02 = 2, /**< GALILEO signal is E5A */
+ GAL_EPH_SIGNAL_SRC_E5B_V02 = 3, /**< GALILEO signal is E5B */
+} GalEphSignalSource;
+
+typedef struct {
+ uint16_t gnssSvId;
+ /**< GNSS SV ID.
+ - Type: uint16
+ \begin{itemize1}
+ \item Range: \begin{itemize1}
+ \item For GPS: 1 to 32
+ \item For QZSS: 193 to 197
+ \item For BDS: 201 to 237
+ \item For GAL: 301 to 336
+ \vspace{-0.18in} \end{itemize1} \end{itemize1} */
+
+ GnssEphAction updateAction;
+ /**< Specifies the action and source of ephemeris. \n
+ - Type: int32 enum */
+
+ uint16_t IODE;
+ /**< Issue of data ephemeris used (unit-less). \n
+ GPS: IODE 8 bits.\n
+ BDS: AODE 5 bits. \n
+ GAL: SIS IOD 10 bits. \n
+ - Type: uint16
+ - Units: Unit-less */
+
+ double aSqrt;
+ /**< Square root of semi-major axis. \n
+ - Type: double
+ - Units: Square Root of Meters */
+
+ double deltaN;
+ /**< Mean motion difference from computed value. \n
+ - Type: double
+ - Units: Radians/Second */
+
+ double m0;
+ /**< Mean anomaly at reference time. \n
+ - Type: double
+ - Units: Radians */
+
+ double eccentricity;
+ /**< Eccentricity . \n
+ - Type: double
+ - Units: Unit-less */
+
+ double omega0;
+ /**< Longitude of ascending node of orbital plane at the weekly epoch. \n
+ - Type: double
+ - Units: Radians */
+
+ double i0;
+ /**< Inclination angle at reference time. \n
+ - Type: double
+ - Units: Radians */
+
+ double omega;
+ /**< Argument of Perigee. \n
+ - Type: double
+ - Units: Radians */
+
+ double omegaDot;
+ /**< Rate of change of right ascension. \n
+ - Type: double
+ - Units: Radians/Second */
+
+ double iDot;
+ /**< Rate of change of inclination angle. \n
+ - Type: double
+ - Units: Radians/Second */
+
+ double cUc;
+ /**< Amplitude of the cosine harmonic correction term to the argument of latitude. \n
+ - Type: double
+ - Units: Radians */
+
+ double cUs;
+ /**< Amplitude of the sine harmonic correction term to the argument of latitude. \n
+ - Type: double
+ - Units: Radians */
+
+ double cRc;
+ /**< Amplitude of the cosine harmonic correction term to the orbit radius. \n
+ - Type: double
+ - Units: Meters */
+
+ double cRs;
+ /**< Amplitude of the sine harmonic correction term to the orbit radius. \n
+ - Type: double
+ - Units: Meters */
+
+ double cIc;
+ /**< Amplitude of the cosine harmonic correction term to the angle of inclination. \n
+ - Type: double
+ - Units: Radians */
+
+ double cIs;
+ /**< Amplitude of the sine harmonic correction term to the angle of inclination. \n
+ - Type: double
+ - Units: Radians */
+
+ uint32_t toe;
+ /**< Reference time of ephemeris. \n
+ - Type: uint32
+ - Units: Seconds */
+
+ uint32_t toc;
+ /**< Clock data reference time of week. \n
+ - Type: uint32
+ - Units: Seconds */
+
+ double af0;
+ /**< Clock bias correction coefficient. \n
+ - Type: double
+ - Units: Seconds */
+
+ double af1;
+ /**< Clock drift coefficient. \n
+ - Type: double
+ - Units: Seconds/Second */
+
+ double af2;
+ /**< Clock drift rate correction coefficient. \n
+ - Type: double
+ - Units: Seconds/Seconds^2 */
+
+} GnssEphCommon;
+
+/* GPS Navigation Model Info */
+typedef struct {
+ GnssEphCommon commonEphemerisData;
+ /**< Common ephemeris data. */
+
+ uint8_t signalHealth;
+ /**< Signal health. \n
+ Bit 0 : L5 Signal Health. \n
+ Bit 1 : L2 Signal Health. \n
+ Bit 2 : L1 Signal Health. \n
+ - Type: uint8
+ - Values: 3 bit mask of signal health, where set bit indicates unhealthy signal */
+
+ uint8_t URAI;
+ /**< User Range Accuracy Index. \n
+ - Type: uint8
+ - Units: Unit-less */
+
+ uint8_t codeL2;
+ /**< Indicates which codes are commanded ON for the L2 channel (2-bits). \n
+ - Type: uint8
+ Valid Values: \n
+ - 00 : Reserved
+ - 01 : P code ON
+ - 10 : C/A code ON */
+
+ uint8_t dataFlagL2P;
+ /**< L2 P-code indication flag. \n
+ - Type: uint8
+ - Value 1 indicates that the Nav data stream was commanded OFF on the P-code of the L2 channel. */
+
+ double tgd;
+ /**< Time of group delay. \n
+ - Type: double
+ - Units: Seconds */
+
+ uint8_t fitInterval;
+ /**< Indicates the curve-fit interval used by the CS. \n
+ - Type: uint8
+ Valid Values:
+ - 0 : Four hours
+ - 1 : Greater than four hours */
+
+ uint16_t IODC;
+ /**< Issue of Data, Clock. \n
+ - Type: uint16
+ - Units: Unit-less */
+} GpsEphemeris;
+
+/* GLONASS Navigation Model Info */
+typedef struct {
+
+ uint16_t gnssSvId;
+ /**< GNSS SV ID.
+ - Type: uint16
+ - Range: 65 to 96 if known. When the slot number to SV ID mapping is unknown, set to 255 */
+
+ GnssEphAction updateAction;
+ /**< Specifies the action and source of ephemeris. \n
+ - Type: int32 enum */
+
+ uint8_t bnHealth;
+ /**< SV health flags. \n
+ - Type: uint8
+ Valid Values: \n
+ - 0 : Healthy
+ - 1 : Unhealthy */
+
+ uint8_t lnHealth;
+ /**< Ln SV health flags. GLONASS-M. \n
+ - Type: uint8
+ Valid Values: \n
+ - 0 : Healthy
+ - 1 : Unhealthy */
+
+ uint8_t tb;
+ /**< Index of a time interval within current day according to UTC(SU) + 03 hours 00 min. \n
+ - Type: uint8
+ - Units: Unit-less */
+
+ uint8_t ft;
+ /**< SV accuracy index. \n
+ - Type: uint8
+ - Units: Unit-less */
+
+ uint8_t gloM;
+ /**< GLONASS-M flag. \n
+ - Type: uint8
+ Valid Values: \n
+ - 0 : GLONASS
+ - 1 : GLONASS-M */
+
+ uint8_t enAge;
+ /**< Characterizes "Age" of current information. \n
+ - Type: uint8
+ - Units: Days */
+
+ uint8_t gloFrequency;
+ /**< GLONASS frequency number + 8. \n
+ - Type: uint8
+ - Range: 1 to 14
+ */
+
+ uint8_t p1;
+ /**< Time interval between two adjacent values of tb parameter. \n
+ - Type: uint8
+ - Units: Minutes */
+
+ uint8_t p2;
+ /**< Flag of oddness ("1") or evenness ("0") of the value of tb \n
+ for intervals 30 or 60 minutes. \n
+ - Type: uint8 */
+
+ float deltaTau;
+ /**< Time difference between navigation RF signal transmitted in L2 sub-band \n
+ and aviation RF signal transmitted in L1 sub-band. \n
+ - Type: floating point
+ - Units: Seconds */
+
+ double position[3];
+ /**< Satellite XYZ position. \n
+ - Type: array of doubles
+ - Units: Meters */
+
+ double velocity[3];
+ /**< Satellite XYZ velocity. \n
+ - Type: array of doubles
+ - Units: Meters/Second */
+
+ double acceleration[3];
+ /**< Satellite XYZ sola-luni acceleration. \n
+ - Type: array of doubles
+ - Units: Meters/Second^2 */
+
+ float tauN;
+ /**< Satellite clock correction relative to GLONASS time. \n
+ - Type: floating point
+ - Units: Seconds */
+
+ float gamma;
+ /**< Relative deviation of predicted carrier frequency value \n
+ from nominal value at the instant tb. \n
+ - Type: floating point
+ - Units: Unit-less */
+
+ double toe;
+ /**< Complete ephemeris time, including N4, NT and Tb. \n
+ [(N4-1)*1461 + (NT-1)]*86400 + tb*900 \n
+ - Type: double
+ - Units: Seconds */
+
+ uint16_t nt;
+ /**< Current date, calendar number of day within four-year interval. \n
+ Starting from the 1-st of January in a leap year. \n
+ - Type: uint16
+ - Units: Days */
+} GlonassEphemeris;
+
+/* BDS Navigation Model Info */
+typedef struct {
+
+ GnssEphCommon commonEphemerisData;
+ /**< Common ephemeris data. */
+
+ uint8_t svHealth;
+ /**< Satellite health information applied to both B1 and B2 (SatH1). \n
+ - Type: uint8
+ Valid Values: \n
+ - 0 : Healthy
+ - 1 : Unhealthy */
+
+ uint8_t AODC;
+ /**< Age of data clock. \n
+ - Type: uint8
+ - Units: Hours */
+
+ double tgd1;
+ /**< Equipment group delay differential on B1 signal. \n
+ - Type: double
+ - Units: Nano-Seconds */
+
+ double tgd2;
+ /**< Equipment group delay differential on B2 signal. \n
+ - Type: double
+ - Units: Nano-Seconds */
+
+ uint8_t URAI;
+ /**< User range accuracy index (4-bits). \n
+ - Type: uint8
+ - Units: Unit-less */
+} BdsEphemeris;
+
+/* GALIELO Navigation Model Info */
+typedef struct {
+
+ GnssEphCommon commonEphemerisData;
+ /**< Common ephemeris data. */
+
+ GalEphSignalSource dataSourceSignal;
+ /**< Galileo Signal Source. \n
+ Valid Values: \n
+ - GAL_EPH_SIGNAL_SRC_UNKNOWN (0) -- GALILEO signal is unknown
+ - GAL_EPH_SIGNAL_SRC_E1B (1) -- GALILEO signal is E1B
+ - GAL_EPH_SIGNAL_SRC_E5A (2) -- GALILEO signal is E5A
+ - GAL_EPH_SIGNAL_SRC_E5B (3) -- GALILEO signal is E5B */
+
+ uint8_t sisIndex;
+ /**< Signal-in-space index for dual frequency E1-E5b/E5a depending on dataSignalSource. \n
+ - Type: uint8
+ - Units: Unit-less */
+
+ double bgdE1E5a;
+ /**< E1-E5a Broadcast group delay from F/Nav (E5A). \n
+ - Type: double
+ - Units: Seconds */
+
+ double bgdE1E5b;
+ /**< E1-E5b Broadcast group delay from I/Nav (E1B or E5B). \n
+ For E1B or E5B signal, both bgdE1E5a and bgdE1E5b are valid. \n
+ For E5A signal, only bgdE1E5a is valid. \n
+ Signal source identified using dataSignalSource. \n
+ - Type: double
+ - Units: Seconds */
+
+ uint8_t svHealth;
+ /**< SV health status of signal identified by dataSourceSignal. \n
+ - Type: uint8
+ Valid Values: \n
+ - 0 : Healthy
+ - 1 : Unhealthy */
+} GalileoEphemeris;
+
+/** GPS Navigation model for each SV */
+typedef struct {
+ uint16_t numOfEphemeris;
+ GpsEphemeris gpsEphemerisData[GNSS_EPHEMERIS_LIST_MAX_SIZE_V02];
+} GpsEphemerisResponse;
+
+/** GLONASS Navigation model for each SV */
+typedef struct {
+ uint16_t numOfEphemeris;
+ GlonassEphemeris gloEphemerisData[GNSS_EPHEMERIS_LIST_MAX_SIZE_V02];
+} GlonassEphemerisResponse;
+
+/** BDS Navigation model for each SV */
+typedef struct {
+ uint16_t numOfEphemeris;
+ BdsEphemeris bdsEphemerisData[GNSS_EPHEMERIS_LIST_MAX_SIZE_V02];
+} BdsEphemerisResponse;
+
+/** GALILEO Navigation model for each SV */
+typedef struct {
+ uint16_t numOfEphemeris;
+ GalileoEphemeris galEphemerisData[GNSS_EPHEMERIS_LIST_MAX_SIZE_V02];
+} GalileoEphemerisResponse;
+
+/** QZSS Navigation model for each SV */
+typedef struct {
+ uint16_t numOfEphemeris;
+ GpsEphemeris qzssEphemerisData[GNSS_EPHEMERIS_LIST_MAX_SIZE_V02];
+} QzssEphemerisResponse;
+
+
+typedef struct {
+ /** Indicates GNSS Constellation Type
+ Mandatory field */
+ Gnss_LocSvSystemEnumType gnssConstellation;
+
+ /** GPS System Time of the ephemeris report */
+ bool isSystemTimeValid;
+ GnssSystemTimeStructType systemTime;
+
+ union {
+ /** GPS Ephemeris */
+ GpsEphemerisResponse gpsEphemeris;
+ /** GLONASS Ephemeris */
+ GlonassEphemerisResponse glonassEphemeris;
+ /** BDS Ephemeris */
+ BdsEphemerisResponse bdsEphemeris;
+ /** GALILEO Ephemeris */
+ GalileoEphemerisResponse galileoEphemeris;
+ /** QZSS Ephemeris */
+ QzssEphemerisResponse qzssEphemeris;
+ } ephInfo;
+} GnssSvEphemerisReport;
+
+typedef struct {
+ /** GPS System Time of the iono model report */
+ bool isSystemTimeValid;
+ GnssSystemTimeStructType systemTime;
+
+ /** Indicates GNSS Constellation Type */
+ Gnss_LocSvSystemEnumType gnssConstellation;
+
+ float alpha0;
+ /**< Klobuchar Model Parameter Alpha 0.
+ - Type: float
+ - Unit: Seconds
+ */
+
+ float alpha1;
+ /**< Klobuchar Model Parameter Alpha 1.
+ - Type: float
+ - Unit: Seconds / Semi-Circle
+ */
+
+ float alpha2;
+ /**< Klobuchar Model Parameter Alpha 2.
+ - Type: float
+ - Unit: Seconds / Semi-Circle^2
+ */
+
+ float alpha3;
+ /**< Klobuchar Model Parameter Alpha 3.
+ - Type: float
+ - Unit: Seconds / Semi-Circle^3
+ */
+
+ float beta0;
+ /**< Klobuchar Model Parameter Beta 0.
+ - Type: float
+ - Unit: Seconds
+ */
+
+ float beta1;
+ /**< Klobuchar Model Parameter Beta 1.
+ - Type: float
+ - Unit: Seconds / Semi-Circle
+ */
+
+ float beta2;
+ /**< Klobuchar Model Parameter Beta 2.
+ - Type: float
+ - Unit: Seconds / Semi-Circle^2
+ */
+
+ float beta3;
+ /**< Klobuchar Model Parameter Beta 3.
+ - Type: float
+ - Unit: Seconds / Semi-Circle^3
+ */
+} GnssKlobucharIonoModel;
+
+typedef struct {
+ /** GPS System Time of the report */
+ bool isSystemTimeValid;
+ GnssSystemTimeStructType systemTime;
+
+ GnssAdditionalSystemInfoMask validityMask;
+ double tauC;
+ int8_t leapSec;
+} GnssAdditionalSystemInfo;
+
/* Various Short Range Node Technology type*/
typedef enum {
SRN_AP_DATA_TECH_TYPE_NONE,
@@ -1266,44 +2125,114 @@ typedef enum {
typedef struct
{
- size_t size;
+ uint32_t size;
Gnss_SrnTech srnTechType; /* SRN Technology type in request */
bool srnRequest; /* scan - start(true) or stop(false) */
bool e911Mode; /* If in E911 emergency */
Gnss_Srn_MacAddr_Type macAddrType; /* SRN AP MAC Address type */
} GnssSrnDataReq;
+/* Mask indicating enabled or disabled constellations */
+typedef uint64_t GnssSvTypesMask;
+typedef enum {
+ GNSS_SV_TYPES_MASK_GLO_BIT = (1<<0),
+ GNSS_SV_TYPES_MASK_BDS_BIT = (1<<1),
+ GNSS_SV_TYPES_MASK_QZSS_BIT = (1<<2),
+ GNSS_SV_TYPES_MASK_GAL_BIT = (1<<3),
+ GNSS_SV_TYPES_MASK_NAVIC_BIT = (1<<4),
+} GnssSvTypesMaskBits;
+
+/* This SV Type config is injected directly to GNSS Adapter
+ * bypassing Location API */
+typedef struct {
+ uint32_t size; // set to sizeof(GnssSvTypeConfig)
+ // Enabled Constellations
+ GnssSvTypesMask enabledSvTypesMask;
+ // Disabled Constellations
+ GnssSvTypesMask blacklistedSvTypesMask;
+} GnssSvTypeConfig;
+
+/* Provides the current GNSS SV Type configuration to the client.
+ * This is fetched via direct call to GNSS Adapter bypassing
+ * Location API */
+typedef std::function<void(
+ const GnssSvTypeConfig& config
+)> GnssSvTypeConfigCallback;
+
/*
* Represents the status of AGNSS augmented to support IPv4.
*/
struct AGnssExtStatusIpV4 {
- AGpsExtType type;
- LocAGpsStatusValue status;
+ AGpsExtType type;
+ LocApnTypeMask apnTypeMask;
+ LocAGpsStatusValue status;
/*
* 32-bit IPv4 address.
*/
- uint32_t ipV4Addr;
+ uint32_t ipV4Addr;
};
/*
* Represents the status of AGNSS augmented to support IPv6.
*/
struct AGnssExtStatusIpV6 {
- AGpsExtType type;
- LocAGpsStatusValue status;
+ AGpsExtType type;
+ LocApnTypeMask apnTypeMask;
+ LocAGpsStatusValue status;
/*
* 128-bit IPv6 address.
*/
- uint8_t ipV6Addr[16];
+ uint8_t ipV6Addr[16];
};
+/*
+* Represents the the Nfw Notification structure
+*/
+#define GNSS_MAX_NFW_APP_STRING_LEN 64
+#define GNSS_MAX_NFW_STRING_LEN 20
+
+typedef enum {
+ GNSS_NFW_CTRL_PLANE = 0,
+ GNSS_NFW_SUPL = 1,
+ GNSS_NFW_IMS = 10,
+ GNSS_NFW_SIM = 11,
+ GNSS_NFW_OTHER_PROTOCOL_STACK = 100
+} GnssNfwProtocolStack;
+
+typedef enum {
+ GNSS_NFW_CARRIER = 0,
+ GNSS_NFW_OEM = 10,
+ GNSS_NFW_MODEM_CHIPSET_VENDOR = 11,
+ GNSS_NFW_GNSS_CHIPSET_VENDOR = 12,
+ GNSS_NFW_OTHER_CHIPSET_VENDOR = 13,
+ GNSS_NFW_AUTOMOBILE_CLIENT = 20,
+ GNSS_NFW_OTHER_REQUESTOR = 100
+} GnssNfwRequestor;
+
+typedef enum {
+ GNSS_NFW_REJECTED = 0,
+ GNSS_NFW_ACCEPTED_NO_LOCATION_PROVIDED = 1,
+ GNSS_NFW_ACCEPTED_LOCATION_PROVIDED = 2,
+} GnssNfwResponseType;
+
+typedef struct {
+ char proxyAppPackageName[GNSS_MAX_NFW_APP_STRING_LEN];
+ GnssNfwProtocolStack protocolStack;
+ char otherProtocolStackName[GNSS_MAX_NFW_STRING_LEN];
+ GnssNfwRequestor requestor;
+ char requestorId[GNSS_MAX_NFW_STRING_LEN];
+ GnssNfwResponseType responseType;
+ bool inEmergencyMode;
+ bool isCachedLocation;
+} GnssNfwNotification;
+
/* ODCPI Request Info */
enum OdcpiRequestType {
ODCPI_REQUEST_TYPE_START,
ODCPI_REQUEST_TYPE_STOP
};
struct OdcpiRequestInfo {
- size_t size;
+ uint32_t size;
OdcpiRequestType type;
uint32_t tbfMillis;
bool isEmergencyMode;
@@ -1319,6 +2248,12 @@ typedef std::function<void(const OdcpiRequestInfo& request)> OdcpiRequestCallbac
typedef void (*AgnssStatusIpV4Cb)(AGnssExtStatusIpV4 status);
/*
+* Callback with NFW information.
+*/
+typedef void(*NfwStatusCb)(GnssNfwNotification notification);
+typedef bool(*IsInEmergencySession)(void);
+
+/*
* Callback with AGNSS(IpV6) status information.
*
* @param status Will be of type AGnssExtStatusIpV6.
@@ -1332,8 +2267,21 @@ typedef void (*LocAgpsOpenResultCb)(bool isSuccess, AGpsExtType agpsType, const
typedef void (*LocAgpsCloseResultCb)(bool isSuccess, AGpsExtType agpsType, void* userDataPtr);
/* Shared resources of LocIpc */
-#define LOC_IPC_HAL "/dev/socket/location/socket_hal"
-#define LOC_IPC_XTRA "/dev/socket/location/xtra/socket_xtra"
+#define LOC_IPC_HAL "/dev/socket/location/socket_hal"
+#define LOC_IPC_XTRA "/dev/socket/location/xtra/socket_xtra"
+
+#define SOCKET_DIR_LOCATION "/dev/socket/location/"
+#define SOCKET_DIR_EHUB "/dev/socket/location/ehub/"
+#define SOCKET_TO_LOCATION_HAL_DAEMON "/dev/socket/loc_client/hal_daemon"
+
+#define SOCKET_LOC_CLIENT_DIR "/dev/socket/loc_client/"
+#define EAP_LOC_CLIENT_DIR "/data/vendor/location/extap_locclient/"
+
+#define LOC_CLIENT_NAME_PREFIX "toclient"
+
+typedef uint64_t NetworkHandle;
+#define NETWORK_HANDLE_UNKNOWN ~0
+#define MAX_NETWORK_HANDLES 10
#ifdef __cplusplus
}
diff --git a/gps/utils/linked_list.h b/gps/utils/linked_list.h
index a85f09a..0b33ecb 100644
--- a/gps/utils/linked_list.h
+++ b/gps/utils/linked_list.h
@@ -50,6 +50,8 @@ typedef enum
/**< Failed because an there were not enough resources. */
eLINKED_LIST_INSUFFICIENT_BUFFER = -5,
/**< Failed because an the supplied buffer was too small. */
+ eLINKED_LIST_EMPTY = -6
+ /**< Failed because list is empty. */
}linked_list_err_type;
/*===========================================================================
diff --git a/gps/utils/loc_cfg.cpp b/gps/utils/loc_cfg.cpp
index e646ea8..8baf8ca 100644
--- a/gps/utils/loc_cfg.cpp
+++ b/gps/utils/loc_cfg.cpp
@@ -37,7 +37,7 @@
#include <ctype.h>
#include <unistd.h>
#include <time.h>
-#include <pwd.h>
+#include <grp.h>
#include <errno.h>
#include <loc_cfg.h>
#include <loc_pla.h>
@@ -57,14 +57,15 @@
/* Parameter data */
static uint32_t DEBUG_LEVEL = 0xff;
static uint32_t TIMESTAMP = 0;
-static uint32_t LOC_MODEM_EMULATOR = 0;
+static uint32_t DATUM_TYPE = 0;
+static bool sVendorEnhanced = true;
/* Parameter spec table */
static const loc_param_s_type loc_param_table[] =
{
{"DEBUG_LEVEL", &DEBUG_LEVEL, NULL, 'n'},
{"TIMESTAMP", &TIMESTAMP, NULL, 'n'},
- {"LOC_MODEM_EMULATOR", &LOC_MODEM_EMULATOR, NULL, 'n'},
+ {"DATUM_TYPE", &DATUM_TYPE, NULL, 'n'},
};
static const int loc_param_num = sizeof(loc_param_table) / sizeof(loc_param_s_type);
@@ -87,21 +88,34 @@ const char LOC_PATH_APDR_CONF[] = LOC_PATH_APDR_CONF_STR;
const char LOC_PATH_XTWIFI_CONF[] = LOC_PATH_XTWIFI_CONF_STR;
const char LOC_PATH_QUIPC_CONF[] = LOC_PATH_QUIPC_CONF_STR;
-bool isXtraDaemonEnabled() {
- bool enabled = property_get_bool("persist.sys.xtra-daemon.enabled", false);
- LOC_LOGe("xtra-daemon enabled: %d\n", enabled);
- return enabled;
+bool isVendorEnhanced() {
+ return sVendorEnhanced;
+}
+void setVendorEnhanced(bool vendorEnhanced) {
+ sVendorEnhanced = vendorEnhanced;
}
/*===========================================================================
-FUNCTION loc_modem_emulator_enabled
+FUNCTION loc_get_datum_type
DESCRIPTION
- Provides access to Modem Emulator config item.
+ get datum type
+
+PARAMETERS:
+ N/A
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ DATUM TYPE
+
+SIDE EFFECTS
+ N/A
===========================================================================*/
-uint32_t loc_modem_emulator_enabled()
+int loc_get_datum_type()
{
- return LOC_MODEM_EMULATOR;
+ return DATUM_TYPE;
}
/*===========================================================================
@@ -147,7 +161,7 @@ int loc_set_config_entry(const loc_param_s_type* config_entry, loc_param_v_type*
else {
strlcpy((char*) config_entry->param_ptr,
config_value->param_str_value,
- LOC_MAX_PARAM_STRING + 1);
+ LOC_MAX_PARAM_STRING);
}
/* Log INI values */
LOC_LOGD("%s: PARAM %s = %s", __FUNCTION__,
@@ -446,19 +460,18 @@ void loc_read_conf(const char* conf_file_name, const loc_param_s_type* config_ta
#define CONFIG_MASK_AUTOPLATFORM_ALL 0x10
#define CONFIG_MASK_AUTOPLATFORM_FOUND 0x20
#define CONFIG_MASK_AUTOPLATFORM_CHECK 0x30
+#define CONFIG_MASK_SOCID_ALL 0x40
+#define CONFIG_MASK_SOCID_FOUND 0x80
+#define CONFIG_MASK_SOCID_CHECK 0xc0
#define LOC_FEATURE_MASK_GTP_WIFI_BASIC 0x01
#define LOC_FEATURE_MASK_GTP_WIFI_PREMIUM 0X02
#define LOC_FEATURE_MASK_GTP_CELL_BASIC 0X04
#define LOC_FEATURE_MASK_GTP_CELL_PREMIUM 0X08
-#define LOC_FEATURE_MASK_GTP_AP_CELL_BASIC LOC_FEATURE_MASK_GTP_CELL_BASIC
-#define LOC_FEATURE_MASK_GTP_AP_CELL_PREMIUM LOC_FEATURE_MASK_GTP_CELL_PREMIUM
#define LOC_FEATURE_MASK_SAP_BASIC 0x40
#define LOC_FEATURE_MASK_SAP_PREMIUM 0X80
#define LOC_FEATURE_MASK_GTP_WAA_BASIC 0X100
-#define LOC_FEATURE_MASK_GTP_WAA_PREMIUM 0x200
#define LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC 0X400
-#define LOC_FEATURE_MASK_GTP_MODEM_CELL_PREMIUM 0X800
#define LOC_FEATURE_MASK_ODCPI 0x1000
#define LOC_FEATURE_MASK_FREE_WIFI_SCAN_INJECT 0x2000
#define LOC_FEATURE_MASK_SUPL_WIFI 0x4000
@@ -473,17 +486,18 @@ typedef struct {
unsigned int loc_feature_mask;
char platform_list[LOC_MAX_PARAM_STRING];
char baseband[LOC_MAX_PARAM_STRING];
+ char low_ram_targets[LOC_MAX_PARAM_STRING];
+ char soc_id_list[LOC_MAX_PARAM_STRING];
unsigned int sglte_target;
- char feature_gtp_cell_proc[LOC_MAX_PARAM_STRING];
+ char feature_gtp_mode[LOC_MAX_PARAM_STRING];
char feature_gtp_waa[LOC_MAX_PARAM_STRING];
- char feature_gtp_cell[LOC_MAX_PARAM_STRING];
- char feature_gtp_wifi[LOC_MAX_PARAM_STRING];
char feature_sap[LOC_MAX_PARAM_STRING];
char feature_odcpi[LOC_MAX_PARAM_STRING];
char feature_free_wifi_scan_inject[LOC_MAX_PARAM_STRING];
char feature_supl_wifi[LOC_MAX_PARAM_STRING];
char feature_wifi_supplicant_info[LOC_MAX_PARAM_STRING];
char auto_platform[LOC_MAX_PARAM_STRING];
+ unsigned int vendor_enhanced_process;
} loc_launcher_conf;
/* process configuration parameters */
@@ -496,9 +510,7 @@ static const loc_param_s_type gps_conf_parameter_table[] = {
/* location feature conf, e.g.: izat.conf feature mode table*/
static const loc_param_s_type loc_feature_conf_table[] = {
- {"GTP_CELL_PROC", &conf.feature_gtp_cell_proc, NULL, 's'},
- {"GTP_CELL", &conf.feature_gtp_cell, NULL, 's'},
- {"GTP_WIFI", &conf.feature_gtp_wifi, NULL, 's'},
+ {"GTP_MODE", &conf.feature_gtp_mode, NULL, 's'},
{"GTP_WAA", &conf.feature_gtp_waa, NULL, 's'},
{"SAP", &conf.feature_sap, NULL, 's'},
{"ODCPI", &conf.feature_odcpi, NULL, 's'},
@@ -509,15 +521,18 @@ static const loc_param_s_type loc_feature_conf_table[] = {
/* location process conf, e.g.: izat.conf Parameter spec table */
static const loc_param_s_type loc_process_conf_parameter_table[] = {
- {"PROCESS_NAME", &conf.proc_name, NULL, 's'},
- {"PROCESS_ARGUMENT", &conf.proc_argument, NULL, 's'},
- {"PROCESS_STATE", &conf.proc_status, NULL, 's'},
- {"PROCESS_GROUPS", &conf.group_list, NULL, 's'},
- {"PREMIUM_FEATURE", &conf.premium_feature, NULL, 'n'},
- {"IZAT_FEATURE_MASK", &conf.loc_feature_mask, NULL, 'n'},
- {"PLATFORMS", &conf.platform_list, NULL, 's'},
- {"BASEBAND", &conf.baseband, NULL, 's'},
- {"HARDWARE_TYPE", &conf.auto_platform, NULL, 's'},
+ {"PROCESS_NAME", &conf.proc_name, NULL, 's'},
+ {"PROCESS_ARGUMENT", &conf.proc_argument, NULL, 's'},
+ {"PROCESS_STATE", &conf.proc_status, NULL, 's'},
+ {"PROCESS_GROUPS", &conf.group_list, NULL, 's'},
+ {"PREMIUM_FEATURE", &conf.premium_feature, NULL, 'n'},
+ {"IZAT_FEATURE_MASK", &conf.loc_feature_mask, NULL, 'n'},
+ {"PLATFORMS", &conf.platform_list, NULL, 's'},
+ {"SOC_IDS", &conf.soc_id_list, NULL, 's'},
+ {"BASEBAND", &conf.baseband, NULL, 's'},
+ {"LOW_RAM_TARGETS", &conf.low_ram_targets, NULL, 's'},
+ {"HARDWARE_TYPE", &conf.auto_platform, NULL, 's'},
+ {"VENDOR_ENHANCED_PROCESS", &conf.vendor_enhanced_process, NULL, 'n'},
};
/*===========================================================================
@@ -553,17 +568,17 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
gid_t gid_list[LOC_PROCESS_MAX_NUM_GROUPS];
char *split_strings[MAX_NUM_STRINGS];
int name_length=0, group_list_length=0, platform_length=0, baseband_length=0, ngroups=0, ret=0;
- int auto_platform_length = 0;
+ int auto_platform_length = 0, soc_id_list_length=0;
int group_index=0, nstrings=0, status_length=0;
FILE* conf_fp = nullptr;
char platform_name[PROPERTY_VALUE_MAX], baseband_name[PROPERTY_VALUE_MAX];
- char autoplatform_name[PROPERTY_VALUE_MAX];
+ int low_ram_target=0;
+ char autoplatform_name[PROPERTY_VALUE_MAX], socid_value[PROPERTY_VALUE_MAX];
unsigned int loc_service_mask=0;
- char config_mask = 0;
+ unsigned char config_mask = 0;
unsigned char proc_list_length=0;
int gtp_cell_ap_enabled = 0;
char arg_gtp_waa[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
- char arg_gtp_ap_cell[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
char arg_gtp_modem_cell[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
char arg_gtp_wifi[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
char arg_sap[LOC_PROCESS_MAX_ARG_STR_LENGTH] = "--";
@@ -580,7 +595,6 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
//Form argument strings
strlcat(arg_gtp_waa, LOC_FEATURE_GTP_WAA, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
- strlcat(arg_gtp_ap_cell, LOC_FEATURE_GTP_AP_CELL, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
strlcat(arg_gtp_modem_cell, LOC_FEATURE_GTP_MODEM_CELL, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
strlcat(arg_gtp_wifi, LOC_FEATURE_GTP_WIFI, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
strlcat(arg_sap, LOC_FEATURE_SAP, LOC_PROCESS_MAX_ARG_STR_LENGTH-3);
@@ -591,86 +605,42 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
loc_get_target_baseband(baseband_name, sizeof(baseband_name));
//Identify if this is an automotive platform
loc_get_auto_platform_name(autoplatform_name,sizeof(autoplatform_name));
+ //Identify if this is a low ram target from ro.config.low_ram property
+ low_ram_target = loc_identify_low_ram_target();
+ // Get the soc-id for this device.
+ loc_get_device_soc_id(socid_value, sizeof(socid_value));
UTIL_READ_CONF(conf_file_name, loc_feature_conf_table);
- //Set service mask for GTP_WIFI
- if(strcmp(conf.feature_gtp_wifi, "DISABLED") == 0) {
- LOC_LOGD("%s:%d]: GTP WIFI DISABLED", __func__, __LINE__);
+ //Set service mask for GTP_MODE
+ if(strcmp(conf.feature_gtp_mode, "DISABLED") == 0) {
+ LOC_LOGD("%s:%d]: GTP MODE DISABLED", __func__, __LINE__);
}
- else if(strcmp(conf.feature_gtp_wifi, "BASIC") == 0) {
- LOC_LOGD("%s:%d]: Setting GTP WIFI to mode: BASIC", __func__, __LINE__);
- loc_service_mask |= LOC_FEATURE_MASK_GTP_WIFI_BASIC;
+ else if(strcmp(conf.feature_gtp_mode, "LEGACY_WWAN") == 0) {
+ LOC_LOGD("%s:%d]: Setting GTP MODE to mode: LEGACY_WWAN", __func__, __LINE__);
+ loc_service_mask |= LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC;
}
- //conf file has a garbage value
- else {
- LOC_LOGE("%s:%d]: Unrecognized value for GTP WIFI Mode."\
- " Setting GTP WIFI to default mode: BASIC", __func__, __LINE__);
+ else if(strcmp(conf.feature_gtp_mode, "SDK") == 0) {
+ LOC_LOGD("%s:%d]: Setting GTP MODE to mode: SDK", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_GTP_WIFI_BASIC;
}
-
- //Set service mask for GTP_CELL
- //Using a temp variable here to indicate wheter GTP cell is
- //enabled on the AP or modem. This variable will be used in
- //further checks below. An alternative was to compare the
- //string again in each place which would've been more expensive
- if(strcmp(conf.feature_gtp_cell_proc, "AP") == 0) {
- gtp_cell_ap_enabled = 1;
- }
-
- if(strcmp(conf.feature_gtp_cell, "PREMIUM") == 0) {
- LOC_LOGE("%s:%d]: Error: location feature GTP CELL does not support PREMIUM mode" \
- " available modes are BASIC and DISABLED. Starting feature in BASIC mode",
- __func__, __LINE__);
- if(gtp_cell_ap_enabled) {
- loc_service_mask |= LOC_FEATURE_MASK_GTP_AP_CELL_BASIC;
- }
- else {
- loc_service_mask |= LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC;
- }
- }
- else if(strcmp(conf.feature_gtp_cell, "BASIC") == 0) {
- LOC_LOGD("%s:%d]: Setting GTP CELL to mode: BASIC", __func__, __LINE__);
- if(gtp_cell_ap_enabled) {
- loc_service_mask |= LOC_FEATURE_MASK_GTP_AP_CELL_BASIC;
- }
- else {
- loc_service_mask |= LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC;
- }
- }
- else if(strcmp(conf.feature_gtp_cell, "DISABLED") == 0) {
- LOC_LOGD("%s:%d]: GTP CELL DISABLED", __func__, __LINE__);
- }
//conf file has a garbage value
else {
- LOC_LOGE("%s:%d]: Unrecognized value for GTP CELL Mode." \
- " Setting GTP CELL to default mode: BASIC", __func__, __LINE__);
- if(gtp_cell_ap_enabled) {
- loc_service_mask |= LOC_FEATURE_MASK_GTP_AP_CELL_BASIC;
- }
- else {
- loc_service_mask |= LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC;
- }
+ LOC_LOGE("%s:%d]: Unrecognized value for GTP MODE Mode."\
+ " Setting GTP WIFI to default mode: DISABLED", __func__, __LINE__);
}
-
//Set service mask for GTP_WAA
- if(strcmp(conf.feature_gtp_waa, "PREMIUM") == 0) {
- LOC_LOGE("%s:%d]: Error: location feature GTP WAA does not support PREMIUM mode" \
- " available modes are BASIC and DISABLED. Starting feature in BASIC mode",
- __func__, __LINE__);
- loc_service_mask |= LOC_FEATURE_MASK_GTP_WAA_BASIC;
- }
- else if(strcmp(conf.feature_gtp_waa, "BASIC") == 0) {
- LOC_LOGD("%s:%d]: Setting GTP WAA to mode: BASIC", __func__, __LINE__);
- loc_service_mask |= LOC_FEATURE_MASK_GTP_WAA_BASIC;
+ if(strcmp(conf.feature_gtp_waa, "BASIC") == 0) {
+ LOC_LOGD("%s:%d]: Setting GTP WAA to mode: BASIC", __func__, __LINE__);
+ loc_service_mask |= LOC_FEATURE_MASK_GTP_WAA_BASIC;
}
else if(strcmp(conf.feature_gtp_waa, "DISABLED") == 0) {
- LOC_LOGD("%s:%d]: GTP WAA DISABLED", __func__, __LINE__);
+ LOC_LOGD("%s:%d]: GTP WAA DISABLED", __func__, __LINE__);
}
//conf file has a garbage value
else {
- LOC_LOGE("%s:%d]: Unrecognized value for GTP WAA Mode."\
- " Setting GTP WAA to default mode: DISABLED", __func__, __LINE__);
+ LOC_LOGE("%s:%d]: Unrecognized value for GTP WAA Mode."\
+ " Setting GTP WAA to default mode: DISABLED", __func__, __LINE__);
}
//Set service mask for SAP
@@ -682,6 +652,9 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
LOC_LOGD("%s:%d]: Setting SAP to mode: BASIC", __func__, __LINE__);
loc_service_mask |= LOC_FEATURE_MASK_SAP_BASIC;
}
+ else if(strcmp(conf.feature_sap, "MODEM_DEFAULT") == 0) {
+ LOC_LOGD("%s:%d]: Setting SAP to mode: MODEM_DEFAULT", __func__, __LINE__);
+ }
else if(strcmp(conf.feature_sap, "DISABLED") == 0) {
LOC_LOGD("%s:%d]: Setting SAP to mode: DISABLED", __func__, __LINE__);
}
@@ -808,18 +781,19 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
baseband_length = (int)strlen(conf.baseband);
status_length = (int)strlen(conf.proc_status);
auto_platform_length = (int)strlen(conf.auto_platform);
+ soc_id_list_length = (int)strlen(conf.soc_id_list);
if(!name_length || !group_list_length || !platform_length ||
- !baseband_length || !status_length || !auto_platform_length) {
+ !baseband_length || !status_length || !auto_platform_length || !soc_id_list_length) {
LOC_LOGE("%s:%d]: Error: i: %d; One of the parameters not specified in conf file",
__func__, __LINE__, i);
continue;
}
- if (strcmp(conf.proc_name, "xtra-daemon") == 0 && !isXtraDaemonEnabled()) {
- LOC_LOGE("%s:%d]: Process xtra-daemon is disabled via property",
- __func__, __LINE__);
- child_proc[j].proc_status = DISABLED_FROM_CONF;
+ if (!isVendorEnhanced() && (conf.vendor_enhanced_process != 0)) {
+ LOC_LOGD("%s:%d]: Process %s is disabled via vendor enhanced process check",
+ __func__, __LINE__, conf.proc_name);
+ child_proc[j].proc_status = DISABLED_VIA_VENDOR_ENHANCED_CHECK;
continue;
}
@@ -844,18 +818,15 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
child_proc[j].num_groups = 0;
ngroups = loc_util_split_string(conf.group_list, split_strings, MAX_NUM_STRINGS, ' ');
-#ifdef __ANDROID__
for(i=0; i<ngroups; i++) {
- struct passwd* pwd = getpwnam(split_strings[i]);
- if (pwd) {
- child_proc[j].group_list[i] = pwd->pw_gid;
+ struct group* grp = getgrnam(split_strings[i]);
+ if (grp) {
+ child_proc[j].group_list[child_proc[j].num_groups] = grp->gr_gid;
child_proc[j].num_groups++;
- LOC_LOGD("%s:%d]:Group %s = %d matches child_group: %d\n",
- __func__, __LINE__, split_strings[i],
- pwd->pw_gid,child_proc[j].group_list[i]);
+ LOC_LOGd("Group %s = %d", split_strings[i], grp->gr_gid);
}
}
-#endif
+
nstrings = loc_util_split_string(conf.platform_list, split_strings, MAX_NUM_STRINGS, ' ');
if(strcmp("all", split_strings[0]) == 0) {
if (nstrings == 1 || (nstrings == 2 && (strcmp("exclude", split_strings[1]) == 0))) {
@@ -884,6 +855,34 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
}
}
+ // SOC Id's check
+ nstrings = loc_util_split_string(conf.soc_id_list, split_strings, MAX_NUM_STRINGS, ' ');
+ if (strcmp("all", split_strings[0]) == 0) {
+ if (nstrings == 1 || (nstrings == 2 && (strcmp("exclude", split_strings[1]) == 0))) {
+ LOC_LOGd("Enabled for all SOC ids\n");
+ config_mask |= CONFIG_MASK_SOCID_ALL;
+ }
+ else if (nstrings > 2 && (strcmp("exclude", split_strings[1]) == 0)) {
+ config_mask |= CONFIG_MASK_SOCID_FOUND;
+ for (i = 2; i < nstrings; i++) {
+ if (strcmp(socid_value, split_strings[i]) == 0) {
+ LOC_LOGd("Disabled for SOC id %s\n", socid_value);
+ config_mask &= ~CONFIG_MASK_SOCID_FOUND;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ for (i = 0; i < nstrings; i++) {
+ if (strcmp(socid_value, split_strings[i]) == 0) {
+ LOC_LOGd("Matched SOC id : %s\n", split_strings[i]);
+ config_mask |= CONFIG_MASK_SOCID_FOUND;
+ break;
+ }
+ }
+ }
+
nstrings = loc_util_split_string(conf.baseband, split_strings, MAX_NUM_STRINGS, ' ');
if(strcmp("all", split_strings[0]) == 0) {
if (nstrings == 1 || (nstrings == 2 && (strcmp("exclude", split_strings[1]) == 0))) {
@@ -936,10 +935,19 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
}
}
+ nstrings = loc_util_split_string(conf.low_ram_targets, split_strings, MAX_NUM_STRINGS, ' ');
+ if (!strcmp("DISABLED", split_strings[0]) && low_ram_target) {
+ LOC_LOGd("Disabled for low ram targets\n");
+ child_proc[j].proc_status = DISABLED;
+ continue;
+ }
+
if((config_mask & CONFIG_MASK_TARGET_CHECK) &&
(config_mask & CONFIG_MASK_BASEBAND_CHECK) &&
(config_mask & CONFIG_MASK_AUTOPLATFORM_CHECK) &&
- (child_proc[j].proc_status != DISABLED_FROM_CONF)) {
+ (config_mask & CONFIG_MASK_SOCID_CHECK) &&
+ (child_proc[j].proc_status != DISABLED_FROM_CONF) &&
+ (child_proc[j].proc_status != DISABLED_VIA_VENDOR_ENHANCED_CHECK)) {
//Set args
//The first argument passed through argv is usually the name of the
@@ -949,8 +957,7 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
i = 0;
char* temp_arg = ('/' == child_proc[j].name[0][0]) ?
(strrchr(child_proc[j].name[0], '/') + 1) : child_proc[j].name[0];
- i++;
- strlcpy (child_proc[j].args[i], temp_arg, sizeof (child_proc[j].args[i]));
+ strlcpy (child_proc[j].args[i++], temp_arg, sizeof (child_proc[j].args[i++]));
if(conf.premium_feature) {
if(conf.loc_feature_mask & loc_service_mask) {
@@ -982,51 +989,13 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
}
if(conf.loc_feature_mask &
(LOC_FEATURE_MASK_GTP_CELL_BASIC | LOC_FEATURE_MASK_GTP_CELL_PREMIUM )) {
- if(loc_service_mask & LOC_FEATURE_MASK_GTP_AP_CELL_BASIC){
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_basic,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else if(loc_service_mask & LOC_FEATURE_MASK_GTP_AP_CELL_PREMIUM){
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_premium,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else if(loc_service_mask & LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC) {
+ if(loc_service_mask & LOC_FEATURE_MASK_GTP_MODEM_CELL_BASIC) {
strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
LOC_PROCESS_MAX_ARG_STR_LENGTH);
strlcpy(child_proc[j].args[i++], arg_basic,
LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else if(loc_service_mask & LOC_FEATURE_MASK_GTP_MODEM_CELL_PREMIUM) {
- strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_premium,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
}
else {
- strlcpy(child_proc[j].args[i++], arg_gtp_ap_cell,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
strlcpy(child_proc[j].args[i++], arg_gtp_modem_cell,
LOC_PROCESS_MAX_ARG_STR_LENGTH);
strlcpy(child_proc[j].args[i++], arg_disabled,
@@ -1034,28 +1003,6 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
}
}
if(conf.loc_feature_mask &
- (LOC_FEATURE_MASK_GTP_WAA_BASIC | LOC_FEATURE_MASK_GTP_WAA_PREMIUM)) {
- if(loc_service_mask & LOC_FEATURE_MASK_GTP_WAA_BASIC) {
- strlcpy(child_proc[j].args[i++], arg_gtp_waa,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_basic,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else if(loc_service_mask & LOC_FEATURE_MASK_GTP_WAA_PREMIUM) {
- strlcpy(child_proc[j].args[i++], arg_gtp_waa,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_premium,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- else
- {
- strlcpy(child_proc[j].args[i++], arg_gtp_waa,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- strlcpy(child_proc[j].args[i++], arg_disabled,
- LOC_PROCESS_MAX_ARG_STR_LENGTH);
- }
- }
- if(conf.loc_feature_mask &
(LOC_FEATURE_MASK_SAP_BASIC | LOC_FEATURE_MASK_SAP_PREMIUM)) {
if(loc_service_mask & LOC_FEATURE_MASK_SAP_BASIC) {
strlcpy(child_proc[j].args[i++], arg_sap,
@@ -1077,6 +1024,22 @@ int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_p
LOC_PROCESS_MAX_ARG_STR_LENGTH);
}
}
+
+ if(conf.loc_feature_mask & LOC_FEATURE_MASK_GTP_WAA_BASIC) {
+ if(loc_service_mask & LOC_FEATURE_MASK_GTP_WAA_BASIC) {
+ strlcpy(child_proc[j].args[i++], arg_gtp_waa,
+ LOC_PROCESS_MAX_ARG_STR_LENGTH);
+ strlcpy(child_proc[j].args[i++], arg_basic,
+ LOC_PROCESS_MAX_ARG_STR_LENGTH);
+ }
+ else
+ {
+ strlcpy(child_proc[j].args[i++], arg_gtp_waa,
+ LOC_PROCESS_MAX_ARG_STR_LENGTH);
+ strlcpy(child_proc[j].args[i++], arg_disabled,
+ LOC_PROCESS_MAX_ARG_STR_LENGTH);
+ }
+ }
IF_LOC_LOGD {
LOC_LOGD("%s:%d]: %s args\n", __func__, __LINE__, child_proc[j].name[0]);
for(unsigned int k=0; k<LOC_PROCESS_MAX_NUM_ARGS; k++) {
diff --git a/gps/utils/loc_cfg.h b/gps/utils/loc_cfg.h
index 652d86e..5c77dc6 100644
--- a/gps/utils/loc_cfg.h
+++ b/gps/utils/loc_cfg.h
@@ -37,7 +37,7 @@
#include <grp.h>
#define LOC_MAX_PARAM_NAME 80
-#define LOC_MAX_PARAM_STRING 80
+#define LOC_MAX_PARAM_STRING 172
#define LOC_MAX_PARAM_LINE (LOC_MAX_PARAM_NAME + LOC_MAX_PARAM_STRING)
#define LOC_FEATURE_MODE_DISABLED "DISABLED"
@@ -72,19 +72,20 @@
*============================================================================*/
typedef struct
{
- const char *param_name;
- void *param_ptr;
- uint8_t *param_set; /* indicate value set by config file */
- char param_type; /* 'n' for number,
- 's' for string,
- 'f' for double */
+ const char *param_name;
+ void *param_ptr; /* for string type, buf size need to be LOC_MAX_PARAM_STRING */
+ uint8_t *param_set; /* indicate value set by config file */
+ char param_type; /* 'n' for number,
+ 's' for string, NOTE: buf size need to be LOC_MAX_PARAM_STRING
+ 'f' for double */
} loc_param_s_type;
typedef enum {
ENABLED,
RUNNING,
DISABLED,
- DISABLED_FROM_CONF
+ DISABLED_FROM_CONF,
+ DISABLED_VIA_VENDOR_ENHANCED_CHECK
} loc_process_e_status;
typedef struct {
@@ -112,6 +113,8 @@ extern "C" {
* MODULE EXPORTED FUNCTIONS
*
*============================================================================*/
+bool isVendorEnhanced();
+void setVendorEnhanced(bool vendorEnhanced);
void loc_read_conf(const char* conf_file_name,
const loc_param_s_type* config_table,
uint32_t table_length);
@@ -132,9 +135,7 @@ extern const char LOC_PATH_QUIPC_CONF[];
int loc_read_process_conf(const char* conf_file_name, uint32_t * process_count_ptr,
loc_process_info_s_type** process_info_table_ptr);
-
-uint32_t loc_modem_emulator_enabled();
-
+int loc_get_datum_type();
#ifdef __cplusplus
}
#endif
diff --git a/gps/utils/loc_gps.h b/gps/utils/loc_gps.h
index 5e915a3..eae7383 100644
--- a/gps/utils/loc_gps.h
+++ b/gps/utils/loc_gps.h
@@ -100,6 +100,19 @@ typedef uint16_t LocGpsLocationFlags;
#define LOC_GPS_LOCATION_HAS_ACCURACY 0x0010
/** LocGpsLocation has valid vertical uncertainity */
#define LOC_GPS_LOCATION_HAS_VERT_UNCERTAINITY 0x0040
+/** LocGpsLocation has valid spoof mask */
+#define LOC_GPS_LOCATION_HAS_SPOOF_MASK 0x0080
+/** LocGpsLocation has valid speed accuracy */
+#define LOC_GPS_LOCATION_HAS_SPEED_ACCURACY 0x0100
+/** LocGpsLocation has valid bearing accuracy */
+#define LOC_GPS_LOCATION_HAS_BEARING_ACCURACY 0x0200
+
+/** Spoof mask in LocGpsLocation */
+typedef uint32_t LocGpsSpoofMask;
+#define LOC_GPS_LOCATION_NONE_SPOOFED 0x0000
+#define LOC_GPS_LOCATION_POSITION_SPOOFED 0x0001
+#define LOC_GPS_LOCATION_TIME_SPOOFED 0x0002
+#define LOC_GPS_LOCATION_NAVIGATION_DATA_SPOOFED 0x0004
/** Flags for the loc_gps_set_capabilities callback. */
@@ -142,13 +155,18 @@ typedef uint16_t LocGpsAidingData;
#define LOC_GPS_DELETE_SVSTEER 0x0100
#define LOC_GPS_DELETE_SADATA 0x0200
#define LOC_GPS_DELETE_RTI 0x0400
+#define LOC_GPS_DELETE_MB_DATA 0x0800
#define LOC_GPS_DELETE_CELLDB_INFO 0x8000
#define LOC_GPS_DELETE_ALL 0xFFFF
/** AGPS type */
typedef uint16_t LocAGpsType;
+#define LOC_AGPS_TYPE_ANY 0
#define LOC_AGPS_TYPE_SUPL 1
#define LOC_AGPS_TYPE_C2K 2
+#define LOC_AGPS_TYPE_WWAN_ANY 3
+#define LOC_AGPS_TYPE_WIFI 4
+#define LOC_AGPS_TYPE_SUPL_ES 5
typedef uint16_t LocAGpsSetIDType;
#define LOC_AGPS_SETID_TYPE_NONE 0
@@ -530,9 +548,11 @@ typedef uint8_t LocGnssConstellationType;
/** Represents a location. */
typedef struct {
/** set to sizeof(LocGpsLocation) */
- size_t size;
+ uint32_t size;
/** Contains LocGpsLocationFlags bits. */
uint16_t flags;
+ /** The spoof mask */
+ LocGpsSpoofMask spoof_mask;
/** Represents latitude in degrees. */
double latitude;
/** Represents longitude in degrees. */
diff --git a/gps/utils/loc_misc_utils.cpp b/gps/utils/loc_misc_utils.cpp
index b7c8406..70fdbc3 100644
--- a/gps/utils/loc_misc_utils.cpp
+++ b/gps/utils/loc_misc_utils.cpp
@@ -30,6 +30,7 @@
#define LOG_TAG "LocSvc_misc_utils"
#include <stdio.h>
#include <string.h>
+#include <dlfcn.h>
#include <log_util.h>
#include <loc_misc_utils.h>
#include <ctype.h>
@@ -112,3 +113,33 @@ void loc_util_trim_space(char *org_string)
err:
return;
}
+
+inline void logDlError(const char* failedCall) {
+ const char * err = dlerror();
+ LOC_LOGe("%s error: %s", failedCall, (nullptr == err) ? "unknown" : err);
+}
+
+void* dlGetSymFromLib(void*& libHandle, const char* libName, const char* symName)
+{
+ void* sym = nullptr;
+ if ((nullptr != libHandle || nullptr != libName) && nullptr != symName) {
+ if (nullptr == libHandle) {
+ libHandle = dlopen(libName, RTLD_NOW);
+ if (nullptr == libHandle) {
+ logDlError("dlopen");
+ }
+ }
+ // NOT else, as libHandle gets assigned 5 line above
+ if (nullptr != libHandle) {
+ sym = dlsym(libHandle, symName);
+ if (nullptr == sym) {
+ logDlError("dlsym");
+ }
+ }
+ } else {
+ LOC_LOGe("Either libHandle (%p) or libName (%p) must not be null; "
+ "symName (%p) can not be null.", libHandle, libName, symName);
+ }
+
+ return sym;
+}
diff --git a/gps/utils/loc_misc_utils.h b/gps/utils/loc_misc_utils.h
index 7d66d84..fad1b6d 100644
--- a/gps/utils/loc_misc_utils.h
+++ b/gps/utils/loc_misc_utils.h
@@ -92,6 +92,34 @@ SIDE EFFECTS
N/A
===========================================================================*/
void loc_util_trim_space(char *org_string);
+
+/*===========================================================================
+FUNCTION dlGetSymFromLib
+
+DESCRIPTION
+ Handy function to get a pointer to a symbol from a library.
+
+ If libHandle is not null, it will be used as the handle to the library. In
+ that case libName wll not be used;
+ libHandle is an in / out parameter.
+ If libHandle is null, libName will be used to dlopen.
+ Either libHandle or libName must not be nullptr.
+ symName must not be null.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ pointer to symName. Could be nullptr if
+ Parameters are incorrect; or
+ libName can not be opened; or
+ symName can not be found.
+
+SIDE EFFECTS
+ N/A
+===========================================================================*/
+void* dlGetSymFromLib(void*& libHandle, const char* libName, const char* symName);
+
#ifdef __cplusplus
}
#endif
diff --git a/gps/utils/loc_nmea.cpp b/gps/utils/loc_nmea.cpp
index 558dc65..24197ff 100644
--- a/gps/utils/loc_nmea.cpp
+++ b/gps/utils/loc_nmea.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 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
@@ -33,24 +33,87 @@
#include <math.h>
#include <log_util.h>
#include <loc_pla.h>
+#include <loc_cfg.h>
#define GLONASS_SV_ID_OFFSET 64
+#define QZSS_SV_ID_OFFSET (-192)
+#define MAX_SV_COUNT_SUPPORTED_IN_ONE_CONSTELLATION 64
#define MAX_SATELLITES_IN_USE 12
+#define MSEC_IN_ONE_WEEK 604800000ULL
+#define UTC_GPS_OFFSET_MSECS 315964800000ULL
// GNSS system id according to NMEA spec
#define SYSTEM_ID_GPS 1
#define SYSTEM_ID_GLONASS 2
#define SYSTEM_ID_GALILEO 3
-// Extended systems
-#define SYSTEM_ID_BEIDOU 4
+#define SYSTEM_ID_BDS 4
#define SYSTEM_ID_QZSS 5
+#define SYSTEM_ID_NAVIC 6
+
+//GNSS signal id according to NMEA spec
+#define SIGNAL_ID_ALL_SIGNALS 0
+#define SIGNAL_ID_GPS_L1CA 1
+#define SIGNAL_ID_GPS_L1P 2
+#define SIGNAL_ID_GPS_L1M 3
+#define SIGNAL_ID_GPS_L2P 4
+#define SIGNAL_ID_GPS_L2CM 5
+#define SIGNAL_ID_GPS_L2CL 6
+#define SIGNAL_ID_GPS_L5I 7
+#define SIGNAL_ID_GPS_L5Q 8
+
+
+#define SIGNAL_ID_GLO_G1CA 1
+#define SIGNAL_ID_GLO_G1P 2
+#define SIGNAL_ID_GLO_G2CA 3
+#define SIGNAL_ID_GLO_G2P 4
+
+
+#define SIGNAL_ID_GAL_E5A 1
+#define SIGNAL_ID_GAL_E5B 2
+#define SIGNAL_ID_GAL_E5AB 3
+#define SIGNAL_ID_GAL_E6A 4
+#define SIGNAL_ID_GAL_E6BC 5
+#define SIGNAL_ID_GAL_L1A 6
+#define SIGNAL_ID_GAL_L1BC 7
+
+#define SIGNAL_ID_BDS_B1I 1
+#define SIGNAL_ID_BDS_B1Q 2
+#define SIGNAL_ID_BDS_B1C 3
+#define SIGNAL_ID_BDS_B1A 4
+#define SIGNAL_ID_BDS_B2A 5
+#define SIGNAL_ID_BDS_B2B 6
+#define SIGNAL_ID_BDS_B2AB 7
+#define SIGNAL_ID_BDS_B3I 8
+#define SIGNAL_ID_BDS_B3Q 9
+#define SIGNAL_ID_BDS_B3A 0xA
+#define SIGNAL_ID_BDS_B2I 0xB
+#define SIGNAL_ID_BDS_B2Q 0xC
+
+#define SIGNAL_ID_QZSS_L1CA 1
+#define SIGNAL_ID_QZSS_L1CD 2
+#define SIGNAL_ID_QZSS_L1CP 3
+#define SIGNAL_ID_QZSS_LIS 4
+#define SIGNAL_ID_QZSS_L2CM 5
+#define SIGNAL_ID_QZSS_L2CL 6
+#define SIGNAL_ID_QZSS_L5I 7
+#define SIGNAL_ID_QZSS_L5Q 8
+#define SIGNAL_ID_QZSS_L6D 9
+#define SIGNAL_ID_QZSS_L6E 0xA
+
+#define SIGNAL_ID_NAVIC_L5SPS 1
+#define SIGNAL_ID_NAVIC_SSPS 2
+#define SIGNAL_ID_NAVIC_L5RS 3
+#define SIGNAL_ID_NAVIC_SRS 4
+#define SIGNAL_ID_NAVIC_L1SPS 5
+
typedef struct loc_nmea_sv_meta_s
{
char talker[3];
LocGnssConstellationType svType;
- uint32_t mask;
+ uint64_t mask;
uint32_t svCount;
+ uint32_t totalSvUsedCount;
uint32_t svIdOffset;
uint32_t signalId;
uint32_t systemId;
@@ -58,22 +121,260 @@ typedef struct loc_nmea_sv_meta_s
typedef struct loc_sv_cache_info_s
{
- uint32_t gps_used_mask;
- uint32_t glo_used_mask;
- uint32_t gal_used_mask;
- uint32_t qzss_used_mask;
- uint32_t bds_used_mask;
- uint32_t gps_count;
- uint32_t glo_count;
- uint32_t gal_count;
- uint32_t qzss_count;
- uint32_t bds_count;
+ uint64_t gps_used_mask;
+ uint64_t glo_used_mask;
+ uint64_t gal_used_mask;
+ uint64_t qzss_used_mask;
+ uint64_t bds_used_mask;
+ uint64_t navic_used_mask;
+ uint32_t gps_l1_count;
+ uint32_t gps_l5_count;
+ uint32_t glo_g1_count;
+ uint32_t glo_g2_count;
+ uint32_t gal_e1_count;
+ uint32_t gal_e5_count;
+ uint32_t qzss_l1_count;
+ uint32_t qzss_l5_count;
+ uint32_t bds_b1_count;
+ uint32_t bds_b2_count;
+ uint32_t navic_l5_count;
float hdop;
float pdop;
float vdop;
} loc_sv_cache_info;
/*===========================================================================
+FUNCTION convert_Lla_to_Ecef
+
+DESCRIPTION
+ Convert LLA to ECEF
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ NONE
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void convert_Lla_to_Ecef(const LocLla& plla, LocEcef& pecef)
+{
+ double r;
+
+ r = MAJA / sqrt(1.0 - ESQR * sin(plla.lat) * sin(plla.lat));
+ pecef.X = (r + plla.alt) * cos(plla.lat) * cos(plla.lon);
+ pecef.Y = (r + plla.alt) * cos(plla.lat) * sin(plla.lon);
+ pecef.Z = (r * OMES + plla.alt) * sin(plla.lat);
+}
+
+/*===========================================================================
+FUNCTION convert_WGS84_to_PZ90
+
+DESCRIPTION
+ Convert datum from WGS84 to PZ90
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ NONE
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void convert_WGS84_to_PZ90(const LocEcef& pWGS84, LocEcef& pPZ90)
+{
+ double deltaX = DatumConstFromWGS84[0];
+ double deltaY = DatumConstFromWGS84[1];
+ double deltaZ = DatumConstFromWGS84[2];
+ double deltaScale = DatumConstFromWGS84[3];
+ double rotX = DatumConstFromWGS84[4];
+ double rotY = DatumConstFromWGS84[5];
+ double rotZ = DatumConstFromWGS84[6];
+
+ pPZ90.X = deltaX + deltaScale * (pWGS84.X + rotZ * pWGS84.Y - rotY * pWGS84.Z);
+ pPZ90.Y = deltaY + deltaScale * (pWGS84.Y - rotZ * pWGS84.X + rotX * pWGS84.Z);
+ pPZ90.Z = deltaZ + deltaScale * (pWGS84.Z + rotY * pWGS84.X - rotX * pWGS84.Y);
+}
+
+/*===========================================================================
+FUNCTION convert_Ecef_to_Lla
+
+DESCRIPTION
+ Convert ECEF to LLA
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ NONE
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void convert_Ecef_to_Lla(const LocEcef& pecef, LocLla& plla)
+{
+ double p, r;
+ double EcefA = C_PZ90A;
+ double EcefB = C_PZ90B;
+ double Ecef1Mf;
+ double EcefE2;
+ double Mu;
+ double Smu;
+ double Cmu;
+ double Phi;
+ double Sphi;
+ double N;
+
+ p = sqrt(pecef.X * pecef.X + pecef.Y * pecef.Y);
+ r = sqrt(p * p + pecef.Z * pecef.Z);
+ if (r < 1.0) {
+ plla.lat = 1.0;
+ plla.lon = 1.0;
+ plla.alt = 1.0;
+ }
+ Ecef1Mf = 1.0 - (EcefA - EcefB) / EcefA;
+ EcefE2 = 1.0 - (EcefB * EcefB) / (EcefA * EcefA);
+ if (p > 1.0) {
+ Mu = atan2(pecef.Z * (Ecef1Mf + EcefE2 * EcefA / r), p);
+ } else {
+ if (pecef.Z > 0.0) {
+ Mu = M_PI / 2.0;
+ } else {
+ Mu = -M_PI / 2.0;
+ }
+ }
+ Smu = sin(Mu);
+ Cmu = cos(Mu);
+ Phi = atan2(pecef.Z * Ecef1Mf + EcefE2 * EcefA * Smu * Smu * Smu,
+ Ecef1Mf * (p - EcefE2 * EcefA * Cmu * Cmu * Cmu));
+ Sphi = sin(Phi);
+ N = EcefA / sqrt(1.0 - EcefE2 * Sphi * Sphi);
+ plla.alt = p * cos(Phi) + pecef.Z * Sphi - EcefA * EcefA/N;
+ plla.lat = Phi;
+ if ( p > 1.0) {
+ plla.lon = atan2(pecef.Y, pecef.X);
+ } else {
+ plla.lon = 0.0;
+ }
+}
+
+/*===========================================================================
+FUNCTION convert_signalType_to_signalId
+
+DESCRIPTION
+ convert signalType to signal ID
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ value of signal ID
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static uint32_t convert_signalType_to_signalId(GnssSignalTypeMask signalType)
+{
+ uint32_t signalId = SIGNAL_ID_ALL_SIGNALS;
+
+ switch (signalType) {
+ case GNSS_SIGNAL_GPS_L1CA:
+ signalId = SIGNAL_ID_GPS_L1CA;
+ break;
+ case GNSS_SIGNAL_GPS_L2:
+ signalId = SIGNAL_ID_GPS_L2CL;
+ break;
+ case GNSS_SIGNAL_GPS_L5:
+ signalId = SIGNAL_ID_GPS_L5Q;
+ break;
+ case GNSS_SIGNAL_GLONASS_G1:
+ signalId = SIGNAL_ID_GLO_G1CA;
+ break;
+ case GNSS_SIGNAL_GLONASS_G2:
+ signalId = SIGNAL_ID_GLO_G2CA;
+ break;
+ case GNSS_SIGNAL_GALILEO_E1:
+ signalId = SIGNAL_ID_GAL_L1BC;
+ break;
+ case GNSS_SIGNAL_GALILEO_E5A:
+ signalId = SIGNAL_ID_GAL_E5A;
+ break;
+ case GNSS_SIGNAL_GALILEO_E5B:
+ signalId = SIGNAL_ID_GAL_E5B;
+ break;
+ case GNSS_SIGNAL_QZSS_L1CA:
+ signalId = SIGNAL_ID_QZSS_L1CA;
+ break;
+ case GNSS_SIGNAL_QZSS_L2:
+ signalId = SIGNAL_ID_QZSS_L2CL;
+ break;
+ case GNSS_SIGNAL_QZSS_L5:
+ signalId = SIGNAL_ID_QZSS_L5Q;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B1I:
+ signalId = SIGNAL_ID_BDS_B1I;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B1C:
+ signalId = SIGNAL_ID_BDS_B1C;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B2I:
+ signalId = SIGNAL_ID_BDS_B2I;
+ break;
+ case GNSS_SIGNAL_BEIDOU_B2AI:
+ case GNSS_SIGNAL_BEIDOU_B2AQ:
+ signalId = SIGNAL_ID_BDS_B2A;
+ break;
+ case GNSS_SIGNAL_NAVIC_L5:
+ signalId = SIGNAL_ID_NAVIC_L5SPS;
+ break;
+ default:
+ signalId = SIGNAL_ID_ALL_SIGNALS;
+ }
+
+ return signalId;
+
+}
+
+/*===========================================================================
+FUNCTION get_sv_count_from_mask
+
+DESCRIPTION
+ get the sv count from bit mask
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ value of sv count
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static uint32_t get_sv_count_from_mask(uint64_t svMask, int totalSvCount)
+{
+ int index = 0;
+ uint32_t svCount = 0;
+
+ if(totalSvCount > MAX_SV_COUNT_SUPPORTED_IN_ONE_CONSTELLATION) {
+ LOC_LOGE("total SV count in this constellation %d exceeded limit %d",
+ totalSvCount, MAX_SV_COUNT_SUPPORTED_IN_ONE_CONSTELLATION);
+ }
+ for(index = 0; index < totalSvCount; index++) {
+ if(svMask & 0x1)
+ svCount += 1;
+ svMask >>= 1;
+ }
+ return svCount;
+}
+
+/*===========================================================================
FUNCTION loc_nmea_sv_meta_init
DESCRIPTION
@@ -92,6 +393,7 @@ SIDE EFFECTS
static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
loc_sv_cache_info& sv_cache_info,
GnssSvType svType,
+ GnssSignalTypeMask signalType,
bool needCombine)
{
memset(&sv_meta, 0, sizeof(sv_meta));
@@ -103,56 +405,97 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta,
sv_meta.talker[0] = 'G';
sv_meta.talker[1] = 'P';
sv_meta.mask = sv_cache_info.gps_used_mask;
- sv_meta.svCount = sv_cache_info.gps_count;
- sv_meta.signalId = 1;
sv_meta.systemId = SYSTEM_ID_GPS;
+ if (GNSS_SIGNAL_GPS_L1CA == signalType) {
+ sv_meta.svCount = sv_cache_info.gps_l1_count;
+ } else if (GNSS_SIGNAL_GPS_L5 == signalType) {
+ sv_meta.svCount = sv_cache_info.gps_l5_count;
+ }
break;
case GNSS_SV_TYPE_GLONASS:
sv_meta.talker[0] = 'G';
sv_meta.talker[1] = 'L';
sv_meta.mask = sv_cache_info.glo_used_mask;
- sv_meta.svCount = sv_cache_info.glo_count;
// GLONASS SV ids are from 65-96
sv_meta.svIdOffset = GLONASS_SV_ID_OFFSET;
- sv_meta.signalId = 1;
sv_meta.systemId = SYSTEM_ID_GLONASS;
+ if (GNSS_SIGNAL_GLONASS_G1 == signalType) {
+ sv_meta.svCount = sv_cache_info.glo_g1_count;
+ } else if (GNSS_SIGNAL_GLONASS_G2 == signalType) {
+ sv_meta.svCount = sv_cache_info.glo_g2_count;
+ }
break;
case GNSS_SV_TYPE_GALILEO:
sv_meta.talker[0] = 'G';
sv_meta.talker[1] = 'A';
sv_meta.mask = sv_cache_info.gal_used_mask;
- sv_meta.svCount = sv_cache_info.gal_count;
- sv_meta.signalId = 7;
sv_meta.systemId = SYSTEM_ID_GALILEO;
+ if (GNSS_SIGNAL_GALILEO_E1 == signalType) {
+ sv_meta.svCount = sv_cache_info.gal_e1_count;
+ } else if (GNSS_SIGNAL_GALILEO_E5A == signalType) {
+ sv_meta.svCount = sv_cache_info.gal_e5_count;
+ }
break;
case GNSS_SV_TYPE_QZSS:
- sv_meta.talker[0] = 'P';
+ sv_meta.talker[0] = 'G';
sv_meta.talker[1] = 'Q';
sv_meta.mask = sv_cache_info.qzss_used_mask;
- sv_meta.svCount = sv_cache_info.qzss_count;
- // QZSS SV ids are from 193-197. So keep svIdOffset 0
- sv_meta.signalId = 0;
+ // QZSS SV ids are from 193-199. So keep svIdOffset -192
+ sv_meta.svIdOffset = QZSS_SV_ID_OFFSET;
sv_meta.systemId = SYSTEM_ID_QZSS;
+ if (GNSS_SIGNAL_QZSS_L1CA == signalType) {
+ sv_meta.svCount = sv_cache_info.qzss_l1_count;
+ } else if (GNSS_SIGNAL_QZSS_L5 == signalType) {
+ sv_meta.svCount = sv_cache_info.qzss_l5_count;
+ }
break;
case GNSS_SV_TYPE_BEIDOU:
- sv_meta.talker[0] = 'P';
- sv_meta.talker[1] = 'Q';
+ sv_meta.talker[0] = 'G';
+ sv_meta.talker[1] = 'B';
sv_meta.mask = sv_cache_info.bds_used_mask;
- sv_meta.svCount = sv_cache_info.bds_count;
// BDS SV ids are from 201-235. So keep svIdOffset 0
- sv_meta.signalId = 0;
- sv_meta.systemId = SYSTEM_ID_BEIDOU;
+ sv_meta.systemId = SYSTEM_ID_BDS;
+ if (GNSS_SIGNAL_BEIDOU_B1I == signalType) {
+ sv_meta.svCount = sv_cache_info.bds_b1_count;
+ } else if (GNSS_SIGNAL_BEIDOU_B2AI == signalType) {
+ sv_meta.svCount = sv_cache_info.bds_b2_count;
+ }
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ sv_meta.talker[0] = 'G';
+ sv_meta.talker[1] = 'I';
+ sv_meta.mask = sv_cache_info.navic_used_mask;
+ // NAVIC SV ids are from 401-414. So keep svIdOffset 0
+ sv_meta.systemId = SYSTEM_ID_NAVIC;
+ if (GNSS_SIGNAL_NAVIC_L5 == signalType) {
+ sv_meta.svCount = sv_cache_info.navic_l5_count;
+ }
break;
default:
LOC_LOGE("NMEA Error unknow constellation type: %d", svType);
return NULL;
}
+ sv_meta.signalId = convert_signalType_to_signalId(signalType);
+ sv_meta.totalSvUsedCount =
+ get_sv_count_from_mask(sv_cache_info.gps_used_mask,
+ GPS_SV_PRN_MAX - GPS_SV_PRN_MIN + 1) +
+ get_sv_count_from_mask(sv_cache_info.glo_used_mask,
+ GLO_SV_PRN_MAX - GLO_SV_PRN_MIN + 1) +
+ get_sv_count_from_mask(sv_cache_info.gal_used_mask,
+ GAL_SV_PRN_MAX - GAL_SV_PRN_MIN + 1) +
+ get_sv_count_from_mask(sv_cache_info.qzss_used_mask,
+ QZSS_SV_PRN_MAX - QZSS_SV_PRN_MIN + 1) +
+ get_sv_count_from_mask(sv_cache_info.bds_used_mask,
+ BDS_SV_PRN_MAX - BDS_SV_PRN_MIN + 1) +
+ get_sv_count_from_mask(sv_cache_info.navic_used_mask,
+ NAVIC_SV_PRN_MAX - NAVIC_SV_PRN_MIN + 1);
if (needCombine &&
(sv_cache_info.gps_used_mask ? 1 : 0) +
(sv_cache_info.glo_used_mask ? 1 : 0) +
(sv_cache_info.gal_used_mask ? 1 : 0) +
(sv_cache_info.qzss_used_mask ? 1 : 0) +
- (sv_cache_info.bds_used_mask ? 1 : 0) > 1)
+ (sv_cache_info.bds_used_mask ? 1 : 0) +
+ (sv_cache_info.navic_used_mask ? 1 : 0) > 1)
{
// If GPS, GLONASS, Galileo, QZSS, BDS etc. are combined
// to obtain the reported position solution,
@@ -240,27 +583,31 @@ static uint32_t loc_nmea_generate_GSA(const GpsLocationExtended &locationExtende
int length = 0;
uint32_t svUsedCount = 0;
- uint32_t svUsedList[32] = {0};
+ uint32_t svUsedList[64] = {0};
char fixType = '\0';
const char* talker = sv_meta_p->talker;
uint32_t svIdOffset = sv_meta_p->svIdOffset;
- uint32_t mask = sv_meta_p->mask;
+ uint64_t mask = sv_meta_p->mask;
+
+ if(sv_meta_p->svType != GNSS_SV_TYPE_GLONASS) {
+ svIdOffset = 0;
+ }
- for (uint8_t i = 1; mask > 0 && svUsedCount < 32; i++)
+ for (uint8_t i = 1; mask > 0 && svUsedCount < 64; i++)
{
if (mask & 1)
svUsedList[svUsedCount++] = i + svIdOffset;
mask = mask >> 1;
}
- if (svUsedCount == 0 && GNSS_SV_TYPE_GPS != sv_meta_p->svType)
+ if (svUsedCount == 0)
return 0;
- if (svUsedCount == 0)
+ if (sv_meta_p->totalSvUsedCount == 0)
fixType = '1'; // no fix
- else if (svUsedCount <= 3)
+ else if (sv_meta_p->totalSvUsedCount <= 3)
fixType = '2'; // 2D fix
else
fixType = '3'; // 3D fix
@@ -371,13 +718,9 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
const char* talker = sv_meta_p->talker;
uint32_t svIdOffset = sv_meta_p->svIdOffset;
int svCount = sv_meta_p->svCount;
-
if (svCount <= 0)
{
- // no svs in view, so just send a blank $--GSV sentence
- snprintf(sentence, lengthRemaining, "$%sGSV,1,1,0,%d", talker, sv_meta_p->signalId);
- length = loc_nmea_put_checksum(sentence, bufSize);
- nmeaArraystr.push_back(sentence);
+ LOC_LOGV("No SV in view for talker ID:%s, signal ID:%X", talker, sv_meta_p->signalId);
return;
}
@@ -403,10 +746,49 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
for (int i=0; (svNumber <= svNotify.count) && (i < 4); svNumber++)
{
- if (sv_meta_p->svType == svNotify.gnssSvs[svNumber - 1].type)
+ GnssSignalTypeMask signalType = svNotify.gnssSvs[svNumber-1].gnssSignalTypeMask;
+ if (0 == signalType) {
+ // If no signal type in report, it means default L1,G1,E1,B1I
+ switch (svNotify.gnssSvs[svNumber - 1].type)
+ {
+ case GNSS_SV_TYPE_GPS:
+ signalType = GNSS_SIGNAL_GPS_L1CA;
+ break;
+ case GNSS_SV_TYPE_GLONASS:
+ signalType = GNSS_SIGNAL_GLONASS_G1;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ signalType = GNSS_SIGNAL_GALILEO_E1;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ signalType = GNSS_SIGNAL_QZSS_L1CA;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ signalType = GNSS_SIGNAL_BEIDOU_B1I;
+ break;
+ case GNSS_SV_TYPE_SBAS:
+ signalType = GNSS_SIGNAL_SBAS_L1;
+ break;
+ case GNSS_SV_TYPE_NAVIC:
+ signalType = GNSS_SIGNAL_NAVIC_L5;
+ break;
+ default:
+ LOC_LOGE("NMEA Error unknow constellation type: %d",
+ svNotify.gnssSvs[svNumber - 1].type);
+ continue;
+ }
+ }
+
+ if (sv_meta_p->svType == svNotify.gnssSvs[svNumber - 1].type &&
+ sv_meta_p->signalId == convert_signalType_to_signalId(signalType))
{
+ uint16_t svId = svNotify.gnssSvs[svNumber - 1].svId;
+ // For QZSS we adjusted SV id's in GnssAdapter, we need to re-adjust here
+ if (GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[svNumber - 1].type) {
+ svId = svId - (QZSS_SV_PRN_MIN - 1);
+ }
length = snprintf(pMarker, lengthRemaining,",%02d,%02d,%03d,",
- svNotify.gnssSvs[svNumber - 1].svId + svIdOffset,
+ svId + svIdOffset,
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].elevation), //float to int
(int)(0.5 + svNotify.gnssSvs[svNumber - 1].azimuth)); //float to int
@@ -438,7 +820,7 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
}
// append signalId
- length = snprintf(pMarker, lengthRemaining,",%d",sv_meta_p->signalId);
+ length = snprintf(pMarker, lengthRemaining,",%X",sv_meta_p->signalId);
pMarker += length;
lengthRemaining -= length;
@@ -450,6 +832,330 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify,
}
/*===========================================================================
+FUNCTION loc_nmea_generate_DTM
+
+DESCRIPTION
+ Generate NMEA DTM sentences generated based on position report
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ NONE
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_nmea_generate_DTM(const LocLla &ref_lla,
+ const LocLla &local_lla,
+ char *talker,
+ char *sentence,
+ int bufSize)
+{
+ char* pMarker = sentence;
+ int lengthRemaining = bufSize;
+ int length = 0;
+ int datum_type;
+ char ref_datum[4] = {0};
+ char local_datum[4] = {0};
+ double lla_offset[3] = {0};
+ char latHem, longHem;
+ double latMins, longMins;
+
+
+
+ datum_type = loc_get_datum_type();
+ switch (datum_type) {
+ case LOC_GNSS_DATUM_WGS84:
+ ref_datum[0] = 'W';
+ ref_datum[1] = '8';
+ ref_datum[2] = '4';
+ local_datum[0] = 'P';
+ local_datum[1] = '9';
+ local_datum[2] = '0';
+ break;
+ case LOC_GNSS_DATUM_PZ90:
+ ref_datum[0] = 'P';
+ ref_datum[1] = '9';
+ ref_datum[2] = '0';
+ local_datum[0] = 'W';
+ local_datum[1] = '8';
+ local_datum[2] = '4';
+ break;
+ default:
+ break;
+ }
+ length = snprintf(pMarker , lengthRemaining , "$%sDTM,%s,," , talker, local_datum);
+ if (length < 0 || length >= lengthRemaining) {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ lla_offset[0] = local_lla.lat - ref_lla.lat;
+ lla_offset[1] = fmod(local_lla.lon - ref_lla.lon, 360.0);
+ if (lla_offset[1] < -180.0) {
+ lla_offset[1] += 360.0;
+ } else if ( lla_offset[1] > 180.0) {
+ lla_offset[1] -= 360.0;
+ }
+ lla_offset[2] = local_lla.alt - ref_lla.alt;
+ if (lla_offset[0] > 0.0) {
+ latHem = 'N';
+ } else {
+ latHem = 'S';
+ lla_offset[0] *= -1.0;
+ }
+ latMins = fmod(lla_offset[0] * 60.0, 60.0);
+ if (lla_offset[1] < 0.0) {
+ longHem = 'W';
+ lla_offset[1] *= -1.0;
+ }else {
+ longHem = 'E';
+ }
+ longMins = fmod(lla_offset[1] * 60.0, 60.0);
+ length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,%.3lf,",
+ (uint8_t)floor(lla_offset[0]), latMins, latHem,
+ (uint8_t)floor(lla_offset[1]), longMins, longHem, lla_offset[2]);
+ if (length < 0 || length >= lengthRemaining) {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+ length = snprintf(pMarker , lengthRemaining , "%s" , ref_datum);
+ if (length < 0 || length >= lengthRemaining) {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ length = loc_nmea_put_checksum(sentence, bufSize);
+}
+
+/*===========================================================================
+FUNCTION get_utctime_with_leapsecond_transition
+
+DESCRIPTION
+ This function returns true if the position report is generated during
+ leap second transition period. If not, then the utc timestamp returned
+ will be set to the timestamp in the position report. If it is,
+ then the utc timestamp returned will need to take into account
+ of the leap second transition so that proper calendar year/month/date
+ can be calculated from the returned utc timestamp.
+
+DEPENDENCIES
+ NONE
+
+RETURN VALUE
+ true: position report is generated in leap second transition period.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static bool get_utctime_with_leapsecond_transition(
+ const UlpLocation &location,
+ const GpsLocationExtended &locationExtended,
+ const LocationSystemInfo &systemInfo,
+ LocGpsUtcTime &utcPosTimestamp)
+{
+ bool inTransition = false;
+
+ // position report is not generated during leap second transition,
+ // we can use the UTC timestamp from position report as is
+ utcPosTimestamp = location.gpsLocation.timestamp;
+
+ // Check whether we are in leap second transition.
+ // If so, per NMEA spec, we need to display the extra second in format of 23:59:60
+ // with year/month/date not getting advanced.
+ if ((locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_GPS_TIME) &&
+ ((systemInfo.systemInfoMask & LOCATION_SYS_INFO_LEAP_SECOND) &&
+ (systemInfo.leapSecondSysInfo.leapSecondInfoMask &
+ LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT))) {
+
+ const LeapSecondChangeInfo &leapSecondChangeInfo =
+ systemInfo.leapSecondSysInfo.leapSecondChangeInfo;
+ const GnssSystemTimeStructType &gpsTimestampLsChange =
+ leapSecondChangeInfo.gpsTimestampLsChange;
+
+ uint64_t gpsTimeLsChange = gpsTimestampLsChange.systemWeek * MSEC_IN_ONE_WEEK +
+ gpsTimestampLsChange.systemMsec;
+ uint64_t gpsTimePosReport = locationExtended.gpsTime.gpsWeek * MSEC_IN_ONE_WEEK +
+ locationExtended.gpsTime.gpsTimeOfWeekMs;
+ // we are only dealing with positive leap second change, as negative
+ // leap second change has never occurred and should not occur in future
+ if (leapSecondChangeInfo.leapSecondsAfterChange >
+ leapSecondChangeInfo.leapSecondsBeforeChange) {
+ // leap second adjustment is always 1 second at a time. It can happen
+ // every quarter end and up to four times per year.
+ if ((gpsTimePosReport >= gpsTimeLsChange) &&
+ (gpsTimePosReport < (gpsTimeLsChange + 1000))) {
+ inTransition = true;
+ utcPosTimestamp = gpsTimeLsChange + UTC_GPS_OFFSET_MSECS -
+ leapSecondChangeInfo.leapSecondsBeforeChange * 1000;
+
+ // we substract 1000 milli-seconds from UTC timestmap in order to calculate the
+ // proper year, month and date during leap second transtion.
+ // Let us give an example, assuming leap second transition is scheduled on 2019,
+ // Dec 31st mid night. When leap second transition is happening,
+ // instead of outputting the time as 2020, Jan, 1st, 00 hour, 00 min, and 00 sec.
+ // The time need to be displayed as 2019, Dec, 31st, 23 hour, 59 min and 60 sec.
+ utcPosTimestamp -= 1000;
+ }
+ }
+ }
+ return inTransition;
+}
+
+/*===========================================================================
+FUNCTION loc_nmea_get_fix_quality
+
+DESCRIPTION
+ This function obtains the fix quality for GGA sentence, mode indicator
+ for RMC and VTG sentence based on nav solution mask and tech mask in
+ the postion report.
+
+DEPENDENCIES
+ NONE
+
+Output parameter
+ ggaGpsQuality: gps quality field in GGA sentence
+ rmcModeIndicator: mode indicator field in RMC sentence
+ vtgModeIndicator: mode indicator field in VTG sentence
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+static void loc_nmea_get_fix_quality(const UlpLocation & location,
+ const GpsLocationExtended & locationExtended,
+ bool custom_gga_fix_quality,
+ char ggaGpsQuality[3],
+ char & rmcModeIndicator,
+ char & vtgModeIndicator) {
+
+ ggaGpsQuality[0] = '0'; // 0 means no fix
+ rmcModeIndicator = 'N'; // N means no fix
+ vtgModeIndicator = 'N'; // N means no fix
+
+ do {
+ // GGA fix quality is defined in NMEA spec as below:
+ // https://www.trimble.com/OEM_ReceiverHelp/V4.44/en/NMEA-0183messages_GGA.html
+ // Fix quality: 0 = invalid
+ // 1 = GPS fix (SPS)
+ // 2 = DGPS fix
+ // 3 = PPS fix
+ // 4 = Real Time Kinematic
+ // 5 = Float RTK
+ // 6 = estimated (dead reckoning) (2.3 feature)
+ // 7 = Manual input mode
+ // 8 = Simulation mode
+ if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)){
+ break;
+ }
+ // NOTE: Order of the check is important
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_NAV_SOLUTION_MASK) {
+ if (LOC_NAV_MASK_PPP_CORRECTION & locationExtended.navSolutionMask) {
+ ggaGpsQuality[0] = '2'; // 2 means DGPS fix
+ rmcModeIndicator = 'P'; // P means precise
+ vtgModeIndicator = 'P'; // P means precise
+ break;
+ } else if (LOC_NAV_MASK_RTK_FIXED_CORRECTION & locationExtended.navSolutionMask){
+ ggaGpsQuality[0] = '4'; // 4 means RTK Fixed fix
+ rmcModeIndicator = 'R'; // use R (RTK fixed)
+ vtgModeIndicator = 'D'; // use D (differential) as
+ // no RTK fixed defined for VTG in NMEA 183 spec
+ break;
+ } else if (LOC_NAV_MASK_RTK_CORRECTION & locationExtended.navSolutionMask){
+ ggaGpsQuality[0] = '5'; // 5 means RTK float fix
+ rmcModeIndicator = 'F'; // F means RTK float fix
+ vtgModeIndicator = 'D'; // use D (differential) as
+ // no RTK float defined for VTG in NMEA 183 spec
+ break;
+ } else if (LOC_NAV_MASK_DGNSS_CORRECTION & locationExtended.navSolutionMask){
+ ggaGpsQuality[0] = '2'; // 2 means DGPS fix
+ rmcModeIndicator = 'D'; // D means differential
+ vtgModeIndicator = 'D'; // D means differential
+ break;
+ } else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask){
+ ggaGpsQuality[0] = '2'; // 2 means DGPS fix
+ rmcModeIndicator = 'D'; // D means differential
+ vtgModeIndicator = 'D'; // D means differential
+ break;
+ }
+ }
+ // NOTE: Order of the check is important
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK) {
+ if (LOC_POS_TECH_MASK_SATELLITE & locationExtended.tech_mask){
+ ggaGpsQuality[0] = '1'; // 1 means GPS
+ rmcModeIndicator = 'A'; // A means autonomous
+ vtgModeIndicator = 'A'; // A means autonomous
+ break;
+ } else if (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask){
+ ggaGpsQuality[0] = '6'; // 6 means estimated (dead reckoning)
+ rmcModeIndicator = 'E'; // E means estimated (dead reckoning)
+ vtgModeIndicator = 'E'; // E means estimated (dead reckoning)
+ break;
+ }
+ }
+ } while (0);
+
+ do {
+ // check for customized nmea enabled or not
+ // with customized GGA quality enabled
+ // PPP fix w/o sensor: 59, PPP fix w/ sensor: 69
+ // DGNSS/SBAS correction fix w/o sensor: 2, w/ sensor: 62
+ // RTK fixed fix w/o sensor: 4, w/ sensor: 64
+ // RTK float fix w/o sensor: 5, w/ sensor: 65
+ // SPE fix w/o sensor: 1, and w/ sensor: 61
+ // Sensor dead reckoning fix: 6
+ if (true == custom_gga_fix_quality) {
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_NAV_SOLUTION_MASK) {
+ // PPP fix w/o sensor: fix quality will now be 59
+ // PPP fix w sensor: fix quality will now be 69
+ if (LOC_NAV_MASK_PPP_CORRECTION & locationExtended.navSolutionMask) {
+ if ((locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK) &&
+ (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask)) {
+ ggaGpsQuality[0] = '6';
+ ggaGpsQuality[1] = '9';
+ } else {
+ ggaGpsQuality[0] = '5';
+ ggaGpsQuality[1] = '9';
+ }
+ break;
+ }
+ }
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_POS_TECH_MASK) {
+ if (LOC_POS_TECH_MASK_SENSORS & locationExtended.tech_mask){
+ char ggaQuality_copy = ggaGpsQuality[0];
+ ggaGpsQuality[0] = '6'; // 6 sensor assisted
+ // RTK fixed fix w/ sensor: fix quality will now be 64
+ // RTK float fix w/ sensor: 65
+ // DGNSS and/or SBAS correction fix and w/ sensor: 62
+ // GPS fix without correction and w/ sensor: 61
+ if ((LOC_NAV_MASK_RTK_FIXED_CORRECTION & locationExtended.navSolutionMask)||
+ (LOC_NAV_MASK_RTK_CORRECTION & locationExtended.navSolutionMask)||
+ (LOC_NAV_MASK_DGNSS_CORRECTION & locationExtended.navSolutionMask)||
+ (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)||
+ (LOC_POS_TECH_MASK_SATELLITE & locationExtended.tech_mask)) {
+ ggaGpsQuality[1] = ggaQuality_copy;
+ break;
+ }
+ }
+ }
+ }
+ } while (0);
+
+ LOC_LOGv("gps quality: %s, rmc mode indicator: %c, vtg mode indicator: %c",
+ ggaGpsQuality, rmcModeIndicator, vtgModeIndicator);
+}
+
+/*===========================================================================
FUNCTION loc_nmea_generate_pos
DESCRIPTION
@@ -475,11 +1181,20 @@ SIDE EFFECTS
===========================================================================*/
void loc_nmea_generate_pos(const UlpLocation &location,
const GpsLocationExtended &locationExtended,
+ const LocationSystemInfo &systemInfo,
unsigned char generate_nmea,
+ bool custom_gga_fix_quality,
std::vector<std::string> &nmeaArraystr)
{
ENTRY_LOG();
- time_t utcTime(location.gpsLocation.timestamp/1000);
+
+ LocGpsUtcTime utcPosTimestamp = 0;
+ bool inLsTransition = false;
+
+ inLsTransition = get_utctime_with_leapsecond_transition
+ (location, locationExtended, systemInfo, utcPosTimestamp);
+
+ time_t utcTime(utcPosTimestamp/1000);
tm * pTm = gmtime(&utcTime);
if (NULL == pTm) {
LOC_LOGE("gmtime failed");
@@ -487,6 +1202,10 @@ void loc_nmea_generate_pos(const UlpLocation &location,
}
char sentence[NMEA_SENTENCE_MAX_LENGTH] = {0};
+ char sentence_DTM[NMEA_SENTENCE_MAX_LENGTH] = {0};
+ char sentence_RMC[NMEA_SENTENCE_MAX_LENGTH] = {0};
+ char sentence_GNS[NMEA_SENTENCE_MAX_LENGTH] = {0};
+ char sentence_GGA[NMEA_SENTENCE_MAX_LENGTH] = {0};
char* pMarker = sentence;
int lengthRemaining = sizeof(sentence);
int length = 0;
@@ -497,22 +1216,45 @@ void loc_nmea_generate_pos(const UlpLocation &location,
int utcMinutes = pTm->tm_min;
int utcSeconds = pTm->tm_sec;
int utcMSeconds = (location.gpsLocation.timestamp)%1000;
- loc_sv_cache_info sv_cache_info = {};
+ int datum_type = loc_get_datum_type();
+ LocEcef ecef_w84;
+ LocEcef ecef_p90;
+ LocLla lla_w84;
+ LocLla lla_p90;
+ LocLla ref_lla;
+ LocLla local_lla;
+
+ if (inLsTransition) {
+ // During leap second transition, we need to display the extra
+ // leap second of hour, minute, second as (23:59:60)
+ utcHours = 23;
+ utcMinutes = 59;
+ utcSeconds = 60;
+ // As UTC timestamp is freezing during leap second transition,
+ // retrieve milli-seconds portion from GPS timestamp.
+ utcMSeconds = locationExtended.gpsTime.gpsTimeOfWeekMs % 1000;
+ }
+
+ loc_sv_cache_info sv_cache_info = {};
if (GPS_LOCATION_EXTENDED_HAS_GNSS_SV_USED_DATA & locationExtended.flags) {
sv_cache_info.gps_used_mask =
- (uint32_t)locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask;
+ locationExtended.gnss_sv_used_ids.gps_sv_used_ids_mask;
sv_cache_info.glo_used_mask =
- (uint32_t)locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask;
+ locationExtended.gnss_sv_used_ids.glo_sv_used_ids_mask;
sv_cache_info.gal_used_mask =
- (uint32_t)locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask;
- sv_cache_info.qzss_used_mask =
- (uint32_t)locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask;
+ locationExtended.gnss_sv_used_ids.gal_sv_used_ids_mask;
sv_cache_info.bds_used_mask =
- (uint32_t)locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask;
+ locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask;
+ sv_cache_info.qzss_used_mask =
+ locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask;
+ sv_cache_info.navic_used_mask =
+ locationExtended.gnss_sv_used_ids.navic_sv_used_ids_mask;
}
+
if (generate_nmea) {
char talker[3] = {'G', 'P', '\0'};
+ char modeIndicator[7] = {0};
uint32_t svUsedCount = 0;
uint32_t count = 0;
loc_nmea_sv_meta sv_meta;
@@ -521,8 +1263,8 @@ void loc_nmea_generate_pos(const UlpLocation &location,
// -------------------
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GPS, true),
- nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GPS,
+ GNSS_SIGNAL_GPS_L1CA, true), nmeaArraystr);
if (count > 0)
{
svUsedCount += count;
@@ -535,8 +1277,8 @@ void loc_nmea_generate_pos(const UlpLocation &location,
// -------------------
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GLONASS, true),
- nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GLONASS,
+ GNSS_SIGNAL_GLONASS_G1, true), nmeaArraystr);
if (count > 0)
{
svUsedCount += count;
@@ -549,8 +1291,8 @@ void loc_nmea_generate_pos(const UlpLocation &location,
// -------------------
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GALILEO, true),
- nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GALILEO,
+ GNSS_SIGNAL_GALILEO_E1, true), nmeaArraystr);
if (count > 0)
{
svUsedCount += count;
@@ -558,31 +1300,39 @@ void loc_nmea_generate_pos(const UlpLocation &location,
talker[1] = sv_meta.talker[1];
}
- // --------------------------
- // ---$PQGSA/$GNGSA (QZSS)---
- // --------------------------
-
+ // ----------------------------
+ // ---$GBGSA/$GNGSA (BEIDOU)---
+ // ----------------------------
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS, false),
- nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
+ GNSS_SIGNAL_BEIDOU_B1I, true), nmeaArraystr);
if (count > 0)
{
svUsedCount += count;
- // talker should be default "GP". If GPS, GLO etc is used, it should be "GN"
+ talker[0] = sv_meta.talker[0];
+ talker[1] = sv_meta.talker[1];
}
- // ----------------------------
- // ---$PQGSA/$GNGSA (BEIDOU)---
- // ----------------------------
+ // --------------------------
+ // ---$GQGSA/$GNGSA (QZSS)---
+ // --------------------------
+
count = loc_nmea_generate_GSA(locationExtended, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU, false),
- nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS,
+ GNSS_SIGNAL_QZSS_L1CA, true), nmeaArraystr);
if (count > 0)
{
svUsedCount += count;
- // talker should be default "GP". If GPS, GLO etc is used, it should be "GN"
+ talker[0] = sv_meta.talker[0];
+ talker[1] = sv_meta.talker[1];
}
+ char ggaGpsQuality[3] = {'0', '\0', '\0'};
+ char rmcModeIndicator = 'N';
+ char vtgModeIndicator = 'N';
+ loc_nmea_get_fix_quality(location, locationExtended, custom_gga_fix_quality,
+ ggaGpsQuality, rmcModeIndicator, vtgModeIndicator);
+
// -------------------
// ------$--VTG-------
// -------------------
@@ -637,27 +1387,57 @@ void loc_nmea_generate_pos(const UlpLocation &location,
pMarker += length;
lengthRemaining -= length;
- if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG))
- // N means no fix
- length = snprintf(pMarker, lengthRemaining, "%c", 'N');
- else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)
- // D means differential
- length = snprintf(pMarker, lengthRemaining, "%c", 'D');
- else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
- // E means estimated (dead reckoning)
- length = snprintf(pMarker, lengthRemaining, "%c", 'E');
- else // A means autonomous
- length = snprintf(pMarker, lengthRemaining, "%c", 'A');
+ length = snprintf(pMarker, lengthRemaining, "%c", vtgModeIndicator);
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
+ memset(&ecef_w84, 0, sizeof(ecef_w84));
+ memset(&ecef_p90, 0, sizeof(ecef_p90));
+ memset(&lla_w84, 0, sizeof(lla_w84));
+ memset(&lla_p90, 0, sizeof(lla_p90));
+ memset(&ref_lla, 0, sizeof(ref_lla));
+ memset(&local_lla, 0, sizeof(local_lla));
+ lla_w84.lat = location.gpsLocation.latitude / 180.0 * M_PI;
+ lla_w84.lon = location.gpsLocation.longitude / 180.0 * M_PI;
+ lla_w84.alt = location.gpsLocation.altitude;
+
+ convert_Lla_to_Ecef(lla_w84, ecef_w84);
+ convert_WGS84_to_PZ90(ecef_w84, ecef_p90);
+ convert_Ecef_to_Lla(ecef_p90, lla_p90);
+
+ switch (datum_type) {
+ case LOC_GNSS_DATUM_WGS84:
+ ref_lla.lat = location.gpsLocation.latitude;
+ ref_lla.lon = location.gpsLocation.longitude;
+ ref_lla.alt = location.gpsLocation.altitude;
+ local_lla.lat = lla_p90.lat / M_PI * 180.0;
+ local_lla.lon = lla_p90.lon / M_PI * 180.0;
+ local_lla.alt = lla_p90.alt;
+ break;
+ case LOC_GNSS_DATUM_PZ90:
+ ref_lla.lat = lla_p90.lat / M_PI * 180.0;
+ ref_lla.lon = lla_p90.lon / M_PI * 180.0;
+ ref_lla.alt = lla_p90.alt;
+ local_lla.lat = location.gpsLocation.latitude;
+ local_lla.lon = location.gpsLocation.longitude;
+ local_lla.alt = location.gpsLocation.altitude;
+ break;
+ default:
+ break;
+ }
+
+ // -------------------
+ // ------$--DTM-------
+ // -------------------
+ loc_nmea_generate_DTM(ref_lla, local_lla, talker, sentence_DTM, sizeof(sentence_DTM));
+
// -------------------
// ------$--RMC-------
// -------------------
- pMarker = sentence;
- lengthRemaining = sizeof(sentence);
+ pMarker = sentence_RMC;
+ lengthRemaining = sizeof(sentence_RMC);
length = snprintf(pMarker, lengthRemaining, "$%sRMC,%02d%02d%02d.%02d,A," ,
talker, utcHours, utcMinutes, utcSeconds,utcMSeconds/10);
@@ -672,8 +1452,8 @@ void loc_nmea_generate_pos(const UlpLocation &location,
if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)
{
- double latitude = location.gpsLocation.latitude;
- double longitude = location.gpsLocation.longitude;
+ double latitude = ref_lla.lat;
+ double longitude = ref_lla.lon;
char latHemisphere;
char lonHemisphere;
double latMinutes;
@@ -795,17 +1575,176 @@ void loc_nmea_generate_pos(const UlpLocation &location,
pMarker += length;
lengthRemaining -= length;
- if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG))
- // N means no fix
- length = snprintf(pMarker, lengthRemaining, "%c", 'N');
+ length = snprintf(pMarker, lengthRemaining, "%c", rmcModeIndicator);
+ pMarker += length;
+ lengthRemaining -= length;
+
+ // hardcode Navigation Status field to 'V'
+ length = snprintf(pMarker, lengthRemaining, ",%c", 'V');
+ pMarker += length;
+ lengthRemaining -= length;
+
+ length = loc_nmea_put_checksum(sentence_RMC, sizeof(sentence_RMC));
+
+ // -------------------
+ // ------$--GNS-------
+ // -------------------
+
+ pMarker = sentence_GNS;
+ lengthRemaining = sizeof(sentence_GNS);
+
+ length = snprintf(pMarker, lengthRemaining, "$%sGNS,%02d%02d%02d.%02d," ,
+ talker, utcHours, utcMinutes, utcSeconds, utcMSeconds/10);
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)
+ {
+ double latitude = ref_lla.lat;
+ double longitude = ref_lla.lon;
+ char latHemisphere;
+ char lonHemisphere;
+ double latMinutes;
+ double lonMinutes;
+
+ if (latitude > 0)
+ {
+ latHemisphere = 'N';
+ }
+ else
+ {
+ latHemisphere = 'S';
+ latitude *= -1.0;
+ }
+
+ if (longitude < 0)
+ {
+ lonHemisphere = 'W';
+ longitude *= -1.0;
+ }
+ else
+ {
+ lonHemisphere = 'E';
+ }
+
+ latMinutes = fmod(latitude * 60.0 , 60.0);
+ lonMinutes = fmod(longitude * 60.0 , 60.0);
+
+ length = snprintf(pMarker, lengthRemaining, "%02d%09.6lf,%c,%03d%09.6lf,%c,",
+ (uint8_t)floor(latitude), latMinutes, latHemisphere,
+ (uint8_t)floor(longitude),lonMinutes, lonHemisphere);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,,,");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if(!(sv_cache_info.gps_used_mask ? 1 : 0))
+ modeIndicator[0] = 'N';
else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)
- // D means differential
- length = snprintf(pMarker, lengthRemaining, "%c", 'D');
+ modeIndicator[0] = 'D';
else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
- // E means estimated (dead reckoning)
- length = snprintf(pMarker, lengthRemaining, "%c", 'E');
- else // A means autonomous
- length = snprintf(pMarker, lengthRemaining, "%c", 'A');
+ modeIndicator[0] = 'E';
+ else
+ modeIndicator[0] = 'A';
+ if(!(sv_cache_info.glo_used_mask ? 1 : 0))
+ modeIndicator[1] = 'N';
+ else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
+ modeIndicator[1] = 'E';
+ else
+ modeIndicator[1] = 'A';
+ if(!(sv_cache_info.gal_used_mask ? 1 : 0))
+ modeIndicator[2] = 'N';
+ else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
+ modeIndicator[2] = 'E';
+ else
+ modeIndicator[2] = 'A';
+ if(!(sv_cache_info.bds_used_mask ? 1 : 0))
+ modeIndicator[3] = 'N';
+ else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
+ modeIndicator[3] = 'E';
+ else
+ modeIndicator[3] = 'A';
+ if(!(sv_cache_info.qzss_used_mask ? 1 : 0))
+ modeIndicator[4] = 'N';
+ else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
+ modeIndicator[4] = 'E';
+ else
+ modeIndicator[4] = 'A';
+ if(!(sv_cache_info.navic_used_mask ? 1 : 0))
+ modeIndicator[5] = 'N';
+ else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
+ modeIndicator[5] = 'E';
+ else
+ modeIndicator[5] = 'A';
+ modeIndicator[6] = '\0';
+ for(int index = 5; index > 0 && 'N' == modeIndicator[index]; index--) {
+ modeIndicator[index] = '\0';
+ }
+ length = snprintf(pMarker, lengthRemaining,"%s,", modeIndicator);
+
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP) {
+ length = snprintf(pMarker, lengthRemaining, "%02d,%.1f,",
+ svUsedCount, locationExtended.hdop);
+ }
+ else { // no hdop
+ length = snprintf(pMarker, lengthRemaining, "%02d,,",
+ svUsedCount);
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL)
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,",
+ locationExtended.altitudeMeanSeaLevel);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",");
+ }
+
+ if (length < 0 || length >= lengthRemaining)
+ {
+ LOC_LOGE("NMEA Error in string formatting");
+ return;
+ }
+ pMarker += length;
+ lengthRemaining -= length;
+
+ if ((location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_ALTITUDE) &&
+ (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
+ {
+ length = snprintf(pMarker, lengthRemaining, "%.1lf,,",
+ ref_lla.alt - locationExtended.altitudeMeanSeaLevel);
+ }
+ else
+ {
+ length = snprintf(pMarker, lengthRemaining,",,");
+ }
pMarker += length;
lengthRemaining -= length;
@@ -815,15 +1754,15 @@ void loc_nmea_generate_pos(const UlpLocation &location,
pMarker += length;
lengthRemaining -= length;
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
- nmeaArraystr.push_back(sentence);
+ length = loc_nmea_put_checksum(sentence_GNS, sizeof(sentence_GNS));
+
// -------------------
// ------$--GGA-------
// -------------------
- pMarker = sentence;
- lengthRemaining = sizeof(sentence);
+ pMarker = sentence_GGA;
+ lengthRemaining = sizeof(sentence_GGA);
length = snprintf(pMarker, lengthRemaining, "$%sGGA,%02d%02d%02d.%02d," ,
talker, utcHours, utcMinutes, utcSeconds, utcMSeconds/10);
@@ -838,8 +1777,8 @@ void loc_nmea_generate_pos(const UlpLocation &location,
if (location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG)
{
- double latitude = location.gpsLocation.latitude;
- double longitude = location.gpsLocation.longitude;
+ double latitude = ref_lla.lat;
+ double longitude = ref_lla.lon;
char latHemisphere;
char lonHemisphere;
double latMinutes;
@@ -885,28 +1824,18 @@ void loc_nmea_generate_pos(const UlpLocation &location,
pMarker += length;
lengthRemaining -= length;
- char gpsQuality;
- if (!(location.gpsLocation.flags & LOC_GPS_LOCATION_HAS_LAT_LONG))
- gpsQuality = '0'; // 0 means no fix
- else if (LOC_NAV_MASK_SBAS_CORRECTION_IONO & locationExtended.navSolutionMask)
- gpsQuality = '2'; // 2 means DGPS fix
- else if (LOC_POS_TECH_MASK_SENSORS == locationExtended.tech_mask)
- gpsQuality = '6'; // 6 means estimated (dead reckoning)
- else
- gpsQuality = '1'; // 1 means GPS fix
-
// Number of satellites in use, 00-12
if (svUsedCount > MAX_SATELLITES_IN_USE)
svUsedCount = MAX_SATELLITES_IN_USE;
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
{
- length = snprintf(pMarker, lengthRemaining, "%c,%02d,%.1f,",
- gpsQuality, svUsedCount, locationExtended.hdop);
+ length = snprintf(pMarker, lengthRemaining, "%s,%02d,%.1f,",
+ ggaGpsQuality, svUsedCount, locationExtended.hdop);
}
else
{ // no hdop
- length = snprintf(pMarker, lengthRemaining, "%c,%02d,,",
- gpsQuality, svUsedCount);
+ length = snprintf(pMarker, lengthRemaining, "%s,%02d,,",
+ ggaGpsQuality, svUsedCount);
}
if (length < 0 || length >= lengthRemaining)
@@ -939,35 +1868,52 @@ void loc_nmea_generate_pos(const UlpLocation &location,
(locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_ALTITUDE_MEAN_SEA_LEVEL))
{
length = snprintf(pMarker, lengthRemaining, "%.1lf,M,,",
- location.gpsLocation.altitude - locationExtended.altitudeMeanSeaLevel);
+ ref_lla.alt - locationExtended.altitudeMeanSeaLevel);
}
else
{
length = snprintf(pMarker, lengthRemaining,",,,");
}
- length = loc_nmea_put_checksum(sentence, sizeof(sentence));
- nmeaArraystr.push_back(sentence);
+ length = loc_nmea_put_checksum(sentence_GGA, sizeof(sentence_GGA));
+
+ // ------$--DTM-------
+ nmeaArraystr.push_back(sentence_DTM);
+ // ------$--RMC-------
+ nmeaArraystr.push_back(sentence_RMC);
+ if(LOC_GNSS_DATUM_PZ90 == datum_type) {
+ // ------$--DTM-------
+ nmeaArraystr.push_back(sentence_DTM);
+ }
+ // ------$--GNS-------
+ nmeaArraystr.push_back(sentence_GNS);
+ if(LOC_GNSS_DATUM_PZ90 == datum_type) {
+ // ------$--DTM-------
+ nmeaArraystr.push_back(sentence_DTM);
+ }
+ // ------$--GGA-------
+ nmeaArraystr.push_back(sentence_GGA);
+
}
//Send blank NMEA reports for non-final fixes
else {
- strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ strlcpy(sentence, "$GPGSA,A,1,,,,,,,,,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
- strlcpy(sentence, "$GNGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
- strlcpy(sentence, "$PQGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
+ strlcpy(sentence, "$GPDTM,,,,,,,,", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
- strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
+ strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N,V", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
- strlcpy(sentence, "$GPRMC,,V,,,,,,,,,,N,V", sizeof(sentence));
+ strlcpy(sentence, "$GPGNS,,,,,,N,,,,,,,V", sizeof(sentence));
length = loc_nmea_put_checksum(sentence, sizeof(sentence));
nmeaArraystr.push_back(sentence);
@@ -1017,9 +1963,15 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
(svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
{
- sv_cache_info.gps_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ sv_cache_info.gps_used_mask |= (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ }
+ if (GNSS_SIGNAL_GPS_L5 == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask) {
+ sv_cache_info.gps_l5_count++;
+ } else {
+ // GNSS_SIGNAL_GPS_L1CA or default
+ // If no signal type in report, it means default L1
+ sv_cache_info.gps_l1_count++;
}
- sv_cache_info.gps_count++;
}
else if (GNSS_SV_TYPE_GLONASS == svNotify.gnssSvs[svNumber - 1].type)
{
@@ -1029,9 +1981,15 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
(svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
{
- sv_cache_info.glo_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ sv_cache_info.glo_used_mask |= (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ }
+ if (GNSS_SIGNAL_GLONASS_G2 == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask){
+ sv_cache_info.glo_g2_count++;
+ } else {
+ // GNSS_SIGNAL_GLONASS_G1 or default
+ // If no signal type in report, it means default G1
+ sv_cache_info.glo_g1_count++;
}
- sv_cache_info.glo_count++;
}
else if (GNSS_SV_TYPE_GALILEO == svNotify.gnssSvs[svNumber - 1].type)
{
@@ -1041,9 +1999,15 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
(svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
{
- sv_cache_info.gal_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ sv_cache_info.gal_used_mask |= (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ }
+ if(GNSS_SIGNAL_GALILEO_E5A == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask){
+ sv_cache_info.gal_e5_count++;
+ } else {
+ // GNSS_SIGNAL_GALILEO_E1 or default
+ // If no signal type in report, it means default E1
+ sv_cache_info.gal_e1_count++;
}
- sv_cache_info.gal_count++;
}
else if (GNSS_SV_TYPE_QZSS == svNotify.gnssSvs[svNumber - 1].type)
{
@@ -1053,9 +2017,17 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
(svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
{
- sv_cache_info.qzss_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ // For QZSS we adjusted SV id's in GnssAdapter, we need to re-adjust here
+ sv_cache_info.qzss_used_mask |=
+ (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - (QZSS_SV_PRN_MIN - 1) - 1));
+ }
+ if (GNSS_SIGNAL_QZSS_L5 == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask) {
+ sv_cache_info.qzss_l5_count++;
+ } else {
+ // GNSS_SIGNAL_QZSS_L1CA or default
+ // If no signal type in report, it means default L1
+ sv_cache_info.qzss_l1_count++;
}
- sv_cache_info.qzss_count++;
}
else if (GNSS_SV_TYPE_BEIDOU == svNotify.gnssSvs[svNumber - 1].type)
{
@@ -1065,50 +2037,117 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
(svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
{
- sv_cache_info.bds_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ sv_cache_info.bds_used_mask |= (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
+ }
+ if(GNSS_SIGNAL_BEIDOU_B2AI == svNotify.gnssSvs[svNumber - 1].gnssSignalTypeMask){
+ sv_cache_info.bds_b2_count++;
+ } else {
+ // GNSS_SIGNAL_BEIDOU_B1I or default
+ // If no signal type in report, it means default B1I
+ sv_cache_info.bds_b1_count++;
+ }
+ }
+ else if (GNSS_SV_TYPE_NAVIC == svNotify.gnssSvs[svNumber - 1].type)
+ {
+ // cache the used in fix mask, as it will be needed to send $PQGSA
+ // during the position report
+ if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT ==
+ (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask &
+ GNSS_SV_OPTIONS_USED_IN_FIX_BIT))
+ {
+ sv_cache_info.navic_used_mask |=
+ (1ULL << (svNotify.gnssSvs[svNumber - 1].svId - 1));
}
- sv_cache_info.bds_count++;
+ // GNSS_SIGNAL_NAVIC_L5 is the only signal type for NAVIC
+ sv_cache_info.navic_l5_count++;
}
}
loc_nmea_sv_meta sv_meta;
- // ------------------
- // ------$GPGSV------
- // ------------------
+ // ---------------------
+ // ------$GPGSV:L1CA----
+ // ---------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GPS, false), nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GPS,
+ GNSS_SIGNAL_GPS_L1CA, false), nmeaArraystr);
+
+ // ---------------------
+ // ------$GPGSV:L5------
+ // ---------------------
- // ------------------
- // ------$GLGSV------
- // ------------------
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GPS,
+ GNSS_SIGNAL_GPS_L5, false), nmeaArraystr);
+ // ---------------------
+ // ------$GLGSV:G1------
+ // ---------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GLONASS, false),
- nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GLONASS,
+ GNSS_SIGNAL_GLONASS_G1, false), nmeaArraystr);
- // ------------------
- // ------$GAGSV------
- // ------------------
+ // ---------------------
+ // ------$GLGSV:G2------
+ // ---------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GALILEO, false),
- nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GLONASS,
+ GNSS_SIGNAL_GLONASS_G2, false), nmeaArraystr);
+
+ // ---------------------
+ // ------$GAGSV:E1------
+ // ---------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GALILEO,
+ GNSS_SIGNAL_GALILEO_E1, false), nmeaArraystr);
// -------------------------
- // ------$PQGSV (QZSS)------
+ // ------$GAGSV:E5A---------
// -------------------------
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_GALILEO,
+ GNSS_SIGNAL_GALILEO_E5A, false), nmeaArraystr);
+
+ // -----------------------------
+ // ------$PQGSV (QZSS):L1CA-----
+ // -----------------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS,
+ GNSS_SIGNAL_QZSS_L1CA, false), nmeaArraystr);
+
+ // -----------------------------
+ // ------$PQGSV (QZSS):L5-------
+ // -----------------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS,
+ GNSS_SIGNAL_QZSS_L5, false), nmeaArraystr);
+ // -----------------------------
+ // ------$PQGSV (BEIDOU:B1I)----
+ // -----------------------------
+
+ loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
+ GNSS_SIGNAL_BEIDOU_B1I,false), nmeaArraystr);
+
+ // -----------------------------
+ // ------$PQGSV (BEIDOU:B2AI)---
+ // -----------------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_QZSS, false), nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU,
+ GNSS_SIGNAL_BEIDOU_B2AI,false), nmeaArraystr);
- // ---------------------------
- // ------$PQGSV (BEIDOU)------
- // ---------------------------
+ // -----------------------------
+ // ------$GIGSV (NAVIC:L5)------
+ // -----------------------------
loc_nmea_generate_GSV(svNotify, sentence, sizeof(sentence),
- loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_BEIDOU, false),
- nmeaArraystr);
+ loc_nmea_sv_meta_init(sv_meta, sv_cache_info, GNSS_SV_TYPE_NAVIC,
+ GNSS_SIGNAL_NAVIC_L5,false), nmeaArraystr);
EXIT_LOG(%d, 0);
}
diff --git a/gps/utils/loc_nmea.h b/gps/utils/loc_nmea.h
index 585a9c1..a9cafb7 100644
--- a/gps/utils/loc_nmea.h
+++ b/gps/utils/loc_nmea.h
@@ -35,12 +35,51 @@
#include <string>
#define NMEA_SENTENCE_MAX_LENGTH 200
+/** gnss datum type */
+#define LOC_GNSS_DATUM_WGS84 0
+#define LOC_GNSS_DATUM_PZ90 1
+
+/* len of semi major axis of ref ellips*/
+#define MAJA (6378137.0)
+/* flattening coef of ref ellipsoid*/
+#define FLAT (1.0/298.2572235630)
+/* 1st eccentricity squared*/
+#define ESQR (FLAT*(2.0 - FLAT))
+/*1 minus eccentricity squared*/
+#define OMES (1.0 - ESQR)
+#define MILARCSEC2RAD (4.848136811095361e-09)
+/*semi major axis */
+#define C_PZ90A (6378136.0)
+/*semi minor axis */
+#define C_PZ90B (6356751.3618)
+/* Transformation from WGS84 to PZ90
+ * Cx,Cy,Cz,Rs,Rx,Ry,Rz,C_SYS_A,C_SYS_B*/
+const double DatumConstFromWGS84[9] =
+ {+0.003, +0.001, 0.000, (1.0+(0.000*1E-6)), (-0.019*MILARCSEC2RAD),
+ (+0.042*MILARCSEC2RAD), (-0.002*MILARCSEC2RAD), C_PZ90A, C_PZ90B};
+
+/** Represents a LTP*/
+typedef struct {
+ double lat;
+ double lon;
+ double alt;
+} LocLla;
+
+/** Represents a ECEF*/
+typedef struct {
+ double X;
+ double Y;
+ double Z;
+} LocEcef;
+
void loc_nmea_generate_sv(const GnssSvNotification &svNotify,
std::vector<std::string> &nmeaArraystr);
void loc_nmea_generate_pos(const UlpLocation &location,
const GpsLocationExtended &locationExtended,
+ const LocationSystemInfo &systemInfo,
unsigned char generate_nmea,
+ bool custom_gga_fix_quality,
std::vector<std::string> &nmeaArraystr);
#define DEBUG_NMEA_MINSIZE 6
diff --git a/gps/utils/loc_target.cpp b/gps/utils/loc_target.cpp
index 569f3a7..3ee42e6 100644
--- a/gps/utils/loc_target.cpp
+++ b/gps/utils/loc_target.cpp
@@ -54,6 +54,7 @@
#define STR_MTP "MTP"
#define STR_APQ "apq"
#define STR_SDC "sdc" // alternative string for APQ targets
+#define STR_QCS "qcs" // string for Gen9 APQ targets
#define STR_MSM "msm"
#define STR_SDM "sdm" // alternative string for MSM targets
#define STR_APQ_NO_WGR "baseband_apq_nowgr"
@@ -79,6 +80,11 @@ static int read_a_line(const char * file_path, char * line, int line_size)
int len;
fgets(line, line_size, fp);
len = strlen(line);
+ while ('\n' == line[len-1]) {
+ // If there is a new line at end of string, replace it with NULL
+ line[len-1] = '\0';
+ len--;
+ }
len = len < line_size - 1? len : line_size - 1;
line[len] = '\0';
LOC_LOGD("cat %s: %s", file_path, line);
@@ -129,16 +135,53 @@ void loc_get_auto_platform_name(char *platform_name, int array_length)
}
}
+/*Reads the property ro.config.low_ram to identify if this is a low ram target
+ Returns:
+ 0 if not a low ram target
+ 1 if this is a low ram target
+*/
+int loc_identify_low_ram_target()
+{
+ int ret = 0;
+ char low_ram_target[PROPERTY_VALUE_MAX];
+ property_get("ro.config.low_ram", low_ram_target, "");
+ LOC_LOGd("low ram target: %s\n", low_ram_target);
+ return !(strncmp(low_ram_target, "true", PROPERTY_VALUE_MAX));
+}
+
+/*The character array passed to this function should have length
+ of atleast PROPERTY_VALUE_MAX*/
+/* Reads the soc_id node and return the soc_id value */
+void loc_get_device_soc_id(char *soc_id_value, int array_length)
+{
+ static const char soc_id[] = "/sys/devices/soc0/soc_id";
+ static const char soc_id_dep[] = "/sys/devices/system/soc/soc0/id";
+ int return_val = 0;
+
+ if (soc_id_value && (array_length >= PROPERTY_VALUE_MAX)) {
+ if (!access(soc_id, F_OK)) {
+ return_val = read_a_line(soc_id, soc_id_value, array_length);
+ } else {
+ return_val = read_a_line(soc_id_dep, soc_id_value, array_length);
+ }
+ if (0 == return_val) {
+ LOC_LOGd("SOC Id value: %s\n", soc_id_value);
+ } else {
+ LOC_LOGe("Unable to read the soc_id value\n");
+ }
+ } else {
+ LOC_LOGe("Null parameter or array length less than PROPERTY_VALUE_MAX\n");
+ }
+}
+
unsigned int loc_get_target(void)
{
if (gTarget != (unsigned int)-1)
return gTarget;
static const char hw_platform[] = "/sys/devices/soc0/hw_platform";
- static const char id[] = "/sys/devices/soc0/soc_id";
static const char hw_platform_dep[] =
"/sys/devices/system/soc/soc0/hw_platform";
- static const char id_dep[] = "/sys/devices/system/soc/soc0/id";
static const char mdm[] = "/target"; // mdm target we are using
char rd_hw_platform[LINE_LEN];
@@ -154,11 +197,8 @@ unsigned int loc_get_target(void)
} else {
read_a_line(hw_platform_dep, rd_hw_platform, LINE_LEN);
}
- if (!access(id, F_OK)) {
- read_a_line(id, rd_id, LINE_LEN);
- } else {
- read_a_line(id_dep, rd_id, LINE_LEN);
- }
+ // Get the soc-id for this device.
+ loc_get_device_soc_id(rd_id, sizeof(rd_id));
/*check automotive platform*/
loc_get_auto_platform_name(rd_auto_platform, sizeof(rd_auto_platform));
@@ -175,7 +215,8 @@ unsigned int loc_get_target(void)
}
if( !memcmp(baseband, STR_APQ, LENGTH(STR_APQ)) ||
- !memcmp(baseband, STR_SDC, LENGTH(STR_SDC)) ) {
+ !memcmp(baseband, STR_SDC, LENGTH(STR_SDC)) ||
+ !memcmp(baseband, STR_QCS, LENGTH(STR_QCS)) ) {
if( !memcmp(rd_id, MPQ8064_ID_1, LENGTH(MPQ8064_ID_1))
&& IS_STR_END(rd_id[LENGTH(MPQ8064_ID_1)]) )
diff --git a/gps/utils/loc_target.h b/gps/utils/loc_target.h
index 172b475..2dcd895 100644
--- a/gps/utils/loc_target.h
+++ b/gps/utils/loc_target.h
@@ -54,6 +54,10 @@ void loc_get_platform_name(char *platform_name, int array_length);
/*The character array passed to this function should have length
of atleast PROPERTY_VALUE_MAX*/
void loc_get_auto_platform_name(char *platform_name, int array_length);
+int loc_identify_low_ram_target();
+/*The character array passed to this function should have length
+ of atleast PROPERTY_VALUE_MAX*/
+void loc_get_device_soc_id(char *soc_id_value, int array_length);
/* Please remember to update 'target_name' in loc_log.cpp,
if do any changes to this enum. */
diff --git a/gps/utils/log_util.h b/gps/utils/log_util.h
index feb4d3c..192baeb 100644
--- a/gps/utils/log_util.h
+++ b/gps/utils/log_util.h
@@ -39,13 +39,41 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/time.h>
#include <unistd.h>
-#include <cutils/log.h>
#ifndef LOG_TAG
#define LOG_TAG "GPS_UTILS"
#endif /* LOG_TAG */
+// LE targets with no logcat support
+#ifdef FEATURE_EXTERNAL_AP
+#include <syslog.h>
+#define ALOGE(...) syslog(LOG_ERR, "LOC_LOGE: " __VA_ARGS__);
+#define ALOGW(...) syslog(LOG_WARNING, "LOC_LOGW: " __VA_ARGS__);
+#define ALOGI(...) syslog(LOG_NOTICE, "LOC_LOGI: " __VA_ARGS__);
+#define ALOGD(...) syslog(LOG_DEBUG, "LOC_LOGD: " __VA_ARGS__);
+#define ALOGV(...) syslog(LOG_NOTICE, "LOC_LOGV: " __VA_ARGS__);
+#else /* FEATURE_EXTERNAL_AP */
+#define TS_PRINTF(format, x...) \
+{ \
+ struct timeval tv; \
+ struct timezone tz; \
+ int hh, mm, ss; \
+ gettimeofday(&tv, &tz); \
+ hh = tv.tv_sec/3600%24; \
+ mm = (tv.tv_sec%3600)/60; \
+ ss = tv.tv_sec%60; \
+ fprintf(stdout,"%02d:%02d:%02d.%06ld]" format "\n", hh, mm, ss, tv.tv_usec, ##x); \
+}
+
+#define ALOGE(format, x...) TS_PRINTF("E/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#define ALOGW(format, x...) TS_PRINTF("W/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#define ALOGI(format, x...) TS_PRINTF("I/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#define ALOGD(format, x...) TS_PRINTF("D/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#define ALOGV(format, x...) TS_PRINTF("V/%s (%d): " format , LOG_TAG, getpid(), ##x)
+#endif /* FEATURE_EXTERNAL_AP */
+
#endif /* #if defined (USE_ANDROID_LOGGING) || defined (ANDROID) */
#ifdef __cplusplus
@@ -148,6 +176,7 @@ extern char* get_timestamp(char* str, unsigned long buf_size);
#define LOG_I(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGI, ID, WHAT, SPEC, VAL)
#define LOG_V(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGV, ID, WHAT, SPEC, VAL)
#define LOG_E(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGE, ID, WHAT, SPEC, VAL)
+#define LOG_D(ID, WHAT, SPEC, VAL) LOG_(LOC_LOGD, ID, WHAT, SPEC, VAL)
#define ENTRY_LOG() LOG_V(ENTRY_TAG, __FUNCTION__, %s, "")
#define EXIT_LOG(SPEC, VAL) LOG_V(EXIT_TAG, __FUNCTION__, SPEC, VAL)
@@ -165,6 +194,8 @@ extern char* get_timestamp(char* str, unsigned long buf_size);
#define EXIT_LOG_CALLFLOW(SPEC, VAL) LOG_I(TO_MODEM, __FUNCTION__, SPEC, VAL)
// Used for logging callflow from Modem(TO_MODEM, __FUNCTION__, %s, "")
#define MODEM_LOG_CALLFLOW(SPEC, VAL) LOG_I(FROM_MODEM, __FUNCTION__, SPEC, VAL)
+// Used for logging high frequency callflow from Modem(TO_MODEM, __FUNCTION__, %s, "")
+#define MODEM_LOG_CALLFLOW_DEBUG(SPEC, VAL) LOG_D(FROM_MODEM, __FUNCTION__, SPEC, VAL)
// Used for logging callflow to Android Framework
#define CALLBACK_LOG_CALLFLOW(CB, SPEC, VAL) LOG_I(TO_AFW, CB, SPEC, VAL)
diff --git a/gps/utils/msg_q.c b/gps/utils/msg_q.c
index 76c1478..2d49b4a 100644
--- a/gps/utils/msg_q.c
+++ b/gps/utils/msg_q.c
@@ -267,6 +267,51 @@ msq_q_err_type msg_q_rcv(void* msg_q_data, void** msg_obj)
/*===========================================================================
+ FUNCTION: msg_q_rmv
+
+ ===========================================================================*/
+msq_q_err_type msg_q_rmv(void* msg_q_data, void** msg_obj)
+{
+ msq_q_err_type rv;
+ if (msg_q_data == NULL) {
+ LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_HANDLE;
+ }
+
+ if (msg_obj == NULL) {
+ LOC_LOGE("%s: Invalid msg_obj parameter!\n", __FUNCTION__);
+ return eMSG_Q_INVALID_PARAMETER;
+ }
+
+ msg_q* p_msg_q = (msg_q*)msg_q_data;
+
+ pthread_mutex_lock(&p_msg_q->list_mutex);
+
+ if (p_msg_q->unblocked) {
+ LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__);
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+ return eMSG_Q_UNAVAILABLE_RESOURCE;
+ }
+
+ if (linked_list_empty(p_msg_q->msg_list)) {
+ LOC_LOGW("%s: list is empty !!\n", __FUNCTION__);
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+ return eLINKED_LIST_EMPTY;
+ }
+
+ rv = convert_linked_list_err_type(linked_list_remove(p_msg_q->msg_list, msg_obj));
+
+ pthread_mutex_unlock(&p_msg_q->list_mutex);
+
+ LOC_LOGV("%s: Removed message %p rv = %d\n", __FUNCTION__, *msg_obj, rv);
+
+ return rv;
+}
+
+
+
+/*===========================================================================
+
FUNCTION: msg_q_flush
===========================================================================*/
diff --git a/gps/utils/msg_q.h b/gps/utils/msg_q.h
index 453b8ce..16df494 100644
--- a/gps/utils/msg_q.h
+++ b/gps/utils/msg_q.h
@@ -158,6 +158,29 @@ SIDE EFFECTS
msq_q_err_type msg_q_rcv(void* msg_q_data, void** msg_obj);
/*===========================================================================
+FUNCTION msg_q_rmv
+
+DESCRIPTION
+ Remove data from the message queue. msg_obj is the oldest message received
+ and pointer is simply removed from message queue.
+
+ msg_q_data: Message Queue to copy data from into msgp.
+ msg_obj: Pointer to space to copy msg_q contents to.
+
+DEPENDENCIES
+ N/A
+
+RETURN VALUE
+ Look at error codes above.
+
+SIDE EFFECTS
+ N/A
+
+===========================================================================*/
+msq_q_err_type msg_q_rmv(void* msg_q_data, void** msg_obj);
+
+
+/*===========================================================================
FUNCTION msg_q_flush
DESCRIPTION
diff --git a/manifest.xml b/manifest.xml
index a06eb00..a31bf79 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -374,15 +374,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</interface>
</hal>
<hal format="hidl">
- <name>android.hardware.gnss</name>
- <transport>hwbinder</transport>
- <version>1.1</version>
- <interface>
- <name>IGnss</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
<name>vendor.display.config</name>
<transport>hwbinder</transport>
<version>1.9</version>
@@ -392,15 +383,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</interface>
</hal>
<hal format="hidl">
- <name>vendor.qti.gnss</name>
- <transport>hwbinder</transport>
- <version>1.0</version>
- <interface>
- <name>ILocHidlGnss</name>
- <instance>gnss_vendor</instance>
- </interface>
- </hal>
- <hal format="hidl">
<name>vendor.qti.data.factory</name>
<transport>hwbinder</transport>
<version>2.0</version>
diff --git a/msm8996.mk b/msm8996.mk
index 796c156..532b55c 100755
--- a/msm8996.mk
+++ b/msm8996.mk
@@ -138,6 +138,7 @@ PRODUCT_COPY_FILES += \
# Bluetooth
PRODUCT_PACKAGES += \
android.hardware.bluetooth@1.0.vendor \
+ android.hardware.bluetooth@1.0 \
android.hardware.bluetooth.audio-impl \
audio.bluetooth.default
@@ -215,13 +216,14 @@ PRODUCT_PACKAGES += \
# GPS / Location
PRODUCT_PACKAGES += \
- android.hardware.gnss@1.0-impl-qti \
- android.hardware.gnss@1.0-service-qti \
+ android.hardware.gnss@2.0-impl-qti \
+ android.hardware.gnss@2.0-service-qti \
android.hardware.gnss@1.1.vendor \
libcurl \
libgnss \
libgnsspps \
- libsensorndkbridge
+ libsensorndkbridge \
+ libwifi-hal-ctrl
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/configs/gps//flp.conf:$(TARGET_COPY_OUT_VENDOR)/etc/flp.conf \
@@ -396,10 +398,6 @@ PRODUCT_PACKAGES += \
# PRODUCT_VENDOR_VERITY_PARTITION=/dev/block/bootdevice/by-name/factory
# $(call inherit-product, build/target/product/verity.mk)
-# Vibrator
-PRODUCT_PACKAGES += \
- vendor.qti.hardware.vibrator.service
-
PRODUCT_COPY_FILES += \
prebuilts/vndk/v29/arm64/arch-arm64-armv8-a/shared/vndk-sp/libcutils.so:$(TARGET_COPY_OUT_SYSTEM_EXT)/lib64/libcutils-v29.so \
prebuilts/vndk/v32/arm64/arch-arm64-armv8-a/shared/vndk-sp/libhidlbase.so:$(TARGET_COPY_OUT_SYSTEM)/lib64/libhidlbase-v32.so \
@@ -409,7 +407,7 @@ PRODUCT_COPY_FILES += \
# WiFi
PRODUCT_PACKAGES += \
- android.hardware.wifi-service \
+ android.hardware.wifi@1.0-service.legacy \
libwpa_client \
hostapd \
WifiOverlay \
diff --git a/wifi/wifi_legacy_service/1.0-legacy/Android.bp b/wifi/wifi_legacy_service/1.0-legacy/Android.bp
new file mode 100644
index 0000000..0d0dfdf
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/Android.bp
@@ -0,0 +1,182 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+soong_config_module_type {
+ name: "wifi_hal_cc_defaults",
+ module_type: "cc_defaults",
+ config_namespace: "wifi",
+ bool_variables: [
+ "hidl_feature_aware", // WIFI_HIDL_FEATURE_AWARE
+ "hidl_feature_dual_interface", // WIFI_HIDL_FEATURE_DUAL_INTERFACE
+ "hidl_feature_disable_ap", // WIFI_HIDL_FEATURE_DISABLE_AP
+ "hidl_feature_disable_ap_mac_randomization", // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
+ "avoid_iface_reset_mac_change", // WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+ "wifi_skip_state_toggle_off_on_for_nan", // WIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN
+ ],
+ value_variables: [
+ "hal_interface_combinations", // WIFI_HAL_INTERFACE_COMBINATIONS
+ ],
+ properties: [
+ "cppflags",
+ ],
+}
+
+wifi_hal_cc_defaults {
+ name: "android.hardware.wifi@1.0-service.legacy-cppflags-defaults",
+ soong_config_variables: {
+ hidl_feature_aware: {
+ cppflags: ["-DWIFI_HIDL_FEATURE_AWARE"],
+ },
+ hidl_feature_dual_interface: {
+ cppflags: ["-DWIFI_HIDL_FEATURE_DUAL_INTERFACE"],
+ },
+ hidl_feature_disable_ap: {
+ cppflags: ["-DWIFI_HIDL_FEATURE_DISABLE_AP"],
+ },
+ hidl_feature_disable_ap_mac_randomization: {
+ cppflags: ["-DWIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION"],
+ },
+ avoid_iface_reset_mac_change: {
+ cppflags: ["-DWIFI_AVOID_IFACE_RESET_MAC_CHANGE"],
+ },
+ wifi_skip_state_toggle_off_on_for_nan: {
+ cppflags: ["-DWIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN"],
+ },
+ hal_interface_combinations: {
+ cppflags: ["-DWIFI_HAL_INTERFACE_COMBINATIONS=%s"],
+ },
+ },
+}
+
+cc_library_static {
+ name: "android.hardware.wifi@1.0-service.legacy-lib",
+ defaults: ["android.hardware.wifi@1.0-service.legacy-cppflags-defaults"],
+ proprietary: true,
+ compile_multilib: "first",
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+ // Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed.
+ cflags: ["-Wno-error=implicit-fallthrough"],
+ srcs: [
+ "hidl_struct_util.cpp",
+ "hidl_sync_util.cpp",
+ "ringbuffer.cpp",
+ "wifi.cpp",
+ "wifi_ap_iface.cpp",
+ "wifi_chip.cpp",
+ "wifi_feature_flags.cpp",
+ "wifi_iface_util.cpp",
+ "wifi_legacy_hal.cpp",
+ "wifi_legacy_hal_factory.cpp",
+ "wifi_legacy_hal_stubs.cpp",
+ "wifi_mode_controller.cpp",
+ "wifi_nan_iface.cpp",
+ "wifi_p2p_iface.cpp",
+ "wifi_rtt_controller.cpp",
+ "wifi_sta_iface.cpp",
+ "wifi_status_util.cpp",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libnl",
+ "libutils",
+ "libwifi-hal",
+ "libwifi-system-iface",
+ "libxml2",
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
+ "android.hardware.wifi@1.6",
+ ],
+
+ export_include_dirs: ["."],
+}
+
+cc_binary {
+ name: "android.hardware.wifi@1.0-service.legacy",
+ vintf_fragments: ["android.hardware.wifi@1.0-service.legacy.xml"],
+ relative_install_path: "hw",
+ proprietary: true,
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+ srcs: ["service.cpp"],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libnl",
+ "libutils",
+ "libwifi-hal",
+ "libwifi-system-iface",
+ "libxml2",
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
+ "android.hardware.wifi@1.6",
+ ],
+ static_libs: ["android.hardware.wifi@1.0-service.legacy-lib"],
+ init_rc: ["android.hardware.wifi@1.0-service.legacy.rc"],
+}
+
+cc_binary {
+ name: "android.hardware.wifi@1.0-service.legacy-lazy",
+ vintf_fragments: ["android.hardware.wifi@1.0-service.legacy.xml"],
+ overrides: ["android.hardware.wifi@1.0-service.legacy"],
+ cflags: ["-DLAZY_SERVICE"],
+ relative_install_path: "hw",
+ proprietary: true,
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+ srcs: ["service.cpp"],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libnl",
+ "libutils",
+ "libwifi-hal",
+ "libwifi-system-iface",
+ "libxml2",
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
+ "android.hardware.wifi@1.3",
+ "android.hardware.wifi@1.4",
+ "android.hardware.wifi@1.5",
+ "android.hardware.wifi@1.6",
+ ],
+ static_libs: ["android.hardware.wifi@1.0-service.legacy-lib"],
+ init_rc: ["android.hardware.wifi@1.0-service.legacy-lazy.rc"],
+}
diff --git a/wifi/wifi_legacy_service/1.0-legacy/THREADING.README b/wifi/wifi_legacy_service/1.0-legacy/THREADING.README
new file mode 100644
index 0000000..8366ca0
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/THREADING.README
@@ -0,0 +1,35 @@
+Vendor HAL Threading Model
+==========================
+The vendor HAL service has two threads:
+1. HIDL thread: This is the main thread which processes all the incoming HIDL
+RPC's.
+2. Legacy HAL event loop thread: This is the thread forked off for processing
+the legacy HAL event loop (wifi_event_loop()). This thread is used to process
+any asynchronous netlink events posted by the driver. Any asynchronous
+callbacks passed to the legacy HAL API's are invoked on this thread.
+
+Synchronization Concerns
+========================
+wifi_legacy_hal.cpp has a bunch of global "C" style functions to handle the
+legacy callbacks. Each of these "C" style function invokes a corresponding
+"std::function" version of the callback which does the actual processing.
+The variables holding these "std::function" callbacks are reset from the HIDL
+thread when they are no longer used. For example: stopGscan() will reset the
+corresponding "on_gscan_*" callback variables which were set when startGscan()
+was invoked. This is not thread safe since these callback variables are
+accesed from the legacy hal event loop thread as well.
+
+Synchronization Solution
+========================
+Adding a global lock seems to be the most trivial solution to the problem.
+a) All of the asynchronous "C" style callbacks will acquire the global lock
+before invoking the corresponding "std::function" callback variables.
+b) All of the HIDL methods will also acquire the global lock before processing
+(in hidl_return_util::validateAndCall()).
+
+Note: It's important that we only acquire the global lock for asynchronous
+callbacks, because there is no guarantee (or documentation to clarify) that the
+synchronous callbacks are invoked on the same invocation thread. If that is not
+the case in some implementation, we will end up deadlocking the system since the
+HIDL thread would have acquired the global lock which is needed by the
+synchronous callback executed on the legacy hal event loop thread.
diff --git a/wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy-lazy.rc b/wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy-lazy.rc
new file mode 100644
index 0000000..5bf3223
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy-lazy.rc
@@ -0,0 +1,14 @@
+service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service.legacy-lazy
+ interface android.hardware.wifi@1.0::IWifi default
+ interface android.hardware.wifi@1.1::IWifi default
+ interface android.hardware.wifi@1.2::IWifi default
+ interface android.hardware.wifi@1.3::IWifi default
+ interface android.hardware.wifi@1.4::IWifi default
+ interface android.hardware.wifi@1.5::IWifi default
+ interface android.hardware.wifi@1.6::IWifi default
+ oneshot
+ disabled
+ class hal
+ capabilities NET_ADMIN NET_RAW SYS_MODULE
+ user wifi
+ group wifi gps
diff --git a/wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy.rc b/wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy.rc
new file mode 100644
index 0000000..fb18f68
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy.rc
@@ -0,0 +1,12 @@
+service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service.legacy
+ interface android.hardware.wifi@1.0::IWifi default
+ interface android.hardware.wifi@1.1::IWifi default
+ interface android.hardware.wifi@1.2::IWifi default
+ interface android.hardware.wifi@1.3::IWifi default
+ interface android.hardware.wifi@1.4::IWifi default
+ interface android.hardware.wifi@1.5::IWifi default
+ interface android.hardware.wifi@1.6::IWifi default
+ class hal
+ capabilities NET_ADMIN NET_RAW SYS_MODULE
+ user wifi
+ group wifi gps
diff --git a/wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy.xml b/wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy.xml
new file mode 100644
index 0000000..771fbaa
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/android.hardware.wifi@1.0-service.legacy.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.wifi</name>
+ <transport>hwbinder</transport>
+ <version>1.6</version>
+ <interface>
+ <name>IWifi</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioHardwareBase.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioHardwareBase.h
new file mode 100644
index 0000000..eb61472
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioHardwareBase.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_HARDWARE_BASE_H
+#define ANDROID_AUDIO_HARDWARE_BASE_H
+
+#include <hardware_legacy/AudioHardwareInterface.h>
+
+#include <system/audio.h>
+
+namespace android_audio_legacy {
+
+// ----------------------------------------------------------------------------
+
+/**
+ * AudioHardwareBase is a convenient base class used for implementing the
+ * AudioHardwareInterface interface.
+ */
+class AudioHardwareBase : public AudioHardwareInterface {
+ public:
+ AudioHardwareBase();
+ virtual ~AudioHardwareBase() {}
+
+ /**
+ * setMode is called when the audio mode changes. NORMAL mode is for
+ * standard audio playback, RINGTONE when a ringtone is playing, IN_CALL
+ * when a telephony call is in progress, IN_COMMUNICATION when a VoIP call is in progress.
+ */
+ virtual status_t setMode(int mode);
+
+ virtual status_t setParameters(const String8& keyValuePairs);
+ virtual String8 getParameters(const String8& keys);
+
+ virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
+ virtual status_t getMasterVolume(float* volume);
+
+ /**This method dumps the state of the audio hardware */
+ virtual status_t dumpState(int fd, const Vector<String16>& args);
+
+ protected:
+ /** returns true if the given mode maps to a telephony or VoIP call is in progress */
+ virtual bool isModeInCall(int mode) {
+ return ((mode == AudioSystem::MODE_IN_CALL) ||
+ (mode == AudioSystem::MODE_IN_COMMUNICATION));
+ };
+ /** returns true if a telephony or VoIP call is in progress */
+ virtual bool isInCall() { return isModeInCall(mMode); };
+ int mMode;
+};
+
+}; // namespace android_audio_legacy
+
+#endif // ANDROID_AUDIO_HARDWARE_BASE_H
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioHardwareInterface.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioHardwareInterface.h
new file mode 100644
index 0000000..7befb79
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioHardwareInterface.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_HARDWARE_INTERFACE_H
+#define ANDROID_AUDIO_HARDWARE_INTERFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include <hardware_legacy/AudioSystemLegacy.h>
+
+#include <hardware/audio.h>
+#include <system/audio.h>
+
+#include <cutils/bitops.h>
+
+namespace android_audio_legacy {
+using android::String16;
+using android::String8;
+using android::Vector;
+
+// ----------------------------------------------------------------------------
+
+/**
+ * AudioStreamOut is the abstraction interface for the audio output hardware.
+ *
+ * It provides information about various properties of the audio output hardware driver.
+ */
+class AudioStreamOut {
+ public:
+ virtual ~AudioStreamOut() = 0;
+
+ /** return audio sampling rate in hz - eg. 44100 */
+ virtual uint32_t sampleRate() const = 0;
+
+ /** returns size of output buffer - eg. 4800 */
+ virtual size_t bufferSize() const = 0;
+
+ /**
+ * returns the output channel mask
+ */
+ virtual uint32_t channels() const = 0;
+
+ /**
+ * return audio format in 8bit or 16bit PCM format -
+ * eg. AudioSystem:PCM_16_BIT
+ */
+ virtual int format() const = 0;
+
+ /**
+ * return the frame size (number of bytes per sample).
+ */
+ uint32_t frameSize() const {
+ return audio_channel_count_from_out_mask(channels()) *
+ ((format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(int8_t));
+ }
+
+ /**
+ * return the audio hardware driver latency in milli seconds.
+ */
+ virtual uint32_t latency() const = 0;
+
+ /**
+ * Use this method in situations where audio mixing is done in the
+ * hardware. This method serves as a direct interface with hardware,
+ * allowing you to directly set the volume as apposed to via the framework.
+ * This method might produce multiple PCM outputs or hardware accelerated
+ * codecs, such as MP3 or AAC.
+ */
+ virtual status_t setVolume(float left, float right) = 0;
+
+ /** write audio buffer to driver. Returns number of bytes written */
+ virtual ssize_t write(const void* buffer, size_t bytes) = 0;
+
+ /**
+ * Put the audio hardware output into standby mode. Returns
+ * status based on include/utils/Errors.h
+ */
+ virtual status_t standby() = 0;
+
+ /** dump the state of the audio output device */
+ virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+
+ // set/get audio output parameters. The function accepts a list of parameters
+ // key value pairs in the form: key1=value1;key2=value2;...
+ // Some keys are reserved for standard parameters (See AudioParameter class).
+ // If the implementation does not accept a parameter change while the output is
+ // active but the parameter is acceptable otherwise, it must return INVALID_OPERATION.
+ // The audio flinger will put the output in standby and then change the parameter value.
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+ virtual String8 getParameters(const String8& keys) = 0;
+
+ // return the number of audio frames written by the audio dsp to DAC since
+ // the output has exited standby
+ virtual status_t getRenderPosition(uint32_t* dspFrames) = 0;
+
+ /**
+ * get the local time at which the next write to the audio driver will be
+ * presented
+ */
+ virtual status_t getNextWriteTimestamp(int64_t* timestamp);
+
+ /**
+ * Return a recent count of the number of audio frames presented to an external observer.
+ */
+ virtual status_t getPresentationPosition(uint64_t* frames, struct timespec* timestamp);
+};
+
+/**
+ * AudioStreamIn is the abstraction interface for the audio input hardware.
+ *
+ * It defines the various properties of the audio hardware input driver.
+ */
+class AudioStreamIn {
+ public:
+ virtual ~AudioStreamIn() = 0;
+
+ /** return audio sampling rate in hz - eg. 44100 */
+ virtual uint32_t sampleRate() const = 0;
+
+ /** return the input buffer size allowed by audio driver */
+ virtual size_t bufferSize() const = 0;
+
+ /** return input channel mask */
+ virtual uint32_t channels() const = 0;
+
+ /**
+ * return audio format in 8bit or 16bit PCM format -
+ * eg. AudioSystem:PCM_16_BIT
+ */
+ virtual int format() const = 0;
+
+ /**
+ * return the frame size (number of bytes per sample).
+ */
+ uint32_t frameSize() const {
+ return audio_channel_count_from_in_mask(channels()) *
+ ((format() == AudioSystem::PCM_16_BIT) ? sizeof(int16_t) : sizeof(int8_t));
+ }
+
+ /** set the input gain for the audio driver. This method is for
+ * for future use */
+ virtual status_t setGain(float gain) = 0;
+
+ /** read audio buffer in from audio driver */
+ virtual ssize_t read(void* buffer, ssize_t bytes) = 0;
+
+ /** dump the state of the audio input device */
+ virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+
+ /**
+ * Put the audio hardware input into standby mode. Returns
+ * status based on include/utils/Errors.h
+ */
+ virtual status_t standby() = 0;
+
+ // set/get audio input parameters. The function accepts a list of parameters
+ // key value pairs in the form: key1=value1;key2=value2;...
+ // Some keys are reserved for standard parameters (See AudioParameter class).
+ // If the implementation does not accept a parameter change while the output is
+ // active but the parameter is acceptable otherwise, it must return INVALID_OPERATION.
+ // The audio flinger will put the input in standby and then change the parameter value.
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+ virtual String8 getParameters(const String8& keys) = 0;
+
+ // Return the number of input frames lost in the audio driver since the last call of this
+ // function. Audio driver is expected to reset the value to 0 and restart counting upon
+ // returning the current value by this function call. Such loss typically occurs when the user
+ // space process is blocked longer than the capacity of audio driver buffers. Unit: the number
+ // of input audio frames
+ virtual unsigned int getInputFramesLost() const = 0;
+
+ virtual status_t addAudioEffect(effect_handle_t effect) = 0;
+ virtual status_t removeAudioEffect(effect_handle_t effect) = 0;
+};
+
+/**
+ * AudioHardwareInterface.h defines the interface to the audio hardware abstraction layer.
+ *
+ * The interface supports setting and getting parameters, selecting audio routing
+ * paths, and defining input and output streams.
+ *
+ * AudioFlinger initializes the audio hardware and immediately opens an output stream.
+ * You can set Audio routing to output to handset, speaker, Bluetooth, or a headset.
+ *
+ * The audio input stream is initialized when AudioFlinger is called to carry out
+ * a record operation.
+ */
+class AudioHardwareInterface {
+ public:
+ virtual ~AudioHardwareInterface() {}
+
+ /**
+ * check to see if the audio hardware interface has been initialized.
+ * return status based on values defined in include/utils/Errors.h
+ */
+ virtual status_t initCheck() = 0;
+
+ /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
+ virtual status_t setVoiceVolume(float volume) = 0;
+
+ /**
+ * set the audio volume for all audio activities other than voice call.
+ * Range between 0.0 and 1.0. If any value other than NO_ERROR is returned,
+ * the software mixer will emulate this capability.
+ */
+ virtual status_t setMasterVolume(float volume) = 0;
+
+ /**
+ * Get the current master volume value for the HAL, if the HAL supports
+ * master volume control. AudioFlinger will query this value from the
+ * primary audio HAL when the service starts and use the value for setting
+ * the initial master volume across all HALs.
+ */
+ virtual status_t getMasterVolume(float* volume) = 0;
+
+ /**
+ * setMode is called when the audio mode changes. NORMAL mode is for
+ * standard audio playback, RINGTONE when a ringtone is playing, and IN_CALL
+ * when a call is in progress.
+ */
+ virtual status_t setMode(int mode) = 0;
+
+ // mic mute
+ virtual status_t setMicMute(bool state) = 0;
+ virtual status_t getMicMute(bool* state) = 0;
+
+ // set/get global audio parameters
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+ virtual String8 getParameters(const String8& keys) = 0;
+
+ // Returns audio input buffer size according to parameters passed or 0 if one of the
+ // parameters is not supported
+ virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0;
+
+ /** This method creates and opens the audio hardware output stream */
+ virtual AudioStreamOut* openOutputStream(uint32_t devices, int* format = 0,
+ uint32_t* channels = 0, uint32_t* sampleRate = 0,
+ status_t* status = 0) = 0;
+ virtual AudioStreamOut* openOutputStreamWithFlags(
+ uint32_t devices, audio_output_flags_t flags = (audio_output_flags_t)0, int* format = 0,
+ uint32_t* channels = 0, uint32_t* sampleRate = 0, status_t* status = 0) = 0;
+ virtual void closeOutputStream(AudioStreamOut* out) = 0;
+
+ /** This method creates and opens the audio hardware input stream */
+ virtual AudioStreamIn* openInputStream(uint32_t devices, int* format, uint32_t* channels,
+ uint32_t* sampleRate, status_t* status,
+ AudioSystem::audio_in_acoustics acoustics) = 0;
+ virtual void closeInputStream(AudioStreamIn* in) = 0;
+
+ /**This method dumps the state of the audio hardware */
+ virtual status_t dumpState(int fd, const Vector<String16>& args) = 0;
+
+ virtual status_t setMasterMute(bool muted) = 0;
+
+ static AudioHardwareInterface* create();
+
+ virtual int createAudioPatch(unsigned int num_sources, const struct audio_port_config* sources,
+ unsigned int num_sinks, const struct audio_port_config* sinks,
+ audio_patch_handle_t* handle) = 0;
+
+ virtual int releaseAudioPatch(audio_patch_handle_t handle) = 0;
+
+ virtual int getAudioPort(struct audio_port* port) = 0;
+
+ virtual int setAudioPortConfig(const struct audio_port_config* config) = 0;
+
+ protected:
+ virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+extern "C" AudioHardwareInterface* createAudioHardware(void);
+
+}; // namespace android_audio_legacy
+
+#endif // ANDROID_AUDIO_HARDWARE_INTERFACE_H
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioPolicyInterface.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioPolicyInterface.h
new file mode 100644
index 0000000..ec9c432
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioPolicyInterface.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIOPOLICYINTERFACE_H
+#define ANDROID_AUDIOPOLICYINTERFACE_H
+
+#include <media/AudioSystem.h>
+#include <media/ToneGenerator.h>
+#include <utils/String8.h>
+
+#include <hardware/audio_policy.h>
+#include <hardware_legacy/AudioSystemLegacy.h>
+
+namespace android_audio_legacy {
+using android::String8;
+using android::ToneGenerator;
+using android::Vector;
+
+// ----------------------------------------------------------------------------
+
+// The AudioPolicyInterface and AudioPolicyClientInterface classes define the communication
+// interfaces between the platform specific audio policy manager and Android generic audio policy
+// manager. The platform specific audio policy manager must implement methods of the
+// AudioPolicyInterface class. This implementation makes use of the AudioPolicyClientInterface to
+// control the activity and configuration of audio input and output streams.
+//
+// The platform specific audio policy manager is in charge of the audio routing and volume control
+// policies for a given platform.
+// The main roles of this module are:
+// - keep track of current system state (removable device connections, phone state, user
+// requests...). System state changes and user actions are notified to audio policy manager with
+// methods of the AudioPolicyInterface.
+// - process getOutput() queries received when AudioTrack objects are created: Those queries
+// return a handler on an output that has been selected, configured and opened by the audio policy
+// manager and that must be used by the AudioTrack when registering to the AudioFlinger with the
+// createTrack() method. When the AudioTrack object is released, a putOutput() query is received
+// and the audio policy manager can decide to close or reconfigure the output depending on other
+// streams using this output and current system state.
+// - similarly process getInput() and putInput() queries received from AudioRecord objects and
+// configure audio inputs.
+// - process volume control requests: the stream volume is converted from an index value (received
+// from UI) to a float value applicable to each output as a function of platform specific settings
+// and current output route (destination device). It also make sure that streams are not muted if
+// not allowed (e.g. camera shutter sound in some countries).
+//
+// The platform specific audio policy manager is provided as a shared library by platform vendors
+// (as for libaudio.so) and is linked with libaudioflinger.so
+
+// Audio Policy Manager Interface
+class AudioPolicyInterface {
+ public:
+ virtual ~AudioPolicyInterface() {}
+ //
+ // configuration functions
+ //
+
+ // indicate a change in device connection status
+ virtual status_t setDeviceConnectionState(audio_devices_t device,
+ AudioSystem::device_connection_state state,
+ const char* device_address) = 0;
+ // retrieve a device connection status
+ virtual AudioSystem::device_connection_state getDeviceConnectionState(
+ audio_devices_t device, const char* device_address) = 0;
+ // indicate a change in phone state. Valid phones states are defined by AudioSystem::audio_mode
+ virtual void setPhoneState(int state) = 0;
+ // force using a specific device category for the specified usage
+ virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) = 0;
+ // retrieve current device category forced for a given usage
+ virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage) = 0;
+ // set a system property (e.g. camera sound always audible)
+ virtual void setSystemProperty(const char* property, const char* value) = 0;
+ // check proper initialization
+ virtual status_t initCheck() = 0;
+
+ //
+ // Audio routing query functions
+ //
+
+ // request an output appropriate for playback of the supplied stream type and parameters
+ virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ AudioSystem::output_flags flags,
+ const audio_offload_info_t* offloadInfo) = 0;
+ // indicates to the audio policy manager that the output starts being used by corresponding
+ // stream.
+ virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream,
+ audio_session_t session = AUDIO_SESSION_NONE) = 0;
+ // indicates to the audio policy manager that the output stops being used by corresponding
+ // stream.
+ virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream,
+ audio_session_t session = AUDIO_SESSION_NONE) = 0;
+ // releases the output.
+ virtual void releaseOutput(audio_io_handle_t output) = 0;
+
+ // request an input appropriate for record from the supplied device with supplied parameters.
+ virtual audio_io_handle_t getInput(int inputSource, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ AudioSystem::audio_in_acoustics acoustics) = 0;
+ // indicates to the audio policy manager that the input starts being used.
+ virtual status_t startInput(audio_io_handle_t input) = 0;
+ // indicates to the audio policy manager that the input stops being used.
+ virtual status_t stopInput(audio_io_handle_t input) = 0;
+ // releases the input.
+ virtual void releaseInput(audio_io_handle_t input) = 0;
+
+ //
+ // volume control functions
+ //
+
+ // initialises stream volume conversion parameters by specifying volume index range.
+ virtual void initStreamVolume(AudioSystem::stream_type stream, int indexMin, int indexMax) = 0;
+
+ // sets the new stream volume at a level corresponding to the supplied index for the
+ // supplied device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
+ // setting volume for all devices
+ virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index,
+ audio_devices_t device) = 0;
+
+ // retrieve current volume index for the specified stream and the
+ // specified device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
+ // querying the volume of the active device.
+ virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int* index,
+ audio_devices_t device) = 0;
+
+ // return the strategy corresponding to a given stream type
+ virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream) = 0;
+
+ // return the enabled output devices for the given stream type
+ virtual audio_devices_t getDevicesForStream(AudioSystem::stream_type stream) = 0;
+
+ // Audio effect management
+ virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t* desc) = 0;
+ virtual status_t registerEffect(const effect_descriptor_t* desc, audio_io_handle_t io,
+ uint32_t strategy, audio_session_t session, int id) = 0;
+ virtual status_t unregisterEffect(int id) = 0;
+ virtual status_t setEffectEnabled(int id, bool enabled) = 0;
+
+ virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const = 0;
+ virtual bool isStreamActiveRemotely(int stream, uint32_t inPastMs = 0) const = 0;
+ virtual bool isSourceActive(audio_source_t source) const = 0;
+
+ // dump state
+ virtual status_t dump(int fd) = 0;
+
+ virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo) = 0;
+};
+
+// Audio Policy client Interface
+class AudioPolicyClientInterface {
+ public:
+ virtual ~AudioPolicyClientInterface() {}
+
+ //
+ // Audio HW module functions
+ //
+
+ // loads a HW module.
+ virtual audio_module_handle_t loadHwModule(const char* name) = 0;
+
+ //
+ // Audio output Control functions
+ //
+
+ // opens an audio output with the requested parameters. The parameter values can indicate to use
+ // the default values in case the audio policy manager has no specific requirements for the
+ // output being opened. When the function returns, the parameter values reflect the actual
+ // values used by the audio hardware output stream. The audio policy manager can check if the
+ // proposed parameters are suitable or not and act accordingly.
+ virtual audio_io_handle_t openOutput(audio_module_handle_t module, audio_devices_t* pDevices,
+ uint32_t* pSamplingRate, audio_format_t* pFormat,
+ audio_channel_mask_t* pChannelMask, uint32_t* pLatencyMs,
+ audio_output_flags_t flags,
+ const audio_offload_info_t* offloadInfo = NULL) = 0;
+ // creates a special output that is duplicated to the two outputs passed as arguments. The
+ // duplication is performed by a special mixer thread in the AudioFlinger.
+ virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
+ audio_io_handle_t output2) = 0;
+ // closes the output stream
+ virtual status_t closeOutput(audio_io_handle_t output) = 0;
+ // suspends the output. When an output is suspended, the corresponding audio hardware output
+ // stream is placed in standby and the AudioTracks attached to the mixer thread are still
+ // processed but the output mix is discarded.
+ virtual status_t suspendOutput(audio_io_handle_t output) = 0;
+ // restores a suspended output.
+ virtual status_t restoreOutput(audio_io_handle_t output) = 0;
+
+ //
+ // Audio input Control functions
+ //
+
+ // opens an audio input
+ virtual audio_io_handle_t openInput(audio_module_handle_t module, audio_devices_t* pDevices,
+ uint32_t* pSamplingRate, audio_format_t* pFormat,
+ audio_channel_mask_t* pChannelMask) = 0;
+ // closes an audio input
+ virtual status_t closeInput(audio_io_handle_t input) = 0;
+ //
+ // misc control functions
+ //
+
+ // set a stream volume for a particular output. For the same user setting, a given stream type
+ // can have different volumes for each output (destination device) it is attached to.
+ virtual status_t setStreamVolume(AudioSystem::stream_type stream, float volume,
+ audio_io_handle_t output, int delayMs = 0) = 0;
+
+ // invalidate a stream type, causing a reroute to an unspecified new output
+ virtual status_t invalidateStream(AudioSystem::stream_type stream) = 0;
+
+ // function enabling to send proprietary informations directly from audio policy manager to
+ // audio hardware interface.
+ virtual void setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs,
+ int delayMs = 0) = 0;
+ // function enabling to receive proprietary informations directly from audio hardware interface
+ // to audio policy manager.
+ virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) = 0;
+
+ // request the playback of a tone on the specified stream: used for instance to replace
+ // notification sounds when playing over a telephony device during a phone call.
+ virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream) = 0;
+ virtual status_t stopTone() = 0;
+
+ // set down link audio volume.
+ virtual status_t setVoiceVolume(float volume, int delayMs = 0) = 0;
+
+ // move effect to the specified output
+ virtual status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
+ audio_io_handle_t dstOutput) = 0;
+};
+
+extern "C" AudioPolicyInterface* createAudioPolicyManager(
+ AudioPolicyClientInterface* clientInterface);
+extern "C" void destroyAudioPolicyManager(AudioPolicyInterface* interface);
+
+}; // namespace android_audio_legacy
+
+#endif // ANDROID_AUDIOPOLICYINTERFACE_H
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioPolicyManagerBase.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioPolicyManagerBase.h
new file mode 100644
index 0000000..ccc0d32
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioPolicyManagerBase.h
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/config_utils.h>
+#include <cutils/misc.h>
+#include <hardware_legacy/AudioPolicyInterface.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
+#include <utils/Timers.h>
+
+namespace android_audio_legacy {
+using android::DefaultKeyedVector;
+using android::KeyedVector;
+using android::SortedVector;
+
+// ----------------------------------------------------------------------------
+
+#define MAX_DEVICE_ADDRESS_LEN 20
+// Attenuation applied to STRATEGY_SONIFICATION streams when a headset is connected: 6dB
+#define SONIFICATION_HEADSET_VOLUME_FACTOR 0.5
+// Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB
+#define SONIFICATION_HEADSET_VOLUME_MIN 0.016
+// Time in milliseconds during which we consider that music is still active after a music
+// track was stopped - see computeVolume()
+#define SONIFICATION_HEADSET_MUSIC_DELAY 5000
+// Time in milliseconds after media stopped playing during which we consider that the
+// sonification should be as unobtrusive as during the time media was playing.
+#define SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY 5000
+// Time in milliseconds during witch some streams are muted while the audio path
+// is switched
+#define MUTE_TIME_MS 2000
+
+#define NUM_TEST_OUTPUTS 5
+
+#define NUM_VOL_CURVE_KNEES 2
+
+// Default minimum length allowed for offloading a compressed track
+// Can be overridden by the audio.offload.min.duration.secs property
+#define OFFLOAD_DEFAULT_MIN_DURATION_SECS 60
+
+// ----------------------------------------------------------------------------
+// AudioPolicyManagerBase implements audio policy manager behavior common to all platforms.
+// Each platform must implement an AudioPolicyManager class derived from AudioPolicyManagerBase
+// and override methods for which the platform specific behavior differs from the implementation
+// in AudioPolicyManagerBase. Even if no specific behavior is required, the AudioPolicyManager
+// class must be implemented as well as the class factory function createAudioPolicyManager()
+// and provided in a shared library libaudiopolicy.so.
+// ----------------------------------------------------------------------------
+
+class AudioPolicyManagerBase : public AudioPolicyInterface
+#ifdef AUDIO_POLICY_TEST
+ ,
+ public Thread
+#endif // AUDIO_POLICY_TEST
+{
+
+ public:
+ AudioPolicyManagerBase(AudioPolicyClientInterface* clientInterface);
+ virtual ~AudioPolicyManagerBase();
+
+ // AudioPolicyInterface
+ virtual status_t setDeviceConnectionState(audio_devices_t device,
+ AudioSystem::device_connection_state state,
+ const char* device_address);
+ virtual AudioSystem::device_connection_state getDeviceConnectionState(
+ audio_devices_t device, const char* device_address);
+ virtual void setPhoneState(int state);
+ virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config);
+ virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage);
+ virtual void setSystemProperty(const char* property, const char* value);
+ virtual status_t initCheck();
+ virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ AudioSystem::output_flags flags,
+ const audio_offload_info_t* offloadInfo);
+ virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream,
+ audio_session_t session = AUDIO_SESSION_NONE);
+ virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream,
+ audio_session_t session = AUDIO_SESSION_NONE);
+ virtual void releaseOutput(audio_io_handle_t output);
+ virtual audio_io_handle_t getInput(int inputSource, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ AudioSystem::audio_in_acoustics acoustics);
+
+ // indicates to the audio policy manager that the input starts being used.
+ virtual status_t startInput(audio_io_handle_t input);
+
+ // indicates to the audio policy manager that the input stops being used.
+ virtual status_t stopInput(audio_io_handle_t input);
+ virtual void releaseInput(audio_io_handle_t input);
+ virtual void closeAllInputs();
+ virtual void initStreamVolume(AudioSystem::stream_type stream, int indexMin, int indexMax);
+ virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index,
+ audio_devices_t device);
+ virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int* index,
+ audio_devices_t device);
+
+ // return the strategy corresponding to a given stream type
+ virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream);
+
+ // return the enabled output devices for the given stream type
+ virtual audio_devices_t getDevicesForStream(AudioSystem::stream_type stream);
+
+ virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t* desc = NULL);
+ virtual status_t registerEffect(const effect_descriptor_t* desc, audio_io_handle_t io,
+ uint32_t strategy, audio_session_t session, int id);
+ virtual status_t unregisterEffect(int id);
+ virtual status_t setEffectEnabled(int id, bool enabled);
+
+ virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const;
+ // return whether a stream is playing remotely, override to change the definition of
+ // local/remote playback, used for instance by notification manager to not make
+ // media players lose audio focus when not playing locally
+ virtual bool isStreamActiveRemotely(int stream, uint32_t inPastMs = 0) const;
+ virtual bool isSourceActive(audio_source_t source) const;
+
+ virtual status_t dump(int fd);
+
+ virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
+
+ protected:
+ enum routing_strategy {
+ STRATEGY_MEDIA,
+ STRATEGY_PHONE,
+ STRATEGY_SONIFICATION,
+ STRATEGY_SONIFICATION_RESPECTFUL,
+ STRATEGY_DTMF,
+ STRATEGY_ENFORCED_AUDIBLE,
+ NUM_STRATEGIES
+ };
+
+ // 4 points to define the volume attenuation curve, each characterized by the volume
+ // index (from 0 to 100) at which they apply, and the attenuation in dB at that index.
+ // we use 100 steps to avoid rounding errors when computing the volume in volIndexToAmpl()
+
+ enum { VOLMIN = 0, VOLKNEE1 = 1, VOLKNEE2 = 2, VOLMAX = 3, VOLCNT = 4 };
+
+ class VolumeCurvePoint {
+ public:
+ int mIndex;
+ float mDBAttenuation;
+ };
+
+ // device categories used for volume curve management.
+ enum device_category {
+ DEVICE_CATEGORY_HEADSET,
+ DEVICE_CATEGORY_SPEAKER,
+ DEVICE_CATEGORY_EARPIECE,
+ DEVICE_CATEGORY_CNT
+ };
+
+ class IOProfile;
+
+ class HwModule {
+ public:
+ HwModule(const char* name);
+ ~HwModule();
+
+ void dump(int fd);
+
+ const char* const mName; // base name of the audio HW module (primary, a2dp ...)
+ audio_module_handle_t mHandle;
+ Vector<IOProfile*> mOutputProfiles; // output profiles exposed by this module
+ Vector<IOProfile*> mInputProfiles; // input profiles exposed by this module
+ };
+
+ // the IOProfile class describes the capabilities of an output or input stream.
+ // It is currently assumed that all combination of listed parameters are supported.
+ // It is used by the policy manager to determine if an output or input is suitable for
+ // a given use case, open/close it accordingly and connect/disconnect audio tracks
+ // to/from it.
+ class IOProfile {
+ public:
+ IOProfile(HwModule* module);
+ ~IOProfile();
+
+ bool isCompatibleProfile(audio_devices_t device, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ audio_output_flags_t flags) const;
+
+ void dump(int fd);
+ void log();
+
+ // by convention, "0' in the first entry in mSamplingRates, mChannelMasks or mFormats
+ // indicates the supported parameters should be read from the output stream
+ // after it is opened for the first time
+ Vector<uint32_t> mSamplingRates; // supported sampling rates
+ Vector<audio_channel_mask_t> mChannelMasks; // supported channel masks
+ Vector<audio_format_t> mFormats; // supported audio formats
+ audio_devices_t mSupportedDevices; // supported devices (devices this output can be
+ // routed to)
+ audio_output_flags_t mFlags; // attribute flags (e.g primary output,
+ // direct output...). For outputs only.
+ HwModule* mModule; // audio HW module exposing this I/O stream
+ };
+
+ // default volume curve
+ static const VolumeCurvePoint sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ // default volume curve for media strategy
+ static const VolumeCurvePoint sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ // volume curve for media strategy on speakers
+ static const VolumeCurvePoint sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ // volume curve for sonification strategy on speakers
+ static const VolumeCurvePoint sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint
+ sSpeakerSonificationVolumeCurveDrc[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sDefaultSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sDefaultSystemVolumeCurveDrc[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sHeadsetSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sDefaultVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ // default volume curves per stream and device category. See initializeVolumeCurves()
+ static const VolumeCurvePoint* sVolumeProfiles[AudioSystem::NUM_STREAM_TYPES]
+ [DEVICE_CATEGORY_CNT];
+
+ // descriptor for audio outputs. Used to maintain current configuration of each opened audio
+ // output and keep track of the usage of this output by each audio stream type.
+ class AudioOutputDescriptor {
+ public:
+ AudioOutputDescriptor(const IOProfile* profile);
+
+ status_t dump(int fd);
+
+ audio_devices_t device() const;
+ void changeRefCount(AudioSystem::stream_type stream, int delta);
+
+ bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
+ audio_devices_t supportedDevices();
+ uint32_t latency();
+ bool sharesHwModuleWith(const AudioOutputDescriptor* outputDesc);
+ bool isActive(uint32_t inPastMs = 0) const;
+ bool isStreamActive(AudioSystem::stream_type stream, uint32_t inPastMs = 0,
+ nsecs_t sysTime = 0) const;
+ bool isStrategyActive(routing_strategy strategy, uint32_t inPastMs = 0,
+ nsecs_t sysTime = 0) const;
+
+ audio_io_handle_t mId; // output handle
+ uint32_t mSamplingRate; //
+ audio_format_t mFormat; //
+ audio_channel_mask_t mChannelMask; // output configuration
+ uint32_t mLatency; //
+ audio_output_flags_t mFlags; //
+ audio_devices_t mDevice; // current device this output is routed to
+ uint32_t mRefCount[AudioSystem::NUM_STREAM_TYPES]; // number of streams of each type using
+ // this output
+ nsecs_t mStopTime[AudioSystem::NUM_STREAM_TYPES];
+ AudioOutputDescriptor* mOutput1; // used by duplicated outputs: first output
+ AudioOutputDescriptor* mOutput2; // used by duplicated outputs: second output
+ float mCurVolume[AudioSystem::NUM_STREAM_TYPES]; // current stream volume
+ int mMuteCount[AudioSystem::NUM_STREAM_TYPES]; // mute request counter
+ const IOProfile* mProfile; // I/O profile this output derives from
+ bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
+ // device selection. See
+ // checkDeviceMuteStrategies()
+ uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
+ bool mForceRouting; // Next routing for this output will be forced as current device routed
+ // is null
+ };
+
+ // descriptor for audio inputs. Used to maintain current configuration of each opened audio
+ // input and keep track of the usage of this input.
+ class AudioInputDescriptor {
+ public:
+ AudioInputDescriptor(const IOProfile* profile);
+
+ status_t dump(int fd);
+
+ audio_io_handle_t mId; // input handle
+ uint32_t mSamplingRate; //
+ audio_format_t mFormat; // input configuration
+ audio_channel_mask_t mChannelMask; //
+ audio_devices_t mDevice; // current device this input is routed to
+ uint32_t mRefCount; // number of AudioRecord clients using this output
+ int mInputSource; // input source selected by application (mediarecorder.h)
+ const IOProfile* mProfile; // I/O profile this output derives from
+ };
+
+ // stream descriptor used for volume control
+ class StreamDescriptor {
+ public:
+ StreamDescriptor();
+
+ int getVolumeIndex(audio_devices_t device);
+ void dump(int fd);
+
+ int mIndexMin; // min volume index
+ int mIndexMax; // max volume index
+ KeyedVector<audio_devices_t, int> mIndexCur; // current volume index per device
+ bool mCanBeMuted; // true is the stream can be muted
+
+ const VolumeCurvePoint* mVolumeCurve[DEVICE_CATEGORY_CNT];
+ };
+
+ // stream descriptor used for volume control
+ class EffectDescriptor {
+ public:
+ status_t dump(int fd);
+
+ int mIo; // io the effect is attached to
+ routing_strategy mStrategy; // routing strategy the effect is associated to
+ audio_session_t mSession; // audio session the effect is on
+ effect_descriptor_t mDesc; // effect descriptor
+ bool mEnabled; // enabled state: CPU load being used or not
+ };
+
+ void addOutput(audio_io_handle_t id, AudioOutputDescriptor* outputDesc);
+ void addInput(audio_io_handle_t id, AudioInputDescriptor* inputDesc);
+
+ // return the strategy corresponding to a given stream type
+ static routing_strategy getStrategy(AudioSystem::stream_type stream);
+
+ // return appropriate device for streams handled by the specified strategy according to current
+ // phone state, connected devices...
+ // if fromCache is true, the device is returned from mDeviceForStrategy[],
+ // otherwise it is determine by current state
+ // (device connected,phone state, force use, a2dp output...)
+ // This allows to:
+ // 1 speed up process when the state is stable (when starting or stopping an output)
+ // 2 access to either current device selection (fromCache == true) or
+ // "future" device selection (fromCache == false) when called from a context
+ // where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
+ // before updateDevicesAndOutputs() is called.
+ virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy, bool fromCache);
+
+ // change the route of the specified output. Returns the number of ms we have slept to
+ // allow new routing to take effect in certain cases.
+ uint32_t setOutputDevice(audio_io_handle_t output, audio_devices_t device, bool force = false,
+ int delayMs = 0);
+
+ // select input device corresponding to requested audio source
+ virtual audio_devices_t getDeviceForInputSource(int inputSource);
+
+ // return io handle of active input or 0 if no input is active
+ // Only considers inputs from physical devices (e.g. main mic, headset mic) when
+ // ignoreVirtualInputs is true.
+ audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true);
+
+ // initialize volume curves for each strategy and device category
+ void initializeVolumeCurves();
+
+ // compute the actual volume for a given stream according to the requested index and a
+ // particular device
+ virtual float computeVolume(int stream, int index, audio_io_handle_t output,
+ audio_devices_t device);
+
+ // check that volume change is permitted, compute and send new volume to audio hardware
+ status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output,
+ audio_devices_t device, int delayMs = 0, bool force = false);
+
+ // apply all stream volumes to the specified output and device
+ void applyStreamVolumes(audio_io_handle_t output, audio_devices_t device, int delayMs = 0,
+ bool force = false);
+
+ // Mute or unmute all streams handled by the specified strategy on the specified output
+ void setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output,
+ int delayMs = 0, audio_devices_t device = (audio_devices_t)0);
+
+ // Mute or unmute the stream on the specified output
+ void setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs = 0,
+ audio_devices_t device = (audio_devices_t)0);
+
+ // handle special cases for sonification strategy while in call: mute streams or replace by
+ // a special tone in the device used for communication
+ void handleIncallSonification(int stream, bool starting, bool stateChange);
+
+ // true if device is in a telephony or VoIP call
+ virtual bool isInCall();
+
+ // true if given state represents a device in a telephony or VoIP call
+ virtual bool isStateInCall(int state);
+
+ // when a device is connected, checks if an open output can be routed
+ // to this device. If none is open, tries to open one of the available outputs.
+ // Returns an output suitable to this device or 0.
+ // when a device is disconnected, checks if an output is not used any more and
+ // returns its handle if any.
+ // transfers the audio tracks and effects from one output thread to another accordingly.
+ status_t checkOutputsForDevice(audio_devices_t device,
+ AudioSystem::device_connection_state state,
+ SortedVector<audio_io_handle_t>& outputs,
+ const String8 paramStr);
+
+ status_t checkInputsForDevice(audio_devices_t device,
+ AudioSystem::device_connection_state state,
+ SortedVector<audio_io_handle_t>& inputs, const String8 paramStr);
+
+ // close an output and its companion duplicating output.
+ void closeOutput(audio_io_handle_t output);
+
+ // checks and if necessary changes outputs used for all strategies.
+ // must be called every time a condition that affects the output choice for a given strategy
+ // changes: connected device, phone state, force use...
+ // Must be called before updateDevicesAndOutputs()
+ void checkOutputForStrategy(routing_strategy strategy);
+
+ // Same as checkOutputForStrategy() but for a all strategies in order of priority
+ void checkOutputForAllStrategies();
+
+ // manages A2DP output suspend/restore according to phone state and BT SCO usage
+ void checkA2dpSuspend();
+
+ // returns the A2DP output handle if it is open or 0 otherwise
+ audio_io_handle_t getA2dpOutput();
+
+ // selects the most appropriate device on output for current state
+ // must be called every time a condition that affects the device choice for a given output is
+ // changed: connected device, phone state, force use, output start, output stop..
+ // see getDeviceForStrategy() for the use of fromCache parameter
+
+ audio_devices_t getNewDevice(audio_io_handle_t output, bool fromCache);
+ // updates cache of device used by all strategies (mDeviceForStrategy[])
+ // must be called every time a condition that affects the device choice for a given strategy is
+ // changed: connected device, phone state, force use...
+ // cached values are used by getDeviceForStrategy() if parameter fromCache is true.
+ // Must be called after checkOutputForAllStrategies()
+
+ void updateDevicesAndOutputs();
+
+ virtual uint32_t getMaxEffectsCpuLoad();
+ virtual uint32_t getMaxEffectsMemory();
+#ifdef AUDIO_POLICY_TEST
+ virtual bool threadLoop();
+ void exit();
+ int testOutputIndex(audio_io_handle_t output);
+#endif // AUDIO_POLICY_TEST
+
+ status_t setEffectEnabled(EffectDescriptor* pDesc, bool enabled);
+
+ // returns the category the device belongs to with regard to volume curve management
+ static device_category getDeviceCategory(audio_devices_t device);
+
+ // extract one device relevant for volume control from multiple device selection
+ static audio_devices_t getDeviceForVolume(audio_devices_t device);
+
+ SortedVector<audio_io_handle_t> getOutputsForDevice(
+ audio_devices_t device,
+ DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor*> openOutputs);
+ bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
+ SortedVector<audio_io_handle_t>& outputs2);
+
+ // mute/unmute strategies using an incompatible device combination
+ // if muting, wait for the audio in pcm buffer to be drained before proceeding
+ // if unmuting, unmute only after the specified delay
+ // Returns the number of ms waited
+ uint32_t checkDeviceMuteStrategies(AudioOutputDescriptor* outputDesc,
+ audio_devices_t prevDevice, uint32_t delayMs);
+
+ audio_io_handle_t selectOutput(const SortedVector<audio_io_handle_t>& outputs,
+ AudioSystem::output_flags flags);
+ IOProfile* getInputProfile(audio_devices_t device, uint32_t samplingRate, audio_format_t format,
+ audio_channel_mask_t channelMask);
+ IOProfile* getProfileForDirectOutput(audio_devices_t device, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ audio_output_flags_t flags);
+
+ audio_io_handle_t selectOutputForEffects(const SortedVector<audio_io_handle_t>& outputs);
+
+ bool isNonOffloadableEffectEnabled();
+
+ //
+ // Audio policy configuration file parsing (audio_policy.conf)
+ //
+ static uint32_t stringToEnum(const struct StringToEnum* table, size_t size, const char* name);
+ static bool stringToBool(const char* value);
+ static audio_output_flags_t parseFlagNames(char* name);
+ static audio_devices_t parseDeviceNames(char* name);
+ void loadSamplingRates(char* name, IOProfile* profile);
+ void loadFormats(char* name, IOProfile* profile);
+ void loadOutChannels(char* name, IOProfile* profile);
+ void loadInChannels(char* name, IOProfile* profile);
+ status_t loadOutput(cnode* root, HwModule* module);
+ status_t loadInput(cnode* root, HwModule* module);
+ void loadHwModule(cnode* root);
+ void loadHwModules(cnode* root);
+ void loadGlobalConfig(cnode* root);
+ status_t loadAudioPolicyConfig(const char* path);
+ void defaultAudioPolicyConfig(void);
+
+ AudioPolicyClientInterface* mpClientInterface; // audio policy client interface
+ audio_io_handle_t mPrimaryOutput; // primary output handle
+ // list of descriptors for outputs currently opened
+ DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor*> mOutputs;
+ // copy of mOutputs before setDeviceConnectionState() opens new outputs
+ // reset to mOutputs when updateDevicesAndOutputs() is called.
+ DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor*> mPreviousOutputs;
+
+ // list of input descriptors currently opened
+ DefaultKeyedVector<audio_io_handle_t, AudioInputDescriptor*> mInputs;
+
+ audio_devices_t mAvailableOutputDevices; // bit field of all available output devices
+ audio_devices_t mAvailableInputDevices; // bit field of all available input devices
+ // without AUDIO_DEVICE_BIT_IN to allow direct bit
+ // field comparisons
+ int mPhoneState; // current phone state
+ AudioSystem::forced_config
+ mForceUse[AudioSystem::NUM_FORCE_USE]; // current forced use configuration
+
+ StreamDescriptor
+ mStreams[AudioSystem::NUM_STREAM_TYPES]; // stream descriptors for volume control
+ String8 mA2dpDeviceAddress; // A2DP device MAC address
+ String8 mScoDeviceAddress; // SCO device MAC address
+ String8 mUsbOutCardAndDevice; // USB audio ALSA card and device numbers:
+ // card=<card_number>;device=<><device_number>
+ bool mLimitRingtoneVolume; // limit ringtone volume to music volume if headset connected
+ audio_devices_t mDeviceForStrategy[NUM_STRATEGIES];
+ float mLastVoiceVolume; // last voice volume value sent to audio HAL
+
+ // Maximum CPU load allocated to audio effects in 0.1 MIPS (ARMv5TE, 0 WS memory) units
+ static const uint32_t MAX_EFFECTS_CPU_LOAD = 1000;
+ // Maximum memory allocated to audio effects in KB
+ static const uint32_t MAX_EFFECTS_MEMORY = 512;
+ uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects
+ uint32_t mTotalEffectsMemory; // current memory used by effects
+ KeyedVector<int, EffectDescriptor*> mEffects; // list of registered audio effects
+ bool mA2dpSuspended; // true if A2DP output is suspended
+ bool mHasA2dp; // true on platforms with support for bluetooth A2DP
+ bool mHasUsb; // true on platforms with support for USB audio
+ bool mHasRemoteSubmix; // true on platforms with support for remote presentation of a submix
+ audio_devices_t mAttachedOutputDevices; // output devices always available on the platform
+ audio_devices_t mDefaultOutputDevice; // output device selected by default at boot time
+ // (must be in mAttachedOutputDevices)
+ bool mSpeakerDrcEnabled; // true on devices that use DRC on the DEVICE_CATEGORY_SPEAKER path
+ // to boost soft sounds, used to adjust volume curves accordingly
+
+ Vector<HwModule*> mHwModules;
+
+#ifdef AUDIO_POLICY_TEST
+ Mutex mLock;
+ Condition mWaitWorkCV;
+
+ int mCurOutput;
+ bool mDirectOutput;
+ audio_io_handle_t mTestOutputs[NUM_TEST_OUTPUTS];
+ int mTestInput;
+ uint32_t mTestDevice;
+ uint32_t mTestSamplingRate;
+ uint32_t mTestFormat;
+ uint32_t mTestChannels;
+ uint32_t mTestLatencyMs;
+#endif // AUDIO_POLICY_TEST
+
+ private:
+ static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
+ int indexInUi);
+ // updates device caching and output for streams that can influence the
+ // routing of notifications
+ void handleNotificationRoutingForStream(AudioSystem::stream_type stream);
+ static bool isVirtualInputDevice(audio_devices_t device);
+};
+
+}; // namespace android_audio_legacy
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioSystemLegacy.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioSystemLegacy.h
new file mode 100644
index 0000000..943b0db
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/AudioSystemLegacy.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIOSYSTEM_LEGACY_H_
+#define ANDROID_AUDIOSYSTEM_LEGACY_H_
+
+#include <cutils/bitops.h>
+#include <media/AudioParameter.h>
+#include <utils/Errors.h>
+
+#include <system/audio.h>
+#include <system/audio_policy.h>
+
+namespace android_audio_legacy {
+
+using android::AudioParameter;
+using android::status_t;
+
+enum {
+ OK = android::OK,
+ NO_ERROR = android::NO_ERROR,
+
+ UNKNOWN_ERROR = android::UNKNOWN_ERROR,
+
+ NO_MEMORY = android::NO_MEMORY,
+ INVALID_OPERATION = android::INVALID_OPERATION,
+ BAD_VALUE = android::BAD_VALUE,
+ BAD_TYPE = android::BAD_TYPE,
+ NAME_NOT_FOUND = android::NAME_NOT_FOUND,
+ PERMISSION_DENIED = android::PERMISSION_DENIED,
+ NO_INIT = android::NO_INIT,
+ ALREADY_EXISTS = android::ALREADY_EXISTS,
+ DEAD_OBJECT = android::DEAD_OBJECT,
+ FAILED_TRANSACTION = android::FAILED_TRANSACTION,
+ BAD_INDEX = android::BAD_INDEX,
+ NOT_ENOUGH_DATA = android::NOT_ENOUGH_DATA,
+ WOULD_BLOCK = android::WOULD_BLOCK,
+ TIMED_OUT = android::TIMED_OUT,
+ UNKNOWN_TRANSACTION = android::UNKNOWN_TRANSACTION,
+};
+
+enum audio_source {
+ AUDIO_SOURCE_DEFAULT = 0,
+ AUDIO_SOURCE_MIC = 1,
+ AUDIO_SOURCE_VOICE_UPLINK = 2,
+ AUDIO_SOURCE_VOICE_DOWNLINK = 3,
+ AUDIO_SOURCE_VOICE_CALL = 4,
+ AUDIO_SOURCE_CAMCORDER = 5,
+ AUDIO_SOURCE_VOICE_RECOGNITION = 6,
+ AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
+ AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_COMMUNICATION,
+
+ AUDIO_SOURCE_LIST_END // must be last - used to validate audio source type
+};
+
+class AudioSystem {
+ public:
+#if 1
+ enum stream_type {
+ DEFAULT = -1,
+ VOICE_CALL = 0,
+ SYSTEM = 1,
+ RING = 2,
+ MUSIC = 3,
+ ALARM = 4,
+ NOTIFICATION = 5,
+ BLUETOOTH_SCO = 6,
+ ENFORCED_AUDIBLE = 7, // Sounds that cannot be muted by user and must be routed to speaker
+ DTMF = 8,
+ TTS = 9,
+ NUM_STREAM_TYPES
+ };
+
+ // Audio sub formats (see AudioSystem::audio_format).
+ enum pcm_sub_format {
+ PCM_SUB_16_BIT = 0x1, // must be 1 for backward compatibility
+ PCM_SUB_8_BIT = 0x2, // must be 2 for backward compatibility
+ };
+
+ enum audio_sessions {
+ SESSION_OUTPUT_STAGE = AUDIO_SESSION_OUTPUT_STAGE,
+ SESSION_OUTPUT_MIX = AUDIO_SESSION_OUTPUT_MIX,
+ };
+
+ // MP3 sub format field definition : can use 11 LSBs in the same way as MP3 frame header to
+ // specify bit rate, stereo mode, version...
+ enum mp3_sub_format {
+ // TODO
+ };
+
+ // AMR NB/WB sub format field definition: specify frame block interleaving, bandwidth efficient
+ // or octet aligned, encoding mode for recording...
+ enum amr_sub_format {
+ // TODO
+ };
+
+ // AAC sub format field definition: specify profile or bitrate for recording...
+ enum aac_sub_format {
+ // TODO
+ };
+
+ // VORBIS sub format field definition: specify quality for recording...
+ enum vorbis_sub_format {
+ // TODO
+ };
+
+ // Audio format consists in a main format field (upper 8 bits) and a sub format field (lower 24
+ // bits). The main format indicates the main codec type. The sub format field indicates options
+ // and parameters for each format. The sub format is mainly used for record to indicate for
+ // instance the requested bitrate or profile. It can also be used for certain formats to give
+ // informations not present in the encoded audio stream (e.g. octet alignement for AMR).
+ enum audio_format {
+ INVALID_FORMAT = -1,
+ FORMAT_DEFAULT = 0,
+ PCM = 0x00000000, // must be 0 for backward compatibility
+ MP3 = 0x01000000,
+ AMR_NB = 0x02000000,
+ AMR_WB = 0x03000000,
+ AAC = 0x04000000,
+ HE_AAC_V1 = 0x05000000,
+ HE_AAC_V2 = 0x06000000,
+ VORBIS = 0x07000000,
+ MAIN_FORMAT_MASK = 0xFF000000,
+ SUB_FORMAT_MASK = 0x00FFFFFF,
+ // Aliases
+ PCM_16_BIT = (PCM | PCM_SUB_16_BIT),
+ PCM_8_BIT = (PCM | PCM_SUB_8_BIT)
+ };
+
+ enum audio_channels {
+ // output channels
+ CHANNEL_OUT_FRONT_LEFT = 0x1,
+ CHANNEL_OUT_FRONT_RIGHT = 0x2,
+ CHANNEL_OUT_FRONT_CENTER = 0x4,
+ CHANNEL_OUT_LOW_FREQUENCY = 0x8,
+ CHANNEL_OUT_BACK_LEFT = 0x10,
+ CHANNEL_OUT_BACK_RIGHT = 0x20,
+ CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40,
+ CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80,
+ CHANNEL_OUT_BACK_CENTER = 0x100,
+ CHANNEL_OUT_SIDE_LEFT = 0x200,
+ CHANNEL_OUT_SIDE_RIGHT = 0x400,
+ CHANNEL_OUT_TOP_CENTER = 0x800,
+ CHANNEL_OUT_TOP_FRONT_LEFT = 0x1000,
+ CHANNEL_OUT_TOP_FRONT_CENTER = 0x2000,
+ CHANNEL_OUT_TOP_FRONT_RIGHT = 0x4000,
+ CHANNEL_OUT_TOP_BACK_LEFT = 0x8000,
+ CHANNEL_OUT_TOP_BACK_CENTER = 0x10000,
+ CHANNEL_OUT_TOP_BACK_RIGHT = 0x20000,
+
+ CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT,
+ CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT),
+ CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+ CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
+ CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+ CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER),
+ CHANNEL_OUT_5POINT1 =
+ (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | CHANNEL_OUT_FRONT_CENTER |
+ CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
+ // matches the correct AudioFormat.CHANNEL_OUT_7POINT1_SURROUND definition for 7.1
+ CHANNEL_OUT_7POINT1 =
+ (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | CHANNEL_OUT_FRONT_CENTER |
+ CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
+ CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT),
+ CHANNEL_OUT_ALL =
+ (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | CHANNEL_OUT_FRONT_CENTER |
+ CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
+ CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
+ CHANNEL_OUT_BACK_CENTER | CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT |
+ CHANNEL_OUT_TOP_CENTER | CHANNEL_OUT_TOP_FRONT_LEFT |
+ CHANNEL_OUT_TOP_FRONT_CENTER | CHANNEL_OUT_TOP_FRONT_RIGHT |
+ CHANNEL_OUT_TOP_BACK_LEFT | CHANNEL_OUT_TOP_BACK_CENTER |
+ CHANNEL_OUT_TOP_BACK_RIGHT),
+
+ // input channels
+ CHANNEL_IN_LEFT = 0x4,
+ CHANNEL_IN_RIGHT = 0x8,
+ CHANNEL_IN_FRONT = 0x10,
+ CHANNEL_IN_BACK = 0x20,
+ CHANNEL_IN_LEFT_PROCESSED = 0x40,
+ CHANNEL_IN_RIGHT_PROCESSED = 0x80,
+ CHANNEL_IN_FRONT_PROCESSED = 0x100,
+ CHANNEL_IN_BACK_PROCESSED = 0x200,
+ CHANNEL_IN_PRESSURE = 0x400,
+ CHANNEL_IN_X_AXIS = 0x800,
+ CHANNEL_IN_Y_AXIS = 0x1000,
+ CHANNEL_IN_Z_AXIS = 0x2000,
+ CHANNEL_IN_VOICE_UPLINK = 0x4000,
+ CHANNEL_IN_VOICE_DNLINK = 0x8000,
+ CHANNEL_IN_MONO = CHANNEL_IN_FRONT,
+ CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT),
+ CHANNEL_IN_ALL = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT | CHANNEL_IN_FRONT | CHANNEL_IN_BACK |
+ CHANNEL_IN_LEFT_PROCESSED | CHANNEL_IN_RIGHT_PROCESSED |
+ CHANNEL_IN_FRONT_PROCESSED | CHANNEL_IN_BACK_PROCESSED |
+ CHANNEL_IN_PRESSURE | CHANNEL_IN_X_AXIS | CHANNEL_IN_Y_AXIS |
+ CHANNEL_IN_Z_AXIS | CHANNEL_IN_VOICE_UPLINK | CHANNEL_IN_VOICE_DNLINK)
+ };
+
+ enum audio_mode {
+ MODE_INVALID = -2,
+ MODE_CURRENT = -1,
+ MODE_NORMAL = 0,
+ MODE_RINGTONE,
+ MODE_IN_CALL,
+ MODE_IN_COMMUNICATION,
+ NUM_MODES // not a valid entry, denotes end-of-list
+ };
+
+ enum audio_in_acoustics {
+ AGC_ENABLE = 0x0001,
+ AGC_DISABLE = 0,
+ NS_ENABLE = 0x0002,
+ NS_DISABLE = 0,
+ TX_IIR_ENABLE = 0x0004,
+ TX_DISABLE = 0
+ };
+
+ // DO NOT USE: the "audio_devices" enumeration below is obsolete, use type "audio_devices_t" and
+ // audio device enumeration from system/audio.h instead.
+ enum audio_devices {
+ // output devices
+ DEVICE_OUT_EARPIECE = 0x1,
+ DEVICE_OUT_SPEAKER = 0x2,
+ DEVICE_OUT_WIRED_HEADSET = 0x4,
+ DEVICE_OUT_WIRED_HEADPHONE = 0x8,
+ DEVICE_OUT_BLUETOOTH_SCO = 0x10,
+ DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
+ DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
+ DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
+ DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
+ DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
+ DEVICE_OUT_AUX_DIGITAL = 0x400,
+ DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800,
+ DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000,
+ DEVICE_OUT_DEFAULT = 0x8000,
+ DEVICE_OUT_ALL =
+ (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET |
+ DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO |
+ DEVICE_OUT_BLUETOOTH_SCO_HEADSET | DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
+ DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+ DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL |
+ DEVICE_OUT_ANLG_DOCK_HEADSET | DEVICE_OUT_DGTL_DOCK_HEADSET | DEVICE_OUT_DEFAULT),
+ DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+ DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
+
+ // input devices
+ DEVICE_IN_COMMUNICATION = 0x10000,
+ DEVICE_IN_AMBIENT = 0x20000,
+ DEVICE_IN_BUILTIN_MIC = 0x40000,
+ DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000,
+ DEVICE_IN_WIRED_HEADSET = 0x100000,
+ DEVICE_IN_AUX_DIGITAL = 0x200000,
+ DEVICE_IN_VOICE_CALL = 0x400000,
+ DEVICE_IN_BACK_MIC = 0x800000,
+ DEVICE_IN_DEFAULT = 0x80000000,
+
+ DEVICE_IN_ALL =
+ (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC |
+ DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL |
+ DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | DEVICE_IN_DEFAULT)
+ };
+
+ // request to open a direct output with getOutput() (by opposition to sharing an output with
+ // other AudioTracks)
+ enum output_flags { OUTPUT_FLAG_INDIRECT = 0x0, OUTPUT_FLAG_DIRECT = 0x1 };
+
+ // device categories used for setForceUse()
+ enum forced_config {
+ FORCE_NONE,
+ FORCE_SPEAKER,
+ FORCE_HEADPHONES,
+ FORCE_BT_SCO,
+ FORCE_BT_A2DP,
+ FORCE_WIRED_ACCESSORY,
+ FORCE_BT_CAR_DOCK,
+ FORCE_BT_DESK_DOCK,
+ FORCE_ANALOG_DOCK,
+ FORCE_DIGITAL_DOCK,
+ FORCE_NO_BT_A2DP,
+ FORCE_SYSTEM_ENFORCED,
+ NUM_FORCE_CONFIG,
+ FORCE_DEFAULT = FORCE_NONE
+ };
+
+ // usages used for setForceUse()
+ enum force_use {
+ FOR_COMMUNICATION,
+ FOR_MEDIA,
+ FOR_RECORD,
+ FOR_DOCK,
+ FOR_SYSTEM,
+ NUM_FORCE_USE
+ };
+
+ //
+ // AudioPolicyService interface
+ //
+
+ // device connection states used for setDeviceConnectionState()
+ enum device_connection_state {
+ DEVICE_STATE_UNAVAILABLE,
+ DEVICE_STATE_AVAILABLE,
+ NUM_DEVICE_STATES
+ };
+
+#endif
+
+ static uint32_t popCount(uint32_t u) { return popcount(u); }
+
+#if 1
+ static bool isOutputDevice(audio_devices device) {
+ if ((popcount(device) == 1) && ((device & ~DEVICE_OUT_ALL) == 0))
+ return true;
+ else
+ return false;
+ }
+ static bool isInputDevice(audio_devices device) {
+ if ((popcount(device) == 1) && ((device & ~DEVICE_IN_ALL) == 0))
+ return true;
+ else
+ return false;
+ }
+ static bool isA2dpDevice(audio_devices device) {
+ return audio_is_a2dp_device((audio_devices_t)device);
+ }
+ static bool isBluetoothScoDevice(audio_devices device) {
+ return audio_is_bluetooth_sco_device((audio_devices_t)device);
+ }
+ static bool isValidFormat(uint32_t format) {
+ return audio_is_valid_format((audio_format_t)format);
+ }
+ static bool isLinearPCM(uint32_t format) { return audio_is_linear_pcm((audio_format_t)format); }
+ static bool isOutputChannel(audio_channel_mask_t channel) {
+ return audio_is_output_channel(channel);
+ }
+ static bool isInputChannel(audio_channel_mask_t channel) {
+ return audio_is_input_channel(channel);
+ }
+
+#endif
+};
+
+}; // namespace android_audio_legacy
+
+#endif // ANDROID_AUDIOSYSTEM_LEGACY_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/IMountService.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/IMountService.h
new file mode 100644
index 0000000..158ff59
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/IMountService.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+#ifndef ANDROID_HARDWARE_IMOUNTSERVICE_H
+#define ANDROID_HARDWARE_IMOUNTSERVICE_H
+
+#include <binder/IInterface.h>
+#include <utils/String16.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IMountService : public IInterface {
+ public:
+ static const int OperationSucceeded = 0;
+ static const int OperationFailedInternalError = -1;
+ static const int OperationFailedNoMedia = -2;
+ static const int OperationFailedMediaBlank = -3;
+ static const int OperationFailedMediaCorrupt = -4;
+ static const int OperationFailedVolumeNotMounted = -5;
+
+ public:
+ DECLARE_META_INTERFACE(MountService);
+
+ virtual void getShareMethodList() = 0;
+ virtual bool getShareMethodAvailable(String16 method) = 0;
+ virtual int shareVolume(String16 path, String16 method) = 0;
+ virtual int unshareVolume(String16 path, String16 method) = 0;
+ virtual bool getVolumeShared(String16 path, String16 method) = 0;
+ virtual int mountVolume(String16 path) = 0;
+ virtual int unmountVolume(String16 path) = 0;
+ virtual int formatVolume(String16 path) = 0;
+ virtual String16 getVolumeState(String16 mountPoint) = 0;
+ virtual int createSecureContainer(String16 id, int sizeMb, String16 fstype, String16 key,
+ int ownerUid) = 0;
+ virtual int finalizeSecureContainer(String16 id) = 0;
+ virtual int destroySecureContainer(String16 id) = 0;
+ virtual int mountSecureContainer(String16 id, String16 key, int ownerUid) = 0;
+ virtual int unmountSecureContainer(String16 id) = 0;
+ virtual int renameSecureContainer(String16 oldId, String16 newId) = 0;
+ virtual String16 getSecureContainerPath(String16 id) = 0;
+ virtual void getSecureContainerList() = 0;
+ virtual void shutdown() = 0;
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_HARDWARE_IMOUNTSERVICE_H
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/audio_policy_conf.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/audio_policy_conf.h
new file mode 100644
index 0000000..13d62f9
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/audio_policy_conf.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_POLICY_CONF_H
+#define ANDROID_AUDIO_POLICY_CONF_H
+
+/////////////////////////////////////////////////
+// Definitions for audio policy configuration file (audio_policy.conf)
+/////////////////////////////////////////////////
+
+#define AUDIO_HARDWARE_MODULE_ID_MAX_LEN 32
+
+#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"
+#define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf"
+
+// global configuration
+#define GLOBAL_CONFIG_TAG "global_configuration"
+
+#define ATTACHED_OUTPUT_DEVICES_TAG "attached_output_devices"
+#define DEFAULT_OUTPUT_DEVICE_TAG "default_output_device"
+#define ATTACHED_INPUT_DEVICES_TAG "attached_input_devices"
+#define SPEAKER_DRC_ENABLED_TAG "speaker_drc_enabled"
+
+// hw modules descriptions
+#define AUDIO_HW_MODULE_TAG "audio_hw_modules"
+
+#define OUTPUTS_TAG "outputs"
+#define INPUTS_TAG "inputs"
+
+#define SAMPLING_RATES_TAG "sampling_rates"
+#define FORMATS_TAG "formats"
+#define CHANNELS_TAG "channel_masks"
+#define DEVICES_TAG "devices"
+#define FLAGS_TAG "flags"
+
+#define DYNAMIC_VALUE_TAG \
+ "dynamic" // special value for "channel_masks", "sampling_rates" and
+ // "formats" in outputs descriptors indicating that supported
+ // values should be queried after opening the output.
+
+#endif // ANDROID_AUDIO_POLICY_CONF_H
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/gscan.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/gscan.h
new file mode 100644
index 0000000..c6c52c6
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/gscan.h
@@ -0,0 +1,427 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_GSCAN_H__
+#define __WIFI_HAL_GSCAN_H__
+
+// Define static_assert() unless already defined by compiler.
+#ifndef __has_feature
+#define __has_feature(__x) 0
+#endif
+#if !(__has_feature(cxx_static_assert)) && !defined(static_assert)
+#define static_assert(__b, __m) \
+ extern int compile_time_assert_failed[(__b) ? 1 : -1] __attribute__((unused));
+#endif
+
+/* AP Scans */
+
+typedef enum {
+ WIFI_BAND_UNSPECIFIED,
+ WIFI_BAND_BG = 1, // 2.4 GHz
+ WIFI_BAND_A = 2, // 5 GHz without DFS
+ WIFI_BAND_A_DFS = 4, // 5 GHz DFS only
+ WIFI_BAND_A_WITH_DFS = 6, // 5 GHz with DFS
+ WIFI_BAND_ABG = 3, // 2.4 GHz + 5 GHz; no DFS
+ WIFI_BAND_ABG_WITH_DFS = 7, // 2.4 GHz + 5 GHz with DFS
+} wifi_band;
+
+#define MAX_CHANNELS 16
+#define MAX_BUCKETS 16
+#define MAX_HOTLIST_APS 128
+#define MAX_SIGNIFICANT_CHANGE_APS 64
+#define MAX_EPNO_NETWORKS 64
+#define MAX_HOTLIST_SSID 8
+#define MAX_AP_CACHE_PER_SCAN 32
+
+wifi_error wifi_get_valid_channels(wifi_interface_handle handle, int band, int max_channels,
+ wifi_channel* channels, int* num_channels);
+
+typedef struct {
+ int max_scan_cache_size; // total space allocated for scan (in bytes)
+ int max_scan_buckets; // maximum number of channel buckets
+ int max_ap_cache_per_scan; // maximum number of APs that can be stored per scan
+ int max_rssi_sample_size; // number of RSSI samples used for averaging RSSI
+ int max_scan_reporting_threshold; // max possible report_threshold as described
+ // in wifi_scan_cmd_params
+ int max_hotlist_bssids; // maximum number of entries for hotlist BSSIDs
+ int max_hotlist_ssids; // maximum number of entries for hotlist SSIDs
+ int max_significant_wifi_change_aps; // maximum number of entries for
+ // significant wifi change APs
+ int max_bssid_history_entries; // number of BSSID/RSSI entries that device can hold
+ int max_number_epno_networks; // max number of epno entries
+ int max_number_epno_networks_by_ssid; // max number of epno entries if ssid is specified,
+ // that is, epno entries for which an exact match is
+ // required, or entries corresponding to hidden ssids
+ int max_number_of_white_listed_ssid; // max number of white listed SSIDs, M target is 2 to 4
+} wifi_gscan_capabilities;
+
+wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
+ wifi_gscan_capabilities* capabilities);
+
+typedef enum {
+ WIFI_SCAN_RESULTS_AVAILABLE, // reported when REPORT_EVENTS_EACH_SCAN is set and a scan
+ // completes. WIFI_SCAN_THRESHOLD_NUM_SCANS or
+ // WIFI_SCAN_THRESHOLD_PERCENT can be reported instead if the
+ // reason for the event is available; however, at most one of
+ // these events should be reported per scan. If there are
+ // multiple buckets that were scanned this period and one has the
+ // EACH_SCAN flag set then this event should be prefered.
+ WIFI_SCAN_THRESHOLD_NUM_SCANS, // can be reported when REPORT_EVENTS_EACH_SCAN is not set and
+ // report_threshold_num_scans is reached.
+ WIFI_SCAN_THRESHOLD_PERCENT, // can be reported when REPORT_EVENTS_EACH_SCAN is not set and
+ // report_threshold_percent is reached.
+ WIFI_SCAN_FAILED, // reported when currently executing gscans have failed.
+ // start_gscan will need to be called again in order to continue
+ // scanning. This is intended to indicate abnormal scan
+ // terminations (not those as a result of stop_gscan).
+} wifi_scan_event;
+
+/* Format of information elements found in the beacon */
+typedef struct {
+ byte id; // element identifier
+ byte len; // number of bytes to follow
+ byte data[];
+} wifi_information_element;
+
+typedef struct {
+ wifi_timestamp ts; // time since boot (in microsecond) when the result was
+ // retrieved
+ char ssid[32 + 1]; // null terminated
+ mac_addr bssid;
+ wifi_channel channel; // channel frequency in MHz
+ wifi_rssi rssi; // in db
+ wifi_timespan rtt; // in nanoseconds
+ wifi_timespan rtt_sd; // standard deviation in rtt
+ unsigned short beacon_period; // period advertised in the beacon
+ unsigned short capability; // capabilities advertised in the beacon
+ unsigned int ie_length; // size of the ie_data blob
+ char ie_data[1]; // blob of all the information elements found in the
+ // beacon; this data should be a packed list of
+ // wifi_information_element objects, one after the other.
+ // other fields
+} wifi_scan_result;
+
+static_assert(
+ MAX_BUCKETS <= 8 * sizeof(unsigned),
+ "The buckets_scanned bitset is represented by an unsigned int and cannot support this many "
+ "buckets on this platform.");
+typedef struct {
+ /* reported when each probe response is received, if report_events
+ * enabled in wifi_scan_cmd_params. buckets_scanned is a bitset of the
+ * buckets that are currently being scanned. See the buckets_scanned field
+ * in the wifi_cached_scan_results struct for more details.
+ */
+ void (*on_full_scan_result)(wifi_request_id id, wifi_scan_result* result,
+ unsigned buckets_scanned);
+
+ /* indicates progress of scanning statemachine */
+ void (*on_scan_event)(wifi_request_id id, wifi_scan_event event);
+
+} wifi_scan_result_handler;
+
+typedef struct {
+ wifi_channel channel; // frequency
+ int dwellTimeMs; // dwell time hint
+ int passive; // 0 => active, 1 => passive scan; ignored for DFS
+ /* Add channel class */
+} wifi_scan_channel_spec;
+
+#define REPORT_EVENTS_EACH_SCAN (1 << 0)
+#define REPORT_EVENTS_FULL_RESULTS (1 << 1)
+#define REPORT_EVENTS_NO_BATCH (1 << 2)
+
+typedef struct {
+ int bucket; // bucket index, 0 based
+ wifi_band band; // when UNSPECIFIED, use channel list
+ int period; // desired period, in millisecond; if this is too
+ // low, the firmware should choose to generate results as
+ // fast as it can instead of failing the command.
+ // for exponential backoff bucket this is the min_period
+ /* report_events semantics -
+ * This is a bit field; which defines following bits -
+ * REPORT_EVENTS_EACH_SCAN => report a scan completion event after scan. If this is not set
+ * then scan completion events should be reported if
+ * report_threshold_percent or report_threshold_num_scans is
+ * reached.
+ * REPORT_EVENTS_FULL_RESULTS => forward scan results (beacons/probe responses + IEs)
+ * in real time to HAL, in addition to completion events
+ * Note: To keep backward compatibility, fire completion
+ * events regardless of REPORT_EVENTS_EACH_SCAN.
+ * REPORT_EVENTS_NO_BATCH => controls if scans for this bucket should be placed in the
+ * history buffer
+ */
+ byte report_events;
+ int max_period; // if max_period is non zero or different than period, then this bucket is
+ // an exponential backoff bucket and the scan period will grow exponentially
+ // as per formula: actual_period(N) = period * (base ^ (N/step_count))
+ // to a maximum period of max_period
+ int base; // for exponential back off bucket: multiplier: new_period=old_period*base
+ int step_count; // for exponential back off bucket, number of scans to perform for a given
+ // period
+
+ int num_channels;
+ // channels to scan; these may include DFS channels
+ // Note that a given channel may appear in multiple buckets
+ wifi_scan_channel_spec channels[MAX_CHANNELS];
+} wifi_scan_bucket_spec;
+
+typedef struct {
+ int base_period; // base timer period in ms
+ int max_ap_per_scan; // number of access points to store in each scan entry in
+ // the BSSID/RSSI history buffer (keep the highest RSSI
+ // access points)
+ int report_threshold_percent; // in %, when scan buffer is this much full, wake up apps
+ // processor
+ int report_threshold_num_scans; // in number of scans, wake up AP after these many scans
+ int num_buckets;
+ wifi_scan_bucket_spec buckets[MAX_BUCKETS];
+} wifi_scan_cmd_params;
+
+/*
+ * Start periodic GSCAN
+ * When this is called all requested buckets should be scanned, starting the beginning of the cycle
+ *
+ * For example:
+ * If there are two buckets specified
+ * - Bucket 1: period=10s
+ * - Bucket 2: period=20s
+ * - Bucket 3: period=30s
+ * Then the following scans should occur
+ * - t=0 buckets 1, 2, and 3 are scanned
+ * - t=10 bucket 1 is scanned
+ * - t=20 bucket 1 and 2 are scanned
+ * - t=30 bucket 1 and 3 are scanned
+ * - t=40 bucket 1 and 2 are scanned
+ * - t=50 bucket 1 is scanned
+ * - t=60 buckets 1, 2, and 3 are scanned
+ * - and the patter repeats
+ *
+ * If any scan does not occur or is incomplete (error, interrupted, etc) then a cached scan result
+ * should still be recorded with the WIFI_SCAN_FLAG_INTERRUPTED flag set.
+ */
+wifi_error wifi_start_gscan(wifi_request_id id, wifi_interface_handle iface,
+ wifi_scan_cmd_params params, wifi_scan_result_handler handler);
+
+/* Stop periodic GSCAN */
+wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface);
+
+typedef enum {
+ WIFI_SCAN_FLAG_INTERRUPTED = 1 // Indicates that scan results are not complete because
+ // probes were not sent on some channels
+} wifi_scan_flags;
+
+/* Get the GSCAN cached scan results */
+typedef struct {
+ int scan_id; // a unique identifier for the scan unit
+ int flags; // a bitmask with additional
+ // information about scan.
+ unsigned buckets_scanned; // a bitset of the buckets that were scanned.
+ // for example a value of 13 (0b1101) would
+ // indicate that buckets 0, 2 and 3 were
+ // scanned to produce this list of results.
+ // should be set to 0 if this information is
+ // not available.
+ int num_results; // number of bssids retrieved by the scan
+ wifi_scan_result results[MAX_AP_CACHE_PER_SCAN]; // scan results - one for each bssid
+} wifi_cached_scan_results;
+
+wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush, int max,
+ wifi_cached_scan_results* results, int* num);
+
+/* BSSID Hotlist */
+typedef struct {
+ void (*on_hotlist_ap_found)(wifi_request_id id, unsigned num_results,
+ wifi_scan_result* results);
+ void (*on_hotlist_ap_lost)(wifi_request_id id, unsigned num_results, wifi_scan_result* results);
+} wifi_hotlist_ap_found_handler;
+
+typedef struct {
+ mac_addr bssid; // AP BSSID
+ wifi_rssi low; // low threshold
+ wifi_rssi high; // high threshold
+} ap_threshold_param;
+
+typedef struct {
+ int lost_ap_sample_size;
+ int num_bssid; // number of hotlist APs
+ ap_threshold_param ap[MAX_HOTLIST_APS]; // hotlist APs
+} wifi_bssid_hotlist_params;
+
+/* Set the BSSID Hotlist */
+wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface,
+ wifi_bssid_hotlist_params params,
+ wifi_hotlist_ap_found_handler handler);
+
+/* Clear the BSSID Hotlist */
+wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface);
+
+/* SSID Hotlist */
+typedef struct {
+ void (*on_hotlist_ssid_found)(wifi_request_id id, unsigned num_results,
+ wifi_scan_result* results);
+ void (*on_hotlist_ssid_lost)(wifi_request_id id, unsigned num_results,
+ wifi_scan_result* results);
+} wifi_hotlist_ssid_handler;
+
+typedef struct {
+ char ssid[32 + 1]; // SSID
+ wifi_band band; // band for this set of threshold params
+ wifi_rssi low; // low threshold
+ wifi_rssi high; // high threshold
+} ssid_threshold_param;
+
+typedef struct {
+ int lost_ssid_sample_size;
+ int num_ssid; // number of hotlist SSIDs
+ ssid_threshold_param ssid[MAX_HOTLIST_SSID]; // hotlist SSIDs
+} wifi_ssid_hotlist_params;
+
+/* Significant wifi change */
+typedef struct {
+ mac_addr bssid; // BSSID
+ wifi_channel channel; // channel frequency in MHz
+ int num_rssi; // number of rssi samples
+ wifi_rssi rssi[]; // RSSI history in db
+} wifi_significant_change_result;
+
+typedef struct {
+ void (*on_significant_change)(wifi_request_id id, unsigned num_results,
+ wifi_significant_change_result** results);
+} wifi_significant_change_handler;
+
+// The sample size parameters in the wifi_significant_change_params structure
+// represent the number of occurence of a g-scan where the BSSID was seen and RSSI was
+// collected for that BSSID, or, the BSSID was expected to be seen and didn't.
+// for instance: lost_ap_sample_size : number of time a g-scan was performed on the
+// channel the BSSID was seen last, and the BSSID was not seen during those g-scans
+typedef struct {
+ int rssi_sample_size; // number of samples for averaging RSSI
+ int lost_ap_sample_size; // number of samples to confirm AP loss
+ int min_breaching; // number of APs breaching threshold
+ int num_bssid; // max 64
+ ap_threshold_param ap[MAX_SIGNIFICANT_CHANGE_APS];
+} wifi_significant_change_params;
+
+/* Set the Signifcant AP change list */
+wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interface_handle iface,
+ wifi_significant_change_params params,
+ wifi_significant_change_handler handler);
+
+/* Clear the Signifcant AP change list */
+wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface);
+
+/* Random MAC OUI for PNO */
+wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui);
+
+// Enhanced PNO:
+// Enhanced PNO feature is expected to be enabled all of the time (e.g. screen lit) and may thus
+// require firmware to store a large number of networks, covering the whole list of known networks.
+// Therefore, it is acceptable for firmware to store a crc24, crc32 or other short hash of the SSID,
+// such that a low but non-zero probability of collision exist. With that scheme it should be
+// possible for firmware to keep an entry as small as 4 bytes for each pno network.
+// For instance, a firmware pn0 entry can be implemented in the form of:
+// PNO ENTRY = crc24(3 bytes) | flags>>3 (5 bits) | auth flags(3 bits)
+//
+// No scans should be automatically performed by the chip. Instead all scan results from gscan
+// should be scored and the wifi_epno_handler on_network_found callback should be called with
+// the scan results.
+//
+// A PNO network shall be reported once, that is, once a network is reported by firmware
+// its entry shall be marked as "done" until framework calls wifi_set_epno_list again.
+// Calling wifi_set_epno_list shall reset the "done" status of pno networks in firmware.
+//
+// A network should only be considered found if its RSSI is above the minimum RSSI for its
+// frequency range (min5GHz_rssi and min24GHz_rssi for 5GHz and 2.4GHz networks respectively).
+// When disconnected the list of scan results should be returned if any network is found.
+// When connected the scan results shall be reported only if the score of any network in the scan
+// is greater than that of the currently connected BSSID.
+//
+// The FW should calculate the score of all the candidates (including currently connected one)
+// with following equation:
+// RSSI score = (RSSI + 85) * 4;
+// If RSSI score > initial_score_max , RSSI score = initial_score_max;
+// final score = RSSI score
+// + current_connection_bonus (if currently connected BSSID)
+// + same_network_bonus (if network has SAME_NETWORK flag)
+// + secure_bonus (if the network is not open)
+// + band5GHz_bonus (if BSSID is on 5G)
+// If there is a BSSID’s score > current BSSID’s score, then report the cached scan results
+// at the end of the scan (excluding the ones on blacklist) to the upper layer.
+// Additionally, all BSSIDs that are in the BSSID blacklist should be ignored by Enhanced PNO
+
+// Whether directed scan needs to be performed (for hidden SSIDs)
+#define WIFI_PNO_FLAG_DIRECTED_SCAN (1 << 0)
+// Whether PNO event shall be triggered if the network is found on A band
+#define WIFI_PNO_FLAG_A_BAND (1 << 1)
+// Whether PNO event shall be triggered if the network is found on G band
+#define WIFI_PNO_FLAG_G_BAND (1 << 2)
+// Whether strict matching is required
+// If required then the firmware must store the network's SSID and not just a hash
+#define WIFI_PNO_FLAG_STRICT_MATCH (1 << 3)
+// If this SSID should be considered the same network as the currently connected one for scoring
+#define WIFI_PNO_FLAG_SAME_NETWORK (1 << 4)
+
+// Code for matching the beacon AUTH IE - additional codes TBD
+#define WIFI_PNO_AUTH_CODE_OPEN (1 << 0) // open
+#define WIFI_PNO_AUTH_CODE_PSK (1 << 1) // WPA_PSK or WPA2PSK
+#define WIFI_PNO_AUTH_CODE_EAPOL (1 << 2) // any EAPOL
+
+typedef struct {
+ char ssid[32 + 1]; // null terminated
+ byte flags; // WIFI_PNO_FLAG_XXX
+ byte auth_bit_field; // auth bit field for matching WPA IE
+} wifi_epno_network;
+
+/* ePNO Parameters */
+typedef struct {
+ int min5GHz_rssi; // minimum 5GHz RSSI for a BSSID to be considered
+ int min24GHz_rssi; // minimum 2.4GHz RSSI for a BSSID to be considered
+ int initial_score_max; // the maximum score that a network can have before bonuses
+ int current_connection_bonus; // only report when there is a network's score this much higher
+ // than the current connection.
+ int same_network_bonus; // score bonus for all networks with the same network flag
+ int secure_bonus; // score bonus for networks that are not open
+ int band5GHz_bonus; // 5GHz RSSI score bonus (applied to all 5GHz networks)
+ int num_networks; // number of wifi_epno_network objects
+ wifi_epno_network networks[MAX_EPNO_NETWORKS]; // PNO networks
+} wifi_epno_params;
+
+typedef struct {
+ // on results
+ void (*on_network_found)(wifi_request_id id, unsigned num_results, wifi_scan_result* results);
+} wifi_epno_handler;
+
+/* Set the ePNO list - enable ePNO with the given parameters */
+wifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface,
+ const wifi_epno_params* epno_params, wifi_epno_handler handler);
+
+/* Reset the ePNO list - no ePNO networks should be matched after this */
+wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface);
+
+typedef struct {
+ int id; // identifier of this network block, report this in event
+ char realm[256]; // null terminated UTF8 encoded realm, 0 if unspecified
+ int64_t roamingConsortiumIds[16]; // roaming consortium ids to match, 0s if unspecified
+ byte plmn[3]; // mcc/mnc combination as per rules, 0s if unspecified
+} wifi_passpoint_network;
+
+typedef struct {
+ void (*on_passpoint_network_found)(
+ wifi_request_id id,
+ int net_id, // network block identifier for the matched network
+ wifi_scan_result* result, // scan result, with channel and beacon information
+ int anqp_len, // length of ANQP blob
+ byte* anqp // ANQP data, in the information_element format
+ );
+} wifi_passpoint_event_handler;
+
+/* Sets a list for passpoint networks for PNO purposes; it should be matched
+ * against any passpoint networks (designated by Interworking element) found
+ * during regular PNO scan. */
+wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle iface, int num,
+ wifi_passpoint_network* networks,
+ wifi_passpoint_event_handler handler);
+
+/* Reset passpoint network list - no Passpoint networks should be matched after this */
+wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface);
+
+#endif
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/link_layer_stats.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/link_layer_stats.h
new file mode 100644
index 0000000..7585cdf
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/link_layer_stats.h
@@ -0,0 +1,285 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_STATS_H
+#define __WIFI_HAL_STATS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define STATS_MAJOR_VERSION 1
+#define STATS_MINOR_VERSION 0
+#define STATS_MICRO_VERSION 0
+
+typedef enum {
+ WIFI_DISCONNECTED = 0,
+ WIFI_AUTHENTICATING = 1,
+ WIFI_ASSOCIATING = 2,
+ WIFI_ASSOCIATED = 3,
+ WIFI_EAPOL_STARTED = 4, // if done by firmware/driver
+ WIFI_EAPOL_COMPLETED = 5, // if done by firmware/driver
+} wifi_connection_state;
+
+typedef enum {
+ WIFI_ROAMING_IDLE = 0,
+ WIFI_ROAMING_ACTIVE = 1,
+} wifi_roam_state;
+
+typedef enum {
+ WIFI_INTERFACE_STA = 0,
+ WIFI_INTERFACE_SOFTAP = 1,
+ WIFI_INTERFACE_IBSS = 2,
+ WIFI_INTERFACE_P2P_CLIENT = 3,
+ WIFI_INTERFACE_P2P_GO = 4,
+ WIFI_INTERFACE_NAN = 5,
+ WIFI_INTERFACE_MESH = 6,
+ WIFI_INTERFACE_TDLS = 7,
+ WIFI_INTERFACE_UNKNOWN = -1
+} wifi_interface_mode;
+
+#define WIFI_CAPABILITY_QOS 0x00000001 // set for QOS association
+#define WIFI_CAPABILITY_PROTECTED \
+ 0x00000002 // set for protected association (802.11 beacon frame control protected bit set)
+#define WIFI_CAPABILITY_INTERWORKING \
+ 0x00000004 // set if 802.11 Extended Capabilities element interworking bit is set
+#define WIFI_CAPABILITY_HS20 0x00000008 // set for HS20 association
+#define WIFI_CAPABILITY_SSID_UTF8 \
+ 0x00000010 // set is 802.11 Extended Capabilities element UTF-8 SSID bit is set
+#define WIFI_CAPABILITY_COUNTRY 0x00000020 // set is 802.11 Country Element is present
+
+typedef struct {
+ wifi_interface_mode mode; // interface mode
+ u8 mac_addr[6]; // interface mac address (self)
+ wifi_connection_state state; // connection state (valid for STA, CLI only)
+ wifi_roam_state roaming; // roaming state
+ u32 capabilities; // WIFI_CAPABILITY_XXX (self)
+ u8 ssid[33]; // null terminated SSID
+ u8 bssid[6]; // bssid
+ u8 ap_country_str[3]; // country string advertised by AP
+ u8 country_str[3]; // country string for this association
+ u8 time_slicing_duty_cycle_percent; // if this iface is being served using time slicing on a
+ // radio with one or more ifaces (i.e MCC), then the duty
+ // cycle assigned to this iface in %. If not using time
+ // slicing (i.e SCC or DBS), set to 100.
+} wifi_interface_link_layer_info;
+
+/* channel information */
+typedef struct {
+ wifi_channel_width width; // channel width (20, 40, 80, 80+80, 160, 320)
+ wifi_channel center_freq; // primary 20 MHz channel
+ wifi_channel center_freq0; // center frequency (MHz) first segment
+ wifi_channel center_freq1; // center frequency (MHz) second segment
+} wifi_channel_info;
+
+/* wifi rate */
+typedef struct {
+ u32 preamble : 3; // 0: OFDM, 1:CCK, 2:HT 3:VHT 4:HE 5:EHT 6..7 reserved
+ u32 nss : 2; // 0:1x1, 1:2x2, 3:3x3, 4:4x4
+ u32 bw : 3; // 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz 4:320Mhz
+ u32 rateMcsIdx : 8; // OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps
+ // HT/VHT/HE/EHT it would be mcs index
+ u32 reserved : 16; // reserved
+ u32 bitrate; // units of 100 Kbps
+} wifi_rate;
+
+/* channel statistics */
+typedef struct {
+ wifi_channel_info channel; // channel
+ u32 on_time; // msecs the radio is awake (32 bits number accruing over time)
+ u32 cca_busy_time; // msecs the CCA register is busy (32 bits number accruing over time)
+} wifi_channel_stat;
+
+// Max number of tx power levels. The actual number vary per device and is specified by
+// |num_tx_levels|
+#define RADIO_STAT_MAX_TX_LEVELS 256
+
+/* radio statistics */
+typedef struct {
+ wifi_radio radio; // wifi radio (if multiple radio supported)
+ u32 on_time; // msecs the radio is awake (32 bits number accruing over time)
+ u32 tx_time; // msecs the radio is transmitting (32 bits number accruing over time)
+ u32 num_tx_levels; // number of radio transmit power levels
+ u32* tx_time_per_levels; // pointer to an array of radio transmit per power levels in
+ // msecs accured over time
+ u32 rx_time; // msecs the radio is in active receive (32 bits number accruing over time)
+ u32 on_time_scan; // msecs the radio is awake due to all scan (32 bits number accruing over
+ // time)
+ u32 on_time_nbd; // msecs the radio is awake due to NAN (32 bits number accruing over time)
+ u32 on_time_gscan; // msecs the radio is awake due to G?scan (32 bits number accruing over
+ // time)
+ u32 on_time_roam_scan; // msecs the radio is awake due to roam?scan (32 bits number accruing
+ // over time)
+ u32 on_time_pno_scan; // msecs the radio is awake due to PNO scan (32 bits number accruing over
+ // time)
+ u32 on_time_hs20; // msecs the radio is awake due to HS2.0 scans and GAS exchange (32 bits
+ // number accruing over time)
+ u32 num_channels; // number of channels
+ wifi_channel_stat channels[]; // channel statistics
+} wifi_radio_stat;
+
+/**
+ * Packet statistics reporting by firmware is performed on MPDU basi (i.e. counters increase by 1
+ * for each MPDU) As well, "data packet" in associated comments, shall be interpreted as 802.11 data
+ * packet, that is, 802.11 frame control subtype == 2 and excluding management and control frames.
+ *
+ * As an example, in the case of transmission of an MSDU fragmented in 16 MPDUs which are
+ * transmitted OTA in a 16 units long a-mpdu, for which a block ack is received with 5 bits set:
+ * tx_mpdu : shall increase by 5
+ * retries : shall increase by 16
+ * tx_ampdu : shall increase by 1
+ * data packet counters shall not increase regardless of the number of BAR potentially sent by
+ * device for this a-mpdu data packet counters shall not increase regardless of the number of BA
+ * received by device for this a-mpdu
+ *
+ * For each subsequent retransmission of the 11 remaining non ACK'ed mpdus
+ * (regardless of the fact that they are transmitted in a-mpdu or not)
+ * retries : shall increase by 1
+ *
+ * If no subsequent BA or ACK are received from AP, until packet lifetime expires for those 11
+ * packet that were not ACK'ed mpdu_lost : shall increase by 11
+ */
+
+/* per rate statistics */
+typedef struct {
+ wifi_rate rate; // rate information
+ u32 tx_mpdu; // number of successfully transmitted data pkts (ACK rcvd)
+ u32 rx_mpdu; // number of received data pkts
+ u32 mpdu_lost; // number of data packet losses (no ACK)
+ u32 retries; // total number of data pkt retries
+ u32 retries_short; // number of short data pkt retries
+ u32 retries_long; // number of long data pkt retries
+} wifi_rate_stat;
+
+/* access categories */
+typedef enum {
+ WIFI_AC_VO = 0,
+ WIFI_AC_VI = 1,
+ WIFI_AC_BE = 2,
+ WIFI_AC_BK = 3,
+ WIFI_AC_MAX = 4,
+} wifi_traffic_ac;
+
+/* wifi peer type */
+typedef enum {
+ WIFI_PEER_STA,
+ WIFI_PEER_AP,
+ WIFI_PEER_P2P_GO,
+ WIFI_PEER_P2P_CLIENT,
+ WIFI_PEER_NAN,
+ WIFI_PEER_TDLS,
+ WIFI_PEER_INVALID,
+} wifi_peer_type;
+
+/* per peer statistics */
+typedef struct bssload_info {
+ u16 sta_count; // station count
+ u16 chan_util; // channel utilization
+ u8 PAD[4];
+} bssload_info_t;
+
+typedef struct {
+ wifi_peer_type type; // peer type (AP, TDLS, GO etc.)
+ u8 peer_mac_address[6]; // mac address
+ u32 capabilities; // peer WIFI_CAPABILITY_XXX
+ bssload_info_t bssload; // STA count and CU
+ u32 num_rate; // number of rates
+ wifi_rate_stat rate_stats[]; // per rate statistics, number of entries = num_rate
+} wifi_peer_info;
+
+/* Per access category statistics */
+typedef struct {
+ wifi_traffic_ac ac; // access category (VI, VO, BE, BK)
+ u32 tx_mpdu; // number of successfully transmitted unicast data pkts (ACK rcvd)
+ u32 rx_mpdu; // number of received unicast data packets
+ u32 tx_mcast; // number of succesfully transmitted multicast data packets
+ // STA case: implies ACK received from AP for the unicast packet in which mcast
+ // pkt was sent
+ u32 rx_mcast; // number of received multicast data packets
+ u32 rx_ampdu; // number of received unicast a-mpdus; support of this counter is optional
+ u32 tx_ampdu; // number of transmitted unicast a-mpdus; support of this counter is optional
+ u32 mpdu_lost; // number of data pkt losses (no ACK)
+ u32 retries; // total number of data pkt retries
+ u32 retries_short; // number of short data pkt retries
+ u32 retries_long; // number of long data pkt retries
+ u32 contention_time_min; // data pkt min contention time (usecs)
+ u32 contention_time_max; // data pkt max contention time (usecs)
+ u32 contention_time_avg; // data pkt avg contention time (usecs)
+ u32 contention_num_samples; // num of data pkts used for contention statistics
+} wifi_wmm_ac_stat;
+
+/* interface statistics */
+typedef struct {
+ wifi_interface_handle iface; // wifi interface
+ wifi_interface_link_layer_info info; // current state of the interface
+ u32 beacon_rx; // access point beacon received count from connected AP
+ u64 average_tsf_offset; // average beacon offset encountered (beacon_TSF - TBTT)
+ // The average_tsf_offset field is used so as to calculate the
+ // typical beacon contention time on the channel as well may be
+ // used to debug beacon synchronization and related power consumption
+ // issue
+ u32 leaky_ap_detected; // indicate that this AP typically leaks packets beyond the driver guard
+ // time.
+ u32 leaky_ap_avg_num_frames_leaked; // average number of frame leaked by AP after frame with PM
+ // bit set was ACK'ed by AP
+ u32 leaky_ap_guard_time; // guard time currently in force (when implementing IEEE power
+ // management based on frame control PM bit), How long driver waits
+ // before shutting down the radio and after receiving an ACK for a
+ // data frame with PM bit set)
+ u32 mgmt_rx; // access point mgmt frames received count from connected AP (including Beacon)
+ u32 mgmt_action_rx; // action frames received count
+ u32 mgmt_action_tx; // action frames transmit count
+ wifi_rssi rssi_mgmt; // access Point Beacon and Management frames RSSI (averaged)
+ wifi_rssi rssi_data; // access Point Data Frames RSSI (averaged) from connected AP
+ wifi_rssi rssi_ack; // access Point ACK RSSI (averaged) from connected AP
+ wifi_wmm_ac_stat ac[WIFI_AC_MAX]; // per ac data packet statistics
+ u32 num_peers; // number of peers
+ wifi_peer_info peer_info[]; // per peer statistics
+} wifi_iface_stat;
+
+/* configuration params */
+typedef struct {
+ u32 mpdu_size_threshold; // threshold to classify the pkts as short or long
+ // packet size < mpdu_size_threshold => short
+ u32 aggressive_statistics_gathering; // set for field debug mode. Driver should collect all
+ // statistics regardless of performance impact.
+} wifi_link_layer_params;
+
+/* API to trigger the link layer statistics collection.
+ Unless his API is invoked - link layer statistics will not be collected.
+ Radio statistics (once started) do not stop or get reset unless wifi_clear_link_stats is invoked
+ Interface statistics (once started) reset and start afresh after each connection */
+wifi_error wifi_set_link_stats(wifi_interface_handle iface, wifi_link_layer_params params);
+
+/* callback for reporting link layer stats */
+typedef struct {
+ void (*on_link_stats_results)(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios,
+ wifi_radio_stat* radio_stat);
+} wifi_stats_result_handler;
+
+/* api to collect the link layer statistics for a given iface and all the radio stats */
+wifi_error wifi_get_link_stats(wifi_request_id id, wifi_interface_handle iface,
+ wifi_stats_result_handler handler);
+
+/* wifi statistics bitmap */
+#define WIFI_STATS_RADIO 0x00000001 // all radio statistics
+#define WIFI_STATS_RADIO_CCA 0x00000002 // cca_busy_time (within radio statistics)
+#define WIFI_STATS_RADIO_CHANNELS 0x00000004 // all channel statistics (within radio statistics)
+#define WIFI_STATS_RADIO_SCAN 0x00000008 // all scan statistics (within radio statistics)
+#define WIFI_STATS_IFACE 0x00000010 // all interface statistics
+#define WIFI_STATS_IFACE_TXRATE 0x00000020 // all tx rate statistics (within interface statistics)
+#define WIFI_STATS_IFACE_AC 0x00000040 // all ac statistics (within interface statistics)
+#define WIFI_STATS_IFACE_CONTENTION \
+ 0x00000080 // all contention (min, max, avg) statistics (within ac statisctics)
+
+/* clear api to reset statistics, stats_clear_rsp_mask identifies what stats have been cleared
+ stop_req = 1 will imply whether to stop the statistics collection.
+ stop_rsp = 1 will imply that stop_req was honored and statistics collection was stopped.
+ */
+wifi_error wifi_clear_link_stats(wifi_interface_handle iface, u32 stats_clear_req_mask,
+ u32* stats_clear_rsp_mask, u8 stop_req, u8* stop_rsp);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_STATS_ */
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/power.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/power.h
new file mode 100644
index 0000000..2b6d12a
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/power.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _HARDWARE_POWER_H
+#define _HARDWARE_POWER_H
+
+#include <stdint.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+enum {
+ PARTIAL_WAKE_LOCK = 1, // the cpu stays on, but the screen is off
+ FULL_WAKE_LOCK = 2 // the screen is also on
+};
+
+// while you have a lock held, the device will stay on at least at the
+// level you request.
+int acquire_wake_lock(int lock, const char* id);
+int release_wake_lock(const char* id);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // _HARDWARE_POWER_H
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/roam.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/roam.h
new file mode 100644
index 0000000..3369e3e
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/roam.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WIFI_HAL_ROAM_H__
+#define __WIFI_HAL_ROAM_H__
+
+#include "wifi_hal.h"
+
+#define MAX_BLACKLIST_BSSID 16
+#define MAX_WHITELIST_SSID 8
+#define MAX_SSID_LENGTH 32
+
+typedef struct {
+ u32 max_blacklist_size;
+ u32 max_whitelist_size;
+} wifi_roaming_capabilities;
+
+typedef enum { ROAMING_DISABLE, ROAMING_ENABLE } fw_roaming_state_t;
+
+typedef struct {
+ u32 length;
+ char ssid_str[MAX_SSID_LENGTH];
+} ssid_t;
+
+typedef struct {
+ u32 num_blacklist_bssid; // Number of bssids valid in blacklist_bssid[].
+ mac_addr blacklist_bssid[MAX_BLACKLIST_BSSID]; // List of bssids which should not be considered
+ // for romaing by firmware/driver.
+ u32 num_whitelist_ssid; // Number of ssids valid in whitelist_ssid[].
+ ssid_t whitelist_ssid[MAX_WHITELIST_SSID]; // List of ssids to which firmware/driver can
+ // consider to roam to.
+} wifi_roaming_config;
+
+/* Get the chipset roaming capabilities. */
+wifi_error wifi_get_roaming_capabilities(wifi_interface_handle handle,
+ wifi_roaming_capabilities* caps);
+/* Enable/disable firmware roaming */
+wifi_error wifi_enable_firmware_roaming(wifi_interface_handle handle, fw_roaming_state_t state);
+
+/* Pass down the blacklist BSSID and whitelist SSID to firmware. */
+wifi_error wifi_configure_roaming(wifi_interface_handle handle,
+ wifi_roaming_config* roaming_config);
+
+#endif /* __WIFI_HAL_ROAM_H__ */
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/rtt.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/rtt.h
new file mode 100644
index 0000000..8be7fd3
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/rtt.h
@@ -0,0 +1,314 @@
+
+#include "gscan.h"
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_RTT_H__
+#define __WIFI_HAL_RTT_H__
+
+/* Ranging status */
+typedef enum {
+ RTT_STATUS_SUCCESS = 0,
+ RTT_STATUS_FAILURE = 1, // general failure status
+ RTT_STATUS_FAIL_NO_RSP = 2, // target STA does not respond to request
+ RTT_STATUS_FAIL_REJECTED = 3, // request rejected. Applies to 2-sided RTT only
+ RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4,
+ RTT_STATUS_FAIL_TM_TIMEOUT = 5, // timing measurement times out
+ RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6, // Target on different channel, cannot range
+ RTT_STATUS_FAIL_NO_CAPABILITY = 7, // ranging not supported
+ RTT_STATUS_ABORTED = 8, // request aborted for unknown reason
+ RTT_STATUS_FAIL_INVALID_TS = 9, // Invalid T1-T4 timestamp
+ RTT_STATUS_FAIL_PROTOCOL = 10, // 11mc protocol failed
+ RTT_STATUS_FAIL_SCHEDULE = 11, // request could not be scheduled
+ RTT_STATUS_FAIL_BUSY_TRY_LATER = 12, // responder cannot collaborate at time of request
+ RTT_STATUS_INVALID_REQ = 13, // bad request args
+ RTT_STATUS_NO_WIFI = 14, // WiFi not enabled
+ RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE =
+ 15, // Responder overrides param info, cannot range with new params
+ RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE = 16, // Negotiation failure
+ RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17, // concurrency not supported (NDP+RTT)
+} wifi_rtt_status;
+
+/* RTT peer type */
+typedef enum {
+ RTT_PEER_AP = 0x1,
+ RTT_PEER_STA = 0x2,
+ RTT_PEER_P2P_GO = 0x3,
+ RTT_PEER_P2P_CLIENT = 0x4,
+ RTT_PEER_NAN = 0x5
+} rtt_peer_type;
+
+/* RTT Measurement Bandwidth */
+typedef enum {
+ WIFI_RTT_BW_5 = 0x01,
+ WIFI_RTT_BW_10 = 0x02,
+ WIFI_RTT_BW_20 = 0x04,
+ WIFI_RTT_BW_40 = 0x08,
+ WIFI_RTT_BW_80 = 0x10,
+ WIFI_RTT_BW_160 = 0x20,
+ WIFI_RTT_BW_320 = 0x40
+} wifi_rtt_bw;
+
+/* RTT Measurement Preamble */
+typedef enum {
+ WIFI_RTT_PREAMBLE_LEGACY = 0x1,
+ WIFI_RTT_PREAMBLE_HT = 0x2,
+ WIFI_RTT_PREAMBLE_VHT = 0x4,
+ WIFI_RTT_PREAMBLE_HE = 0x8,
+ WIFI_RTT_PREAMBLE_EHT = 0x10,
+} wifi_rtt_preamble;
+
+/* RTT Type */
+typedef enum {
+ RTT_TYPE_1_SIDED = 0x1,
+ RTT_TYPE_2_SIDED = 0x2,
+} wifi_rtt_type;
+
+/* RTT configuration */
+typedef struct {
+ mac_addr addr; // peer device mac address
+ wifi_rtt_type type; // 1-sided or 2-sided RTT
+ rtt_peer_type peer; // optional - peer device hint (STA, P2P, AP)
+ wifi_channel_info channel; // Required for STA-AP mode, optional for P2P, NBD etc.
+ unsigned burst_period; // Time interval between bursts (units: 100 ms).
+ // Applies to 1-sided and 2-sided RTT multi-burst requests.
+ // Range: 0-31, 0: no preference by initiator (2-sided RTT)
+ unsigned num_burst; // Total number of RTT bursts to be executed. It will be
+ // specified in the same way as the parameter "Number of
+ // Burst Exponent" found in the FTM frame format. It
+ // applies to both: 1-sided RTT and 2-sided RTT. Valid
+ // values are 0 to 15 as defined in 802.11mc std.
+ // 0 means single shot
+ // The implication of this parameter on the maximum
+ // number of RTT results is the following:
+ // for 1-sided RTT: max num of RTT results =
+ // (2^num_burst)*(num_frames_per_burst) for 2-sided RTT: max num of RTT
+ // results = (2^num_burst)*(num_frames_per_burst - 1)
+ unsigned num_frames_per_burst; // num of frames per burst.
+ // Minimum value = 1, Maximum value = 31
+ // For 2-sided this equals the number of FTM frames
+ // to be attempted in a single burst. This also
+ // equals the number of FTM frames that the
+ // initiator will request that the responder send
+ // in a single frame.
+ unsigned
+ num_retries_per_rtt_frame; // number of retries for a failed RTT frame. Applies
+ // to 1-sided RTT only. Minimum value = 0, Maximum value = 3
+
+ // following fields are only valid for 2-side RTT
+ unsigned num_retries_per_ftmr; // Maximum number of retries that the initiator can
+ // retry an FTMR frame.
+ // Minimum value = 0, Maximum value = 3
+ byte LCI_request; // 1: request LCI, 0: do not request LCI
+ byte LCR_request; // 1: request LCR, 0: do not request LCR
+ unsigned burst_duration; // Applies to 1-sided and 2-sided RTT. Valid values will
+ // be 2-11 and 15 as specified by the 802.11mc std for
+ // the FTM parameter burst duration. In a multi-burst
+ // request, if responder overrides with larger value,
+ // the initiator will return failure. In a single-burst
+ // request if responder overrides with larger value,
+ // the initiator will sent TMR_STOP to terminate RTT
+ // at the end of the burst_duration it requested.
+ wifi_rtt_preamble preamble; // RTT preamble to be used in the RTT frames
+ wifi_rtt_bw bw; // RTT BW to be used in the RTT frames
+} wifi_rtt_config;
+
+/* RTT results */
+typedef struct {
+ mac_addr addr; // device mac address
+ unsigned burst_num; // burst number in a multi-burst request
+ unsigned measurement_number; // Total RTT measurement frames attempted
+ unsigned success_number; // Total successful RTT measurement frames
+ byte number_per_burst_peer; // Maximum number of "FTM frames per burst" supported by
+ // the responder STA. Applies to 2-sided RTT only.
+ // If reponder overrides with larger value:
+ // - for single-burst request initiator will truncate the
+ // larger value and send a TMR_STOP after receiving as
+ // many frames as originally requested.
+ // - for multi-burst request, initiator will return
+ // failure right away.
+ wifi_rtt_status status; // ranging status
+ byte retry_after_duration; // When status == RTT_STATUS_FAIL_BUSY_TRY_LATER,
+ // this will be the time provided by the responder as to
+ // when the request can be tried again. Applies to 2-sided
+ // RTT only. In sec, 1-31sec.
+ wifi_rtt_type type; // RTT type
+ wifi_rssi rssi; // average rssi in 0.5 dB steps e.g. 143 implies -71.5 dB
+ wifi_rssi rssi_spread; // rssi spread in 0.5 dB steps e.g. 5 implies 2.5 dB spread (optional)
+ wifi_rate tx_rate; // 1-sided RTT: TX rate of RTT frame.
+ // 2-sided RTT: TX rate of initiator's Ack in response to FTM frame.
+ wifi_rate rx_rate; // 1-sided RTT: TX rate of Ack from other side.
+ // 2-sided RTT: TX rate of FTM frame coming from responder.
+ wifi_timespan rtt; // round trip time in picoseconds
+ wifi_timespan rtt_sd; // rtt standard deviation in picoseconds
+ wifi_timespan rtt_spread; // difference between max and min rtt times recorded in picoseconds
+ int distance_mm; // distance in mm (optional)
+ int distance_sd_mm; // standard deviation in mm (optional)
+ int distance_spread_mm; // difference between max and min distance recorded in mm (optional)
+ wifi_timestamp ts; // time of the measurement (in microseconds since boot)
+ int burst_duration; // in ms, actual time taken by the FW to finish one burst
+ // measurement. Applies to 1-sided and 2-sided RTT.
+ int negotiated_burst_num; // Number of bursts allowed by the responder. Applies
+ // to 2-sided RTT only.
+ wifi_information_element* LCI; // for 11mc only
+ wifi_information_element* LCR; // for 11mc only
+} wifi_rtt_result;
+
+/* RTT result callback */
+typedef struct {
+ void (*on_rtt_results)(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_result[]);
+} wifi_rtt_event_handler;
+
+/* API to request RTT measurement */
+wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle iface,
+ unsigned num_rtt_config, wifi_rtt_config rtt_config[],
+ wifi_rtt_event_handler handler);
+
+/* API to cancel RTT measurements */
+wifi_error wifi_rtt_range_cancel(wifi_request_id id, wifi_interface_handle iface,
+ unsigned num_devices, mac_addr addr[]);
+
+/* NBD ranging channel map */
+typedef struct {
+ wifi_channel availablity[32]; // specifies the channel map for each of the 16 TU windows
+ // frequency of 0 => unspecified; which means firmware is
+ // free to do whatever it wants in this window.
+} wifi_channel_map;
+
+/* API to start publishing the channel map on responder device in a NBD cluster.
+ Responder device will take this request and schedule broadcasting the channel map
+ in a NBD ranging attribute in a SDF. DE will automatically remove the ranging
+ attribute from the OTA queue after number of DW specified by num_dw
+ where Each DW is 512 TUs apart */
+wifi_error wifi_rtt_channel_map_set(wifi_request_id id, wifi_interface_handle iface,
+ wifi_channel_map* params, unsigned num_dw);
+
+/* API to clear the channel map on the responder device in a NBD cluster.
+ Responder device will cancel future ranging channel request, starting from “next”
+ DW interval and will also stop broadcasting NBD ranging attribute in SDF */
+wifi_error wifi_rtt_channel_map_clear(wifi_request_id id, wifi_interface_handle iface);
+
+// Preamble definition for bit mask used in wifi_rtt_capabilities
+#define PREAMBLE_LEGACY 0x1
+#define PREAMBLE_HT 0x2
+#define PREAMBLE_VHT 0x4
+#define PREAMBLE_HE 0x8
+#define PREAMBLE_EHT 0x10
+
+// BW definition for bit mask used in wifi_rtt_capabilities
+#define BW_5_SUPPORT 0x1
+#define BW_10_SUPPORT 0x2
+#define BW_20_SUPPORT 0x4
+#define BW_40_SUPPORT 0x8
+#define BW_80_SUPPORT 0x10
+#define BW_160_SUPPORT 0x20
+#define BW_320_SUPPORT 0x40
+
+/* RTT Capabilities */
+typedef struct {
+ byte rtt_one_sided_supported; // if 1-sided rtt data collection is supported
+ byte rtt_ftm_supported; // if ftm rtt data collection is supported
+ byte lci_support; // if initiator supports LCI request. Applies to 2-sided RTT
+ byte lcr_support; // if initiator supports LCR request. Applies to 2-sided RTT
+ byte preamble_support; // bit mask indicates what preamble is supported by initiator
+ byte bw_support; // bit mask indicates what BW is supported by initiator
+ byte responder_supported; // if 11mc responder mode is supported
+ byte mc_version; // draft 11mc spec version supported by chip. For instance,
+ // version 4.0 should be 40 and version 4.3 should be 43 etc.
+} wifi_rtt_capabilities;
+
+/* RTT capabilities of the device */
+wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
+ wifi_rtt_capabilities* capabilities);
+
+/* debugging definitions */
+enum {
+ RTT_DEBUG_DISABLE,
+ RTT_DEBUG_LOG,
+ RTT_DEBUG_PROTO,
+ RTT_DEBUG_BURST,
+ RTT_DEBUG_ACCURACY,
+ RTT_DEBUG_LOGDETAIL
+}; // rtt debug type
+
+enum { RTT_DEBUG_FORMAT_TXT, RTT_DEBUG_FORMAT_BINARY }; // rtt debug format
+
+typedef struct rtt_debug {
+ unsigned version;
+ unsigned len; // total length of after len field
+ unsigned type; // rtt debug type
+ unsigned format; // rtt debug format
+ char dbuf[0]; // debug content
+} rtt_debug_t;
+
+/* set configuration for debug */
+wifi_error wifi_rtt_debug_cfg(wifi_interface_handle h, unsigned rtt_dbg_type, char* cfgbuf,
+ unsigned cfg_buf_size);
+/* get the debug information */
+wifi_error wifi_rtt_debug_get(wifi_interface_handle h, rtt_debug_t** debugbuf);
+/* free the debug buffer */
+wifi_error wifi_rtt_debug_free(wifi_interface_handle h, rtt_debug_t* debugbuf);
+
+/* API for setting LCI/LCR information to be provided to a requestor */
+typedef enum {
+ WIFI_MOTION_NOT_EXPECTED = 0, // Not expected to change location
+ WIFI_MOTION_EXPECTED = 1, // Expected to change location
+ WIFI_MOTION_UNKNOWN = 2, // Movement pattern unknown
+} wifi_motion_pattern;
+
+typedef struct {
+ long latitude; // latitude in degrees * 2^25 , 2's complement
+ long longitude; // latitude in degrees * 2^25 , 2's complement
+ int altitude; // Altitude in units of 1/256 m
+ byte latitude_unc; // As defined in Section 2.3.2 of IETF RFC 6225
+ byte longitude_unc; // As defined in Section 2.3.2 of IETF RFC 6225
+ byte altitude_unc; // As defined in Section 2.4.5 from IETF RFC 6225:
+
+ // Following element for configuring the Z subelement
+ wifi_motion_pattern motion_pattern;
+ int floor; // floor in units of 1/16th of floor. 0x80000000 if unknown.
+ int height_above_floor; // in units of 1/64 m
+ int height_unc; // in units of 1/64 m. 0 if unknown
+} wifi_lci_information;
+
+typedef struct {
+ char country_code[2]; // country code
+ int length; // length of the info field
+ char civic_info[256]; // Civic info to be copied in FTM frame
+} wifi_lcr_information;
+
+// API to configure the LCI. Used in RTT Responder mode only
+wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface, wifi_lci_information* lci);
+
+// API to configure the LCR. Used in RTT Responder mode only.
+wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface, wifi_lcr_information* lcr);
+
+/**
+ * RTT Responder information
+ */
+typedef struct {
+ wifi_channel_info channel;
+ wifi_rtt_preamble preamble;
+} wifi_rtt_responder;
+
+/**
+ * Get RTT responder information e.g. WiFi channel to enable responder on.
+ */
+wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
+ wifi_rtt_responder* responder_info);
+
+/**
+ * Enable RTT responder mode.
+ * channel_hint - hint of the channel information where RTT responder should be enabled on.
+ * max_duration_seconds - timeout of responder mode.
+ * channel_used - channel used for RTT responder, NULL if responder is not enabled.
+ */
+wifi_error wifi_enable_responder(wifi_request_id id, wifi_interface_handle iface,
+ wifi_channel_info channel_hint, unsigned max_duration_seconds,
+ wifi_rtt_responder* responder_info);
+
+/**
+ * Disable RTT responder mode.
+ */
+wifi_error wifi_disable_responder(wifi_request_id id, wifi_interface_handle iface);
+
+#endif
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/tdls.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/tdls.h
new file mode 100644
index 0000000..787b13a
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/tdls.h
@@ -0,0 +1,84 @@
+
+#include "wifi_hal.h"
+
+#ifndef _TDLS_H_
+#define _TDLS_H_
+
+typedef enum {
+ WIFI_TDLS_DISABLED = 1, /* TDLS is not enabled, default status for all STAs */
+ WIFI_TDLS_ENABLED, /* TDLS is enabled, but not yet tried */
+ WIFI_TDLS_ESTABLISHED, /* Direct link is established */
+ WIFI_TDLS_ESTABLISHED_OFF_CHANNEL, /* Direct link is established using MCC */
+ WIFI_TDLS_DROPPED, /* Direct link was established,
+ * but is temporarily dropped now */
+ WIFI_TDLS_FAILED /* TDLS permanent failed. Inform error to upper layer
+ * and go back to WIFI_TDLS_DISABLED */
+} wifi_tdls_state;
+
+typedef enum {
+ WIFI_TDLS_SUCCESS, /* Success */
+ WIFI_TDLS_UNSPECIFIED = -1, /* Unspecified reason */
+ WIFI_TDLS_NOT_SUPPORTED = -2, /* Remote side doesn't support TDLS */
+ WIFI_TDLS_UNSUPPORTED_BAND = -3, /* Remote side doesn't support this band */
+ WIFI_TDLS_NOT_BENEFICIAL = -4, /* Going to AP is better than going direct */
+ WIFI_TDLS_DROPPED_BY_REMOTE = -5 /* Remote side doesn't want it anymore */
+} wifi_tdls_reason;
+
+typedef struct {
+ int channel; /* channel hint, in channel number (NOT frequency ) */
+ int global_operating_class; /* operating class to use */
+ int max_latency_ms; /* max latency that can be tolerated by apps */
+ int min_bandwidth_kbps; /* bandwidth required by apps, in kilo bits per second */
+} wifi_tdls_params;
+
+typedef struct {
+ int channel;
+ int global_operating_class;
+ wifi_tdls_state state;
+ wifi_tdls_reason reason;
+} wifi_tdls_status;
+
+typedef struct {
+ int max_concurrent_tdls_session_num; /* Maximum TDLS session number can be supported by the
+ * Firmware and hardware*/
+ int is_global_tdls_supported; /* 1 -- support, 0 -- not support */
+ int is_per_mac_tdls_supported; /* 1 -- support, 0 -- not support */
+ int is_off_channel_tdls_supported; /* 1 -- support, 0 -- not support */
+} wifi_tdls_capabilities;
+
+typedef struct {
+ /* on_tdls_state_changed - reports state of TDLS link to framework
+ * Report this event when the state of TDLS link changes */
+ void (*on_tdls_state_changed)(mac_addr addr, wifi_tdls_status status);
+} wifi_tdls_handler;
+
+/* wifi_enable_tdls - enables TDLS-auto mode for a specific route
+ *
+ * params specifies hints, which provide more information about
+ * why TDLS is being sought. The firmware should do its best to
+ * honor the hints before downgrading regular AP link
+ * If upper layer has no specific values, this should be NULL
+ *
+ * handler is used to inform the upper layer about the status change and the corresponding reason
+ */
+wifi_error wifi_enable_tdls(wifi_interface_handle iface, mac_addr addr, wifi_tdls_params* params,
+ wifi_tdls_handler handler);
+
+/* wifi_disable_tdls - disables TDLS-auto mode for a specific route
+ *
+ * This terminates any existing TDLS with addr device, and frees the
+ * device resources to make TDLS connections on new routes.
+ *
+ * DON'T fire any more events on 'handler' specified in earlier call to
+ * wifi_enable_tdls after this action.
+ */
+wifi_error wifi_disable_tdls(wifi_interface_handle iface, mac_addr addr);
+
+/* wifi_get_tdls_status - allows getting the status of TDLS for a specific route */
+wifi_error wifi_get_tdls_status(wifi_interface_handle iface, mac_addr addr,
+ wifi_tdls_status* status);
+
+/* return the current HW + Firmware combination's TDLS capabilities */
+wifi_error wifi_get_tdls_capabilities(wifi_interface_handle iface,
+ wifi_tdls_capabilities* capabilities);
+#endif
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/uevent.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/uevent.h
new file mode 100644
index 0000000..5b82b32
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/uevent.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _HARDWARE_UEVENT_H
+#define _HARDWARE_UEVENT_H
+
+#if __cplusplus
+extern "C" {
+#endif
+
+int uevent_init();
+int uevent_get_fd();
+int uevent_next_event(char* buffer, int buffer_length);
+int uevent_add_native_handler(void (*handler)(void* data, const char* msg, int msg_len),
+ void* handler_data);
+int uevent_remove_native_handler(void (*handler)(void* data, const char* msg, int msg_len));
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // _HARDWARE_UEVENT_H
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_cached_scan_results.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_cached_scan_results.h
new file mode 100644
index 0000000..c7392c2
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_cached_scan_results.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WIFI_CACHED_SCAN_RESULTS_H__
+#define __WIFI_CACHED_SCAN_RESULTS_H__
+
+#include "wifi_hal.h"
+
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_NONE (0)
+/* Element ID 61 (HT Operation) is present (see HT 7.3.2) */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_HT_OPS_PRESENT (1 << 0)
+/* Element ID 192 (VHT Operation) is present (see VHT 8.4.2) */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT (1 << 1)
+/* Element ID 255 + Extension 36 (HE Operation) is present
+ * (see 802.11ax 9.4.2.1)
+ */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT (1 << 2)
+/* Element ID 255 + Extension 106 (HE Operation) is present
+ * (see 802.11be D1.5 9.4.2.1)
+ */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_EHT_OPS_PRESENT (1 << 3)
+/* Element ID 127 (Extended Capabilities) is present, and bit 70
+ * (Fine Timing Measurement Responder) is set to 1
+ * (see IEEE Std 802.11-2016 9.4.2.27)
+ */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER (1 << 4)
+
+/**
+ * Provides information about a single access point (AP) detected in a scan.
+ */
+typedef struct {
+ /* Number of milliseconds prior to ts in the enclosing
+ * wifi_cached_scan_result_report struct when
+ * the probe response or beacon frame that
+ * was used to populate this structure was received.
+ */
+ u32 age_ms;
+ /* The Capability Information field */
+ u16 capability;
+ /* null terminated */
+ u8 ssid[33];
+ u8 ssid_len;
+ u8 bssid[6];
+ /* A set of flags from WIFI_CACHED_SCAN_RESULT_FLAGS_* */
+ u8 flags;
+ s8 rssi;
+ wifi_channel_spec chanspec;
+} wifi_cached_scan_result;
+
+/*
+ * Data structure sent with events of type WifiCachedScanResult.
+ */
+typedef struct {
+ /* time since boot (in microsecond) when the result was retrieved */
+ wifi_timestamp ts;
+ /* If 0, indicates that all frequencies in current regulation were
+ * scanned. Otherwise, indicates the number of frequencies scanned, as
+ * specified in scanned_freq_list.
+ */
+ u16 scanned_freq_num;
+ /* Pointer to an array containing scanned_freq_num values comprising the
+ * set of frequencies that were scanned. Frequencies are specified as
+ * channel center frequencies in MHz. May be NULL if scannedFreqListLen is
+ * 0.
+ */
+ const u32* scanned_freq_list;
+ /* The total number of cached results returned. */
+ u8 result_cnt;
+ /* Pointer to an array containing result_cnt entries. May be NULL if
+ * result_cnt is 0.
+ */
+ const wifi_cached_scan_result* results;
+} wifi_cached_scan_report;
+
+/* callback for reporting cached scan report */
+typedef struct {
+ void (*on_cached_scan_results)(wifi_cached_scan_report* cache_report);
+} wifi_cached_scan_result_handler;
+#endif
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_config.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_config.h
new file mode 100644
index 0000000..459a3fe
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_config.h
@@ -0,0 +1,44 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_CONFIG_H
+#define __WIFI_HAL_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define CONFIG_MAJOR_VERSION 1
+#define CONFIG_MINOR_VERSION 0
+#define CONFIG_MICRO_VERSION 0
+
+// whether the wifi chipset wakes at every dtim beacon or a multiple of the dtim period
+// if extended_dtim is set to 3, the STA shall wake up every 3 DTIM beacons
+wifi_error wifi_extended_dtim_config_set(wifi_request_id id, wifi_interface_handle iface,
+ int extended_dtim);
+
+// set the country code to driver
+wifi_error wifi_set_country_code(wifi_interface_handle iface, const char* country_code);
+
+// set the wifi_iface stats averaging factor used to calculate
+// statistics like average the TSF offset or average number of frame leaked
+// For instance, upon beacon reception:
+// current_avg = ((beacon_TSF - TBTT) * factor + previous_avg * (0x10000 - factor) ) / 0x10000
+// For instance, when evaluating leaky APs:
+// current_avg = ((num frame received within guard time) * factor + previous_avg * (0x10000 -
+// factor)) / 0x10000
+
+wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor(wifi_request_id id,
+ wifi_interface_handle iface,
+ u16 factor);
+
+// configure guard time, i.e. when implementing IEEE power management based on
+// frame control PM bit, how long driver waits before shutting down the radio and
+// after receiving an ACK for a data frame with PM bit set
+wifi_error wifi_set_guard_time(wifi_request_id id, wifi_interface_handle iface, u32 guard_time);
+
+#ifdef __cplusplus
+}
+
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_STATS_ */
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_hal.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_hal.h
new file mode 100644
index 0000000..383ba71
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_hal.h
@@ -0,0 +1,1020 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WIFI_HAL_H__
+#define __WIFI_HAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <stdint.h>
+
+#define IFNAMSIZ 16
+
+/* typedefs */
+typedef unsigned char byte;
+typedef unsigned char u8;
+typedef signed char s8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef int32_t s32;
+typedef uint64_t u64;
+typedef int64_t s64;
+typedef int wifi_request_id;
+typedef int wifi_channel; // indicates channel frequency in MHz
+typedef int wifi_rssi;
+typedef int wifi_radio;
+typedef byte mac_addr[6];
+typedef byte oui[3];
+typedef int64_t wifi_timestamp; // In microseconds (us)
+typedef int64_t wifi_timespan; // In picoseconds (ps)
+typedef uint64_t feature_set;
+
+/* forward declarations */
+struct wifi_info;
+struct wifi_interface_info;
+typedef struct wifi_info* wifi_handle;
+typedef struct wifi_interface_info* wifi_interface_handle;
+
+/* WiFi Common definitions */
+/* channel operating width */
+typedef enum {
+ WIFI_CHAN_WIDTH_20 = 0,
+ WIFI_CHAN_WIDTH_40 = 1,
+ WIFI_CHAN_WIDTH_80 = 2,
+ WIFI_CHAN_WIDTH_160 = 3,
+ WIFI_CHAN_WIDTH_80P80 = 4,
+ WIFI_CHAN_WIDTH_5 = 5,
+ WIFI_CHAN_WIDTH_10 = 6,
+ WIFI_CHAN_WIDTH_320 = 7,
+ WIFI_CHAN_WIDTH_INVALID = -1
+} wifi_channel_width;
+
+/* Pre selected Power scenarios to be applied from BDF file */
+typedef enum {
+ WIFI_POWER_SCENARIO_INVALID = -2,
+ WIFI_POWER_SCENARIO_DEFAULT = -1,
+ WIFI_POWER_SCENARIO_VOICE_CALL = 0,
+ WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF = 1,
+ WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON = 2,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF = 3,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_ON = 4,
+ WIFI_POWER_SCENARIO_ON_BODY_BT = 5,
+ WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT = 6,
+ WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_MMW = 7,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT = 8,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT = 9,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT = 10,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_MMW = 11,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_MMW = 12,
+ WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF_UNFOLDED = 13,
+ WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON_UNFOLDED = 14,
+ WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_UNFOLDED = 15,
+ WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_MMW_UNFOLDED = 16,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF_UNFOLDED = 17,
+ WIFI_POWER_SCENARIO_ON_BODY_BT_UNFOLDED = 18,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_UNFOLDED = 19,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT_UNFOLDED = 20,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_UNFOLDED = 21,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_UNFOLDED = 22,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_MMW_UNFOLDED = 23,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_MMW_UNFOLDED = 24,
+} wifi_power_scenario;
+
+typedef enum {
+ WIFI_LATENCY_MODE_NORMAL = 0,
+ WIFI_LATENCY_MODE_LOW = 1,
+} wifi_latency_mode;
+
+/* Wifi Thermal mitigation modes */
+typedef enum {
+ WIFI_MITIGATION_NONE = 0,
+ WIFI_MITIGATION_LIGHT = 1,
+ WIFI_MITIGATION_MODERATE = 2,
+ WIFI_MITIGATION_SEVERE = 3,
+ WIFI_MITIGATION_CRITICAL = 4,
+ WIFI_MITIGATION_EMERGENCY = 5,
+} wifi_thermal_mode;
+
+/*
+ * Wifi voice over IP mode
+ * may add new modes later, for example, voice + video over IP mode.
+ */
+typedef enum {
+ WIFI_VOIP_MODE_OFF = 0,
+ WIFI_VOIP_MODE_ON = 1,
+} wifi_voip_mode;
+
+/* List of interface types supported */
+typedef enum {
+ WIFI_INTERFACE_TYPE_STA = 0,
+ WIFI_INTERFACE_TYPE_AP = 1,
+ WIFI_INTERFACE_TYPE_P2P = 2,
+ WIFI_INTERFACE_TYPE_NAN = 3,
+} wifi_interface_type;
+
+/*
+ * enum wlan_mac_band - Band information corresponding to the WLAN MAC.
+ */
+typedef enum {
+ /* WLAN MAC Operates in 2.4 GHz Band */
+ WLAN_MAC_2_4_BAND = 1 << 0,
+ /* WLAN MAC Operates in 5 GHz Band */
+ WLAN_MAC_5_0_BAND = 1 << 1,
+ /* WLAN MAC Operates in 6 GHz Band */
+ WLAN_MAC_6_0_BAND = 1 << 2,
+ /* WLAN MAC Operates in 60 GHz Band */
+ WLAN_MAC_60_0_BAND = 1 << 3,
+} wlan_mac_band;
+
+/* List of chre nan rtt state */
+typedef enum {
+ CHRE_PREEMPTED = 0,
+ CHRE_UNAVAILABLE = 1,
+ CHRE_AVAILABLE = 2,
+} chre_nan_rtt_state;
+
+typedef struct {
+ wifi_channel_width width;
+ int center_frequency0;
+ int center_frequency1;
+ int primary_frequency;
+} wifi_channel_spec;
+
+/*
+ * wifi_usable_channel specifies a channel frequency, bandwidth, and bitmask
+ * of modes allowed on the channel.
+ */
+typedef struct {
+ /* Channel frequency in MHz */
+ wifi_channel freq;
+ /* Channel operating width (20, 40, 80, 160, 320 etc.) */
+ wifi_channel_width width;
+ /* BIT MASK of BIT(WIFI_INTERFACE_*) represented by |wifi_interface_mode|
+ * Bitmask does not represent concurrency.
+ * Examples:
+ * - If a channel is usable only for STA, then only the WIFI_INTERFACE_STA
+ * bit would be set for that channel.
+ * - If 5GHz SAP is not allowed, then none of the 5GHz channels will have
+ * WIFI_INTERFACE_SOFTAP bit set.
+ * Note: TDLS bit is set only if there is a STA connection. TDLS bit is set
+ * on non-STA channels only if TDLS off channel is supported.
+ */
+ u32 iface_mode_mask;
+} wifi_usable_channel;
+
+/*
+ * wifi_usable_channel_filter
+ */
+typedef enum {
+ /* Filter Wifi channels that should be avoided due to cellular coex
+ * restrictions. Some Wifi channels can have extreme interference
+ * from/to cellular due to short frequency separation with neighboring
+ * cellular channels or when there is harmonic and intermodulation
+ * interference. Channels which only have some performance degradation
+ * (e.g. power back off is sufficient to deal with coexistence issue)
+ * can be included and should not be filtered out.
+ */
+ WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE = 1 << 0,
+ /* Filter channels due to concurrency state.
+ * Examples:
+ * - 5GHz SAP operation may be supported in standalone mode, but if
+ * there is STA connection on 5GHz DFS channel, none of the 5GHz
+ * channels are usable for SAP if device does not support DFS SAP mode.
+ * - P2P GO may not be supported on indoor channels in EU during
+ * standalone mode but if there is a STA connection on indoor channel,
+ * P2P GO may be supported by some vendors on the same STA channel.
+ */
+ WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY = 1 << 1,
+ /* This Filter queries Wifi channels and bands that are supported for
+ * NAN3.1 Instant communication mode. This filter should only be applied to NAN interface.
+ * If 5G is supported default discovery channel 149/44 is considered,
+ * If 5G is not supported then channel 6 has to be considered.
+ * Based on regulatory domain if channel 149 and 44 are restricted, channel 6 should
+ * be considered for instant communication channel
+ */
+ WIFI_USABLE_CHANNEL_FILTER_NAN_INSTANT_MODE = 1 << 2,
+} wifi_usable_channel_filter;
+
+typedef enum {
+ WIFI_SUCCESS = 0,
+ WIFI_ERROR_NONE = 0,
+ WIFI_ERROR_UNKNOWN = -1,
+ WIFI_ERROR_UNINITIALIZED = -2,
+ WIFI_ERROR_NOT_SUPPORTED = -3,
+ WIFI_ERROR_NOT_AVAILABLE = -4, // Not available right now, but try later
+ WIFI_ERROR_INVALID_ARGS = -5,
+ WIFI_ERROR_INVALID_REQUEST_ID = -6,
+ WIFI_ERROR_TIMED_OUT = -7,
+ WIFI_ERROR_TOO_MANY_REQUESTS = -8, // Too many instances of this request
+ WIFI_ERROR_OUT_OF_MEMORY = -9,
+ WIFI_ERROR_BUSY = -10,
+} wifi_error;
+
+typedef enum {
+ WIFI_ACCESS_CATEGORY_BEST_EFFORT = 0,
+ WIFI_ACCESS_CATEGORY_BACKGROUND = 1,
+ WIFI_ACCESS_CATEGORY_VIDEO = 2,
+ WIFI_ACCESS_CATEGORY_VOICE = 3
+} wifi_access_category;
+
+/* Antenna configuration */
+typedef enum {
+ WIFI_ANTENNA_UNSPECIFIED = 0,
+ WIFI_ANTENNA_1X1 = 1,
+ WIFI_ANTENNA_2X2 = 2,
+ WIFI_ANTENNA_3X3 = 3,
+ WIFI_ANTENNA_4X4 = 4,
+} wifi_antenna_configuration;
+
+/* Wifi Radio configuration */
+typedef struct {
+ /* Operating band */
+ wlan_mac_band band;
+ /* Antenna configuration */
+ wifi_antenna_configuration antenna_cfg;
+} wifi_radio_configuration;
+
+/* WiFi Radio Combination */
+typedef struct {
+ u32 num_radio_configurations;
+ wifi_radio_configuration radio_configurations[];
+} wifi_radio_combination;
+
+/* WiFi Radio combinations matrix */
+/* For Example in case of a chip which has two radios, where one radio is
+ * capable of 2.4GHz 2X2 only and another radio which is capable of either
+ * 5GHz or 6GHz 2X2, number of possible radio combinations in this case
+ * are 5 and possible combinations are
+ * {{{2G 2X2}}, //Standalone 2G
+ * {{5G 2X2}}, //Standalone 5G
+ * {{6G 2X2}}, //Standalone 6G
+ * {{2G 2X2}, {5G 2X2}}, //2G+5G DBS
+ * {{2G 2X2}, {6G 2X2}}} //2G+6G DBS
+ * Note: Since this chip doesn’t support 5G+6G simultaneous operation
+ * as there is only one radio which can support both, So it can only
+ * do MCC 5G+6G. This table should not get populated with possible MCC
+ * configurations. This is only for simultaneous radio configurations
+ * (such as Standalone, multi band simultaneous or single band simultaneous).
+ */
+typedef struct {
+ u32 num_radio_combinations;
+ /* Each row represents possible radio combinations */
+ wifi_radio_combination radio_combinations[];
+} wifi_radio_combination_matrix;
+
+/* Initialize/Cleanup */
+
+wifi_error wifi_initialize(wifi_handle* handle);
+
+/**
+ * wifi_wait_for_driver
+ * Function should block until the driver is ready to proceed.
+ * Any errors from this function is considered fatal & will fail the HAL startup sequence.
+ *
+ * on success returns WIFI_SUCCESS
+ * on failure returns WIFI_ERROR_TIMED_OUT
+ */
+wifi_error wifi_wait_for_driver_ready(void);
+
+typedef void (*wifi_cleaned_up_handler)(wifi_handle handle);
+void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler);
+void wifi_event_loop(wifi_handle handle);
+
+/* Error handling */
+void wifi_get_error_info(wifi_error err, const char** msg); // return a pointer to a static string
+
+/* Feature enums */
+#define WIFI_FEATURE_INFRA (uint64_t)0x1 // Basic infrastructure mode
+#define WIFI_FEATURE_INFRA_5G (uint64_t)0x2 // Support for 5 GHz Band
+#define WIFI_FEATURE_HOTSPOT (uint64_t)0x4 // Support for GAS/ANQP
+#define WIFI_FEATURE_P2P (uint64_t)0x8 // Wifi-Direct
+#define WIFI_FEATURE_SOFT_AP (uint64_t)0x10 // Soft AP
+#define WIFI_FEATURE_GSCAN (uint64_t)0x20 // Google-Scan APIs
+#define WIFI_FEATURE_NAN (uint64_t)0x40 // Neighbor Awareness Networking
+#define WIFI_FEATURE_D2D_RTT (uint64_t)0x80 // Device-to-device RTT
+#define WIFI_FEATURE_D2AP_RTT (uint64_t)0x100 // Device-to-AP RTT
+#define WIFI_FEATURE_BATCH_SCAN (uint64_t)0x200 // Batched Scan (legacy)
+#define WIFI_FEATURE_PNO (uint64_t)0x400 // Preferred network offload
+#define WIFI_FEATURE_ADDITIONAL_STA (uint64_t)0x800 // Support for two STAs
+#define WIFI_FEATURE_TDLS (uint64_t)0x1000 // Tunnel directed link setup
+#define WIFI_FEATURE_TDLS_OFFCHANNEL (uint64_t)0x2000 // Support for TDLS off channel
+#define WIFI_FEATURE_EPR (uint64_t)0x4000 // Enhanced power reporting
+#define WIFI_FEATURE_AP_STA (uint64_t)0x8000 // Support for AP STA Concurrency
+#define WIFI_FEATURE_LINK_LAYER_STATS (uint64_t)0x10000 // Link layer stats collection
+#define WIFI_FEATURE_LOGGER (uint64_t)0x20000 // WiFi Logger
+#define WIFI_FEATURE_HAL_EPNO (uint64_t)0x40000 // WiFi PNO enhanced
+#define WIFI_FEATURE_RSSI_MONITOR (uint64_t)0x80000 // RSSI Monitor
+#define WIFI_FEATURE_MKEEP_ALIVE (uint64_t)0x100000 // WiFi mkeep_alive
+#define WIFI_FEATURE_CONFIG_NDO (uint64_t)0x200000 // ND offload configure
+#define WIFI_FEATURE_TX_TRANSMIT_POWER (uint64_t)0x400000 // Capture Tx transmit power levels
+#define WIFI_FEATURE_CONTROL_ROAMING (uint64_t)0x800000 // Enable/Disable firmware roaming
+#define WIFI_FEATURE_IE_WHITELIST (uint64_t)0x1000000 // Support Probe IE white listing
+#define WIFI_FEATURE_SCAN_RAND \
+ (uint64_t)0x2000000 // Support MAC & Probe Sequence Number randomization
+#define WIFI_FEATURE_SET_TX_POWER_LIMIT (uint64_t)0x4000000 // Support Tx Power Limit setting
+#define WIFI_FEATURE_USE_BODY_HEAD_SAR \
+ (uint64_t)0x8000000 // Support Using Body/Head Proximity for SAR
+#define WIFI_FEATURE_DYNAMIC_SET_MAC \
+ (uint64_t)0x10000000 // Support changing MAC address without iface reset(down and up)
+#define WIFI_FEATURE_SET_LATENCY_MODE (uint64_t)0x40000000 // Support Latency mode setting
+#define WIFI_FEATURE_P2P_RAND_MAC (uint64_t)0x80000000 // Support P2P MAC randomization
+#define WIFI_FEATURE_INFRA_60G (uint64_t)0x100000000 // Support for 60GHz Band
+// Add more features here
+
+#define IS_MASK_SET(mask, flags) (((flags) & (mask)) == (mask))
+
+#define IS_SUPPORTED_FEATURE(feature, featureSet) IS_MASK_SET(feature, featureSet)
+
+/* Feature set */
+wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set* set);
+
+/*
+ * Each row represents a valid feature combination;
+ * all other combinations are invalid!
+ */
+wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
+ feature_set set[], int* set_size);
+
+/* multiple interface support */
+
+wifi_error wifi_get_ifaces(wifi_handle handle, int* num_ifaces, wifi_interface_handle** ifaces);
+wifi_error wifi_get_iface_name(wifi_interface_handle iface, char* name, size_t size);
+wifi_interface_handle wifi_get_iface_handle(wifi_handle handle, char* name);
+
+/* STA + STA support - Supported if WIFI_FEATURE_ADDITIONAL_STA is set */
+
+/**
+ * Invoked to indicate that the provided iface is the primary STA iface when there are more
+ * than 1 STA iface concurrently active.
+ *
+ * Note: If the wifi firmware/chip cannot support multiple instances of any offload
+ * (like roaming, APF, rssi threshold, etc), the firmware should ensure that these
+ * offloads are at least enabled for the primary interface. If the new primary interface is
+ * already connected to a network, the firmware must switch all the offloads on
+ * this new interface without disconnecting.
+ */
+wifi_error wifi_multi_sta_set_primary_connection(wifi_handle handle, wifi_interface_handle iface);
+
+/**
+ * When there are 2 or more simultaneous STA connections, this use case hint indicates what
+ * use-case is being enabled by the framework. This use case hint can be used by the firmware
+ * to modify various firmware configurations like:
+ * - Allowed BSSIDs the firmware can choose for the initial connection/roaming attempts.
+ * - Duty cycle to choose for the 2 STA connections if the radio is in MCC mode.
+ * - Whether roaming, APF and other offloads needs to be enabled or not.
+ *
+ * Note:
+ * - This will be invoked before an active wifi connection is established on the second interface.
+ * - This use-case hint is implicitly void when the second STA interface is brought down.
+ */
+typedef enum {
+ /**
+ * Usage:
+ * - This will be sent down for make before break use-case.
+ * - Platform is trying to speculatively connect to a second network and evaluate it without
+ * disrupting the primary connection.
+ *
+ * Requirements for Firmware:
+ * - Do not reduce the number of tx/rx chains of primary connection.
+ * - If using MCC, should set the MCC duty cycle of the primary connection to be higher than
+ * the secondary connection (maybe 70/30 split).
+ * - Should pick the best BSSID for the secondary STA (disregard the chip mode) independent of
+ * the primary STA:
+ * - Don’t optimize for DBS vs MCC/SCC
+ * - Should not impact the primary connection’s bssid selection:
+ * - Don’t downgrade chains of the existing primary connection.
+ * - Don’t optimize for DBS vs MCC/SCC.
+ */
+ WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
+ /**
+ * Usage:
+ * - This will be sent down for any app requested peer to peer connections.
+ * - In this case, both the connections needs to be allocated equal resources.
+ * - For the peer to peer use case, BSSID for the secondary connection will be chosen by the
+ * framework.
+ *
+ * Requirements for Firmware:
+ * - Can choose MCC or DBS mode depending on the MCC efficiency and HW capability.
+ * - If using MCC, set the MCC duty cycle of the primary connection to be equal to the secondary
+ * connection.
+ * - Prefer BSSID candidates which will help provide the best "overall" performance for both the
+ * connections.
+ */
+ WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED = 1
+} wifi_multi_sta_use_case;
+
+wifi_error wifi_multi_sta_set_use_case(wifi_handle handle, wifi_multi_sta_use_case use_case);
+
+/* Configuration events */
+
+typedef struct {
+ void (*on_country_code_changed)(char code[2]); // We can get this from supplicant too
+
+ // More event handlers
+} wifi_event_handler;
+
+typedef struct {
+ char iface_name[IFNAMSIZ + 1];
+ wifi_channel channel;
+} wifi_iface_info;
+
+typedef struct {
+ u32 wlan_mac_id;
+ /* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */
+ u32 mac_band;
+ /* Represents the connected Wi-Fi interfaces associated with each MAC */
+ int num_iface;
+ wifi_iface_info* iface_info;
+} wifi_mac_info;
+
+typedef struct {
+ void (*on_radio_mode_change)(wifi_request_id id, unsigned num_mac, wifi_mac_info* mac_info);
+} wifi_radio_mode_change_handler;
+
+typedef struct {
+ void (*on_rssi_threshold_breached)(wifi_request_id id, u8* cur_bssid, s8 cur_rssi);
+} wifi_rssi_event_handler;
+
+typedef struct {
+ void (*on_subsystem_restart)(const char* error);
+} wifi_subsystem_restart_handler;
+
+typedef struct {
+ void (*on_chre_nan_rtt_change)(chre_nan_rtt_state state);
+} wifi_chre_handler;
+
+wifi_error wifi_set_iface_event_handler(wifi_request_id id, wifi_interface_handle iface,
+ wifi_event_handler eh);
+wifi_error wifi_reset_iface_event_handler(wifi_request_id id, wifi_interface_handle iface);
+
+wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs);
+wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle,
+ wifi_power_scenario scenario);
+wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle);
+wifi_error wifi_set_latency_mode(wifi_interface_handle handle, wifi_latency_mode mode);
+wifi_error wifi_map_dscp_access_category(wifi_handle handle, uint32_t start, uint32_t end,
+ uint32_t access_category);
+wifi_error wifi_reset_dscp_mapping(wifi_handle handle);
+
+wifi_error wifi_set_subsystem_restart_handler(wifi_handle handle,
+ wifi_subsystem_restart_handler handler);
+
+/**
+ * Wifi HAL Thermal Mitigation API
+ *
+ * wifi_handle : wifi global handle (note: this is not a interface specific
+ * command). Mitigation is expected to be applied across all active interfaces
+ * The implementation and the mitigation action mapping to each mode is chip
+ * specific. Mitigation will be active until Wifi is turned off or
+ * WIFI_MITIGATION_NONE mode is sent
+ *
+ * mode: Thermal mitigation mode
+ * WIFI_MITIGATION_NONE : Clear all Wifi thermal mitigation actions
+ * WIFI_MITIGATION_LIGHT : Light Throttling where UX is not impacted
+ * WIFI_MITIGATION_MODERATE : Moderate throttling where UX not largely impacted
+ * WIFI_MITIGATION_SEVERE : Severe throttling where UX is largely impacted
+ * WIFI_MITIGATION_CRITICAL : Platform has done everything to reduce power
+ * WIFI_MITIGATION_EMERGENCY: Key components in platform are shutting down
+ *
+ * completion_window
+ * Deadline (in milliseconds) to complete this request, value 0 implies apply
+ * immediately. Deadline is basically a relaxed limit and allows vendors to
+ * apply the mitigation within the window (if it cannot apply immediately)
+ *
+ * Return
+ * WIFI_ERROR_NOT_SUPPORTED : Chip does not support thermal mitigation
+ * WIFI_ERROR_BUSY : Mitigation is supported, but retry later
+ * WIFI_ERROR_NONE : Mitigation request has been accepted
+ */
+wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle, wifi_thermal_mode mode,
+ u32 completion_window);
+
+typedef struct rx_data_cnt_details_t {
+ int rx_unicast_cnt; /*Total rx unicast packet which woke up host */
+ int rx_multicast_cnt; /*Total rx multicast packet which woke up host */
+ int rx_broadcast_cnt; /*Total rx broadcast packet which woke up host */
+} RX_DATA_WAKE_CNT_DETAILS;
+
+typedef struct rx_wake_pkt_type_classification_t {
+ int icmp_pkt; /*wake icmp packet count */
+ int icmp6_pkt; /*wake icmp6 packet count */
+ int icmp6_ra; /*wake icmp6 RA packet count */
+ int icmp6_na; /*wake icmp6 NA packet count */
+ int icmp6_ns; /*wake icmp6 NS packet count */
+ // ToDo: Any more interesting classification to add?
+} RX_WAKE_PKT_TYPE_CLASSFICATION;
+
+typedef struct rx_multicast_cnt_t {
+ int ipv4_rx_multicast_addr_cnt; /*Rx wake packet was ipv4 multicast */
+ int ipv6_rx_multicast_addr_cnt; /*Rx wake packet was ipv6 multicast */
+ int other_rx_multicast_addr_cnt; /*Rx wake packet was non-ipv4 and non-ipv6*/
+} RX_MULTICAST_WAKE_DATA_CNT;
+
+/*
+ * Structure holding all the driver/firmware wake count reasons.
+ *
+ * Buffers for the array fields (cmd_event_wake_cnt/driver_fw_local_wake_cnt)
+ * are allocated and freed by the framework. The size of each allocated
+ * array is indicated by the corresponding |_cnt| field. HAL needs to fill in
+ * the corresponding |_used| field to indicate the number of elements used in
+ * the array.
+ */
+typedef struct wlan_driver_wake_reason_cnt_t {
+ int total_cmd_event_wake; /* Total count of cmd event wakes */
+ int* cmd_event_wake_cnt; /* Individual wake count array, each index a reason */
+ int cmd_event_wake_cnt_sz; /* Max number of cmd event wake reasons */
+ int cmd_event_wake_cnt_used; /* Number of cmd event wake reasons specific to the driver */
+
+ int total_driver_fw_local_wake; /* Total count of drive/fw wakes, for local reasons */
+ int* driver_fw_local_wake_cnt; /* Individual wake count array, each index a reason */
+ int driver_fw_local_wake_cnt_sz; /* Max number of local driver/fw wake reasons */
+ int driver_fw_local_wake_cnt_used; /* Number of local driver/fw wake reasons specific to the
+ driver */
+
+ int total_rx_data_wake; /* total data rx packets, that woke up host */
+ RX_DATA_WAKE_CNT_DETAILS rx_wake_details;
+ RX_WAKE_PKT_TYPE_CLASSFICATION rx_wake_pkt_classification_info;
+ RX_MULTICAST_WAKE_DATA_CNT rx_multicast_wake_pkt_info;
+} WLAN_DRIVER_WAKE_REASON_CNT;
+
+/* Wi-Fi coex channel avoidance support */
+
+#define WIFI_COEX_NO_POWER_CAP (int32_t)0x7FFFFFF
+
+typedef enum { WIFI_AWARE = 1 << 0, SOFTAP = 1 << 1, WIFI_DIRECT = 1 << 2 } wifi_coex_restriction;
+
+/**
+ * Representation of a Wi-Fi channel to be avoided for Wi-Fi coex channel avoidance.
+ *
+ * band is represented as an WLAN_MAC* enum value defined in wlan_mac_band.
+ * If power_cap_dbm is WIFI_COEX_NO_POWER_CAP, then no power cap should be applied if the specified
+ * channel is used.
+ */
+typedef struct {
+ wlan_mac_band band;
+ u32 channel;
+ s32 power_cap_dbm;
+} wifi_coex_unsafe_channel;
+
+/* include various feature headers */
+
+#include "gscan.h"
+#include "link_layer_stats.h"
+#include "roam.h"
+#include "rtt.h"
+#include "tdls.h"
+#include "wifi_cached_scan_results.h"
+#include "wifi_config.h"
+#include "wifi_logger.h"
+#include "wifi_nan.h"
+#include "wifi_offload.h"
+#include "wifi_twt.h"
+
+// wifi HAL function pointer table
+typedef struct {
+ wifi_error (*wifi_initialize)(wifi_handle*);
+ wifi_error (*wifi_wait_for_driver_ready)(void);
+ void (*wifi_cleanup)(wifi_handle, wifi_cleaned_up_handler);
+ void (*wifi_event_loop)(wifi_handle);
+ void (*wifi_get_error_info)(wifi_error, const char**);
+ wifi_error (*wifi_get_supported_feature_set)(wifi_interface_handle, feature_set*);
+ wifi_error (*wifi_get_concurrency_matrix)(wifi_interface_handle, int, feature_set*, int*);
+ wifi_error (*wifi_set_scanning_mac_oui)(wifi_interface_handle, unsigned char*);
+ wifi_error (*wifi_get_supported_channels)(wifi_handle, int*, wifi_channel*);
+ wifi_error (*wifi_is_epr_supported)(wifi_handle);
+ wifi_error (*wifi_get_ifaces)(wifi_handle, int*, wifi_interface_handle**);
+ wifi_error (*wifi_get_iface_name)(wifi_interface_handle, char* name, size_t);
+ wifi_error (*wifi_set_iface_event_handler)(wifi_request_id, wifi_interface_handle,
+ wifi_event_handler);
+ wifi_error (*wifi_reset_iface_event_handler)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_start_gscan)(wifi_request_id, wifi_interface_handle, wifi_scan_cmd_params,
+ wifi_scan_result_handler);
+ wifi_error (*wifi_stop_gscan)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_get_cached_gscan_results)(wifi_interface_handle, byte, int,
+ wifi_cached_scan_results*, int*);
+ wifi_error (*wifi_set_bssid_hotlist)(wifi_request_id, wifi_interface_handle,
+ wifi_bssid_hotlist_params, wifi_hotlist_ap_found_handler);
+ wifi_error (*wifi_reset_bssid_hotlist)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_set_significant_change_handler)(wifi_request_id, wifi_interface_handle,
+ wifi_significant_change_params,
+ wifi_significant_change_handler);
+ wifi_error (*wifi_reset_significant_change_handler)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_get_gscan_capabilities)(wifi_interface_handle, wifi_gscan_capabilities*);
+ wifi_error (*wifi_set_link_stats)(wifi_interface_handle, wifi_link_layer_params);
+ wifi_error (*wifi_get_link_stats)(wifi_request_id, wifi_interface_handle,
+ wifi_stats_result_handler);
+ wifi_error (*wifi_clear_link_stats)(wifi_interface_handle, u32, u32*, u8, u8*);
+ wifi_error (*wifi_get_valid_channels)(wifi_interface_handle, int, int, wifi_channel*, int*);
+ wifi_error (*wifi_rtt_range_request)(wifi_request_id, wifi_interface_handle, unsigned,
+ wifi_rtt_config[], wifi_rtt_event_handler);
+ wifi_error (*wifi_rtt_range_cancel)(wifi_request_id, wifi_interface_handle, unsigned,
+ mac_addr[]);
+ wifi_error (*wifi_get_rtt_capabilities)(wifi_interface_handle, wifi_rtt_capabilities*);
+ wifi_error (*wifi_rtt_get_responder_info)(wifi_interface_handle iface,
+ wifi_rtt_responder* responder_info);
+ wifi_error (*wifi_enable_responder)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_channel_info channel_hint,
+ unsigned max_duration_seconds,
+ wifi_rtt_responder* responder_info);
+ wifi_error (*wifi_disable_responder)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_set_nodfs_flag)(wifi_interface_handle, u32);
+ wifi_error (*wifi_start_logging)(wifi_interface_handle, u32, u32, u32, u32, char*);
+ wifi_error (*wifi_set_epno_list)(wifi_request_id, wifi_interface_handle,
+ const wifi_epno_params*, wifi_epno_handler);
+ wifi_error (*wifi_reset_epno_list)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_set_country_code)(wifi_interface_handle, const char*);
+ wifi_error (*wifi_get_firmware_memory_dump)(wifi_interface_handle iface,
+ wifi_firmware_memory_dump_handler handler);
+ wifi_error (*wifi_set_log_handler)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_ring_buffer_data_handler handler);
+ wifi_error (*wifi_reset_log_handler)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_set_alert_handler)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_alert_handler handler);
+ wifi_error (*wifi_reset_alert_handler)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_get_firmware_version)(wifi_interface_handle iface, char* buffer,
+ int buffer_size);
+ wifi_error (*wifi_get_ring_buffers_status)(wifi_interface_handle iface, u32* num_rings,
+ wifi_ring_buffer_status* status);
+ wifi_error (*wifi_get_logger_supported_feature_set)(wifi_interface_handle iface,
+ unsigned int* support);
+ wifi_error (*wifi_get_ring_data)(wifi_interface_handle iface, char* ring_name);
+ wifi_error (*wifi_enable_tdls)(wifi_interface_handle, mac_addr, wifi_tdls_params*,
+ wifi_tdls_handler);
+ wifi_error (*wifi_disable_tdls)(wifi_interface_handle, mac_addr);
+ wifi_error (*wifi_get_tdls_status)(wifi_interface_handle, mac_addr, wifi_tdls_status*);
+ wifi_error (*wifi_get_tdls_capabilities)(wifi_interface_handle iface,
+ wifi_tdls_capabilities* capabilities);
+ wifi_error (*wifi_get_driver_version)(wifi_interface_handle iface, char* buffer,
+ int buffer_size);
+ wifi_error (*wifi_set_passpoint_list)(wifi_request_id id, wifi_interface_handle iface, int num,
+ wifi_passpoint_network* networks,
+ wifi_passpoint_event_handler handler);
+ wifi_error (*wifi_reset_passpoint_list)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_set_lci)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_lci_information* lci);
+ wifi_error (*wifi_set_lcr)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_lcr_information* lcr);
+ wifi_error (*wifi_start_sending_offloaded_packet)(wifi_request_id id,
+ wifi_interface_handle iface, u16 ether_type,
+ u8* ip_packet, u16 ip_packet_len,
+ u8* src_mac_addr, u8* dst_mac_addr,
+ u32 period_msec);
+ wifi_error (*wifi_stop_sending_offloaded_packet)(wifi_request_id id,
+ wifi_interface_handle iface);
+ wifi_error (*wifi_start_rssi_monitoring)(wifi_request_id id, wifi_interface_handle iface,
+ s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh);
+ wifi_error (*wifi_stop_rssi_monitoring)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_get_wake_reason_stats)(wifi_interface_handle iface,
+ WLAN_DRIVER_WAKE_REASON_CNT* wifi_wake_reason_cnt);
+ wifi_error (*wifi_configure_nd_offload)(wifi_interface_handle iface, u8 enable);
+ wifi_error (*wifi_get_driver_memory_dump)(wifi_interface_handle iface,
+ wifi_driver_memory_dump_callbacks callbacks);
+ wifi_error (*wifi_start_pkt_fate_monitoring)(wifi_interface_handle iface);
+ wifi_error (*wifi_get_tx_pkt_fates)(wifi_interface_handle handle,
+ wifi_tx_report* tx_report_bufs, size_t n_requested_fates,
+ size_t* n_provided_fates);
+ wifi_error (*wifi_get_rx_pkt_fates)(wifi_interface_handle handle,
+ wifi_rx_report* rx_report_bufs, size_t n_requested_fates,
+ size_t* n_provided_fates);
+
+ /* NAN functions */
+ wifi_error (*wifi_nan_enable_request)(transaction_id id, wifi_interface_handle iface,
+ NanEnableRequest* msg);
+ wifi_error (*wifi_nan_disable_request)(transaction_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_nan_publish_request)(transaction_id id, wifi_interface_handle iface,
+ NanPublishRequest* msg);
+ wifi_error (*wifi_nan_publish_cancel_request)(transaction_id id, wifi_interface_handle iface,
+ NanPublishCancelRequest* msg);
+ wifi_error (*wifi_nan_subscribe_request)(transaction_id id, wifi_interface_handle iface,
+ NanSubscribeRequest* msg);
+ wifi_error (*wifi_nan_subscribe_cancel_request)(transaction_id id, wifi_interface_handle iface,
+ NanSubscribeCancelRequest* msg);
+ wifi_error (*wifi_nan_transmit_followup_request)(transaction_id id, wifi_interface_handle iface,
+ NanTransmitFollowupRequest* msg);
+ wifi_error (*wifi_nan_stats_request)(transaction_id id, wifi_interface_handle iface,
+ NanStatsRequest* msg);
+ wifi_error (*wifi_nan_config_request)(transaction_id id, wifi_interface_handle iface,
+ NanConfigRequest* msg);
+ wifi_error (*wifi_nan_tca_request)(transaction_id id, wifi_interface_handle iface,
+ NanTCARequest* msg);
+ wifi_error (*wifi_nan_beacon_sdf_payload_request)(transaction_id id,
+ wifi_interface_handle iface,
+ NanBeaconSdfPayloadRequest* msg);
+ wifi_error (*wifi_nan_register_handler)(wifi_interface_handle iface,
+ NanCallbackHandler handlers);
+ wifi_error (*wifi_nan_get_version)(wifi_handle handle, NanVersion* version);
+ wifi_error (*wifi_nan_get_capabilities)(transaction_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_nan_data_interface_create)(transaction_id id, wifi_interface_handle iface,
+ char* iface_name);
+ wifi_error (*wifi_nan_data_interface_delete)(transaction_id id, wifi_interface_handle iface,
+ char* iface_name);
+ wifi_error (*wifi_nan_data_request_initiator)(transaction_id id, wifi_interface_handle iface,
+ NanDataPathInitiatorRequest* msg);
+ wifi_error (*wifi_nan_data_indication_response)(transaction_id id, wifi_interface_handle iface,
+ NanDataPathIndicationResponse* msg);
+ wifi_error (*wifi_nan_data_end)(transaction_id id, wifi_interface_handle iface,
+ NanDataPathEndRequest* msg);
+ wifi_error (*wifi_select_tx_power_scenario)(wifi_interface_handle iface,
+ wifi_power_scenario scenario);
+ wifi_error (*wifi_reset_tx_power_scenario)(wifi_interface_handle iface);
+
+ /**
+ * Returns the chipset's hardware filtering capabilities:
+ * @param version pointer to version of the packet filter interpreter
+ *                supported, filled in upon return. 0 indicates no support.
+ * @param max_len pointer to maximum size of the filter bytecode, filled in
+ *                upon return.
+ */
+ wifi_error (*wifi_get_packet_filter_capabilities)(wifi_interface_handle handle, u32* version,
+ u32* max_len);
+ /**
+     * Programs the packet filter.
+ * @param program pointer to the program byte-code.
+ * @param len length of the program byte-code.
+     */
+ wifi_error (*wifi_set_packet_filter)(wifi_interface_handle handle, const u8* program, u32 len);
+ wifi_error (*wifi_read_packet_filter)(wifi_interface_handle handle, u32 src_offset,
+ u8* host_dst, u32 length);
+ wifi_error (*wifi_get_roaming_capabilities)(wifi_interface_handle handle,
+ wifi_roaming_capabilities* caps);
+ wifi_error (*wifi_enable_firmware_roaming)(wifi_interface_handle handle,
+ fw_roaming_state_t state);
+ wifi_error (*wifi_configure_roaming)(wifi_interface_handle handle,
+ wifi_roaming_config* roaming_config);
+ wifi_error (*wifi_set_radio_mode_change_handler)(wifi_request_id id,
+ wifi_interface_handle iface,
+ wifi_radio_mode_change_handler eh);
+ wifi_error (*wifi_set_latency_mode)(wifi_interface_handle iface, wifi_latency_mode mode);
+ wifi_error (*wifi_set_thermal_mitigation_mode)(wifi_handle handle, wifi_thermal_mode mode,
+ u32 completion_window);
+ wifi_error (*wifi_map_dscp_access_category)(wifi_handle handle, u32 start, u32 end,
+ u32 access_category);
+ wifi_error (*wifi_reset_dscp_mapping)(wifi_handle handle);
+
+ wifi_error (*wifi_virtual_interface_create)(wifi_handle handle, const char* ifname,
+ wifi_interface_type iface_type);
+ wifi_error (*wifi_virtual_interface_delete)(wifi_handle handle, const char* ifname);
+
+ wifi_error (*wifi_set_subsystem_restart_handler)(wifi_handle handle,
+ wifi_subsystem_restart_handler handler);
+
+ /**
+ * Allow vendor HAL to choose interface name when creating
+ * an interface. This can be implemented by chips with their
+ * own interface naming policy.
+ * If not implemented, the default naming will be used.
+ */
+ wifi_error (*wifi_get_supported_iface_name)(wifi_handle handle, u32 iface_type, char* name,
+ size_t len);
+
+ /**
+ * Perform early initialization steps that are needed when WIFI
+ * is disabled.
+ * If the function returns failure, it means the vendor HAL is unusable
+ * (for example, if chip hardware is not installed) and no further
+ * functions should be called.
+ */
+ wifi_error (*wifi_early_initialize)(void);
+
+ /**
+ * Get supported feature set which are chip-global, that is
+ * not dependent on any created interface.
+ */
+ wifi_error (*wifi_get_chip_feature_set)(wifi_handle handle, feature_set* set);
+
+ /**
+ * Invoked to indicate that the provided iface is the primary STA iface when there are more
+ * than 1 STA iface concurrently active.
+ */
+ wifi_error (*wifi_multi_sta_set_primary_connection)(wifi_handle handle,
+ wifi_interface_handle iface);
+
+ /**
+ * When there are 2 simultaneous STA connections, this use case hint
+ * indicates what STA + STA use-case is being enabled by the framework.
+ */
+ wifi_error (*wifi_multi_sta_set_use_case)(wifi_handle handle, wifi_multi_sta_use_case use_case);
+
+ /**
+ * Invoked to indicate that the following list of wifi_coex_unsafe_channel should be avoided
+ * with the specified restrictions.
+ * @param unsafeChannels list of current |wifi_coex_unsafe_channel| to avoid.
+ * @param restrictions bitmask of |wifi_coex_restriction| indicating wifi interfaces to
+ * restrict from the current unsafe channels.
+ */
+ wifi_error (*wifi_set_coex_unsafe_channels)(wifi_handle handle, u32 num_channels,
+ wifi_coex_unsafe_channel* unsafeChannels,
+ u32 restrictions);
+
+ /**
+ * Invoked to set voip optimization mode for the provided STA iface
+ */
+ wifi_error (*wifi_set_voip_mode)(wifi_interface_handle iface, wifi_voip_mode mode);
+
+ /**@brief twt_register_handler
+ * Request to register TWT callback before sending any TWT request
+ * @param wifi_interface_handle:
+ * @param TwtCallbackHandler: callback function pointers
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_twt_register_handler)(wifi_interface_handle iface,
+ TwtCallbackHandler handler);
+
+ /**@brief twt_get_capability
+ * Request TWT capability
+ * @param wifi_interface_handle:
+ * @return Synchronous wifi_error and TwtCapabilitySet
+ */
+ wifi_error (*wifi_twt_get_capability)(wifi_interface_handle iface,
+ TwtCapabilitySet* twt_cap_set);
+
+ /**@brief twt_setup_request
+ * Request to send TWT setup frame
+ * @param wifi_interface_handle:
+ * @param TwtSetupRequest: detailed parameters of setup request
+ * @return Synchronous wifi_error
+ * @return Asynchronous EventTwtSetupResponse CB return TwtSetupResponse
+ */
+ wifi_error (*wifi_twt_setup_request)(wifi_interface_handle iface, TwtSetupRequest* msg);
+
+ /**@brief twt_teardown_request
+ * Request to send TWT teardown frame
+ * @param wifi_interface_handle:
+ * @param TwtTeardownRequest: detailed parameters of teardown request
+ * @return Synchronous wifi_error
+ * @return Asynchronous EventTwtTeardownCompletion CB return TwtTeardownCompletion
+ * TwtTeardownCompletion may also be received due to other events
+ * like CSA, BTCX, TWT scheduler, MultiConnection, peer-initiated teardown, etc.
+ */
+ wifi_error (*wifi_twt_teardown_request)(wifi_interface_handle iface, TwtTeardownRequest* msg);
+
+ /**@brief twt_info_frame_request
+ * Request to send TWT info frame
+ * @param wifi_interface_handle:
+ * @param TwtInfoFrameRequest: detailed parameters in info frame
+ * @return Synchronous wifi_error
+ * @return Asynchronous EventTwtInfoFrameReceived CB return TwtInfoFrameReceived
+ * Driver may also receive Peer-initiated TwtInfoFrame
+ */
+ wifi_error (*wifi_twt_info_frame_request)(wifi_interface_handle iface,
+ TwtInfoFrameRequest* msg);
+
+ /**@brief twt_get_stats
+ * Request to get TWT stats
+ * @param wifi_interface_handle:
+ * @param config_id: configuration ID of TWT request
+ * @return Synchronous wifi_error and TwtStats
+ */
+ wifi_error (*wifi_twt_get_stats)(wifi_interface_handle iface, u8 config_id, TwtStats* stats);
+
+ /**@brief twt_clear_stats
+ * Request to clear TWT stats
+ * @param wifi_interface_handle:
+ * @param config_id: configuration ID of TWT request
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_twt_clear_stats)(wifi_interface_handle iface, u8 config_id);
+
+ /**
+ * Invoked to set DTIM configuration when the host is in the suspend mode
+ * @param wifi_interface_handle:
+ * @param multiplier: when STA in the power saving mode, the wake up interval will be set to
+ * 1) multiplier * DTIM period if multiplier > 0.
+ * 2) the device default value if multiplier <=0
+ * Some implementations may apply an additional cap to wake up interval in the case of 1).
+ */
+ wifi_error (*wifi_set_dtim_config)(wifi_interface_handle handle, u32 multiplier);
+
+ /**@brief wifi_get_usable_channels
+ * Request list of usable channels for the requested bands and modes. Usable
+ * implies channel is allowed as per regulatory for the current country code
+ * and not restricted due to other hard limitations (e.g. DFS, Coex) In
+ * certain modes (e.g. STA+SAP) there could be other hard restrictions
+ * since MCC operation many not be supported by SAP. This API also allows
+ * driver to return list of usable channels for each mode uniquely to
+ * distinguish cases where only a limited set of modes are allowed on
+ * a given channel e.g. srd channels may be supported for P2P but not
+ * for SAP or P2P-Client may be allowed on an indoor channel but P2P-GO
+ * may not be allowed. This API is not interface specific and will be
+ * used to query capabilities of driver in terms of what modes (STA, SAP,
+ * P2P_CLI, P2P_GO, NAN, TDLS) can be supported on each of the channels.
+ * @param handle global wifi_handle
+ * @param band_mask BIT MASK of WLAN_MAC* as represented by |wlan_mac_band|
+ * @param iface_mode_mask BIT MASK of BIT(WIFI_INTERFACE_*) represented by
+ * |wifi_interface_mode|. Bitmask respresents all the modes that the
+ * caller is interested in (e.g. STA, SAP, WFD-CLI, WFD-GO, TDLS, NAN).
+ * Note: Bitmask does not represent concurrency matrix. If the caller
+ * is interested in CLI, GO modes, the iface_mode_mask would be set
+ * to WIFI_INTERFACE_P2P_CLIENT|WIFI_INTERFACE_P2P_GO.
+ * @param filter_mask BIT MASK of WIFI_USABLE_CHANNEL_FILTER_* represented by
+ * |wifi_usable_channel_filter|. Indicates if the channel list should
+ * be filtered based on additional criteria. If filter_mask is not
+ * specified, driver should return list of usable channels purely
+ * based on regulatory constraints.
+ * @param max_size maximum number of |wifi_usable_channel|
+ * @param size actual number of |wifi_usable_channel| entries returned by driver
+ * @param channels list of usable channels represented by |wifi_usable_channel|
+ */
+ wifi_error (*wifi_get_usable_channels)(wifi_handle handle, u32 band_mask, u32 iface_mode_mask,
+ u32 filter_mask, u32 max_size, u32* size,
+ wifi_usable_channel* channels);
+
+ /**
+ * Trigger wifi subsystem restart to reload firmware
+ */
+ wifi_error (*wifi_trigger_subsystem_restart)(wifi_handle handle);
+
+ /**
+ * Invoked to set that the device is operating in an indoor environment.
+ * @param handle global wifi_handle
+ * @param isIndoor: true if the device is operating in an indoor
+ * environment, false otherwise.
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_set_indoor_state)(wifi_handle handle, bool isIndoor);
+
+ /**@brief wifi_get_supported_radio_combinations_matrix
+ * Request all the possible radio combinations this device can offer.
+ * @param handle global wifi_handle
+ * @param max_size maximum size allocated for filling the wifi_radio_combination_matrix
+ * @param wifi_radio_combination_matrix to return all the possible radio
+ * combinations.
+ * @param size actual size of wifi_radio_combination_matrix returned from
+ * lower layer
+ *
+ */
+ wifi_error (*wifi_get_supported_radio_combinations_matrix)(
+ wifi_handle handle, u32 max_size, u32* size,
+ wifi_radio_combination_matrix* radio_combination_matrix);
+
+ /**@brief wifi_nan_rtt_chre_enable_request
+ * Request to enable CHRE NAN RTT
+ * @param transaction_id: NAN transaction id
+ * @param wifi_interface_handle
+ * @param NanEnableRequest request message
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_nan_rtt_chre_enable_request)(transaction_id id, wifi_interface_handle iface,
+ NanEnableRequest* msg);
+
+ /**@brief wifi_nan_rtt_chre_disable_request
+ * Request to disable CHRE NAN RTT
+ * @param transaction_id: NAN transaction id
+ * @param wifi_interface_handle
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_nan_rtt_chre_disable_request)(transaction_id id, wifi_interface_handle iface);
+
+ /**@brief wifi_chre_register_handler
+ * register a handler to get the state of CHR
+ * @param wifi_interface_handle
+ * @param wifi_chre_handler: callback function pointer
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_chre_register_handler)(wifi_interface_handle iface,
+ wifi_chre_handler handler);
+
+ /**@brief wifi_enable_tx_power_limits
+ * Enable WiFi Tx power limis
+ * @param wifi_interface_handle
+ * @param isEnable : If enable TX limit or not
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_enable_tx_power_limits)(wifi_interface_handle iface, bool isEnable);
+
+ /**@brief wifi_get_cached_scan_results
+ * Retrieve scan results cached in wifi firmware
+ * @param wifi_interface_handle
+ * @param wifi_cached_scan_result_handler : callback function pointer
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_get_cached_scan_results)(wifi_interface_handle iface,
+ wifi_cached_scan_result_handler handler);
+ /*
+ * when adding new functions make sure to add stubs in
+ * hal_tool.cpp::init_wifi_stub_hal_func_table
+ */
+} wifi_hal_fn;
+
+wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn* fn);
+typedef wifi_error (*init_wifi_vendor_hal_func_table_t)(wifi_hal_fn* fn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_logger.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_logger.h
new file mode 100644
index 0000000..76d6f74
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_logger.h
@@ -0,0 +1,650 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_LOGGER_H
+#define __WIFI_HAL_LOGGER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define LOGGER_MAJOR_VERSION 1
+#define LOGGER_MINOR_VERSION 0
+#define LOGGER_MICRO_VERSION 0
+
+/**
+ * WiFi logger life cycle is as follow:
+ *
+ * - At initialization time, framework will call wifi_get_ring_buffers_status
+ * so as to obtain the names and list of supported buffers.
+ * - When WiFi operation start framework will call wifi_start_logging
+ * so as to trigger log collection.
+ * - Developper UI will provide an option to the user, so as it can set the verbose level
+ * of individual buffer as reported by wifi_get_ring_buffers_status.
+ * - During wifi operations, driver will periodically report per ring data to framework
+ * by invoking the on_ring_buffer_data call back.
+ * - when capturing a bug report, framework will indicate to driver that all the data
+ * has to be uploaded, urgently, by calling wifi_get_ring_data.
+ *
+ * The data uploaded by driver will be stored by framework in separate files, with one stream
+ * of file per ring.
+ * Framework will store the files in pcapng format, allowing for easy merging and parsing
+ * with network analyzer tools.
+ */
+
+typedef int wifi_ring_buffer_id;
+
+#define PER_PACKET_ENTRY_FLAGS_DIRECTION_TX 1 // 0: TX, 1: RX
+#define PER_PACKET_ENTRY_FLAGS_TX_SUCCESS \
+ 2 // whether packet was transmitted or
+ // received/decrypted successfully
+#define PER_PACKET_ENTRY_FLAGS_80211_HEADER 4 // has full 802.11 header, else has 802.3 header
+#define PER_PACKET_ENTRY_FLAGS_PROTECTED 8 // whether packet was encrypted
+
+typedef struct {
+ u8 flags;
+ u8 tid; // transmit or received tid
+ u16 MCS; // modulation and bandwidth
+ u8 rssi; // TX: RSSI of ACK for that packet
+ // RX: RSSI of packet
+ u8 num_retries; // number of attempted retries
+ u16 last_transmit_rate; // last transmit rate in .5 mbps
+ u16 link_layer_transmit_sequence; // transmit/reeive sequence for that MPDU packet
+ u64 firmware_entry_timestamp; // TX: firmware timestamp (us) when packet is queued within
+ // firmware buffer for SDIO/HSIC or into PCIe buffer
+ // RX: firmware receive timestamp
+ u64 start_contention_timestamp; // firmware timestamp (us) when packet start contending for the
+ // medium for the first time, at head of its AC queue,
+ // or as part of an MPDU or A-MPDU. This timestamp is
+ // not updated for each retry, only the first transmit attempt.
+ u64 transmit_success_timestamp; // fimrware timestamp (us) when packet is successfully
+ // transmitted or aborted because it has exhausted
+ // its maximum number of retries.
+ u8 data[0]; // packet data. The length of packet data is determined by the entry_size field of
+ // the wifi_ring_buffer_entry structure. It is expected that first bytes of the
+ // packet, or packet headers only (up to TCP or RTP/UDP headers)
+ // will be copied into the ring
+} __attribute__((packed)) wifi_ring_per_packet_status_entry;
+
+/* Below events refer to the wifi_connectivity_event ring and shall be supported */
+#define WIFI_EVENT_ASSOCIATION_REQUESTED 0 // driver receives association command from kernel
+#define WIFI_EVENT_AUTH_COMPLETE 1
+#define WIFI_EVENT_ASSOC_COMPLETE 2
+#define WIFI_EVENT_FW_AUTH_STARTED 3 // fw event indicating auth frames are sent
+#define WIFI_EVENT_FW_ASSOC_STARTED 4 // fw event indicating assoc frames are sent
+#define WIFI_EVENT_FW_RE_ASSOC_STARTED 5 // fw event indicating reassoc frames are sent
+#define WIFI_EVENT_DRIVER_SCAN_REQUESTED 6
+#define WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND 7
+#define WIFI_EVENT_DRIVER_SCAN_COMPLETE 8
+#define WIFI_EVENT_G_SCAN_STARTED 9
+#define WIFI_EVENT_G_SCAN_COMPLETE 10
+#define WIFI_EVENT_DISASSOCIATION_REQUESTED 11
+#define WIFI_EVENT_RE_ASSOCIATION_REQUESTED 12
+#define WIFI_EVENT_ROAM_REQUESTED 13
+#define WIFI_EVENT_BEACON_RECEIVED \
+ 14 // received beacon from AP (event enabled
+ // only in verbose mode)
+#define WIFI_EVENT_ROAM_SCAN_STARTED 15 // firmware has triggered a roam scan (not g-scan)
+#define WIFI_EVENT_ROAM_SCAN_COMPLETE 16 // firmware has completed a roam scan (not g-scan)
+#define WIFI_EVENT_ROAM_SEARCH_STARTED \
+ 17 // firmware has started searching for roam
+ // candidates (with reason =xx)
+#define WIFI_EVENT_ROAM_SEARCH_STOPPED \
+ 18 // firmware has stopped searching for roam
+ // candidates (with reason =xx)
+#define WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT 20 // received channel switch anouncement from AP
+#define WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START \
+ 21 // fw start transmit eapol frame, with
+ // EAPOL index 1-4
+#define WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP \
+ 22 // fw gives up eapol frame, with rate,
+ // success/failure and number retries
+#define WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED \
+ 23 // kernel queue EAPOL for transmission
+ // in driver with EAPOL index 1-4
+#define WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED \
+ 24 // with rate, regardless of the fact that
+ // EAPOL frame is accepted or rejected by fw
+#define WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED \
+ 26 // with rate, and eapol index, driver has
+ // received EAPOL frame and will queue it up
+ // to wpa_supplicant
+#define WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE 27 // with success/failure, parameters
+#define WIFI_EVENT_BT_COEX_BT_SCO_START 28
+#define WIFI_EVENT_BT_COEX_BT_SCO_STOP 29
+#define WIFI_EVENT_BT_COEX_BT_SCAN_START \
+ 30 // for paging/scan etc., when BT starts transmiting
+ // twice per BT slot
+#define WIFI_EVENT_BT_COEX_BT_SCAN_STOP 31
+#define WIFI_EVENT_BT_COEX_BT_HID_START 32
+#define WIFI_EVENT_BT_COEX_BT_HID_STOP 33
+#define WIFI_EVENT_ROAM_AUTH_STARTED 34 // fw sends auth frame in roaming to next candidate
+#define WIFI_EVENT_ROAM_AUTH_COMPLETE 35 // fw receive auth confirm from ap
+#define WIFI_EVENT_ROAM_ASSOC_STARTED \
+ 36 // firmware sends assoc/reassoc frame in
+ // roaming to next candidate
+#define WIFI_EVENT_ROAM_ASSOC_COMPLETE 37 // firmware receive assoc/reassoc confirm from ap
+#define WIFI_EVENT_G_SCAN_STOP 38 // firmware sends stop G_SCAN
+#define WIFI_EVENT_G_SCAN_CYCLE_STARTED 39 // firmware indicates G_SCAN scan cycle started
+#define WIFI_EVENT_G_SCAN_CYCLE_COMPLETED 40 // firmware indicates G_SCAN scan cycle completed
+#define WIFI_EVENT_G_SCAN_BUCKET_STARTED \
+ 41 // firmware indicates G_SCAN scan start
+ // for a particular bucket
+#define WIFI_EVENT_G_SCAN_BUCKET_COMPLETED \
+ 42 // firmware indicates G_SCAN scan completed for
+ // for a particular bucket
+#define WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE \
+ 43 // Event received from firmware about G_SCAN scan
+ // results being available
+#define WIFI_EVENT_G_SCAN_CAPABILITIES \
+ 44 // Event received from firmware with G_SCAN
+ // capabilities
+#define WIFI_EVENT_ROAM_CANDIDATE_FOUND \
+ 45 // Event received from firmware when eligible
+ // candidate is found
+#define WIFI_EVENT_ROAM_SCAN_CONFIG \
+ 46 // Event received from firmware when roam scan
+ // configuration gets enabled or disabled
+#define WIFI_EVENT_AUTH_TIMEOUT 47 // firmware/driver timed out authentication
+#define WIFI_EVENT_ASSOC_TIMEOUT 48 // firmware/driver timed out association
+#define WIFI_EVENT_MEM_ALLOC_FAILURE 49 // firmware/driver encountered allocation failure
+#define WIFI_EVENT_DRIVER_PNO_ADD 50 // driver added a PNO network in firmware
+#define WIFI_EVENT_DRIVER_PNO_REMOVE 51 // driver removed a PNO network in firmware
+#define WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND \
+ 52 // driver received PNO networks
+ // found indication from firmware
+#define WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED 53 // driver triggered a scan for PNO networks
+#define WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND \
+ 54 // driver received scan results
+ // of PNO networks
+#define WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE \
+ 55 // driver updated scan results from
+ // PNO networks to cfg80211
+
+/**
+ * Parameters of wifi logger events are TLVs
+ * Event parameters tags are defined as:
+ */
+#define WIFI_TAG_VENDOR_SPECIFIC 0 // take a byte stream as parameter
+#define WIFI_TAG_BSSID 1 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR 2 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_SSID 3 // takes a 32 bytes SSID address as parameter
+#define WIFI_TAG_STATUS 4 // takes an integer as parameter
+#define WIFI_TAG_CHANNEL_SPEC 5 // takes one or more wifi_channel_spec as parameter
+#define WIFI_TAG_WAKE_LOCK_EVENT 6 // takes a wake_lock_event struct as parameter
+#define WIFI_TAG_ADDR1 7 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR2 8 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR3 9 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR4 10 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_TSF 11 // take a 64 bits TSF value as parameter
+#define WIFI_TAG_IE \
+ 12 // take one or more specific 802.11 IEs parameter,
+ // IEs are in turn indicated in TLV format as per
+ // 802.11 spec
+#define WIFI_TAG_INTERFACE 13 // take interface name as parameter
+#define WIFI_TAG_REASON_CODE 14 // take a reason code as per 802.11 as parameter
+#define WIFI_TAG_RATE_MBPS 15 // take a wifi rate in 0.5 mbps
+#define WIFI_TAG_REQUEST_ID 16 // take an integer as parameter
+#define WIFI_TAG_BUCKET_ID 17 // take an integer as parameter
+#define WIFI_TAG_GSCAN_PARAMS 18 // takes a wifi_scan_cmd_params struct as parameter
+#define WIFI_TAG_GSCAN_CAPABILITIES 19 // takes a wifi_gscan_capabilities struct as parameter
+#define WIFI_TAG_SCAN_ID 20 // take an integer as parameter
+#define WIFI_TAG_RSSI 21 // take an integer as parameter
+#define WIFI_TAG_CHANNEL 22 // take an integer as parameter
+#define WIFI_TAG_LINK_ID 23 // take an integer as parameter
+#define WIFI_TAG_LINK_ROLE 24 // take an integer as parameter
+#define WIFI_TAG_LINK_STATE 25 // take an integer as parameter
+#define WIFI_TAG_LINK_TYPE 26 // take an integer as parameter
+#define WIFI_TAG_TSCO 27 // take an integer as parameter
+#define WIFI_TAG_RSCO 28 // take an integer as parameter
+#define WIFI_TAG_EAPOL_MESSAGE_TYPE \
+ 29 // take an integer as parameter
+ // M1-1, M2-2, M3-3, M4-4
+
+typedef struct {
+ u16 tag;
+ u16 length; // length of value
+ u8 value[0];
+} __attribute__((packed)) tlv_log;
+
+typedef struct {
+ u16 event;
+ tlv_log tlvs[0]; // separate parameter structure per event to be provided and optional data
+ // the event_data is expected to include an official android part, with some
+ // parameter as transmit rate, num retries, num scan result found etc...
+ // as well, event_data can include a vendor proprietary part which is
+ // understood by the developer only.
+} __attribute__((packed)) wifi_ring_buffer_driver_connectivity_event;
+
+/**
+ * Ring buffer name for power events ring. note that power event are extremely frequents
+ * and thus should be stored in their own ring/file so as not to clobber connectivity events.
+ */
+typedef struct {
+ int status; // 0 taken, 1 released
+ int reason; // reason why this wake lock is taken
+ char name[0]; // null terminated
+} __attribute__((packed)) wake_lock_event;
+
+typedef struct {
+ u16 event;
+ tlv_log tlvs[0];
+} __attribute__((packed)) wifi_power_event;
+
+/**
+ * This structure represent a logger entry within a ring buffer.
+ * Wifi driver are responsible to manage the ring buffer and write the debug
+ * information into those rings.
+ *
+ * In general, the debug entries can be used to store meaningful 802.11 information (SME, MLME,
+ * connection and packet statistics) as well as vendor proprietary data that is specific to a
+ * specific driver or chipset.
+ * Binary entries can be used so as to store packet data or vendor specific information and
+ * will be treated as blobs of data by android.
+ *
+ * A user land process will be started by framework so as to periodically retrieve the
+ * data logged by drivers into their ring buffer, store the data into log files and include
+ * the logs into android bugreports.
+ */
+enum {
+ RING_BUFFER_ENTRY_FLAGS_HAS_BINARY = (1 << (0)), // set for binary entries
+ RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP = (1 << (1)) // set if 64 bits timestamp is present
+};
+
+enum {
+ ENTRY_TYPE_CONNECT_EVENT = 1,
+ ENTRY_TYPE_PKT,
+ ENTRY_TYPE_WAKE_LOCK,
+ ENTRY_TYPE_POWER_EVENT,
+ ENTRY_TYPE_DATA
+};
+
+typedef struct {
+ u16 entry_size; // the size of payload excluding the header.
+ u8 flags;
+ u8 type; // entry type
+ u64 timestamp; // present if has_timestamp bit is set.
+} __attribute__((packed)) wifi_ring_buffer_entry;
+
+#define WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES 0x00000001 // set if binary entries are present
+#define WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES 0x00000002 // set if ascii entries are present
+
+/* ring buffer params */
+/**
+ * written_bytes and read_bytes implement a producer consumer API
+ * hence written_bytes >= read_bytes
+ * a modulo arithmetic of the buffer size has to be applied to those counters:
+ * actual offset into ring buffer = written_bytes % ring_buffer_byte_size
+ *
+ */
+typedef struct {
+ u8 name[32];
+ u32 flags;
+ wifi_ring_buffer_id ring_id; // unique integer representing the ring
+ u32 ring_buffer_byte_size; // total memory size allocated for the buffer
+ u32 verbose_level; // verbose level for ring buffer
+ u32 written_bytes; // number of bytes that was written to the buffer by driver,
+ // monotonously increasing integer
+ u32 read_bytes; // number of bytes that was read from the buffer by user land,
+ // monotonously increasing integer
+ u32 written_records; // number of records that was written to the buffer by driver,
+ // monotonously increasing integer
+} wifi_ring_buffer_status;
+
+/**
+ * Callback for reporting ring data
+ *
+ * The ring buffer data collection is event based:
+ * - Driver calls on_ring_buffer_data when new records are available, the wifi_ring_buffer_status
+ * passed up to framework in the call back indicates to framework if more data is available in
+ * the ring buffer. It is not expected that driver will necessarily always empty the ring
+ * immediately as data is available, instead driver will report data every X seconds or if
+ * N bytes are available.
+ * - In the case where a bug report has to be captured, framework will require driver to upload
+ * all data immediately. This is indicated to driver when framework calls wifi_get_ringdata.
+ * When framework calls wifi_get_ring_data, driver will start sending all available data in the
+ * indicated ring by repeatedly invoking the on_ring_buffer_data callback.
+ *
+ * The callback is called by log handler whenever ring data comes in driver.
+ */
+typedef struct {
+ void (*on_ring_buffer_data)(char* ring_name, char* buffer, int buffer_size,
+ wifi_ring_buffer_status* status);
+} wifi_ring_buffer_data_handler;
+
+/**
+ * API to set the log handler for getting ring data
+ * - Only a single instance of log handler can be instantiated for each ring buffer.
+ */
+wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface,
+ wifi_ring_buffer_data_handler handler);
+
+/* API to reset the log handler */
+wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface);
+
+/**
+ * Callback for reporting FW dump
+ *
+ * The buffer data collection is event based such as FW health check or FW dump.
+ * The callback is called by alert handler.
+ */
+typedef struct {
+ void (*on_alert)(wifi_request_id id, char* buffer, int buffer_size, int err_code);
+} wifi_alert_handler;
+
+/*
+ * API to set the alert handler for the alert case in Wi-Fi Chip
+ * - Only a single instance of alert handler can be instantiated.
+ */
+wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle iface,
+ wifi_alert_handler handler);
+
+/* API to reset the alert handler */
+wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface);
+
+/* API for framework to indicate driver has to upload and drain all data of a given ring */
+wifi_error wifi_get_ring_data(wifi_interface_handle iface, char* ring_name);
+
+/**
+ * API to trigger the debug collection.
+ * Unless his API is invoked - logging is not triggered.
+ * - Verbose_level 0 corresponds to no collection,
+ * and it makes log handler stop by no more events from driver.
+ * - Verbose_level 1 correspond to normal log level, with minimal user impact.
+ * This is the default value.
+ * - Verbose_level 2 are enabled when user is lazily trying to reproduce a problem,
+ * wifi performances and power can be impacted but device should not otherwise be
+ * significantly impacted.
+ * - Verbose_level 3+ are used when trying to actively debug a problem.
+ *
+ * ring_name represent the name of the ring for which data collection shall start.
+ *
+ * flags: TBD parameter used to enable/disable specific events on a ring
+ * max_interval: maximum interval in seconds for driver to invoke on_ring_buffer_data,
+ * ignore if zero
+ * min_data_size: minimum data size in buffer for driver to invoke on_ring_buffer_data,
+ * ignore if zero
+ */
+wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level, u32 flags,
+ u32 max_interval_sec, u32 min_data_size, char* ring_name);
+
+/**
+ * API to get the status of all ring buffers supported by driver.
+ * - Caller is responsible to allocate / free ring buffer status.
+ * - Maximum no of ring buffer would be 10.
+ */
+wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface, u32* num_rings,
+ wifi_ring_buffer_status* status);
+
+/**
+ * Synchronous memory dump by user request.
+ * - Caller is responsible to store memory dump data into a local,
+ * e.g., /data/misc/wifi/memdump.bin
+ */
+typedef struct {
+ void (*on_firmware_memory_dump)(char* buffer, int buffer_size);
+} wifi_firmware_memory_dump_handler;
+
+/**
+ * API to collect a firmware memory dump for a given iface by async memdump event.
+ * - Triggered by Alerthandler, esp. when FW problem or FW health check happens
+ * - Caller is responsible to store fw dump data into a local,
+ * e.g., /data/misc/wifi/alertdump-1.bin
+ */
+wifi_error wifi_get_firmware_memory_dump(wifi_interface_handle iface,
+ wifi_firmware_memory_dump_handler handler);
+
+/**
+ * API to collect a firmware version string.
+ * - Caller is responsible to allocate / free a buffer to retrieve firmware verion info.
+ * - Max string will be at most 256 bytes.
+ */
+wifi_error wifi_get_firmware_version(wifi_interface_handle iface, char* buffer, int buffer_size);
+
+/**
+ * API to collect a driver version string.
+ * - Caller is responsible to allocate / free a buffer to retrieve driver verion info.
+ * - Max string will be at most 256 bytes.
+ */
+wifi_error wifi_get_driver_version(wifi_interface_handle iface, char* buffer, int buffer_size);
+
+/* Feature set */
+enum {
+ WIFI_LOGGER_MEMORY_DUMP_SUPPORTED = (1 << (0)), // Memory dump of FW
+ WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED = (1 << (1)), // PKT status
+ WIFI_LOGGER_CONNECT_EVENT_SUPPORTED = (1 << (2)), // Connectivity event
+ WIFI_LOGGER_POWER_EVENT_SUPPORTED = (1 << (3)), // POWER of Driver
+ WIFI_LOGGER_WAKE_LOCK_SUPPORTED = (1 << (4)), // WAKE LOCK of Driver
+ WIFI_LOGGER_VERBOSE_SUPPORTED = (1 << (5)), // verbose log of FW
+ WIFI_LOGGER_WATCHDOG_TIMER_SUPPORTED = (1 << (6)), // monitor the health of FW
+ WIFI_LOGGER_DRIVER_DUMP_SUPPORTED = (1 << (7)), // dumps driver state
+ WIFI_LOGGER_PACKET_FATE_SUPPORTED = (1 << (8)), // tracks connection packets' fate
+};
+
+/**
+ * API to retrieve the current supportive features.
+ * - An integer variable is enough to have bit mapping info by caller.
+ */
+wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
+ unsigned int* support);
+
+typedef struct {
+ /* Buffer is to be allocated and freed by HAL implementation. */
+ void (*on_driver_memory_dump)(char* buffer, int buffer_size);
+} wifi_driver_memory_dump_callbacks;
+
+/**
+ API to collect driver state.
+
+ Framework will call this API soon before or after (but not
+ concurrently with) wifi_get_firmware_memory_dump(). Capturing
+ firmware and driver dumps is intended to help identify
+ inconsistent state between these components.
+
+ - In response to this call, HAL implementation should make one or
+ more calls to callbacks.on_driver_memory_dump(). Framework will
+ copy data out of the received |buffer|s, and concatenate the
+ contents thereof.
+ - HAL implemention will indicate completion of the driver memory
+ dump by returning from this call.
+*/
+wifi_error wifi_get_driver_memory_dump(wifi_interface_handle iface,
+ wifi_driver_memory_dump_callbacks callbacks);
+
+/* packet fate logs */
+
+#define MD5_PREFIX_LEN 4
+#define MAX_FATE_LOG_LEN 32
+#define MAX_FRAME_LEN_ETHERNET 1518
+#define MAX_FRAME_LEN_80211_MGMT 2352 // 802.11-2012 Fig. 8-34
+
+typedef enum {
+ // Sent over air and ACKed.
+ TX_PKT_FATE_ACKED,
+
+ // Sent over air but not ACKed. (Normal for broadcast/multicast.)
+ TX_PKT_FATE_SENT,
+
+ // Queued within firmware, but not yet sent over air.
+ TX_PKT_FATE_FW_QUEUED,
+
+ // Dropped by firmware as invalid. E.g. bad source address, bad checksum,
+ // or invalid for current state.
+ TX_PKT_FATE_FW_DROP_INVALID,
+
+ // Dropped by firmware due to lack of buffer space.
+ TX_PKT_FATE_FW_DROP_NOBUFS,
+
+ // Dropped by firmware for any other reason. Includes frames that
+ // were sent by driver to firmware, but unaccounted for by
+ // firmware.
+ TX_PKT_FATE_FW_DROP_OTHER,
+
+ // Queued within driver, not yet sent to firmware.
+ TX_PKT_FATE_DRV_QUEUED,
+
+ // Dropped by driver as invalid. E.g. bad source address, or
+ // invalid for current state.
+ TX_PKT_FATE_DRV_DROP_INVALID,
+
+ // Dropped by driver due to lack of buffer space.
+ TX_PKT_FATE_DRV_DROP_NOBUFS,
+
+ // Dropped by driver for any other reason.
+ TX_PKT_FATE_DRV_DROP_OTHER,
+} wifi_tx_packet_fate;
+
+typedef enum {
+ // Valid and delivered to network stack (e.g., netif_rx()).
+ RX_PKT_FATE_SUCCESS,
+
+ // Queued within firmware, but not yet sent to driver.
+ RX_PKT_FATE_FW_QUEUED,
+
+ // Dropped by firmware due to host-programmable filters.
+ RX_PKT_FATE_FW_DROP_FILTER,
+
+ // Dropped by firmware as invalid. E.g. bad checksum, decrypt failed,
+ // or invalid for current state.
+ RX_PKT_FATE_FW_DROP_INVALID,
+
+ // Dropped by firmware due to lack of buffer space.
+ RX_PKT_FATE_FW_DROP_NOBUFS,
+
+ // Dropped by firmware for any other reason.
+ RX_PKT_FATE_FW_DROP_OTHER,
+
+ // Queued within driver, not yet delivered to network stack.
+ RX_PKT_FATE_DRV_QUEUED,
+
+ // Dropped by driver due to filter rules.
+ RX_PKT_FATE_DRV_DROP_FILTER,
+
+ // Dropped by driver as invalid. E.g. not permitted in current state.
+ RX_PKT_FATE_DRV_DROP_INVALID,
+
+ // Dropped by driver due to lack of buffer space.
+ RX_PKT_FATE_DRV_DROP_NOBUFS,
+
+ // Dropped by driver for any other reason.
+ RX_PKT_FATE_DRV_DROP_OTHER,
+} wifi_rx_packet_fate;
+
+typedef enum {
+ FRAME_TYPE_UNKNOWN,
+ FRAME_TYPE_ETHERNET_II,
+ FRAME_TYPE_80211_MGMT,
+} frame_type;
+
+typedef struct {
+ // The type of MAC-layer frame that this frame_info holds.
+ // - For data frames, use FRAME_TYPE_ETHERNET_II.
+ // - For management frames, use FRAME_TYPE_80211_MGMT.
+ // - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN.
+ frame_type payload_type;
+
+ // The number of bytes included in |frame_content|. If the frame
+ // contents are missing (e.g. RX frame dropped in firmware),
+ // |frame_len| should be set to 0.
+ size_t frame_len;
+
+ // Host clock when this frame was received by the driver (either
+ // outbound from the host network stack, or inbound from the
+ // firmware).
+ // - The timestamp should be taken from a clock which includes time
+ // the host spent suspended (e.g. ktime_get_boottime()).
+ // - If no host timestamp is available (e.g. RX frame was dropped in
+ // firmware), this field should be set to 0.
+ u32 driver_timestamp_usec;
+
+ // Firmware clock when this frame was received by the firmware
+ // (either outbound from the host, or inbound from a remote
+ // station).
+ // - The timestamp should be taken from a clock which includes time
+ // firmware spent suspended (if applicable).
+ // - If no firmware timestamp is available (e.g. TX frame was
+ // dropped by driver), this field should be set to 0.
+ // - Consumers of |frame_info| should _not_ assume any
+ // synchronization between driver and firmware clocks.
+ u32 firmware_timestamp_usec;
+
+ // Actual frame content.
+ // - Should be provided for TX frames originated by the host.
+ // - Should be provided for RX frames received by the driver.
+ // - Optionally provided for TX frames originated by firmware. (At
+ // discretion of HAL implementation.)
+ // - Optionally provided for RX frames dropped in firmware. (At
+ // discretion of HAL implementation.)
+ // - If frame content is not provided, |frame_len| should be set
+ // to 0.
+ union {
+ char ethernet_ii_bytes[MAX_FRAME_LEN_ETHERNET];
+ char ieee_80211_mgmt_bytes[MAX_FRAME_LEN_80211_MGMT];
+ } frame_content;
+} frame_info;
+
+typedef struct {
+ // Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+ // content is not provided, prefix of MD5 hash over the same data
+ // that would be in frame_content, if frame content were provided.
+ char md5_prefix[MD5_PREFIX_LEN];
+ wifi_tx_packet_fate fate;
+ frame_info frame_inf;
+} wifi_tx_report;
+
+typedef struct {
+ // Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+ // content is not provided, prefix of MD5 hash over the same data
+ // that would be in frame_content, if frame content were provided.
+ char md5_prefix[MD5_PREFIX_LEN];
+ wifi_rx_packet_fate fate;
+ frame_info frame_inf;
+} wifi_rx_report;
+
+/**
+ API to start packet fate monitoring.
+ - Once stared, monitoring should remain active until HAL is unloaded.
+ - When HAL is unloaded, all packet fate buffers should be cleared.
+*/
+wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle);
+
+/**
+ API to retrieve fates of outbound packets.
+ - HAL implementation should fill |tx_report_bufs| with fates of
+ _first_ min(n_requested_fates, actual packets) frames
+ transmitted for the most recent association. The fate reports
+ should follow the same order as their respective packets.
+ - HAL implementation may choose (but is not required) to include
+ reports for management frames.
+ - Packets reported by firmware, but not recognized by driver,
+ should be included. However, the ordering of the corresponding
+ reports is at the discretion of HAL implementation.
+ - Framework may call this API multiple times for the same association.
+ - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
+ - Framework will allocate and free the referenced storage.
+*/
+wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle, wifi_tx_report* tx_report_bufs,
+ size_t n_requested_fates, size_t* n_provided_fates);
+
+/**
+ API to retrieve fates of inbound packets.
+ - HAL implementation should fill |rx_report_bufs| with fates of
+ _first_ min(n_requested_fates, actual packets) frames
+ received for the most recent association. The fate reports
+ should follow the same order as their respective packets.
+ - HAL implementation may choose (but is not required) to include
+ reports for management frames.
+ - Packets reported by firmware, but not recognized by driver,
+ should be included. However, the ordering of the corresponding
+ reports is at the discretion of HAL implementation.
+ - Framework may call this API multiple times for the same association.
+ - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
+ - Framework will allocate and free the referenced storage.
+*/
+wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle, wifi_rx_report* rx_report_bufs,
+ size_t n_requested_fates, size_t* n_provided_fates);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_STATS_ */
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_nan.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_nan.h
new file mode 100644
index 0000000..3591b98
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_nan.h
@@ -0,0 +1,2726 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NAN_H__
+#define __NAN_H__
+
+#include <net/if.h>
+#include <stdbool.h>
+#include "wifi_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*****************************************************************************
+ * Neighbour Aware Network Service Structures and Functions
+ *****************************************************************************/
+
+/*
+ Definitions
+ All multi-byte fields within all NAN protocol stack messages are assumed to be in Little Endian
+ order.
+*/
+
+typedef int NanVersion;
+typedef u16 transaction_id;
+typedef u32 NanDataPathId;
+
+#define NAN_MAC_ADDR_LEN 6
+#define NAN_MAJOR_VERSION 2
+#define NAN_MINOR_VERSION 0
+#define NAN_MICRO_VERSION 1
+#define NAN_MAX_SOCIAL_CHANNELS 3
+
+/* NAN Maximum Lengths */
+#define NAN_MAX_SERVICE_NAME_LEN 255
+#define NAN_MAX_MATCH_FILTER_LEN 255
+#define NAN_MAX_SERVICE_SPECIFIC_INFO_LEN 1024
+#define NAN_MAX_VSA_DATA_LEN 1024
+#define NAN_MAX_MESH_DATA_LEN 32
+#define NAN_MAX_INFRA_DATA_LEN 32
+#define NAN_MAX_CLUSTER_ATTRIBUTE_LEN 255
+#define NAN_MAX_SUBSCRIBE_MAX_ADDRESS 42
+#define NAN_MAX_FAM_CHANNELS 32
+#define NAN_MAX_POSTDISCOVERY_LEN 5
+#define NAN_MAX_FRAME_DATA_LEN 504
+#define NAN_DP_MAX_APP_INFO_LEN 512
+#define NAN_ERROR_STR_LEN 255
+#define NAN_PMK_INFO_LEN 32
+#define NAN_MAX_SCID_BUF_LEN 1024
+#define NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN 1024
+#define NAN_SECURITY_MIN_PASSPHRASE_LEN 8
+#define NAN_SECURITY_MAX_PASSPHRASE_LEN 63
+#define NAN_MAX_CHANNEL_INFO_SUPPORTED 4
+
+/*
+ Definition of various NanResponseType
+*/
+typedef enum {
+ NAN_RESPONSE_ENABLED = 0,
+ NAN_RESPONSE_DISABLED = 1,
+ NAN_RESPONSE_PUBLISH = 2,
+ NAN_RESPONSE_PUBLISH_CANCEL = 3,
+ NAN_RESPONSE_TRANSMIT_FOLLOWUP = 4,
+ NAN_RESPONSE_SUBSCRIBE = 5,
+ NAN_RESPONSE_SUBSCRIBE_CANCEL = 6,
+ NAN_RESPONSE_STATS = 7,
+ NAN_RESPONSE_CONFIG = 8,
+ NAN_RESPONSE_TCA = 9,
+ NAN_RESPONSE_ERROR = 10,
+ NAN_RESPONSE_BEACON_SDF_PAYLOAD = 11,
+ NAN_GET_CAPABILITIES = 12,
+ NAN_DP_INTERFACE_CREATE = 13,
+ NAN_DP_INTERFACE_DELETE = 14,
+ NAN_DP_INITIATOR_RESPONSE = 15,
+ NAN_DP_RESPONDER_RESPONSE = 16,
+ NAN_DP_END = 17
+} NanResponseType;
+
+/* NAN Publish Types */
+typedef enum {
+ NAN_PUBLISH_TYPE_UNSOLICITED = 0,
+ NAN_PUBLISH_TYPE_SOLICITED,
+ NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED
+} NanPublishType;
+
+/* NAN Transmit Priorities */
+typedef enum { NAN_TX_PRIORITY_NORMAL = 0, NAN_TX_PRIORITY_HIGH } NanTxPriority;
+
+/* NAN Statistics Request ID Codes */
+typedef enum {
+ NAN_STATS_ID_DE_PUBLISH = 0,
+ NAN_STATS_ID_DE_SUBSCRIBE,
+ NAN_STATS_ID_DE_MAC,
+ NAN_STATS_ID_DE_TIMING_SYNC,
+ NAN_STATS_ID_DE_DW,
+ NAN_STATS_ID_DE
+} NanStatsType;
+
+/* NAN Protocol Event ID Codes */
+typedef enum {
+ NAN_EVENT_ID_DISC_MAC_ADDR = 0,
+ NAN_EVENT_ID_STARTED_CLUSTER,
+ NAN_EVENT_ID_JOINED_CLUSTER
+} NanDiscEngEventType;
+
+/* NAN Data Path type */
+typedef enum { NAN_DATA_PATH_UNICAST_MSG = 0, NAN_DATA_PATH_MULTICAST_MSG } NdpType;
+
+/* NAN Ranging Configuration */
+typedef enum { NAN_RANGING_DISABLE = 0, NAN_RANGING_ENABLE } NanRangingState;
+
+/* TCA Type */
+typedef enum { NAN_TCA_ID_CLUSTER_SIZE = 0 } NanTcaType;
+
+/* NAN Channel Info */
+typedef struct {
+ u32 channel;
+ u32 bandwidth;
+ u32 nss;
+} NanChannelInfo;
+
+/*
+ Various NAN Protocol Response code
+*/
+typedef enum {
+ /* NAN Protocol Response Codes */
+ NAN_STATUS_SUCCESS = 0,
+ /* NAN Discovery Engine/Host driver failures */
+ NAN_STATUS_INTERNAL_FAILURE = 1,
+ /* NAN OTA failures */
+ NAN_STATUS_PROTOCOL_FAILURE = 2,
+ /* if the publish/subscribe id is invalid */
+ NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID = 3,
+ /* If we run out of resources allocated */
+ NAN_STATUS_NO_RESOURCE_AVAILABLE = 4,
+ /* if invalid params are passed */
+ NAN_STATUS_INVALID_PARAM = 5,
+ /* if the requestor instance id is invalid */
+ NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID = 6,
+ /* if the ndp id is invalid */
+ NAN_STATUS_INVALID_NDP_ID = 7,
+ /* if NAN is enabled when wifi is turned off */
+ NAN_STATUS_NAN_NOT_ALLOWED = 8,
+ /* if over the air ack is not received */
+ NAN_STATUS_NO_OTA_ACK = 9,
+ /* If NAN is already enabled and we are try to re-enable the same */
+ NAN_STATUS_ALREADY_ENABLED = 10,
+ /* If followup message internal queue is full */
+ NAN_STATUS_FOLLOWUP_QUEUE_FULL = 11,
+ /* Unsupported concurrency session enabled, NAN disabled notified */
+ NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12
+} NanStatusType;
+
+/* NAN Transmit Types */
+typedef enum { NAN_TX_TYPE_BROADCAST = 0, NAN_TX_TYPE_UNICAST } NanTxType;
+
+/* NAN Subscribe Type */
+typedef enum { NAN_SUBSCRIBE_TYPE_PASSIVE = 0, NAN_SUBSCRIBE_TYPE_ACTIVE } NanSubscribeType;
+
+/* NAN Service Response Filter Attribute Bit */
+typedef enum { NAN_SRF_ATTR_BLOOM_FILTER = 0, NAN_SRF_ATTR_PARTIAL_MAC_ADDR } NanSRFType;
+
+/* NAN Service Response Filter Include Bit */
+typedef enum { NAN_SRF_INCLUDE_DO_NOT_RESPOND = 0, NAN_SRF_INCLUDE_RESPOND } NanSRFIncludeType;
+
+/* NAN Match indication type */
+typedef enum {
+ NAN_MATCH_ALG_MATCH_ONCE = 0,
+ NAN_MATCH_ALG_MATCH_CONTINUOUS,
+ NAN_MATCH_ALG_MATCH_NEVER
+} NanMatchAlg;
+
+/* NAN Transmit Window Type */
+typedef enum { NAN_TRANSMIT_IN_DW = 0, NAN_TRANSMIT_IN_FAW } NanTransmitWindowType;
+
+/* NAN SRF State in Subscribe */
+typedef enum { NAN_DO_NOT_USE_SRF = 0, NAN_USE_SRF } NanSRFState;
+
+/* NAN Include SSI in MatchInd */
+typedef enum {
+ NAN_SSI_NOT_REQUIRED_IN_MATCH_IND = 0,
+ NAN_SSI_REQUIRED_IN_MATCH_IND
+} NanSsiInMatchInd;
+
+/* NAN DP security Configuration */
+typedef enum { NAN_DP_CONFIG_NO_SECURITY = 0, NAN_DP_CONFIG_SECURITY } NanDataPathSecurityCfgStatus;
+
+typedef enum { NAN_QOS_NOT_REQUIRED = 0, NAN_QOS_REQUIRED } NanQosCfgStatus;
+
+/* Data request Responder's response */
+typedef enum { NAN_DP_REQUEST_ACCEPT = 0, NAN_DP_REQUEST_REJECT } NanDataPathResponseCode;
+
+/* NAN DP channel config options */
+typedef enum {
+ NAN_DP_CHANNEL_NOT_REQUESTED = 0,
+ NAN_DP_REQUEST_CHANNEL_SETUP,
+ NAN_DP_FORCE_CHANNEL_SETUP
+} NanDataPathChannelCfg;
+
+/* Enable/Disable NAN Ranging Auto response */
+typedef enum {
+ NAN_RANGING_AUTO_RESPONSE_ENABLE = 1,
+ NAN_RANGING_AUTO_RESPONSE_DISABLE
+} NanRangingAutoResponse;
+
+/* Enable/Disable NAN service range report */
+typedef enum { NAN_DISABLE_RANGE_REPORT = 1, NAN_ENABLE_RANGE_REPORT } NanRangeReport;
+
+/* NAN Range Response */
+typedef enum {
+ NAN_RANGE_REQUEST_ACCEPT = 1,
+ NAN_RANGE_REQUEST_REJECT,
+ NAN_RANGE_REQUEST_CANCEL
+} NanRangeResponse;
+
+/* NAN Security Key Input Type*/
+typedef enum {
+ NAN_SECURITY_KEY_INPUT_PMK = 1,
+ NAN_SECURITY_KEY_INPUT_PASSPHRASE
+} NanSecurityKeyInputType;
+
+typedef struct {
+ /* pmk length */
+ u32 pmk_len;
+ /*
+ PMK: Info is optional in Discovery phase.
+ PMK info can be passed during
+ the NDP session.
+ */
+ u8 pmk[NAN_PMK_INFO_LEN];
+} NanSecurityPmk;
+
+typedef struct {
+ /* passphrase length */
+ u32 passphrase_len;
+ /*
+ passphrase info is optional in Discovery phase.
+ passphrase info can be passed during
+ the NDP session.
+ */
+ u8 passphrase[NAN_SECURITY_MAX_PASSPHRASE_LEN];
+} NanSecurityPassPhrase;
+
+typedef struct {
+ NanSecurityKeyInputType key_type;
+ union {
+ NanSecurityPmk pmk_info;
+ NanSecurityPassPhrase passphrase_info;
+ } body;
+} NanSecurityKeyInfo;
+
+/* NAN Security Cipher Suites Mask */
+#define NAN_CIPHER_SUITE_SHARED_KEY_NONE 0x00
+#define NAN_CIPHER_SUITE_SHARED_KEY_128_MASK 0x01
+#define NAN_CIPHER_SUITE_SHARED_KEY_256_MASK 0x02
+#define NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK 0x04
+#define NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK 0x08
+
+/* NAN ranging indication condition MASKS */
+#define NAN_RANGING_INDICATE_CONTINUOUS_MASK 0x01
+#define NAN_RANGING_INDICATE_INGRESS_MET_MASK 0x02
+#define NAN_RANGING_INDICATE_EGRESS_MET_MASK 0x04
+
+/* NAN schedule update reason MASKS */
+#define NAN_SCHEDULE_UPDATE_NSS_MASK 0x01
+#define NAN_SCHEDULE_UPDATE_CHANNEL_MASK 0x02
+
+/*
+ Structure to set the Service Descriptor Extension
+ Attribute (SDEA) passed as part of NanPublishRequest/
+ NanSubscribeRequest/NanMatchInd.
+*/
+typedef struct {
+ /*
+ Optional configuration of Data Path Enable request.
+ configure flag determines whether configuration needs
+ to be passed or not.
+ */
+ u8 config_nan_data_path;
+ NdpType ndp_type;
+ /*
+ NAN secuirty required flag to indicate
+ if the security is enabled or disabled
+ */
+ NanDataPathSecurityCfgStatus security_cfg;
+ /*
+ NAN ranging required flag to indicate
+ if ranging is enabled on disabled
+ */
+ NanRangingState ranging_state;
+ /*
+ Enable/Disable Ranging report,
+ when configured NanRangeReportInd received
+ */
+ NanRangeReport range_report;
+ /*
+ NAN QOS required flag to indicate
+ if QOS is required or not.
+ */
+ NanQosCfgStatus qos_cfg;
+} NanSdeaCtrlParams;
+
+/*
+ Nan Ranging Peer Info in MatchInd
+*/
+typedef struct {
+ /*
+ Distance to the NAN device with the MAC address indicated
+ with ranged mac address.
+ */
+ u32 range_measurement_mm;
+ /* Ranging event matching the configuration of continuous/ingress/egress. */
+ u32 ranging_event_type;
+} NanRangeInfo;
+
+/* Nan/NDP Capabilites info */
+typedef struct {
+ u32 max_concurrent_nan_clusters;
+ u32 max_publishes;
+ u32 max_subscribes;
+ u32 max_service_name_len;
+ u32 max_match_filter_len;
+ u32 max_total_match_filter_len;
+ u32 max_service_specific_info_len;
+ u32 max_vsa_data_len;
+ u32 max_mesh_data_len;
+ u32 max_ndi_interfaces;
+ u32 max_ndp_sessions;
+ u32 max_app_info_len;
+ u32 max_queued_transmit_followup_msgs;
+ u32 ndp_supported_bands;
+ u32 cipher_suites_supported;
+ u32 max_scid_len;
+ bool is_ndp_security_supported;
+ u32 max_sdea_service_specific_info_len;
+ u32 max_subscribe_address;
+ u32 ndpe_attr_supported;
+ bool is_instant_mode_supported;
+} NanCapabilities;
+
+/*
+ Nan accept policy: Per service basis policy
+ Based on this policy(ALL/NONE), responder side
+ will send ACCEPT/REJECT
+*/
+typedef enum {
+ NAN_SERVICE_ACCEPT_POLICY_NONE = 0,
+ /* Default value */
+ NAN_SERVICE_ACCEPT_POLICY_ALL
+} NanServiceAcceptPolicy;
+
+/*
+ Host can send Vendor specific attributes which the Discovery Engine can
+ enclose in Beacons and/or Service Discovery frames transmitted.
+ Below structure is used to populate that.
+*/
+typedef struct {
+ /*
+ 0 = transmit only in the next discovery window
+ 1 = transmit in next 16 discovery window
+ */
+ u8 payload_transmit_flag;
+ /*
+ Below flags will determine in which all frames
+ the vendor specific attributes should be included
+ */
+ u8 tx_in_discovery_beacon;
+ u8 tx_in_sync_beacon;
+ u8 tx_in_service_discovery;
+ /* Organizationally Unique Identifier */
+ u32 vendor_oui;
+ /*
+ vendor specific attribute to be transmitted
+ vsa_len : Length of the vsa data.
+ */
+ u32 vsa_len;
+ u8 vsa[NAN_MAX_VSA_DATA_LEN];
+} NanTransmitVendorSpecificAttribute;
+
+/*
+ Discovery Engine will forward any Vendor Specific Attributes
+ which it received as part of this structure.
+*/
+/* Mask to determine on which frames attribute was received */
+#define RX_DISCOVERY_BEACON_MASK 0x01
+#define RX_SYNC_BEACON_MASK 0x02
+#define RX_SERVICE_DISCOVERY_MASK 0x04
+typedef struct {
+ /*
+ Frames on which this vendor specific attribute
+ was received. Mask defined above
+ */
+ u8 vsa_received_on;
+ /* Organizationally Unique Identifier */
+ u32 vendor_oui;
+ /* vendor specific attribute */
+ u32 attr_len;
+ u8 vsa[NAN_MAX_VSA_DATA_LEN];
+} NanReceiveVendorSpecificAttribute;
+
+/*
+ NAN Beacon SDF Payload Received structure
+ Discovery engine sends the details of received Beacon or
+ Service Discovery Frames as part of this structure.
+*/
+typedef struct {
+ /* Frame data */
+ u32 frame_len;
+ u8 frame_data[NAN_MAX_FRAME_DATA_LEN];
+} NanBeaconSdfPayloadReceive;
+
+/*
+ Host can set the Periodic scan parameters for each of the
+ 3(6, 44, 149) Social channels. Only these channels are allowed
+ any other channels are rejected
+*/
+typedef enum {
+ NAN_CHANNEL_24G_BAND = 0,
+ NAN_CHANNEL_5G_BAND_LOW,
+ NAN_CHANNEL_5G_BAND_HIGH
+} NanChannelIndex;
+
+/*
+ Structure to set the Social Channel Scan parameters
+ passed as part of NanEnableRequest/NanConfigRequest
+*/
+typedef struct {
+ /*
+ Dwell time of each social channel in milliseconds
+ NanChannelIndex corresponds to the respective channel
+ If time set to 0 then the FW default time will be used.
+ */
+ u8 dwell_time[NAN_MAX_SOCIAL_CHANNELS]; // default value 200 msec
+
+ /*
+ Scan period of each social channel in seconds
+ NanChannelIndex corresponds to the respective channel
+ If time set to 0 then the FW default time will be used.
+ */
+ u16 scan_period[NAN_MAX_SOCIAL_CHANNELS]; // default value 20 sec
+} NanSocialChannelScanParams;
+
+/*
+ Host can send Post Connectivity Capability attributes
+ to be included in Service Discovery frames transmitted
+ as part of this structure.
+*/
+typedef struct {
+ /*
+ 0 = transmit only in the next discovery window
+ 1 = transmit in next 16 discovery window
+ */
+ u8 payload_transmit_flag;
+ /* 1 - Wifi Direct supported 0 - Not supported */
+ u8 is_wfd_supported;
+ /* 1 - Wifi Direct Services supported 0 - Not supported */
+ u8 is_wfds_supported;
+ /* 1 - TDLS supported 0 - Not supported */
+ u8 is_tdls_supported;
+ /* 1 - IBSS supported 0 - Not supported */
+ u8 is_ibss_supported;
+ /* 1 - Mesh supported 0 - Not supported */
+ u8 is_mesh_supported;
+ /*
+ 1 - NAN Device currently connect to WLAN Infra AP
+ 0 - otherwise
+ */
+ u8 wlan_infra_field;
+} NanTransmitPostConnectivityCapability;
+
+/*
+ Discovery engine providing the post connectivity capability
+ received.
+*/
+typedef struct {
+ /* 1 - Wifi Direct supported 0 - Not supported */
+ u8 is_wfd_supported;
+ /* 1 - Wifi Direct Services supported 0 - Not supported */
+ u8 is_wfds_supported;
+ /* 1 - TDLS supported 0 - Not supported */
+ u8 is_tdls_supported;
+ /* 1 - IBSS supported 0 - Not supported */
+ u8 is_ibss_supported;
+ /* 1 - Mesh supported 0 - Not supported */
+ u8 is_mesh_supported;
+ /*
+ 1 - NAN Device currently connect to WLAN Infra AP
+ 0 - otherwise
+ */
+ u8 wlan_infra_field;
+} NanReceivePostConnectivityCapability;
+
+/*
+ Indicates the availability interval duration associated with the
+ Availability Intervals Bitmap field
+*/
+typedef enum {
+ NAN_DURATION_16MS = 0,
+ NAN_DURATION_32MS = 1,
+ NAN_DURATION_64MS = 2
+} NanAvailDuration;
+
+/* Further availability per channel information */
+typedef struct {
+ /* Defined above */
+ NanAvailDuration entry_control;
+ /*
+ 1 byte field indicating the frequency band the NAN Device
+ will be available as defined in IEEE Std. 802.11-2012
+ Annex E Table E-4 Global Operating Classes
+ */
+ u8 class_val;
+ /*
+ 1 byte field indicating the channel the NAN Device
+ will be available.
+ */
+ u8 channel;
+ /*
+ Map Id - 4 bit field which identifies the Further
+ availability map attribute.
+ */
+ u8 mapid;
+ /*
+ divides the time between the beginnings of consecutive Discovery
+ Windows of a given NAN cluster into consecutive time intervals
+ of equal durations. The time interval duration is specified by
+ the Availability Interval Duration subfield of the Entry Control
+ field.
+
+ A Nan device that sets the i-th bit of the Availability
+ Intervals Bitmap to 1 shall be present during the corresponding
+ i-th time interval in the operation channel indicated by the
+ Operating Class and Channel Number fields in the same Availability Entry.
+
+ A Nan device that sets the i-th bit of the Availability Intervals Bitmap to
+ 0 may be present during the corresponding i-th time interval in the operation
+ channel indicated by the Operating Class and Channel Number fields in the same
+ Availability Entry.
+
+ The size of the Bitmap is dependent upon the Availability Interval Duration
+ chosen in the Entry Control Field. The size can be either 1, 2 or 4 bytes long
+
+ - Duration field is equal to 0, only AIB[0] is valid
+ - Duration field is equal to 1, only AIB [0] and AIB [1] is valid
+ - Duration field is equal to 2, AIB [0], AIB [1], AIB [2] and AIB [3] are valid
+ */
+ u32 avail_interval_bitmap;
+} NanFurtherAvailabilityChannel;
+
+/*
+ Further availability map which can be sent and received from
+ Discovery engine
+*/
+typedef struct {
+ /*
+ Number of channels indicates the number of channel
+ entries which is part of fam
+ */
+ u8 numchans;
+ NanFurtherAvailabilityChannel famchan[NAN_MAX_FAM_CHANNELS];
+} NanFurtherAvailabilityMap;
+
+/*
+ Host can send Post-Nan Discovery attributes which the Discovery Engine can
+ enclose in Service Discovery frames
+*/
+/* Possible connection types in Post NAN Discovery attributes */
+typedef enum {
+ NAN_CONN_WLAN_INFRA = 0,
+ NAN_CONN_P2P_OPER = 1,
+ NAN_CONN_WLAN_IBSS = 2,
+ NAN_CONN_WLAN_MESH = 3,
+ NAN_CONN_FURTHER_SERVICE_AVAILABILITY = 4,
+ NAN_CONN_WLAN_RANGING = 5
+} NanConnectionType;
+
+/* Possible device roles in Post NAN Discovery attributes */
+typedef enum {
+ NAN_WLAN_INFRA_AP = 0,
+ NAN_WLAN_INFRA_STA = 1,
+ NAN_P2P_OPER_GO = 2,
+ NAN_P2P_OPER_DEV = 3,
+ NAN_P2P_OPER_CLI = 4
+} NanDeviceRole;
+
+/* Configuration params of NAN Ranging */
+typedef struct {
+ /*
+ Interval in milli sec between two ranging measurements.
+ If the Awake DW intervals in NanEnable/Config are larger
+ than the ranging intervals priority is given to Awake DW
+ Intervals. Only on a match the ranging is initiated for the
+ peer
+ */
+ u32 ranging_interval_msec;
+ /*
+ Flags indicating the type of ranging event to be notified
+ NAN_RANGING_INDICATE_ MASKS are used to set these.
+ BIT0 - Continuous Ranging event notification.
+ BIT1 - Ingress distance is <=.
+ BIT2 - Egress distance is >=.
+ */
+ u32 config_ranging_indications;
+ /* Ingress distance in millimeters (optional) */
+ u32 distance_ingress_mm;
+ /* Egress distance in millmilliimeters (optional) */
+ u32 distance_egress_mm;
+} NanRangingCfg;
+
+/* NAN Ranging request's response */
+typedef struct {
+ /* Publish Id of an earlier Publisher */
+ u16 publish_id;
+ /*
+ A 32 bit Requestor instance Id which is sent to the Application.
+ This Id will be used in subsequent RangeResponse on Subscribe side.
+ */
+ u32 requestor_instance_id;
+ /* Peer MAC addr of Range Requestor */
+ u8 peer_addr[NAN_MAC_ADDR_LEN];
+ /* Response indicating ACCEPT/REJECT/CANCEL of Range Request */
+ NanRangeResponse ranging_response;
+} NanRangeResponseCfg;
+
+/* Structure of Post NAN Discovery attribute */
+typedef struct {
+ /* Connection type of the host */
+ NanConnectionType type;
+ /*
+ Device role of the host based on
+ the connection type
+ */
+ NanDeviceRole role;
+ /*
+ Flag to send the information as a single shot or repeated
+ for next 16 discovery windows
+ 0 - Single_shot
+ 1 - next 16 discovery windows
+ */
+ u8 transmit_freq;
+ /* Duration of the availability bitmask */
+ NanAvailDuration duration;
+ /* Availability interval bitmap based on duration */
+ u32 avail_interval_bitmap;
+ /*
+ Mac address depending on the conn type and device role
+ --------------------------------------------------
+ | Conn Type | Device Role | Mac address Usage |
+ --------------------------------------------------
+ | WLAN_INFRA | AP/STA | BSSID of the AP |
+ --------------------------------------------------
+ | P2P_OPER | GO | GO's address |
+ --------------------------------------------------
+ | P2P_OPER | P2P_DEVICE | Address of who |
+ | | | would become GO |
+ --------------------------------------------------
+ | WLAN_IBSS | NA | BSSID |
+ --------------------------------------------------
+ | WLAN_MESH | NA | BSSID |
+ --------------------------------------------------
+ */
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ Mandatory mesh id value if connection type is WLAN_MESH
+ Mesh id contains 0-32 octet identifier and should be
+ as per IEEE Std.802.11-2012 spec.
+ */
+ u16 mesh_id_len;
+ u8 mesh_id[NAN_MAX_MESH_DATA_LEN];
+ /*
+ Optional infrastructure SSID if conn_type is set to
+ NAN_CONN_WLAN_INFRA
+ */
+ u16 infrastructure_ssid_len;
+ u8 infrastructure_ssid_val[NAN_MAX_INFRA_DATA_LEN];
+} NanTransmitPostDiscovery;
+
+/*
+ Discovery engine providing the structure of Post NAN
+ Discovery
+*/
+typedef struct {
+ /* Connection type of the host */
+ NanConnectionType type;
+ /*
+ Device role of the host based on
+ the connection type
+ */
+ NanDeviceRole role;
+ /* Duration of the availability bitmask */
+ NanAvailDuration duration;
+ /* Availability interval bitmap based on duration */
+ u32 avail_interval_bitmap;
+ /*
+ Map Id - 4 bit field which identifies the Further
+ availability map attribute.
+ */
+ u8 mapid;
+ /*
+ Mac address depending on the conn type and device role
+ --------------------------------------------------
+ | Conn Type | Device Role | Mac address Usage |
+ --------------------------------------------------
+ | WLAN_INFRA | AP/STA | BSSID of the AP |
+ --------------------------------------------------
+ | P2P_OPER | GO | GO's address |
+ --------------------------------------------------
+ | P2P_OPER | P2P_DEVICE | Address of who |
+ | | | would become GO |
+ --------------------------------------------------
+ | WLAN_IBSS | NA | BSSID |
+ --------------------------------------------------
+ | WLAN_MESH | NA | BSSID |
+ --------------------------------------------------
+ */
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ Mandatory mesh id value if connection type is WLAN_MESH
+ Mesh id contains 0-32 octet identifier and should be
+ as per IEEE Std.802.11-2012 spec.
+ */
+ u16 mesh_id_len;
+ u8 mesh_id[NAN_MAX_MESH_DATA_LEN];
+ /*
+ Optional infrastructure SSID if conn_type is set to
+ NAN_CONN_WLAN_INFRA
+ */
+ u16 infrastructure_ssid_len;
+ u8 infrastructure_ssid_val[NAN_MAX_INFRA_DATA_LEN];
+} NanReceivePostDiscovery;
+
+/*
+ NAN device level configuration of SDF and Sync beacons in both
+ 2.4/5GHz bands
+*/
+typedef struct {
+ /* Configure 2.4GHz DW Band */
+ u8 config_2dot4g_dw_band;
+ /*
+ Indicates the interval for Sync beacons and SDF's in 2.4GHz band.
+ Valid values of DW Interval are: 1, 2, 3, 4 and 5, 0 is reserved.
+ The SDF includes in OTA when enabled. The publish/subscribe period
+ values don't override the device level configurations.
+ */
+ u32 dw_2dot4g_interval_val; // default value 1
+ /* Configure 5GHz DW Band */
+ u8 config_5g_dw_band;
+ /*
+ Indicates the interval for Sync beacons and SDF's in 5GHz band
+ Valid values of DW Interval are: 1, 2, 3, 4 and 5, 0 no wake up for
+ any interval. The SDF includes in OTA when enabled. The publish/subscribe
+ period values don't override the device level configurations.
+ */
+ u32 dw_5g_interval_val; // default value 1 when 5G is enabled
+} NanConfigDW;
+
+/*
+ Enable Request Message Structure
+ The NanEnableReq message instructs the Discovery Engine to enter an operational state
+*/
+typedef struct {
+ /* Mandatory parameters below */
+ u8 master_pref; // default value 0x02
+ /*
+ A cluster_low value matching cluster_high indicates a request to join
+ a cluster with that value. If the requested cluster is not found the
+ device will start its own cluster.
+ */
+ u16 cluster_low; // default value 0
+ u16 cluster_high; // default value 0xFFFF
+
+ /*
+ Optional configuration of Enable request.
+ Each of the optional parameters have configure flag which
+ determine whether configuration is to be passed or not.
+ */
+ u8 config_support_5g;
+ u8 support_5g_val; // default value 0; turned off by default
+ /*
+ BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+ 0 - Do not include SIDs in any beacons
+ 1 - Include SIDs in all beacons.
+ Rest 7 bits are count field which allows control over the number of SIDs
+ included in the Beacon. 0 means to include as many SIDs that fit into
+ the maximum allow Beacon frame size
+ */
+ u8 config_sid_beacon;
+ u8 sid_beacon_val; // default value 0x01
+ /*
+ The rssi values below should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_2dot4g_rssi_close;
+ u8 rssi_close_2dot4g_val; // default value -60 dBm
+
+ u8 config_2dot4g_rssi_middle;
+ u8 rssi_middle_2dot4g_val; // default value -70 dBm
+
+ u8 config_2dot4g_rssi_proximity;
+ u8 rssi_proximity_2dot4g_val; // default value -60dBm
+
+ u8 config_hop_count_limit;
+ u8 hop_count_limit_val; // default value 0x02
+
+ /*
+ Defines 2.4G channel access support
+ 0 - No Support
+ 1 - Supported
+ */
+ u8 config_2dot4g_support;
+ u8 support_2dot4g_val; // default value 0x01
+ /*
+ Defines 2.4G channels will be used for sync/discovery beacons
+ 0 - 2.4G channels not used for beacons
+ 1 - 2.4G channels used for beacons
+ */
+ u8 config_2dot4g_beacons;
+ u8 beacon_2dot4g_val; // default value 1
+ /*
+ Defines 2.4G channels will be used for Service Discovery frames
+ 0 - 2.4G channels not used for Service Discovery frames
+ 1 - 2.4G channels used for Service Discovery frames
+ */
+ u8 config_2dot4g_sdf;
+ u8 sdf_2dot4g_val; // default value 1
+ /*
+ Defines 5G channels will be used for sync/discovery beacons
+ 0 - 5G channels not used for beacons
+ 1 - 5G channels used for beacons
+ */
+ u8 config_5g_beacons;
+ u8 beacon_5g_val; // default value 1 when 5G is enabled
+ /*
+ Defines 5G channels will be used for Service Discovery frames
+ 0 - 5G channels not used for Service Discovery frames
+ 1 - 5G channels used for Service Discovery frames
+ */
+ u8 config_5g_sdf;
+ u8 sdf_5g_val; // default value is 0 when 5G is enabled
+ /*
+ 1 byte value which defines the RSSI in
+ dBm for a close by Peer in 5 Ghz channels.
+ The rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_5g_rssi_close;
+ u8 rssi_close_5g_val; // default value -60dBm when 5G is enabled
+ /*
+ 1 byte value which defines the RSSI value in
+ dBm for a close by Peer in 5 Ghz channels.
+ The rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_5g_rssi_middle;
+ u8 rssi_middle_5g_val; // default value -75dBm when 5G is enabled
+ /*
+ 1 byte value which defines the RSSI filter
+ threshold. Any Service Descriptors received above this
+ value that are configured for RSSI filtering will be dropped.
+ The rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_5g_rssi_close_proximity;
+ u8 rssi_close_proximity_5g_val; // default value -60dBm when 5G is enabled
+ /*
+ 1 byte quantity which defines the window size over
+ which the “average RSSI†will be calculated over.
+ */
+ u8 config_rssi_window_size;
+ u8 rssi_window_size_val; // default value 0x08
+ /*
+ The 24 bit Organizationally Unique ID + the 8 bit Network Id.
+ */
+ u8 config_oui;
+ u32 oui_val; // default value {0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00}
+ /*
+ NAN Interface Address, If not configured the Discovery Engine
+ will generate a 6 byte Random MAC.
+ */
+ u8 config_intf_addr;
+ u8 intf_addr_val[NAN_MAC_ADDR_LEN];
+ /*
+ If set to 1, the Discovery Engine will enclose the Cluster
+ Attribute only sent in Beacons in a Vendor Specific Attribute
+ and transmit in a Service Descriptor Frame.
+ */
+ u8 config_cluster_attribute_val;
+ /*
+ The periodicity in seconds between full scan’s to find any new
+ clusters available in the area. A Full scan should not be done
+ more than every 10 seconds and should not be done less than every
+ 30 seconds.
+ */
+ u8 config_scan_params;
+ NanSocialChannelScanParams scan_params_val;
+ /*
+ 1 byte quantity which forces the Random Factor to a particular
+ value for all transmitted Sync/Discovery beacons
+ */
+ u8 config_random_factor_force;
+ u8 random_factor_force_val; // default value off and set to 0x00
+ /*
+ 1 byte quantity which forces the HC for all transmitted Sync and
+ Discovery Beacon NO matter the real HC being received over the
+ air.
+ */
+ u8 config_hop_count_force;
+ u8 hop_count_force_val; // default value 0x00
+
+ /* channel frequency in MHz to enable Nan on */
+ u8 config_24g_channel;
+ wifi_channel channel_24g_val; // default value channel 0x6
+
+ u8 config_5g_channel;
+ wifi_channel channel_5g_val; // default value channel 44 or 149 regulatory
+ // domain
+ /* Configure 2.4/5GHz DW */
+ NanConfigDW config_dw;
+
+ /*
+ By default discovery MAC address randomization is enabled
+ and default interval value is 30 minutes i.e. 1800 seconds.
+ The value 0 is used to disable MAC addr randomization.
+ */
+ u8 config_disc_mac_addr_randomization;
+ u32 disc_mac_addr_rand_interval_sec; // default value 1800 sec
+
+ /*
+ Set/Enable corresponding bits to disable Discovery indications:
+ BIT0 - Disable Discovery MAC Address Event.
+ BIT1 - Disable Started Cluster Event.
+ BIT2 - Disable Joined Cluster Event.
+ */
+ u8 discovery_indication_cfg; // default value 0x0
+ /*
+ BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+ 0 - Do not include SIDs in any beacons
+ 1 - Include SIDs in all beacons.
+ Rest 7 bits are count field which allows control over the number of SIDs
+ included in the Beacon. 0 means to include as many SIDs that fit into
+ the maximum allow Beacon frame size
+ */
+ u8 config_subscribe_sid_beacon;
+ u32 subscribe_sid_beacon_val; // default value 0x0
+ /*
+ Discovery Beacon Interval config.
+ Default value is 128 msec in 2G DW and 176 msec in 2G/5G DW.
+ When 0 value is passed it is reset to default value of 128 or 176 msec.
+ */
+ u8 config_discovery_beacon_int;
+ u32 discovery_beacon_interval;
+ /*
+ Enable Number of Spatial Streams.
+ This is NAN Power Optimization feature for NAN discovery.
+ */
+ u8 config_nss;
+ // default value is implementation specific and passing 0 sets it to default
+ u32 nss;
+ /*
+ Enable device level NAN Ranging feature.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_enable_ranging;
+ u32 enable_ranging;
+ /*
+ Enable/Disable DW Early termination.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_dw_early_termination;
+ u32 enable_dw_termination;
+ /*
+ Indicate whether to use NDPE attribute to bring-up TCP/IP connection.
+ If config_ndpe_attr is not configured, the default behavior is
+ not using NDPE attr, and the capability is not advertised.
+ 0 - Not use
+ 1 - Use
+ */
+ u8 config_ndpe_attr;
+ u32 use_ndpe_attr;
+ /*
+ Enable NAN v3.1 instant communication mode.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_enable_instant_mode;
+ u32 enable_instant_mode;
+ /*
+ Config NAN v3.1 instant communication channel frequency selected over NFC/OOB method.
+ If dual band is supported default channel is 149 or 44 as per regulatory domain,
+ else channel 6 (send frequency in MHz).
+ Sometimes depending on country code retrictions, even 149/44 may be restricted
+ in those cases instant channel will be operational only in 2.4GHz.
+ Use wifi_get_usable_channels() API to get supported bands/channels before
+ Instant mode NFC handshake is triggered
+ */
+ u8 config_instant_mode_channel;
+ wifi_channel instant_mode_channel;
+} NanEnableRequest;
+
+/*
+ Publish Msg Structure
+ Message is used to request the DE to publish the Service Name
+ using the parameters passed into the Discovery Window
+*/
+typedef struct {
+ u16 publish_id; /* id 0 means new publish, any other id is existing publish */
+ u16 ttl; /* how many seconds to run for. 0 means forever until canceled */
+ /*
+ period: Awake DW Interval for publish(service)
+ Indicates the interval between two Discovery Windows in which
+ the device supporting the service is awake to transmit or
+ receive the Service Discovery frames.
+ Valid values of Awake DW Interval are: 1, 2, 4, 8 and 16, value 0 will
+ default to 1.
+ */
+ u16 period;
+ NanPublishType publish_type; /* 0= unsolicited, solicited = 1, 2= both */
+ NanTxType tx_type; /* 0 = broadcast, 1= unicast if solicited publish */
+ u8 publish_count; /* number of OTA Publish, 0 means forever until canceled */
+ u16 service_name_len; /* length of service name */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN]; /* UTF-8 encoded string identifying the service */
+ /*
+ Field which specifies how the matching indication to host is controlled.
+ 0 - Match and Indicate Once
+ 1 - Match and Indicate continuous
+ 2 - Match and Indicate never. This means don't indicate the match to the host.
+ 3 - Reserved
+ */
+ NanMatchAlg publish_match_indicator;
+
+ /*
+ Sequence of values
+ NAN Device that has invoked a Subscribe method corresponding to this Publish method
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs which specify further response conditions
+ beyond the service name used to filter subscribe messages to respond to.
+ This is only needed when the PT is set to NAN_SOLICITED or NAN_SOLICITED_UNSOLICITED.
+ */
+ u16 rx_match_filter_len;
+ u8 rx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs to be included in the Discovery Frame.
+ If present it is always sent in a Discovery Frame
+ */
+ u16 tx_match_filter_len;
+ u8 tx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ flag which specifies that the Publish should use the configured RSSI
+ threshold and the received RSSI in order to filter requests
+ 0 – ignore the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+ 1 – use the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+
+ */
+ u8 rssi_threshold_flag;
+
+ /*
+ 8-bit bitmap which allows the Host to associate this publish
+ with a particular Post-NAN Connectivity attribute
+ which has been sent down in a NanConfigureRequest/NanEnableRequest
+ message. If the DE fails to find a configured Post-NAN
+ connectivity attributes referenced by the bitmap,
+ the DE will return an error code to the Host.
+ If the Publish is configured to use a Post-NAN Connectivity
+ attribute and the Host does not refresh the Post-NAN Connectivity
+ attribute the Publish will be canceled and the Host will be sent
+ a PublishTerminatedIndication message.
+ */
+ u8 connmap;
+ /*
+ Set/Enable corresponding bits to disable any indications that follow a publish.
+ BIT0 - Disable publish termination indication.
+ BIT1 - Disable match expired indication.
+ BIT2 - Disable followUp indication received (OTA).
+ BIT3 - Disable publishReplied indication.
+ */
+ u8 recv_indication_cfg;
+ /*
+ Nan accept policy for the specific service(publish)
+ */
+ NanServiceAcceptPolicy service_responder_policy;
+ /* NAN Cipher Suite Type */
+ u32 cipher_type;
+ /*
+ Nan Security Key Info is optional in Discovery phase.
+ PMK or passphrase info can be passed during
+ the NDP session.
+ */
+ NanSecurityKeyInfo key_info;
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+ /* NAN configure service discovery extended attributes */
+ NanSdeaCtrlParams sdea_params;
+
+ /* NAN Ranging configuration */
+ NanRangingCfg ranging_cfg;
+
+ /* Enable/disable NAN serivce Ranging auto response mode */
+ NanRangingAutoResponse ranging_auto_response;
+
+ /*
+ When the ranging_auto_response_cfg is not set, NanRangeRequestInd is
+ received. Nan Range Response to Peer MAC Addr is notified to indicate
+ ACCEPT/REJECT/CANCEL to the requestor.
+ */
+ NanRangeResponseCfg range_response_cfg;
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanPublishRequest;
+
+/*
+ Publish Cancel Msg Structure
+ The PublishServiceCancelReq Message is used to request the DE to stop publishing
+ the Service Name identified by the Publish Id in the message.
+*/
+typedef struct {
+ u16 publish_id;
+} NanPublishCancelRequest;
+
+/*
+ NAN Subscribe Structure
+ The SubscribeServiceReq message is sent to the Discovery Engine
+ whenever the Upper layers would like to listen for a Service Name
+*/
+typedef struct {
+ u16 subscribe_id; /* id 0 means new subscribe, non zero is existing subscribe */
+ u16 ttl; /* how many seconds to run for. 0 means forever until canceled */
+ /*
+ period: Awake DW Interval for subscribe(service)
+ Indicates the interval between two Discovery Windows in which
+ the device supporting the service is awake to transmit or
+ receive the Service Discovery frames.
+ Valid values of Awake DW Interval are: 1, 2, 4, 8 and 16, value 0 will
+ default to 1.
+ */
+ u16 period;
+
+ /* Flag which specifies how the Subscribe request shall be processed. */
+ NanSubscribeType subscribe_type; /* 0 - PASSIVE , 1- ACTIVE */
+
+ /* Flag which specifies on Active Subscribes how the Service Response Filter attribute is
+ * populated.*/
+ NanSRFType serviceResponseFilter; /* 0 - Bloom Filter, 1 - MAC Addr */
+
+ /* Flag which specifies how the Service Response Filter Include bit is populated.*/
+ NanSRFIncludeType
+ serviceResponseInclude; /* 0=Do not respond if in the Address Set, 1= Respond */
+
+ /* Flag which specifies if the Service Response Filter should be used when creating
+ * Subscribes.*/
+ NanSRFState useServiceResponseFilter; /* 0=Do not send the Service Response Filter,1= send */
+
+ /*
+ Flag which specifies if the Service Specific Info is needed in
+ the Publish message before creating the MatchIndication
+ */
+ NanSsiInMatchInd ssiRequiredForMatchIndication; /* 0=Not needed, 1= Required */
+
+ /*
+ Field which specifies how the matching indication to host is controlled.
+ 0 - Match and Indicate Once
+ 1 - Match and Indicate continuous
+ 2 - Match and Indicate never. This means don't indicate the match to the host.
+ 3 - Reserved
+ */
+ NanMatchAlg subscribe_match_indicator;
+
+ /*
+ The number of Subscribe Matches which should occur
+ before the Subscribe request is automatically terminated.
+ */
+ u8 subscribe_count; /* If this value is 0 this field is not used by the DE.*/
+
+ u16 service_name_len; /* length of service name */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN]; /* UTF-8 encoded string identifying the service */
+
+ /* Sequence of values which further specify the published service beyond the service name*/
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs used to filter out received publish discovery
+ messages. This can be sent both for a Passive or an Active Subscribe
+ */
+ u16 rx_match_filter_len;
+ u8 rx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs included in the
+ Discovery Frame when an Active Subscribe is used.
+ */
+ u16 tx_match_filter_len;
+ u8 tx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ Flag which specifies that the Subscribe should use the configured RSSI
+ threshold and the received RSSI in order to filter requests
+ 0 – ignore the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+ 1 – use the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+
+ */
+ u8 rssi_threshold_flag;
+
+ /*
+ 8-bit bitmap which allows the Host to associate this Active
+ Subscribe with a particular Post-NAN Connectivity attribute
+ which has been sent down in a NanConfigureRequest/NanEnableRequest
+ message. If the DE fails to find a configured Post-NAN
+ connectivity attributes referenced by the bitmap,
+ the DE will return an error code to the Host.
+ If the Subscribe is configured to use a Post-NAN Connectivity
+ attribute and the Host does not refresh the Post-NAN Connectivity
+ attribute the Subscribe will be canceled and the Host will be sent
+ a SubscribeTerminatedIndication message.
+ */
+ u8 connmap;
+ /*
+ NAN Interface Address, conforming to the format as described in
+ 8.2.4.3.2 of IEEE Std. 802.11-2012.
+ */
+ u8 num_intf_addr_present;
+ u8 intf_addr[NAN_MAX_SUBSCRIBE_MAX_ADDRESS][NAN_MAC_ADDR_LEN];
+ /*
+ Set/Enable corresponding bits to disable indications that follow a subscribe.
+ BIT0 - Disable subscribe termination indication.
+ BIT1 - Disable match expired indication.
+ BIT2 - Disable followUp indication received (OTA).
+ */
+ u8 recv_indication_cfg;
+
+ /* NAN Cipher Suite Type */
+ u32 cipher_type;
+ /*
+ Nan Security Key Info is optional in Discovery phase.
+ PMK or passphrase info can be passed during
+ the NDP session.
+ */
+ NanSecurityKeyInfo key_info;
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+ /* NAN configure service discovery extended attributes */
+ NanSdeaCtrlParams sdea_params;
+
+ /* NAN Ranging configuration */
+ NanRangingCfg ranging_cfg;
+
+ /* Enable/disable NAN serivce Ranging auto response mode */
+ NanRangingAutoResponse ranging_auto_response;
+
+ /*
+ When the ranging_auto_response_cfg is not set, NanRangeRequestInd is
+ received. Nan Range Response to Peer MAC Addr is notified to indicate
+ ACCEPT/REJECT/CANCEL to the requestor.
+ */
+ NanRangeResponseCfg range_response_cfg;
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanSubscribeRequest;
+
+/*
+ NAN Subscribe Cancel Structure
+ The SubscribeCancelReq Message is used to request the DE to stop looking for the Service Name.
+*/
+typedef struct {
+ u16 subscribe_id;
+} NanSubscribeCancelRequest;
+
+/*
+ Transmit follow up Structure
+ The TransmitFollowupReq message is sent to the DE to allow the sending of the
+ Service_Specific_Info to a particular MAC address.
+*/
+typedef struct {
+ /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+ u16 publish_subscribe_id;
+
+ /*
+ This Id is the Requestor Instance that is passed as
+ part of earlier MatchInd/FollowupInd message.
+ */
+ u32 requestor_instance_id;
+ u8 addr[NAN_MAC_ADDR_LEN]; /* Unicast address */
+ NanTxPriority priority; /* priority of the request 2=high */
+ NanTransmitWindowType dw_or_faw; /* 0= send in a DW, 1=send in FAW */
+
+ /*
+ Sequence of values which further specify the published service beyond
+ the service name.
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+ /*
+ Set/Enable corresponding bits to disable responses after followUp.
+ BIT0 - Disable followUp response from FW.
+ */
+ u8 recv_indication_cfg;
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanTransmitFollowupRequest;
+
+/*
+ Stats Request structure
+ The Discovery Engine can be queried at runtime by the Host processor for statistics
+ concerning various parts of the Discovery Engine.
+*/
+typedef struct {
+ NanStatsType stats_type; /* NAN Statistics Request Type */
+ u8 clear; /* 0= Do not clear the stats and return the current contents , 1= Clear the associated
+ stats */
+} NanStatsRequest;
+
+/*
+ Config Structure
+ The NanConfigurationReq message is sent by the Host to the
+ Discovery Engine in order to configure the Discovery Engine during runtime.
+*/
+typedef struct {
+ u8 config_sid_beacon;
+ u8 sid_beacon;
+ u8 config_rssi_proximity;
+ u8 rssi_proximity; // default value -60dBm
+ u8 config_master_pref;
+ u8 master_pref; // default value 0x02
+ /*
+ 1 byte value which defines the RSSI filter threshold.
+ Any Service Descriptors received above this value
+ that are configured for RSSI filtering will be dropped.
+ The rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_5g_rssi_close_proximity;
+ u8 rssi_close_proximity_5g_val; // default value -60dBm
+ /*
+ Optional configuration of Configure request.
+ Each of the optional parameters have configure flag which
+ determine whether configuration is to be passed or not.
+ */
+ /*
+ 1 byte quantity which defines the window size over
+ which the “average RSSI†will be calculated over.
+ */
+ u8 config_rssi_window_size;
+ u8 rssi_window_size_val; // default value 0x08
+ /*
+ If set to 1, the Discovery Engine will enclose the Cluster
+ Attribute only sent in Beacons in a Vendor Specific Attribute
+ and transmit in a Service Descriptor Frame.
+ */
+ u8 config_cluster_attribute_val;
+ /*
+ The periodicity in seconds between full scan’s to find any new
+ clusters available in the area. A Full scan should not be done
+ more than every 10 seconds and should not be done less than every
+ 30 seconds.
+ */
+ u8 config_scan_params;
+ NanSocialChannelScanParams scan_params_val;
+ /*
+ 1 byte quantity which forces the Random Factor to a particular
+ value for all transmitted Sync/Discovery beacons
+ */
+ u8 config_random_factor_force;
+ u8 random_factor_force_val; // default value 0x00
+ /*
+ 1 byte quantity which forces the HC for all transmitted Sync and
+ Discovery Beacon NO matter the real HC being received over the
+ air.
+ */
+ u8 config_hop_count_force;
+ u8 hop_count_force_val; // default value of 0
+ /* NAN Post Connectivity Capability */
+ u8 config_conn_capability;
+ NanTransmitPostConnectivityCapability conn_capability_val;
+ /* NAN Post Discover Capability */
+ u8 num_config_discovery_attr;
+ NanTransmitPostDiscovery discovery_attr_val[NAN_MAX_POSTDISCOVERY_LEN];
+ /* NAN Further availability Map */
+ u8 config_fam;
+ NanFurtherAvailabilityMap fam_val;
+ /* Configure 2.4/5GHz DW */
+ NanConfigDW config_dw;
+ /*
+ By default discovery MAC address randomization is enabled
+ and default interval value is 30 minutes i.e. 1800 seconds.
+ The value 0 is used to disable MAC addr randomization.
+ */
+ u8 config_disc_mac_addr_randomization;
+ u32 disc_mac_addr_rand_interval_sec; // default value of 30 minutes
+
+ /*
+ Set/Enable corresponding bits to disable Discovery indications:
+ BIT0 - Disable Discovery MAC Address Event.
+ BIT1 - Disable Started Cluster Event.
+ BIT2 - Disable Joined Cluster Event.
+ */
+ u8 discovery_indication_cfg; // default value of 0
+ /*
+ BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+ 0 - Do not include SIDs in any beacons
+ 1 - Include SIDs in all beacons.
+ Rest 7 bits are count field which allows control over the number of SIDs
+ included in the Beacon. 0 means to include as many SIDs that fit into
+ the maximum allow Beacon frame size
+ */
+ u8 config_subscribe_sid_beacon;
+ u32 subscribe_sid_beacon_val; // default value 0x0
+ /*
+ Discovery Beacon Interval config.
+ Default value is 128 msec in 2G DW and 176 msec in 2G/5G DW.
+ When 0 value is passed it is reset to default value of 128 or 176 msec.
+ */
+ u8 config_discovery_beacon_int;
+ u32 discovery_beacon_interval;
+ /*
+ Enable Number of Spatial Streams.
+ This is NAN Power Optimization feature for NAN discovery.
+ */
+ u8 config_nss;
+ // default value is implementation specific and passing 0 sets it to default
+ u32 nss;
+ /*
+ Enable device level NAN Ranging feature.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_enable_ranging;
+ u32 enable_ranging;
+ /*
+ Enable/Disable DW Early termination.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_dw_early_termination;
+ u32 enable_dw_termination;
+ /*
+ Indicate whether to use NDPE attribute to bring-up TCP/IP connection
+ If config_ndpe_attr is not configured, the default behavior is
+ not using NDPE attr, and the capability is not advertised.
+ 0 - Not use
+ 1 - Use
+ */
+ u8 config_ndpe_attr;
+ u32 use_ndpe_attr;
+ /*
+ Enable NAN v3.1 instant communication mode.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_enable_instant_mode;
+ u32 enable_instant_mode;
+ /*
+ Config NAN v3.1 instant communication channel selected over NFC/OOB method.
+ If dual band is supported default channel is 149 or 44 as per regulatory domain,
+ else channel 6 (send frequency in MHz).
+ Sometimes depending on country code retrictions, even 149/44 may be restricted
+ in those cases instant channel will be operational only in 2.4GHz.
+ Use wifi_get_usable_channels() API to get supported bands/channels before
+ Instant mode NFC handshake is triggered
+ */
+ u8 config_instant_mode_channel;
+ wifi_channel instant_mode_channel;
+} NanConfigRequest;
+
+/*
+ TCA Structure
+ The Discovery Engine can be configured to send up Events whenever a configured
+ Threshold Crossing Alert (TCA) Type crosses an integral threshold in a particular direction.
+*/
+typedef struct {
+ NanTcaType tca_type; /* Nan Protocol Threshold Crossing Alert (TCA) Codes */
+
+ /* flag which control whether or not an event is generated for the Rising direction */
+ u8 rising_direction_evt_flag; /* 0 - no event, 1 - event */
+
+ /* flag which control whether or not an event is generated for the Falling direction */
+ u8 falling_direction_evt_flag; /* 0 - no event, 1 - event */
+
+ /* flag which requests a previous TCA request to be cleared from the DE */
+ u8 clear; /*0= Do not clear the TCA, 1=Clear the TCA */
+
+ /* 32 bit value which represents the threshold to be used.*/
+ u32 threshold;
+} NanTCARequest;
+
+/*
+ Beacon Sdf Payload Structure
+ The Discovery Engine can be configured to publish vendor specific attributes as part of
+ beacon or service discovery frame transmitted as part of this request..
+*/
+typedef struct {
+ /*
+ NanVendorAttribute will have the Vendor Specific Attribute which the
+ vendor wants to publish as part of Discovery or Sync or Service discovery frame
+ */
+ NanTransmitVendorSpecificAttribute vsa;
+} NanBeaconSdfPayloadRequest;
+
+/* Publish statistics. */
+typedef struct {
+ u32 validPublishServiceReqMsgs;
+ u32 validPublishServiceRspMsgs;
+ u32 validPublishServiceCancelReqMsgs;
+ u32 validPublishServiceCancelRspMsgs;
+ u32 validPublishRepliedIndMsgs;
+ u32 validPublishTerminatedIndMsgs;
+ u32 validActiveSubscribes;
+ u32 validMatches;
+ u32 validFollowups;
+ u32 invalidPublishServiceReqMsgs;
+ u32 invalidPublishServiceCancelReqMsgs;
+ u32 invalidActiveSubscribes;
+ u32 invalidMatches;
+ u32 invalidFollowups;
+ u32 publishCount;
+ u32 publishNewMatchCount;
+ u32 pubsubGlobalNewMatchCount;
+} NanPublishStats;
+
+/* Subscribe statistics. */
+typedef struct {
+ u32 validSubscribeServiceReqMsgs;
+ u32 validSubscribeServiceRspMsgs;
+ u32 validSubscribeServiceCancelReqMsgs;
+ u32 validSubscribeServiceCancelRspMsgs;
+ u32 validSubscribeTerminatedIndMsgs;
+ u32 validSubscribeMatchIndMsgs;
+ u32 validSubscribeUnmatchIndMsgs;
+ u32 validSolicitedPublishes;
+ u32 validMatches;
+ u32 validFollowups;
+ u32 invalidSubscribeServiceReqMsgs;
+ u32 invalidSubscribeServiceCancelReqMsgs;
+ u32 invalidSubscribeFollowupReqMsgs;
+ u32 invalidSolicitedPublishes;
+ u32 invalidMatches;
+ u32 invalidFollowups;
+ u32 subscribeCount;
+ u32 bloomFilterIndex;
+ u32 subscribeNewMatchCount;
+ u32 pubsubGlobalNewMatchCount;
+} NanSubscribeStats;
+
+/* NAN DW Statistics*/
+typedef struct {
+ /* RX stats */
+ u32 validFrames;
+ u32 validActionFrames;
+ u32 validBeaconFrames;
+ u32 ignoredActionFrames;
+ u32 ignoredBeaconFrames;
+ u32 invalidFrames;
+ u32 invalidActionFrames;
+ u32 invalidBeaconFrames;
+ u32 invalidMacHeaders;
+ u32 invalidPafHeaders;
+ u32 nonNanBeaconFrames;
+
+ u32 earlyActionFrames;
+ u32 inDwActionFrames;
+ u32 lateActionFrames;
+
+ /* TX stats */
+ u32 framesQueued;
+ u32 totalTRSpUpdates;
+ u32 completeByTRSp;
+ u32 completeByTp75DW;
+ u32 completeByTendDW;
+ u32 lateActionFramesTx;
+} NanDWStats;
+
+/* NAN MAC Statistics. */
+typedef struct {
+ /* RX stats */
+ u32 validFrames;
+ u32 validActionFrames;
+ u32 validBeaconFrames;
+ u32 ignoredActionFrames;
+ u32 ignoredBeaconFrames;
+ u32 invalidFrames;
+ u32 invalidActionFrames;
+ u32 invalidBeaconFrames;
+ u32 invalidMacHeaders;
+ u32 invalidPafHeaders;
+ u32 nonNanBeaconFrames;
+
+ u32 earlyActionFrames;
+ u32 inDwActionFrames;
+ u32 lateActionFrames;
+
+ /* TX stats */
+ u32 framesQueued;
+ u32 totalTRSpUpdates;
+ u32 completeByTRSp;
+ u32 completeByTp75DW;
+ u32 completeByTendDW;
+ u32 lateActionFramesTx;
+
+ u32 twIncreases;
+ u32 twDecreases;
+ u32 twChanges;
+ u32 twHighwater;
+ u32 bloomFilterIndex;
+} NanMacStats;
+
+/* NAN Sync Statistics*/
+typedef struct {
+ u64 currTsf;
+ u64 myRank;
+ u64 currAmRank;
+ u64 lastAmRank;
+ u32 currAmBTT;
+ u32 lastAmBTT;
+ u8 currAmHopCount;
+ u8 currRole;
+ u16 currClusterId;
+
+ u64 timeSpentInCurrRole;
+ u64 totalTimeSpentAsMaster;
+ u64 totalTimeSpentAsNonMasterSync;
+ u64 totalTimeSpentAsNonMasterNonSync;
+ u32 transitionsToAnchorMaster;
+ u32 transitionsToMaster;
+ u32 transitionsToNonMasterSync;
+ u32 transitionsToNonMasterNonSync;
+ u32 amrUpdateCount;
+ u32 amrUpdateRankChangedCount;
+ u32 amrUpdateBTTChangedCount;
+ u32 amrUpdateHcChangedCount;
+ u32 amrUpdateNewDeviceCount;
+ u32 amrExpireCount;
+ u32 mergeCount;
+ u32 beaconsAboveHcLimit;
+ u32 beaconsBelowRssiThresh;
+ u32 beaconsIgnoredNoSpace;
+ u32 beaconsForOurCluster;
+ u32 beaconsForOtherCluster;
+ u32 beaconCancelRequests;
+ u32 beaconCancelFailures;
+ u32 beaconUpdateRequests;
+ u32 beaconUpdateFailures;
+ u32 syncBeaconTxAttempts;
+ u32 syncBeaconTxFailures;
+ u32 discBeaconTxAttempts;
+ u32 discBeaconTxFailures;
+ u32 amHopCountExpireCount;
+ u32 ndpChannelFreq;
+ u32 ndpChannelFreq2;
+ u32 schedUpdateChannelFreq;
+} NanSyncStats;
+
+/* NAN Misc DE Statistics */
+typedef struct {
+ u32 validErrorRspMsgs;
+ u32 validTransmitFollowupReqMsgs;
+ u32 validTransmitFollowupRspMsgs;
+ u32 validFollowupIndMsgs;
+ u32 validConfigurationReqMsgs;
+ u32 validConfigurationRspMsgs;
+ u32 validStatsReqMsgs;
+ u32 validStatsRspMsgs;
+ u32 validEnableReqMsgs;
+ u32 validEnableRspMsgs;
+ u32 validDisableReqMsgs;
+ u32 validDisableRspMsgs;
+ u32 validDisableIndMsgs;
+ u32 validEventIndMsgs;
+ u32 validTcaReqMsgs;
+ u32 validTcaRspMsgs;
+ u32 validTcaIndMsgs;
+ u32 invalidTransmitFollowupReqMsgs;
+ u32 invalidConfigurationReqMsgs;
+ u32 invalidStatsReqMsgs;
+ u32 invalidEnableReqMsgs;
+ u32 invalidDisableReqMsgs;
+ u32 invalidTcaReqMsgs;
+} NanDeStats;
+
+/* Publish Response Message structure */
+typedef struct {
+ u16 publish_id;
+} NanPublishResponse;
+
+/* Subscribe Response Message structure */
+typedef struct {
+ u16 subscribe_id;
+} NanSubscribeResponse;
+
+/*
+ Stats Response Message structure
+ The Discovery Engine response to a request by the Host for statistics.
+*/
+typedef struct {
+ NanStatsType stats_type;
+ union {
+ NanPublishStats publish_stats;
+ NanSubscribeStats subscribe_stats;
+ NanMacStats mac_stats;
+ NanSyncStats sync_stats;
+ NanDeStats de_stats;
+ NanDWStats dw_stats;
+ } data;
+} NanStatsResponse;
+
+/* Response returned for Initiators Data request */
+typedef struct {
+ /*
+ Unique token Id generated on the initiator
+ side used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id;
+} NanDataPathRequestResponse;
+
+/*
+ NAN Response messages
+*/
+typedef struct {
+ NanStatusType status; /* contains the result code */
+ char nan_error[NAN_ERROR_STR_LEN]; /* Describe the NAN error type */
+ NanResponseType response_type; /* NanResponseType Definitions */
+ union {
+ NanPublishResponse publish_response;
+ NanSubscribeResponse subscribe_response;
+ NanStatsResponse stats_response;
+ NanDataPathRequestResponse data_request_response;
+ NanCapabilities nan_capabilities;
+ } body;
+} NanResponseMsg;
+
+/*
+ Publish Replied Indication
+ The PublishRepliedInd Message is sent by the DE when an Active Subscribe is
+ received over the air and it matches a Solicited PublishServiceReq which had
+ been created with the replied_event_flag set.
+*/
+typedef struct {
+ /*
+ A 32 bit Requestor Instance Id which is sent to the Application.
+ This Id will be sent in any subsequent UnmatchInd/FollowupInd
+ messages
+ */
+ u32 requestor_instance_id;
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ If RSSI filtering was configured in NanPublishRequest then this
+ field will contain the received RSSI value. 0 if not
+ */
+ u8 rssi_value;
+} NanPublishRepliedInd;
+
+/*
+ Publish Terminated
+ The PublishTerminatedInd message is sent by the DE whenever a Publish
+ terminates from a user-specified timeout or a unrecoverable error in the DE.
+*/
+typedef struct {
+ /* Id returned during the initial Publish */
+ u16 publish_id;
+ /*
+ For all user configured termination NAN_STATUS_SUCCESS
+ and no other reasons expected from firmware.
+ */
+ NanStatusType reason;
+ char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanPublishTerminatedInd;
+
+/*
+ Match Indication
+ The MatchInd message is sent once per responding MAC address whenever
+ the Discovery Engine detects a match for a previous SubscribeServiceReq
+ or PublishServiceReq.
+*/
+typedef struct {
+ /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+ u16 publish_subscribe_id;
+ /*
+ A 32 bit Requestor Instance Id which is sent to the Application.
+ This Id will be sent in any subsequent UnmatchInd/FollowupInd
+ messages
+ */
+ u32 requestor_instance_id;
+ u8 addr[NAN_MAC_ADDR_LEN];
+
+ /*
+ Sequence of octets which were received in a Discovery Frame matching the
+ Subscribe Request.
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs received in the Discovery Frame
+ matching the Subscribe Request.
+ */
+ u16 sdf_match_filter_len;
+ u8 sdf_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ flag to indicate if the Match occurred in a Beacon Frame or in a
+ Service Discovery Frame.
+ 0 - Match occured in a Service Discovery Frame
+ 1 - Match occured in a Beacon Frame
+ */
+ u8 match_occured_flag;
+
+ /*
+ flag to indicate FW is out of resource and that it can no longer
+ track this Service Name. The Host still need to send the received
+ Match_Handle but duplicate MatchInd messages may be received on
+ this Handle until the resource frees up.
+ 0 - FW is caching this match
+ 1 - FW is unable to cache this match
+ */
+ u8 out_of_resource_flag;
+
+ /*
+ If RSSI filtering was configured in NanSubscribeRequest then this
+ field will contain the received RSSI value. 0 if not.
+ All rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 rssi_value;
+
+ /*
+ optional attributes. Each optional attribute is associated with a flag
+ which specifies whether the attribute is valid or not
+ */
+ /* NAN Post Connectivity Capability received */
+ u8 is_conn_capability_valid;
+ NanReceivePostConnectivityCapability conn_capability;
+
+ /* NAN Post Discover Capability */
+ u8 num_rx_discovery_attr;
+ NanReceivePostDiscovery discovery_attr[NAN_MAX_POSTDISCOVERY_LEN];
+
+ /* NAN Further availability Map */
+ u8 num_chans;
+ NanFurtherAvailabilityChannel famchan[NAN_MAX_FAM_CHANNELS];
+
+ /* NAN Cluster Attribute */
+ u8 cluster_attribute_len;
+ u8 cluster_attribute[NAN_MAX_CLUSTER_ATTRIBUTE_LEN];
+
+ /* NAN Cipher Suite */
+ u32 peer_cipher_type;
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+ /* Peer service discovery extended attributes */
+ NanSdeaCtrlParams peer_sdea_params;
+
+ /*
+ Ranging indication and NanMatchAlg are not tied.
+ Ex: NanMatchAlg can indicate Match_ONCE, but ranging
+ indications can be continuous. All ranging indications
+ depend on SDEA control parameters of ranging required for
+ continuous, and ingress/egress values in the ranging config.
+ Ranging indication data is notified if:
+ 1) Ranging required is enabled in SDEA.
+ range info notified continuous.
+ 2) if range_limit ingress/egress MASKS are enabled
+ notify once for ingress >= ingress_distance
+ and egress <= egress_distance, same for ingress_egress_both
+ 3) if the Awake DW intervals are higher than the ranging intervals,
+ priority is given to the device DW intervalsi.
+ */
+ /*
+ Range Info includes:
+ 1) distance to the NAN device with the MAC address indicated
+ with ranged mac address.
+ 2) Ranging event matching the configuration of continuous/ingress/egress.
+ */
+ NanRangeInfo range_info;
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanMatchInd;
+
+/*
+ MatchExpired Indication
+ The MatchExpiredInd message is sent whenever the Discovery Engine detects that
+ a previously Matched Service has been gone for too long. If the previous
+ MatchInd message for this Publish/Subscribe Id had the out_of_resource_flag
+ set then this message will not be received
+*/
+typedef struct {
+ /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+ u16 publish_subscribe_id;
+ /*
+ 32 bit value sent by the DE in a previous
+ MatchInd/FollowupInd to the application.
+ */
+ u32 requestor_instance_id;
+} NanMatchExpiredInd;
+
+/*
+ Subscribe Terminated
+ The SubscribeTerminatedInd message is sent by the DE whenever a
+ Subscribe terminates from a user-specified timeout or a unrecoverable error in the DE.
+*/
+typedef struct {
+ /* Id returned during initial Subscribe */
+ u16 subscribe_id;
+ /*
+ For all user configured termination NAN_STATUS_SUCCESS
+ and no other reasons expected from firmware.
+ */
+ NanStatusType reason;
+ char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanSubscribeTerminatedInd;
+
+/*
+ Followup Indication Message
+ The FollowupInd message is sent by the DE to the Host whenever it receives a
+ Followup message from another peer.
+*/
+typedef struct {
+ /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+ u16 publish_subscribe_id;
+ /*
+ A 32 bit Requestor instance Id which is sent to the Application.
+ This Id will be used in subsequent UnmatchInd/FollowupInd messages.
+ */
+ u32 requestor_instance_id;
+ u8 addr[NAN_MAC_ADDR_LEN];
+
+ /* Flag which the DE uses to decide if received in a DW or a FAW*/
+ u8 dw_or_faw; /* 0=Received in a DW, 1 = Received in a FAW*/
+
+ /*
+ Sequence of values which further specify the published service beyond
+ the service name
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanFollowupInd;
+
+/*
+ Event data notifying the Mac address of the Discovery engine.
+ which is reported as one of the Discovery engine event
+*/
+typedef struct {
+ u8 addr[NAN_MAC_ADDR_LEN];
+} NanMacAddressEvent;
+
+/*
+ Event data notifying the Cluster address of the cluster
+ which is reported as one of the Discovery engine event
+*/
+typedef struct {
+ u8 addr[NAN_MAC_ADDR_LEN];
+} NanClusterEvent;
+
+/*
+ Discovery Engine Event Indication
+ The Discovery Engine can inform the Host when significant events occur
+ The data following the EventId is dependent upon the EventId type.
+ In other words, each new event defined will carry a different
+ structure of information back to the host.
+*/
+typedef struct {
+ NanDiscEngEventType event_type; /* NAN Protocol Event Codes */
+ union {
+ /*
+ MacAddressEvent which will have 6 byte mac address
+ of the Discovery engine.
+ */
+ NanMacAddressEvent mac_addr;
+ /*
+ Cluster Event Data which will be obtained when the
+ device starts a new cluster or joins a cluster.
+ The event data will have 6 byte octet string of the
+ cluster started or joined.
+ */
+ NanClusterEvent cluster;
+ } data;
+} NanDiscEngEventInd;
+
+/* Cluster size TCA event*/
+typedef struct {
+ /* size of the cluster*/
+ u32 cluster_size;
+} NanTcaClusterEvent;
+
+/*
+ NAN TCA Indication
+ The Discovery Engine can inform the Host when significant events occur.
+ The data following the TcaId is dependent upon the TcaId type.
+ In other words, each new event defined will carry a different structure
+ of information back to the host.
+*/
+typedef struct {
+ NanTcaType tca_type;
+ /* flag which defines if the configured Threshold has risen above the threshold */
+ u8 rising_direction_evt_flag; /* 0 - no event, 1 - event */
+
+ /* flag which defines if the configured Threshold has fallen below the threshold */
+ u8 falling_direction_evt_flag; /* 0 - no event, 1 - event */
+ union {
+ /*
+ This event in obtained when the cluser size threshold
+ is crossed. Event will have the cluster size
+ */
+ NanTcaClusterEvent cluster;
+ } data;
+} NanTCAInd;
+
+/*
+ NAN Disabled Indication
+ The NanDisableInd message indicates to the upper layers that the Discovery
+ Engine has flushed all state and has been shutdown. When this message is received
+ the DE is guaranteed to have left the NAN cluster it was part of and will have terminated
+ any in progress Publishes or Subscribes.
+*/
+typedef struct {
+ /*
+ Following reasons expected:
+ NAN_STATUS_SUCCESS
+ NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED
+ */
+ NanStatusType reason;
+ char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanDisabledInd;
+
+/*
+ NAN Beacon or SDF Payload Indication
+ The NanBeaconSdfPayloadInd message indicates to the upper layers that information
+ elements were received either in a Beacon or SDF which needs to be delivered
+ outside of a Publish/Subscribe Handle.
+*/
+typedef struct {
+ /* The MAC address of the peer which sent the attributes.*/
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ Optional attributes. Each optional attribute is associated with a flag
+ which specifies whether the attribute is valid or not
+ */
+ /* NAN Receive Vendor Specific Attribute*/
+ u8 is_vsa_received;
+ NanReceiveVendorSpecificAttribute vsa;
+
+ /* NAN Beacon or SDF Payload Received*/
+ u8 is_beacon_sdf_payload_received;
+ NanBeaconSdfPayloadReceive data;
+} NanBeaconSdfPayloadInd;
+
+/*
+ Event Indication notifying the
+ transmit followup in progress
+*/
+typedef struct {
+ transaction_id id;
+ /*
+ Following reason codes returned:
+ NAN_STATUS_SUCCESS
+ NAN_STATUS_NO_OTA_ACK
+ NAN_STATUS_PROTOCOL_FAILURE
+ */
+ NanStatusType reason;
+ char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanTransmitFollowupInd;
+
+/*
+ Data request Initiator/Responder
+ app/service related info
+*/
+typedef struct {
+ u16 ndp_app_info_len;
+ u8 ndp_app_info[NAN_DP_MAX_APP_INFO_LEN];
+} NanDataPathAppInfo;
+
+/* QoS configuration */
+typedef enum { NAN_DP_CONFIG_NO_QOS = 0, NAN_DP_CONFIG_QOS } NanDataPathQosCfg;
+
+/* Configuration params of Data request Initiator/Responder */
+typedef struct {
+ /* Status Indicating Security/No Security */
+ NanDataPathSecurityCfgStatus security_cfg;
+ NanDataPathQosCfg qos_cfg;
+} NanDataPathCfg;
+
+/* Nan Data Path Initiator requesting a data session */
+typedef struct {
+ /*
+ Unique Instance Id identifying the Responder's service.
+ This is same as publish_id notified on the subscribe side
+ in a publish/subscribe scenario
+ */
+ u32 requestor_instance_id; /* Value 0 for no publish/subscribe */
+
+ /* Config flag for channel request */
+ NanDataPathChannelCfg channel_request_type;
+ /* Channel frequency in MHz to start data-path */
+ wifi_channel channel;
+ /*
+ Discovery MAC addr of the publisher/peer
+ */
+ u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+ /*
+ Interface name on which this NDP session is to be started.
+ This will be the same interface name provided during interface
+ create.
+ */
+ char ndp_iface[IFNAMSIZ + 1];
+ /* Initiator/Responder Security/QoS configuration */
+ NanDataPathCfg ndp_cfg;
+ /* App/Service information of the Initiator */
+ NanDataPathAppInfo app_info;
+ /* NAN Cipher Suite Type */
+ u32 cipher_type;
+ /*
+ Nan Security Key Info is optional in Discovery phase.
+ PMK or passphrase info can be passed during
+ the NDP session.
+ */
+ NanSecurityKeyInfo key_info;
+ /* length of service name */
+ u32 service_name_len;
+ /*
+ UTF-8 encoded string identifying the service name.
+ The service name field is only used if a Nan discovery
+ is not associated with the NDP (out-of-band discovery).
+ */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN];
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+} NanDataPathInitiatorRequest;
+
+/*
+ Data struct to initiate a data response on the responder side
+ for an indication received with a data request
+*/
+typedef struct {
+ /*
+ Unique token Id generated on the initiator/responder
+ side used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id;
+ /*
+ Interface name on which this NDP session is to be started.
+ This will be the same interface name provided during interface
+ create.
+ */
+ char ndp_iface[IFNAMSIZ + 1];
+ /* Initiator/Responder Security/QoS configuration */
+ NanDataPathCfg ndp_cfg;
+ /* App/Service information of the responder */
+ NanDataPathAppInfo app_info;
+ /* Response Code indicating ACCEPT/REJECT/DEFER */
+ NanDataPathResponseCode rsp_code;
+ /* NAN Cipher Suite Type */
+ u32 cipher_type;
+ /*
+ Nan Security Key Info is optional in Discovery phase.
+ PMK or passphrase info can be passed during
+ the NDP session.
+ */
+ NanSecurityKeyInfo key_info;
+ /* length of service name */
+ u32 service_name_len;
+ /*
+ UTF-8 encoded string identifying the service name.
+ The service name field is only used if a Nan discovery
+ is not associated with the NDP (out-of-band discovery).
+ */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN];
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+} NanDataPathIndicationResponse;
+
+/* NDP termination info */
+typedef struct {
+ u8 num_ndp_instances;
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id[];
+} NanDataPathEndRequest;
+
+/*
+ Event indication received on the
+ responder side when a Nan Data request or
+ NDP session is initiated on the Initiator side
+*/
+typedef struct {
+ /*
+ Unique Instance Id corresponding to a service/session.
+ This is similar to the publish_id generated on the
+ publisher side
+ */
+ u16 service_instance_id;
+ /* Discovery MAC addr of the peer/initiator */
+ u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id;
+ /* Initiator/Responder Security/QoS configuration */
+ NanDataPathCfg ndp_cfg;
+ /* App/Service information of the initiator */
+ NanDataPathAppInfo app_info;
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+} NanDataPathRequestInd;
+
+/*
+ Event indication of data confirm is received on both
+ initiator and responder side confirming a NDP session
+*/
+typedef struct {
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id;
+ /*
+ NDI mac address of the peer
+ (required to derive target ipv6 address)
+ */
+ u8 peer_ndi_mac_addr[NAN_MAC_ADDR_LEN];
+ /* App/Service information of Initiator/Responder */
+ NanDataPathAppInfo app_info;
+ /* Response code indicating ACCEPT/REJECT/DEFER */
+ NanDataPathResponseCode rsp_code;
+ /*
+ Reason code indicating the cause for REJECT.
+ NAN_STATUS_SUCCESS and NAN_STATUS_PROTOCOL_FAILURE are
+ expected reason codes.
+ */
+ NanStatusType reason_code;
+ /* Number of channels for which info is indicated */
+ u32 num_channels;
+ /*
+ Data indicating the Channel list and BW of the channel.
+ */
+ NanChannelInfo channel_info[NAN_MAX_CHANNEL_INFO_SUPPORTED];
+} NanDataPathConfirmInd;
+
+/*
+ Event indication of schedule update is received on both
+ initiator and responder when a schedule change occurs
+*/
+typedef struct {
+ /*
+ NMI mac address
+ */
+ u8 peer_mac_addr[NAN_MAC_ADDR_LEN];
+ /*
+ Reason code indicating the cause of schedule update.
+ BIT_0 NSS Update
+ BIT_1 Channel list update
+ */
+ u32 schedule_update_reason_code;
+ /* Number of channels for which info is indicated */
+ u32 num_channels;
+ /*
+ Data indicating the Channel list and BW of the channel.
+ */
+ NanChannelInfo channel_info[NAN_MAX_CHANNEL_INFO_SUPPORTED];
+ /* Number of NDP instance Ids */
+ u8 num_ndp_instances;
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id[];
+} NanDataPathScheduleUpdateInd;
+
+/*
+ Event indication received on the
+ initiator/responder side terminating
+ a NDP session
+*/
+typedef struct {
+ u8 num_ndp_instances;
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id[];
+} NanDataPathEndInd;
+
+/*
+ Event indicating Range Request received on the
+ Published side.
+*/
+typedef struct {
+ u16 publish_id; /* id is existing publish */
+ /* Range Requestor's MAC address */
+ u8 range_req_intf_addr[NAN_MAC_ADDR_LEN];
+} NanRangeRequestInd;
+
+/*
+ Event indicating Range report on the
+ Published side.
+*/
+typedef struct {
+ u16 publish_id; /* id is existing publish */
+ /* Range Requestor's MAC address */
+ u8 range_req_intf_addr[NAN_MAC_ADDR_LEN];
+ /*
+ Distance to the NAN device with the MAC address indicated
+ with ranged mac address.
+ */
+ u32 range_measurement_mm;
+} NanRangeReportInd;
+
+/* Response and Event Callbacks */
+typedef struct {
+ /* NotifyResponse invoked to notify the status of the Request */
+ void (*NotifyResponse)(transaction_id id, NanResponseMsg* rsp_data);
+ /* Callbacks for various Events */
+ void (*EventPublishReplied)(NanPublishRepliedInd* event);
+ void (*EventPublishTerminated)(NanPublishTerminatedInd* event);
+ void (*EventMatch)(NanMatchInd* event);
+ void (*EventMatchExpired)(NanMatchExpiredInd* event);
+ void (*EventSubscribeTerminated)(NanSubscribeTerminatedInd* event);
+ void (*EventFollowup)(NanFollowupInd* event);
+ void (*EventDiscEngEvent)(NanDiscEngEventInd* event);
+ void (*EventDisabled)(NanDisabledInd* event);
+ void (*EventTca)(NanTCAInd* event);
+ void (*EventBeaconSdfPayload)(NanBeaconSdfPayloadInd* event);
+ void (*EventDataRequest)(NanDataPathRequestInd* event);
+ void (*EventDataConfirm)(NanDataPathConfirmInd* event);
+ void (*EventDataEnd)(NanDataPathEndInd* event);
+ void (*EventTransmitFollowup)(NanTransmitFollowupInd* event);
+ void (*EventRangeRequest)(NanRangeRequestInd* event);
+ void (*EventRangeReport)(NanRangeReportInd* event);
+ void (*EventScheduleUpdate)(NanDataPathScheduleUpdateInd* event);
+} NanCallbackHandler;
+
+/**@brief nan_enable_request
+ * Enable NAN functionality
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanEnableRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_ALREADY_ENABLED
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_NAN_NOT_ALLOWED
+ */
+wifi_error nan_enable_request(transaction_id id, wifi_interface_handle iface,
+ NanEnableRequest* msg);
+
+/**@brief nan_disbale_request
+ * Disable NAN functionality.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDisableRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_PROTOCOL_FAILURE
+ *
+ */
+wifi_error nan_disable_request(transaction_id id, wifi_interface_handle iface);
+
+/**@brief nan_publish_request
+ * Publish request to advertize a service
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanPublishRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_NO_RESOURCE_AVAILABLE
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ */
+wifi_error nan_publish_request(transaction_id id, wifi_interface_handle iface,
+ NanPublishRequest* msg);
+
+/**@brief nan_publish_cancel_request
+ * Cancel previous publish request
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanPublishCancelRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_publish_cancel_request(transaction_id id, wifi_interface_handle iface,
+ NanPublishCancelRequest* msg);
+
+/**@brief nan_subscribe_request
+ * Subscribe request to search for a service
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanSubscribeRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_NO_SPACE_AVAILABLE
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ */
+wifi_error nan_subscribe_request(transaction_id id, wifi_interface_handle iface,
+ NanSubscribeRequest* msg);
+
+/**@brief nan_subscribe_cancel_request
+ * Cancel previous subscribe requests.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanSubscribeRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_subscribe_cancel_request(transaction_id id, wifi_interface_handle iface,
+ NanSubscribeCancelRequest* msg);
+
+/**@brief nan_transmit_followup_request
+ * NAN transmit follow up request
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanTransmitFollowupRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ * NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID
+ * NAN_STATUS_FOLLOWUP_QUEUE_FULL
+ * @return Asynchronous TransmitFollowupInd CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_NO_OTA_ACK
+ */
+wifi_error nan_transmit_followup_request(transaction_id id, wifi_interface_handle iface,
+ NanTransmitFollowupRequest* msg);
+
+/**@brief nan_stats_request
+ * Request NAN statistics from Discovery Engine.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanStatsRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_INVALID_PARAM
+ */
+wifi_error nan_stats_request(transaction_id id, wifi_interface_handle iface, NanStatsRequest* msg);
+
+/**@brief nan_config_request
+ * NAN configuration request.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanConfigRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_config_request(transaction_id id, wifi_interface_handle iface,
+ NanConfigRequest* msg);
+
+/**@brief nan_tca_request
+ * Configure the various Threshold crossing alerts
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanStatsRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_tca_request(transaction_id id, wifi_interface_handle iface, NanTCARequest* msg);
+
+/**@brief nan_beacon_sdf_payload_request
+ * Set NAN Beacon or sdf payload to discovery engine.
+ * This instructs the Discovery Engine to begin publishing the
+ * received payload in any Beacon or Service Discovery Frame transmitted
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanStatsRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_beacon_sdf_payload_request(transaction_id id, wifi_interface_handle iface,
+ NanBeaconSdfPayloadRequest* msg);
+
+/* Register NAN callbacks. */
+wifi_error nan_register_handler(wifi_interface_handle iface, NanCallbackHandler handlers);
+
+/* Get NAN HAL version. */
+wifi_error nan_get_version(wifi_handle handle, NanVersion* version);
+
+/**@brief nan_get_capabilities
+ * Get NAN Capabilities
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ */
+/* Get NAN capabilities. */
+wifi_error nan_get_capabilities(transaction_id id, wifi_interface_handle iface);
+
+/* ========== Nan Data Path APIs ================ */
+/**@brief nan_data_interface_create
+ * Create NAN Data Interface.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param iface_name:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_data_interface_create(transaction_id id, wifi_interface_handle iface,
+ char* iface_name);
+
+/**@brief nan_data_interface_delete
+ * Delete NAN Data Interface.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param iface_name:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_data_interface_delete(transaction_id id, wifi_interface_handle iface,
+ char* iface_name);
+
+/**@brief nan_data_request_initiator
+ * Initiate a NAN Data Path session.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDataPathInitiatorRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID
+ */
+wifi_error nan_data_request_initiator(transaction_id id, wifi_interface_handle iface,
+ NanDataPathInitiatorRequest* msg);
+
+/**@brief nan_data_indication_response
+ * Response to a data indication received
+ * corresponding to a NDP session. An indication
+ * is received with a data request and the responder
+ * will send a data response
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDataPathIndicationResponse:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INVALID_NDP_ID
+ */
+wifi_error nan_data_indication_response(transaction_id id, wifi_interface_handle iface,
+ NanDataPathIndicationResponse* msg);
+
+/**@brief nan_data_end
+ * NDL termination request: from either Initiator/Responder
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDataPathEndRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INVALID_NDP_ID
+ */
+wifi_error nan_data_end(transaction_id id, wifi_interface_handle iface, NanDataPathEndRequest* msg);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __NAN_H__ */
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_offload.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_offload.h
new file mode 100644
index 0000000..0c69e39
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_offload.h
@@ -0,0 +1,30 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_OFFLOAD_H
+#define __WIFI_HAL_OFFLOAD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define ETHER_ADDR_LEN 6 // Ethernet frame address length
+#define N_AVAIL_ID 3 // available mkeep_alive IDs from 1 to 3
+#define MKEEP_ALIVE_IP_PKT_MAX 256 // max size of IP packet for keep alive
+
+/**
+ * Send specified keep alive packet periodically.
+ */
+wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id, wifi_interface_handle iface,
+ u16 ether_type, u8* ip_packet, u16 ip_packet_len,
+ u8* src_mac_addr, u8* dst_mac_addr, u32 period_msec);
+
+/**
+ * Stop sending keep alive packet.
+ */
+wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id id, wifi_interface_handle iface);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_OFFLOAD_H */
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_twt.h b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_twt.h
new file mode 100644
index 0000000..994bb18
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hal_legacy/wifi_twt.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WIFI_HAL_TWT_H__
+#define __WIFI_HAL_TWT_H__
+
+#include "wifi_hal.h"
+
+typedef struct {
+ u8 requester_supported; // 0 for not supporting requester
+ u8 responder_supported; // 0 for not supporting responder
+ u8 broadcast_twt_supported; // 0 for not supporting broadcast TWT
+ u8 flexibile_twt_supported; // 0 for not supporting flexible TWT
+} TwtCapability;
+
+typedef struct {
+ TwtCapability device_capability;
+ TwtCapability peer_capability;
+} TwtCapabilitySet;
+
+// For all optional fields below, if no value specify -1
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 negotiation_type; // 0 for individual TWT, 1 for broadcast TWT
+ u8 trigger_type; // 0 for non-triggered TWT, 1 for triggered TWT
+ s32 wake_dur_us; // Proposed wake duration in us
+ s32 wake_int_us; // Average wake interval in us
+ s32 wake_int_min_us; // Min wake interval in us. Optional.
+ s32 wake_int_max_us; // Max wake interval in us. Optional.
+ s32 wake_dur_min_us; // Min wake duration in us. Optional.
+ s32 wake_dur_max_us; // Max wake duration in us. Optional.
+ s32 avg_pkt_size; // Average bytes of each packet to send in each wake
+ // duration. Optional.
+ s32 avg_pkt_num; // Average number of packets to send in each wake
+ // duration. Optional.
+ s32 wake_time_off_us; // First wake duration time offset in us. Optional.
+} TwtSetupRequest;
+
+typedef enum {
+ TWT_SETUP_SUCCESS = 0, // TWT setup is accepted.
+ TWT_SETUP_REJECT = 1, // TWT setup is rejected by AP.
+ TWT_SETUP_TIMEOUT = 2, // TWT setup response from AP times out.
+ TWT_SETUP_IE = 3, // AP sent TWT Setup IE parsing failure.
+ TWT_SETUP_PARAMS = 4, // AP sent TWT Setup IE Parameters invalid.
+ TWT_SETUP_ERROR = 255, // Generic error
+} TwtSetupReasonCode;
+
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 status; // 0 for success, non-zero for failure
+ TwtSetupReasonCode reason_code;
+ u8 negotiation_type; // 0 for individual TWT, 1 for broadcast TWT
+ u8 trigger_type; // 0 for non-triggered TWT, 1 for triggered TWT
+ s32 wake_dur_us; // Proposed wake duration in us
+ s32 wake_int_us; // Average wake interval in us
+ s32 wake_time_off_us; // First wake duration time offset in us.
+} TwtSetupResponse;
+
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 all_twt; // 0 for individual setp request, 1 for all TWT
+ u8 negotiation_type; // 0 for individual TWT, 1 for broadcast TWT
+} TwtTeardownRequest;
+
+typedef enum {
+ TWT_TD_RC_HOST = 0, // Teardown triggered by Host
+ TWT_TD_RC_PEER = 1, // Peer initiated teardown
+ TWT_TD_RC_MCHAN = 2, // Teardown due to MCHAN Active
+ TWT_TD_RC_MCNX = 3, // Teardown due to MultiConnection
+ TWT_TD_RC_CSA = 4, // Teardown due to CSA
+ TWT_TD_RC_BTCX = 5, // Teardown due to BT Coex
+ TWT_TD_RC_SETUP_FAIL = 6, // Setup fails midway. Teardown all connections
+ TWT_TD_RC_SCHED = 7, // Teardown by TWT Scheduler
+ TWT_TD_RC_ERROR = 255, // Generic error cases
+} TwtTeardownReason;
+
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 all_twt; // 0 for individual setp request, 1 for all TWT
+ u8 status; // 0 for success, non-zero for failure
+ TwtTeardownReason reason;
+} TwtTeardownCompletion;
+
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 all_twt; // 0 for individual setup request, 1 for all TWT
+ s32 resume_time_us; // If -1, TWT is suspended for indefinite time.
+ // Otherwise, TWT is suspended for resume_time_us
+} TwtInfoFrameRequest;
+
+typedef enum {
+ TWT_INFO_RC_HOST = 0, // Host initiated TWT Info frame */
+ TWT_INFO_RC_PEER = 1, // Peer initiated TWT Info frame
+ TWT_INFO_RC_ERROR = 2, // Generic error conditions */
+} TwtInfoFrameReason;
+
+// TWT Info frame triggered externally.
+// Device should not send TwtInfoFrameReceived to Host for internally
+// triggered TWT Info frame during SCAN, MCHAN operations.
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 all_twt; // 0 for individual setup request, 1 for all TWT
+ u8 status; // 0 for success, non-zero for failure
+ TwtInfoFrameReason reason;
+ u8 twt_resumed; // 1 - TWT resumed, 0 - TWT suspended
+} TwtInfoFrameReceived;
+
+typedef struct {
+ u8 config_id;
+ u32 avg_pkt_num_tx; // Average number of Tx packets in each wake duration.
+ u32 avg_pkt_num_rx; // Average number of Rx packets in each wake duration.
+ u32 avg_tx_pkt_size; // Average bytes per Rx packet in each wake duration.
+ u32 avg_rx_pkt_size; // Average bytes per Rx packet in each wake duration.
+ u32 avg_eosp_dur_us; // Average duration of early terminated SP
+ u32 eosp_count; // Count of early terminations
+ u32 num_sp; // Count of service period (SP), also known as wake duration.
+} TwtStats;
+
+// Asynchronous notification from the device.
+// For example, TWT was torn down by the device and later when the device is
+// ready, it can send this async notification.
+// This can be expandable in future.
+typedef enum {
+ TWT_NOTIF_ALLOW_TWT = 1, // Device ready to process TWT Setup request
+} TwtNotification;
+
+typedef struct {
+ TwtNotification notification;
+} TwtDeviceNotify;
+
+// Callbacks for various TWT responses and events
+typedef struct {
+ // Callback for TWT setup response
+ void (*EventTwtSetupResponse)(TwtSetupResponse* event);
+ // Callback for TWT teardown completion
+ void (*EventTwtTeardownCompletion)(TwtTeardownCompletion* event);
+ // Callback for TWT info frame received event
+ void (*EventTwtInfoFrameReceived)(TwtInfoFrameReceived* event);
+ // Callback for TWT notification from the device
+ void (*EventTwtDeviceNotify)(TwtDeviceNotify* event);
+} TwtCallbackHandler;
+
+#endif /* __WIFI_HAL_TWT_H__ */
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hidl_callback_util.h b/wifi/wifi_legacy_service/1.0-legacy/hidl_callback_util.h
new file mode 100644
index 0000000..aab0ae5
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hidl_callback_util.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HIDL_CALLBACK_UTIL_H_
+#define HIDL_CALLBACK_UTIL_H_
+
+#include <set>
+
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+
+namespace {
+// Type of callback invoked by the death handler.
+using on_death_cb_function = std::function<void(uint64_t)>;
+
+// Private class used to keep track of death of individual
+// callbacks stored in HidlCallbackHandler.
+template <typename CallbackType>
+class HidlDeathHandler : public android::hardware::hidl_death_recipient {
+ public:
+ HidlDeathHandler(const on_death_cb_function& user_cb_function)
+ : cb_function_(user_cb_function) {}
+ ~HidlDeathHandler() = default;
+
+ // Death notification for callbacks.
+ void serviceDied(uint64_t cookie,
+ const android::wp<android::hidl::base::V1_0::IBase>& /* who */) override {
+ cb_function_(cookie);
+ }
+
+ private:
+ on_death_cb_function cb_function_;
+
+ DISALLOW_COPY_AND_ASSIGN(HidlDeathHandler);
+};
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace hidl_callback_util {
+template <typename CallbackType>
+// Provides a class to manage callbacks for the various HIDL interfaces and
+// handle the death of the process hosting each callback.
+class HidlCallbackHandler {
+ public:
+ HidlCallbackHandler()
+ : death_handler_(new HidlDeathHandler<CallbackType>(
+ std::bind(&HidlCallbackHandler::onObjectDeath, this, std::placeholders::_1))) {}
+ ~HidlCallbackHandler() = default;
+
+ bool addCallback(const sp<CallbackType>& cb) {
+ // TODO(b/33818800): Can't compare proxies yet. So, use the cookie
+ // (callback proxy's raw pointer) to track the death of individual
+ // clients.
+ uint64_t cookie = reinterpret_cast<uint64_t>(cb.get());
+ for (const auto& s : cb_set_) {
+ if (interfacesEqual(cb, s)) {
+ LOG(ERROR) << "Duplicate death notification registration";
+ return true;
+ }
+ }
+ if (!cb->linkToDeath(death_handler_, cookie)) {
+ LOG(ERROR) << "Failed to register death notification";
+ return false;
+ }
+ cb_set_.insert(cb);
+ return true;
+ }
+
+ const std::set<android::sp<CallbackType>>& getCallbacks() { return cb_set_; }
+
+ // Death notification for callbacks.
+ void onObjectDeath(uint64_t cookie) {
+ CallbackType* cb = reinterpret_cast<CallbackType*>(cookie);
+ const auto& iter = cb_set_.find(cb);
+ if (iter == cb_set_.end()) {
+ LOG(ERROR) << "Unknown callback death notification received";
+ return;
+ }
+ cb_set_.erase(iter);
+ LOG(DEBUG) << "Dead callback removed from list";
+ }
+
+ void invalidate() {
+ for (const sp<CallbackType>& cb : cb_set_) {
+ if (!cb->unlinkToDeath(death_handler_)) {
+ LOG(ERROR) << "Failed to deregister death notification";
+ }
+ }
+ cb_set_.clear();
+ }
+
+ private:
+ std::set<sp<CallbackType>> cb_set_;
+ sp<HidlDeathHandler<CallbackType>> death_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(HidlCallbackHandler);
+};
+
+} // namespace hidl_callback_util
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+#endif // HIDL_CALLBACK_UTIL_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hidl_return_util.h b/wifi/wifi_legacy_service/1.0-legacy/hidl_return_util.h
new file mode 100644
index 0000000..a0efac2
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hidl_return_util.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HIDL_RETURN_UTIL_H_
+#define HIDL_RETURN_UTIL_H_
+
+#include "hidl_sync_util.h"
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace hidl_return_util {
+using namespace android::hardware::wifi::V1_0;
+
+/**
+ * These utility functions are used to invoke a method on the provided
+ * HIDL interface object.
+ * These functions checks if the provided HIDL interface object is valid.
+ * a) if valid, Invokes the corresponding internal implementation function of
+ * the HIDL method. It then invokes the HIDL continuation callback with
+ * the status and any returned values.
+ * b) if invalid, invokes the HIDL continuation callback with the
+ * provided error status and default values.
+ */
+// Use for HIDL methods which return only an instance of WifiStatus.
+template <typename ObjT, typename WorkFuncT, typename... Args>
+Return<void> validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
+ const std::function<void(const WifiStatus&)>& hidl_cb,
+ Args&&... args) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (obj->isValid()) {
+ hidl_cb((obj->*work)(std::forward<Args>(args)...));
+ } else {
+ hidl_cb(createWifiStatus(status_code_if_invalid));
+ }
+ return Void();
+}
+
+// Use for HIDL methods which return only an instance of WifiStatus.
+// This version passes the global lock acquired to the body of the method.
+// Note: Only used by IWifi::stop() currently.
+template <typename ObjT, typename WorkFuncT, typename... Args>
+Return<void> validateAndCallWithLock(ObjT* obj, WifiStatusCode status_code_if_invalid,
+ WorkFuncT&& work,
+ const std::function<void(const WifiStatus&)>& hidl_cb,
+ Args&&... args) {
+ auto lock = hidl_sync_util::acquireGlobalLock();
+ if (obj->isValid()) {
+ hidl_cb((obj->*work)(&lock, std::forward<Args>(args)...));
+ } else {
+ hidl_cb(createWifiStatus(status_code_if_invalid));
+ }
+ return Void();
+}
+
+// Use for HIDL methods which return instance of WifiStatus and a single return
+// value.
+template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
+Return<void> validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
+ const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb,
+ Args&&... args) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (obj->isValid()) {
+ const auto& ret_pair = (obj->*work)(std::forward<Args>(args)...);
+ const WifiStatus& status = std::get<0>(ret_pair);
+ const auto& ret_value = std::get<1>(ret_pair);
+ hidl_cb(status, ret_value);
+ } else {
+ hidl_cb(createWifiStatus(status_code_if_invalid),
+ typename std::remove_reference<ReturnT>::type());
+ }
+ return Void();
+}
+
+// Use for HIDL methods which return instance of WifiStatus and 2 return
+// values.
+template <typename ObjT, typename WorkFuncT, typename ReturnT1, typename ReturnT2, typename... Args>
+Return<void> validateAndCall(
+ ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
+ const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb, Args&&... args) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (obj->isValid()) {
+ const auto& ret_tuple = (obj->*work)(std::forward<Args>(args)...);
+ const WifiStatus& status = std::get<0>(ret_tuple);
+ const auto& ret_value1 = std::get<1>(ret_tuple);
+ const auto& ret_value2 = std::get<2>(ret_tuple);
+ hidl_cb(status, ret_value1, ret_value2);
+ } else {
+ hidl_cb(createWifiStatus(status_code_if_invalid),
+ typename std::remove_reference<ReturnT1>::type(),
+ typename std::remove_reference<ReturnT2>::type());
+ }
+ return Void();
+}
+
+} // namespace hidl_return_util
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+#endif // HIDL_RETURN_UTIL_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hidl_struct_util.cpp b/wifi/wifi_legacy_service/1.0-legacy/hidl_struct_util.cpp
new file mode 100644
index 0000000..2112b26
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hidl_struct_util.cpp
@@ -0,0 +1,3007 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <utils/SystemClock.h>
+
+#include "hidl_struct_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace hidl_struct_util {
+
+using V1_6::NanConfigRequestSupplemental;
+
+WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(legacy_hal::wifi_channel_width type);
+
+hidl_string safeConvertChar(const char* str, size_t max_len) {
+ const char* c = str;
+ size_t size = 0;
+ while (*c && (unsigned char)*c < 128 && size < max_len) {
+ ++size;
+ ++c;
+ }
+ return hidl_string(str, size);
+}
+
+IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability(uint32_t feature) {
+ using HidlChipCaps = IWifiChip::ChipCapabilityMask;
+ switch (feature) {
+ case legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED:
+ return HidlChipCaps::DEBUG_MEMORY_FIRMWARE_DUMP;
+ case legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED:
+ return HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP;
+ case legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED:
+ return HidlChipCaps::DEBUG_RING_BUFFER_CONNECT_EVENT;
+ case legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED:
+ return HidlChipCaps::DEBUG_RING_BUFFER_POWER_EVENT;
+ case legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED:
+ return HidlChipCaps::DEBUG_RING_BUFFER_WAKELOCK_EVENT;
+ };
+ CHECK(false) << "Unknown legacy feature: " << feature;
+ return {};
+}
+
+IWifiStaIface::StaIfaceCapabilityMask convertLegacyLoggerFeatureToHidlStaIfaceCapability(
+ uint32_t feature) {
+ using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
+ switch (feature) {
+ case legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED:
+ return HidlStaIfaceCaps::DEBUG_PACKET_FATE;
+ };
+ CHECK(false) << "Unknown legacy feature: " << feature;
+ return {};
+}
+
+V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability(uint64_t feature) {
+ using HidlChipCaps = V1_5::IWifiChip::ChipCapabilityMask;
+ switch (feature) {
+ case WIFI_FEATURE_SET_TX_POWER_LIMIT:
+ return HidlChipCaps::SET_TX_POWER_LIMIT;
+ case WIFI_FEATURE_USE_BODY_HEAD_SAR:
+ return HidlChipCaps::USE_BODY_HEAD_SAR;
+ case WIFI_FEATURE_D2D_RTT:
+ return HidlChipCaps::D2D_RTT;
+ case WIFI_FEATURE_D2AP_RTT:
+ return HidlChipCaps::D2AP_RTT;
+ case WIFI_FEATURE_INFRA_60G:
+ return HidlChipCaps::WIGIG;
+ case WIFI_FEATURE_SET_LATENCY_MODE:
+ return HidlChipCaps::SET_LATENCY_MODE;
+ case WIFI_FEATURE_P2P_RAND_MAC:
+ return HidlChipCaps::P2P_RAND_MAC;
+ };
+ CHECK(false) << "Unknown legacy feature: " << feature;
+ return {};
+}
+
+IWifiStaIface::StaIfaceCapabilityMask convertLegacyFeatureToHidlStaIfaceCapability(
+ uint64_t feature) {
+ using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
+ switch (feature) {
+ case WIFI_FEATURE_GSCAN:
+ return HidlStaIfaceCaps::BACKGROUND_SCAN;
+ case WIFI_FEATURE_LINK_LAYER_STATS:
+ return HidlStaIfaceCaps::LINK_LAYER_STATS;
+ case WIFI_FEATURE_RSSI_MONITOR:
+ return HidlStaIfaceCaps::RSSI_MONITOR;
+ case WIFI_FEATURE_CONTROL_ROAMING:
+ return HidlStaIfaceCaps::CONTROL_ROAMING;
+ case WIFI_FEATURE_IE_WHITELIST:
+ return HidlStaIfaceCaps::PROBE_IE_WHITELIST;
+ case WIFI_FEATURE_SCAN_RAND:
+ return HidlStaIfaceCaps::SCAN_RAND;
+ case WIFI_FEATURE_INFRA_5G:
+ return HidlStaIfaceCaps::STA_5G;
+ case WIFI_FEATURE_HOTSPOT:
+ return HidlStaIfaceCaps::HOTSPOT;
+ case WIFI_FEATURE_PNO:
+ return HidlStaIfaceCaps::PNO;
+ case WIFI_FEATURE_TDLS:
+ return HidlStaIfaceCaps::TDLS;
+ case WIFI_FEATURE_TDLS_OFFCHANNEL:
+ return HidlStaIfaceCaps::TDLS_OFFCHANNEL;
+ case WIFI_FEATURE_CONFIG_NDO:
+ return HidlStaIfaceCaps::ND_OFFLOAD;
+ case WIFI_FEATURE_MKEEP_ALIVE:
+ return HidlStaIfaceCaps::KEEP_ALIVE;
+ };
+ CHECK(false) << "Unknown legacy feature: " << feature;
+ return {};
+}
+
+bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set,
+ uint32_t legacy_logger_feature_set,
+ uint32_t* hidl_caps) {
+ if (!hidl_caps) {
+ return false;
+ }
+ *hidl_caps = {};
+ using HidlChipCaps = IWifiChip::ChipCapabilityMask;
+ for (const auto feature : {legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED,
+ legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED,
+ legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED,
+ legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED,
+ legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED}) {
+ if (feature & legacy_logger_feature_set) {
+ *hidl_caps |= convertLegacyLoggerFeatureToHidlChipCapability(feature);
+ }
+ }
+ std::vector<uint64_t> features = {WIFI_FEATURE_SET_TX_POWER_LIMIT,
+ WIFI_FEATURE_USE_BODY_HEAD_SAR,
+ WIFI_FEATURE_D2D_RTT,
+ WIFI_FEATURE_D2AP_RTT,
+ WIFI_FEATURE_INFRA_60G,
+ WIFI_FEATURE_SET_LATENCY_MODE,
+ WIFI_FEATURE_P2P_RAND_MAC};
+ for (const auto feature : features) {
+ if (feature & legacy_feature_set) {
+ *hidl_caps |= convertLegacyFeatureToHidlChipCapability(feature);
+ }
+ }
+
+ // There are no flags for these 3 in the legacy feature set. Adding them to
+ // the set because all the current devices support it.
+ *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA;
+ *hidl_caps |= HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS;
+ *hidl_caps |= HidlChipCaps::DEBUG_ERROR_ALERTS;
+ return true;
+}
+
+WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToHidl(uint32_t flag) {
+ switch (flag) {
+ case WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES:
+ return WifiDebugRingBufferFlags::HAS_BINARY_ENTRIES;
+ case WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES:
+ return WifiDebugRingBufferFlags::HAS_ASCII_ENTRIES;
+ };
+ CHECK(false) << "Unknown legacy flag: " << flag;
+ return {};
+}
+
+bool convertLegacyDebugRingBufferStatusToHidl(
+ const legacy_hal::wifi_ring_buffer_status& legacy_status,
+ WifiDebugRingBufferStatus* hidl_status) {
+ if (!hidl_status) {
+ return false;
+ }
+ *hidl_status = {};
+ hidl_status->ringName = safeConvertChar(reinterpret_cast<const char*>(legacy_status.name),
+ sizeof(legacy_status.name));
+ hidl_status->flags = 0;
+ for (const auto flag :
+ {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES, WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) {
+ if (flag & legacy_status.flags) {
+ hidl_status->flags |= static_cast<std::underlying_type<WifiDebugRingBufferFlags>::type>(
+ convertLegacyDebugRingBufferFlagsToHidl(flag));
+ }
+ }
+ hidl_status->ringId = legacy_status.ring_id;
+ hidl_status->sizeInBytes = legacy_status.ring_buffer_byte_size;
+ // Calculate free size of the ring the buffer. We don't need to send the
+ // exact read/write pointers that were there in the legacy HAL interface.
+ if (legacy_status.written_bytes >= legacy_status.read_bytes) {
+ hidl_status->freeSizeInBytes = legacy_status.ring_buffer_byte_size -
+ (legacy_status.written_bytes - legacy_status.read_bytes);
+ } else {
+ hidl_status->freeSizeInBytes = legacy_status.read_bytes - legacy_status.written_bytes;
+ }
+ hidl_status->verboseLevel = legacy_status.verbose_level;
+ return true;
+}
+
+bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
+ const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
+ std::vector<WifiDebugRingBufferStatus>* hidl_status_vec) {
+ if (!hidl_status_vec) {
+ return false;
+ }
+ *hidl_status_vec = {};
+ for (const auto& legacy_status : legacy_status_vec) {
+ WifiDebugRingBufferStatus hidl_status;
+ if (!convertLegacyDebugRingBufferStatusToHidl(legacy_status, &hidl_status)) {
+ return false;
+ }
+ hidl_status_vec->push_back(hidl_status);
+ }
+ return true;
+}
+
+bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats,
+ WifiDebugHostWakeReasonStats* hidl_stats) {
+ if (!hidl_stats) {
+ return false;
+ }
+ *hidl_stats = {};
+ hidl_stats->totalCmdEventWakeCnt = legacy_stats.wake_reason_cnt.total_cmd_event_wake;
+ hidl_stats->cmdEventWakeCntPerType = legacy_stats.cmd_event_wake_cnt;
+ hidl_stats->totalDriverFwLocalWakeCnt = legacy_stats.wake_reason_cnt.total_driver_fw_local_wake;
+ hidl_stats->driverFwLocalWakeCntPerType = legacy_stats.driver_fw_local_wake_cnt;
+ hidl_stats->totalRxPacketWakeCnt = legacy_stats.wake_reason_cnt.total_rx_data_wake;
+ hidl_stats->rxPktWakeDetails.rxUnicastCnt =
+ legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt;
+ hidl_stats->rxPktWakeDetails.rxMulticastCnt =
+ legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt;
+ hidl_stats->rxPktWakeDetails.rxBroadcastCnt =
+ legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt;
+ hidl_stats->rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt =
+ legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt;
+ hidl_stats->rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt =
+ legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt;
+ hidl_stats->rxMulticastPkWakeDetails.otherRxMulticastAddrCnt =
+ legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt;
+ hidl_stats->rxIcmpPkWakeDetails.icmpPkt =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt;
+ hidl_stats->rxIcmpPkWakeDetails.icmp6Pkt =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt;
+ hidl_stats->rxIcmpPkWakeDetails.icmp6Ra =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra;
+ hidl_stats->rxIcmpPkWakeDetails.icmp6Na =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na;
+ hidl_stats->rxIcmpPkWakeDetails.icmp6Ns =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns;
+ return true;
+}
+
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
+ V1_1::IWifiChip::TxPowerScenario hidl_scenario) {
+ switch (hidl_scenario) {
+ // This is the only supported scenario for V1_1
+ case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL:
+ return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL;
+ };
+ CHECK(false);
+}
+
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2(
+ V1_2::IWifiChip::TxPowerScenario hidl_scenario) {
+ switch (hidl_scenario) {
+ // This is the only supported scenario for V1_1
+ case V1_2::IWifiChip::TxPowerScenario::VOICE_CALL:
+ return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL;
+ // Those are the supported scenarios for V1_2
+ case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF:
+ return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
+ case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_ON:
+ return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
+ case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF:
+ return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
+ case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_ON:
+ return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
+ };
+ CHECK(false);
+}
+
+legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy(
+ V1_3::IWifiChip::LatencyMode hidl_latency_mode) {
+ switch (hidl_latency_mode) {
+ case V1_3::IWifiChip::LatencyMode::NORMAL:
+ return legacy_hal::WIFI_LATENCY_MODE_NORMAL;
+ case V1_3::IWifiChip::LatencyMode::LOW:
+ return legacy_hal::WIFI_LATENCY_MODE_LOW;
+ }
+ CHECK(false);
+}
+
+bool convertLegacyWifiMacInfoToHidl(
+ const legacy_hal::WifiMacInfo& legacy_mac_info,
+ V1_4::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) {
+ if (!hidl_radio_mode_info) {
+ return false;
+ }
+ *hidl_radio_mode_info = {};
+
+ hidl_radio_mode_info->radioId = legacy_mac_info.wlan_mac_id;
+ // Convert from bitmask of bands in the legacy HAL to enum value in
+ // the HIDL interface.
+ if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
+ hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND) {
+ hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
+ hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ;
+ } else {
+ hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_UNSPECIFIED;
+ }
+ std::vector<V1_2::IWifiChipEventCallback::IfaceInfo> iface_info_vec;
+ for (const auto& legacy_iface_info : legacy_mac_info.iface_infos) {
+ V1_2::IWifiChipEventCallback::IfaceInfo iface_info;
+ iface_info.name = legacy_iface_info.name;
+ iface_info.channel = legacy_iface_info.channel;
+ iface_info_vec.push_back(iface_info);
+ }
+ hidl_radio_mode_info->ifaceInfos = iface_info_vec;
+ return true;
+}
+
+uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) {
+ switch (hidl_band) {
+ case V1_5::WifiBand::BAND_24GHZ:
+ return legacy_hal::WLAN_MAC_2_4_BAND;
+ case V1_5::WifiBand::BAND_5GHZ:
+ case V1_5::WifiBand::BAND_5GHZ_DFS:
+ case V1_5::WifiBand::BAND_5GHZ_WITH_DFS:
+ return legacy_hal::WLAN_MAC_5_0_BAND;
+ case V1_5::WifiBand::BAND_24GHZ_5GHZ:
+ case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+ return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND);
+ case V1_5::WifiBand::BAND_6GHZ:
+ return legacy_hal::WLAN_MAC_6_0_BAND;
+ case V1_5::WifiBand::BAND_5GHZ_6GHZ:
+ return (legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_6_0_BAND);
+ case V1_5::WifiBand::BAND_24GHZ_5GHZ_6GHZ:
+ case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ:
+ return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
+ legacy_hal::WLAN_MAC_6_0_BAND);
+ case V1_5::WifiBand::BAND_60GHZ:
+ return legacy_hal::WLAN_MAC_60_0_BAND;
+ default:
+ return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
+ legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND);
+ }
+}
+
+V1_5::WifiBand convertLegacyMacBandToHidlWifiBand(uint32_t band) {
+ switch (band) {
+ case legacy_hal::WLAN_MAC_2_4_BAND:
+ return V1_5::WifiBand::BAND_24GHZ;
+ case legacy_hal::WLAN_MAC_5_0_BAND:
+ return V1_5::WifiBand::BAND_5GHZ;
+ case legacy_hal::WLAN_MAC_6_0_BAND:
+ return V1_5::WifiBand::BAND_6GHZ;
+ case legacy_hal::WLAN_MAC_60_0_BAND:
+ return V1_5::WifiBand::BAND_60GHZ;
+ default:
+ return V1_5::WifiBand::BAND_UNSPECIFIED;
+ }
+}
+
+uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask) {
+ uint32_t legacy_iface_mask = 0;
+ if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_STA) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA);
+ }
+ if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP);
+ }
+ if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT);
+ }
+ if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO);
+ }
+ if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_NAN) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN);
+ }
+ if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_TDLS) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS);
+ }
+ if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_MESH) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH);
+ }
+ if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_IBSS) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS);
+ }
+ return legacy_iface_mask;
+}
+
+uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) {
+ uint32_t hidl_iface_mask = 0;
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) {
+ hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_STA;
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) {
+ hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP;
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) {
+ hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT;
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) {
+ hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO;
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) {
+ hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_NAN;
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) {
+ hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_TDLS;
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) {
+ hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_MESH;
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) {
+ hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_IBSS;
+ }
+ return hidl_iface_mask;
+}
+
+uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask) {
+ uint32_t legacy_filter_mask = 0;
+ if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) {
+ legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
+ }
+ if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CONCURRENCY) {
+ legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
+ }
+ if (hidl_filter_mask & V1_6::IWifiChip::UsableChannelFilter::NAN_INSTANT_MODE) {
+ legacy_filter_mask |= WIFI_USABLE_CHANNEL_FILTER_NAN_INSTANT_MODE;
+ }
+ return legacy_filter_mask;
+}
+
+bool convertLegacyWifiUsableChannelToHidl(
+ const legacy_hal::wifi_usable_channel& legacy_usable_channel,
+ V1_6::WifiUsableChannel* hidl_usable_channel) {
+ if (!hidl_usable_channel) {
+ return false;
+ }
+ *hidl_usable_channel = {};
+ hidl_usable_channel->channel = legacy_usable_channel.freq;
+ hidl_usable_channel->channelBandwidth =
+ convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width);
+ hidl_usable_channel->ifaceModeMask =
+ convertLegacyWifiInterfaceModeToHidl(legacy_usable_channel.iface_mode_mask);
+
+ return true;
+}
+
+bool convertLegacyWifiUsableChannelsToHidl(
+ const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+ std::vector<V1_6::WifiUsableChannel>* hidl_usable_channels) {
+ if (!hidl_usable_channels) {
+ return false;
+ }
+ *hidl_usable_channels = {};
+ for (const auto& legacy_usable_channel : legacy_usable_channels) {
+ V1_6::WifiUsableChannel hidl_usable_channel;
+ if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel, &hidl_usable_channel)) {
+ return false;
+ }
+ hidl_usable_channels->push_back(hidl_usable_channel);
+ }
+ return true;
+}
+
+bool convertLegacyWifiMacInfosToHidl(
+ const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+ std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos) {
+ if (!hidl_radio_mode_infos) {
+ return false;
+ }
+ *hidl_radio_mode_infos = {};
+
+ for (const auto& legacy_mac_info : legacy_mac_infos) {
+ V1_4::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info;
+ if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info, &hidl_radio_mode_info)) {
+ return false;
+ }
+ hidl_radio_mode_infos->push_back(hidl_radio_mode_info);
+ }
+ return true;
+}
+
+bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set,
+ uint32_t legacy_logger_feature_set,
+ uint32_t* hidl_caps) {
+ if (!hidl_caps) {
+ return false;
+ }
+ *hidl_caps = {};
+ using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
+ for (const auto feature : {legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED}) {
+ if (feature & legacy_logger_feature_set) {
+ *hidl_caps |= convertLegacyLoggerFeatureToHidlStaIfaceCapability(feature);
+ }
+ }
+ for (const auto feature :
+ {WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, WIFI_FEATURE_RSSI_MONITOR,
+ WIFI_FEATURE_CONTROL_ROAMING, WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
+ WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, WIFI_FEATURE_TDLS,
+ WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
+ if (feature & legacy_feature_set) {
+ *hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature);
+ }
+ }
+ // There is no flag for this one in the legacy feature set. Adding it to the
+ // set because all the current devices support it.
+ *hidl_caps |= HidlStaIfaceCaps::APF;
+ return true;
+}
+
+bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
+ StaApfPacketFilterCapabilities* hidl_caps) {
+ if (!hidl_caps) {
+ return false;
+ }
+ *hidl_caps = {};
+ hidl_caps->version = legacy_caps.version;
+ hidl_caps->maxLength = legacy_caps.max_len;
+ return true;
+}
+
+uint8_t convertHidlGscanReportEventFlagToLegacy(
+ StaBackgroundScanBucketEventReportSchemeMask hidl_flag) {
+ using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
+ switch (hidl_flag) {
+ case HidlFlag::EACH_SCAN:
+ return REPORT_EVENTS_EACH_SCAN;
+ case HidlFlag::FULL_RESULTS:
+ return REPORT_EVENTS_FULL_RESULTS;
+ case HidlFlag::NO_BATCH:
+ return REPORT_EVENTS_NO_BATCH;
+ };
+ CHECK(false);
+}
+
+StaScanDataFlagMask convertLegacyGscanDataFlagToHidl(uint8_t legacy_flag) {
+ switch (legacy_flag) {
+ case legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED:
+ return StaScanDataFlagMask::INTERRUPTED;
+ };
+ CHECK(false) << "Unknown legacy flag: " << legacy_flag;
+ // To silence the compiler warning about reaching the end of non-void
+ // function.
+ return {};
+}
+
+bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
+ StaBackgroundScanCapabilities* hidl_caps) {
+ if (!hidl_caps) {
+ return false;
+ }
+ *hidl_caps = {};
+ hidl_caps->maxCacheSize = legacy_caps.max_scan_cache_size;
+ hidl_caps->maxBuckets = legacy_caps.max_scan_buckets;
+ hidl_caps->maxApCachePerScan = legacy_caps.max_ap_cache_per_scan;
+ hidl_caps->maxReportingThreshold = legacy_caps.max_scan_reporting_threshold;
+ return true;
+}
+
+legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band) {
+ switch (band) {
+ case V1_0::WifiBand::BAND_UNSPECIFIED:
+ return legacy_hal::WIFI_BAND_UNSPECIFIED;
+ case V1_0::WifiBand::BAND_24GHZ:
+ return legacy_hal::WIFI_BAND_BG;
+ case V1_0::WifiBand::BAND_5GHZ:
+ return legacy_hal::WIFI_BAND_A;
+ case V1_0::WifiBand::BAND_5GHZ_DFS:
+ return legacy_hal::WIFI_BAND_A_DFS;
+ case V1_0::WifiBand::BAND_5GHZ_WITH_DFS:
+ return legacy_hal::WIFI_BAND_A_WITH_DFS;
+ case V1_0::WifiBand::BAND_24GHZ_5GHZ:
+ return legacy_hal::WIFI_BAND_ABG;
+ case V1_0::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+ return legacy_hal::WIFI_BAND_ABG_WITH_DFS;
+ };
+ CHECK(false);
+}
+
+bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params,
+ legacy_hal::wifi_scan_cmd_params* legacy_scan_params) {
+ if (!legacy_scan_params) {
+ return false;
+ }
+ *legacy_scan_params = {};
+ legacy_scan_params->base_period = hidl_scan_params.basePeriodInMs;
+ legacy_scan_params->max_ap_per_scan = hidl_scan_params.maxApPerScan;
+ legacy_scan_params->report_threshold_percent = hidl_scan_params.reportThresholdPercent;
+ legacy_scan_params->report_threshold_num_scans = hidl_scan_params.reportThresholdNumScans;
+ if (hidl_scan_params.buckets.size() > MAX_BUCKETS) {
+ return false;
+ }
+ legacy_scan_params->num_buckets = hidl_scan_params.buckets.size();
+ for (uint32_t bucket_idx = 0; bucket_idx < hidl_scan_params.buckets.size(); bucket_idx++) {
+ const StaBackgroundScanBucketParameters& hidl_bucket_spec =
+ hidl_scan_params.buckets[bucket_idx];
+ legacy_hal::wifi_scan_bucket_spec& legacy_bucket_spec =
+ legacy_scan_params->buckets[bucket_idx];
+ if (hidl_bucket_spec.bucketIdx >= MAX_BUCKETS) {
+ return false;
+ }
+ legacy_bucket_spec.bucket = hidl_bucket_spec.bucketIdx;
+ legacy_bucket_spec.band = convertHidlWifiBandToLegacy(hidl_bucket_spec.band);
+ legacy_bucket_spec.period = hidl_bucket_spec.periodInMs;
+ legacy_bucket_spec.max_period = hidl_bucket_spec.exponentialMaxPeriodInMs;
+ legacy_bucket_spec.base = hidl_bucket_spec.exponentialBase;
+ legacy_bucket_spec.step_count = hidl_bucket_spec.exponentialStepCount;
+ legacy_bucket_spec.report_events = 0;
+ using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
+ for (const auto flag : {HidlFlag::EACH_SCAN, HidlFlag::FULL_RESULTS, HidlFlag::NO_BATCH}) {
+ if (hidl_bucket_spec.eventReportScheme &
+ static_cast<std::underlying_type<HidlFlag>::type>(flag)) {
+ legacy_bucket_spec.report_events |= convertHidlGscanReportEventFlagToLegacy(flag);
+ }
+ }
+ if (hidl_bucket_spec.frequencies.size() > MAX_CHANNELS) {
+ return false;
+ }
+ legacy_bucket_spec.num_channels = hidl_bucket_spec.frequencies.size();
+ for (uint32_t freq_idx = 0; freq_idx < hidl_bucket_spec.frequencies.size(); freq_idx++) {
+ legacy_bucket_spec.channels[freq_idx].channel = hidl_bucket_spec.frequencies[freq_idx];
+ }
+ }
+ return true;
+}
+
+bool convertLegacyIeToHidl(const legacy_hal::wifi_information_element& legacy_ie,
+ WifiInformationElement* hidl_ie) {
+ if (!hidl_ie) {
+ return false;
+ }
+ *hidl_ie = {};
+ hidl_ie->id = legacy_ie.id;
+ hidl_ie->data = std::vector<uint8_t>(legacy_ie.data, legacy_ie.data + legacy_ie.len);
+ return true;
+}
+
+bool convertLegacyIeBlobToHidl(const uint8_t* ie_blob, uint32_t ie_blob_len,
+ std::vector<WifiInformationElement>* hidl_ies) {
+ if (!ie_blob || !hidl_ies) {
+ return false;
+ }
+ *hidl_ies = {};
+ const uint8_t* ies_begin = ie_blob;
+ const uint8_t* ies_end = ie_blob + ie_blob_len;
+ const uint8_t* next_ie = ies_begin;
+ using wifi_ie = legacy_hal::wifi_information_element;
+ constexpr size_t kIeHeaderLen = sizeof(wifi_ie);
+ // Each IE should atleast have the header (i.e |id| & |len| fields).
+ while (next_ie + kIeHeaderLen <= ies_end) {
+ const wifi_ie& legacy_ie = (*reinterpret_cast<const wifi_ie*>(next_ie));
+ uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len;
+ if (next_ie + curr_ie_len > ies_end) {
+ LOG(ERROR) << "Error parsing IE blob. Next IE: " << (void*)next_ie
+ << ", Curr IE len: " << curr_ie_len << ", IEs End: " << (void*)ies_end;
+ break;
+ }
+ WifiInformationElement hidl_ie;
+ if (!convertLegacyIeToHidl(legacy_ie, &hidl_ie)) {
+ LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id << ", len: " << legacy_ie.len;
+ break;
+ }
+ hidl_ies->push_back(std::move(hidl_ie));
+ next_ie += curr_ie_len;
+ }
+ // Check if the blob has been fully consumed.
+ if (next_ie != ies_end) {
+ LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " << (void*)next_ie
+ << ", IEs End: " << (void*)ies_end;
+ }
+ return true;
+}
+
+bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
+ bool has_ie_data, StaScanResult* hidl_scan_result) {
+ if (!hidl_scan_result) {
+ return false;
+ }
+ *hidl_scan_result = {};
+ hidl_scan_result->timeStampInUs = legacy_scan_result.ts;
+ hidl_scan_result->ssid = std::vector<uint8_t>(
+ legacy_scan_result.ssid,
+ legacy_scan_result.ssid +
+ strnlen(legacy_scan_result.ssid, sizeof(legacy_scan_result.ssid) - 1));
+ memcpy(hidl_scan_result->bssid.data(), legacy_scan_result.bssid,
+ hidl_scan_result->bssid.size());
+ hidl_scan_result->frequency = legacy_scan_result.channel;
+ hidl_scan_result->rssi = legacy_scan_result.rssi;
+ hidl_scan_result->beaconPeriodInMs = legacy_scan_result.beacon_period;
+ hidl_scan_result->capability = legacy_scan_result.capability;
+ if (has_ie_data) {
+ std::vector<WifiInformationElement> ies;
+ if (!convertLegacyIeBlobToHidl(reinterpret_cast<const uint8_t*>(legacy_scan_result.ie_data),
+ legacy_scan_result.ie_length, &ies)) {
+ return false;
+ }
+ hidl_scan_result->informationElements = std::move(ies);
+ }
+ return true;
+}
+
+bool convertLegacyCachedGscanResultsToHidl(
+ const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result,
+ StaScanData* hidl_scan_data) {
+ if (!hidl_scan_data) {
+ return false;
+ }
+ *hidl_scan_data = {};
+ hidl_scan_data->flags = 0;
+ for (const auto flag : {legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED}) {
+ if (legacy_cached_scan_result.flags & flag) {
+ hidl_scan_data->flags |= static_cast<std::underlying_type<StaScanDataFlagMask>::type>(
+ convertLegacyGscanDataFlagToHidl(flag));
+ }
+ }
+ hidl_scan_data->bucketsScanned = legacy_cached_scan_result.buckets_scanned;
+
+ CHECK(legacy_cached_scan_result.num_results >= 0 &&
+ legacy_cached_scan_result.num_results <= MAX_AP_CACHE_PER_SCAN);
+ std::vector<StaScanResult> hidl_scan_results;
+ for (int32_t result_idx = 0; result_idx < legacy_cached_scan_result.num_results; result_idx++) {
+ StaScanResult hidl_scan_result;
+ if (!convertLegacyGscanResultToHidl(legacy_cached_scan_result.results[result_idx], false,
+ &hidl_scan_result)) {
+ return false;
+ }
+ hidl_scan_results.push_back(hidl_scan_result);
+ }
+ hidl_scan_data->results = std::move(hidl_scan_results);
+ return true;
+}
+
+bool convertLegacyVectorOfCachedGscanResultsToHidl(
+ const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
+ std::vector<StaScanData>* hidl_scan_datas) {
+ if (!hidl_scan_datas) {
+ return false;
+ }
+ *hidl_scan_datas = {};
+ for (const auto& legacy_cached_scan_result : legacy_cached_scan_results) {
+ StaScanData hidl_scan_data;
+ if (!convertLegacyCachedGscanResultsToHidl(legacy_cached_scan_result, &hidl_scan_data)) {
+ return false;
+ }
+ hidl_scan_datas->push_back(hidl_scan_data);
+ }
+ return true;
+}
+
+WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToHidl(legacy_hal::wifi_tx_packet_fate fate) {
+ switch (fate) {
+ case legacy_hal::TX_PKT_FATE_ACKED:
+ return WifiDebugTxPacketFate::ACKED;
+ case legacy_hal::TX_PKT_FATE_SENT:
+ return WifiDebugTxPacketFate::SENT;
+ case legacy_hal::TX_PKT_FATE_FW_QUEUED:
+ return WifiDebugTxPacketFate::FW_QUEUED;
+ case legacy_hal::TX_PKT_FATE_FW_DROP_INVALID:
+ return WifiDebugTxPacketFate::FW_DROP_INVALID;
+ case legacy_hal::TX_PKT_FATE_FW_DROP_NOBUFS:
+ return WifiDebugTxPacketFate::FW_DROP_NOBUFS;
+ case legacy_hal::TX_PKT_FATE_FW_DROP_OTHER:
+ return WifiDebugTxPacketFate::FW_DROP_OTHER;
+ case legacy_hal::TX_PKT_FATE_DRV_QUEUED:
+ return WifiDebugTxPacketFate::DRV_QUEUED;
+ case legacy_hal::TX_PKT_FATE_DRV_DROP_INVALID:
+ return WifiDebugTxPacketFate::DRV_DROP_INVALID;
+ case legacy_hal::TX_PKT_FATE_DRV_DROP_NOBUFS:
+ return WifiDebugTxPacketFate::DRV_DROP_NOBUFS;
+ case legacy_hal::TX_PKT_FATE_DRV_DROP_OTHER:
+ return WifiDebugTxPacketFate::DRV_DROP_OTHER;
+ };
+ CHECK(false) << "Unknown legacy fate type: " << fate;
+}
+
+WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToHidl(legacy_hal::wifi_rx_packet_fate fate) {
+ switch (fate) {
+ case legacy_hal::RX_PKT_FATE_SUCCESS:
+ return WifiDebugRxPacketFate::SUCCESS;
+ case legacy_hal::RX_PKT_FATE_FW_QUEUED:
+ return WifiDebugRxPacketFate::FW_QUEUED;
+ case legacy_hal::RX_PKT_FATE_FW_DROP_FILTER:
+ return WifiDebugRxPacketFate::FW_DROP_FILTER;
+ case legacy_hal::RX_PKT_FATE_FW_DROP_INVALID:
+ return WifiDebugRxPacketFate::FW_DROP_INVALID;
+ case legacy_hal::RX_PKT_FATE_FW_DROP_NOBUFS:
+ return WifiDebugRxPacketFate::FW_DROP_NOBUFS;
+ case legacy_hal::RX_PKT_FATE_FW_DROP_OTHER:
+ return WifiDebugRxPacketFate::FW_DROP_OTHER;
+ case legacy_hal::RX_PKT_FATE_DRV_QUEUED:
+ return WifiDebugRxPacketFate::DRV_QUEUED;
+ case legacy_hal::RX_PKT_FATE_DRV_DROP_FILTER:
+ return WifiDebugRxPacketFate::DRV_DROP_FILTER;
+ case legacy_hal::RX_PKT_FATE_DRV_DROP_INVALID:
+ return WifiDebugRxPacketFate::DRV_DROP_INVALID;
+ case legacy_hal::RX_PKT_FATE_DRV_DROP_NOBUFS:
+ return WifiDebugRxPacketFate::DRV_DROP_NOBUFS;
+ case legacy_hal::RX_PKT_FATE_DRV_DROP_OTHER:
+ return WifiDebugRxPacketFate::DRV_DROP_OTHER;
+ };
+ CHECK(false) << "Unknown legacy fate type: " << fate;
+}
+
+WifiDebugPacketFateFrameType convertLegacyDebugPacketFateFrameTypeToHidl(
+ legacy_hal::frame_type type) {
+ switch (type) {
+ case legacy_hal::FRAME_TYPE_UNKNOWN:
+ return WifiDebugPacketFateFrameType::UNKNOWN;
+ case legacy_hal::FRAME_TYPE_ETHERNET_II:
+ return WifiDebugPacketFateFrameType::ETHERNET_II;
+ case legacy_hal::FRAME_TYPE_80211_MGMT:
+ return WifiDebugPacketFateFrameType::MGMT_80211;
+ };
+ CHECK(false) << "Unknown legacy frame type: " << type;
+}
+
+bool convertLegacyDebugPacketFateFrameToHidl(const legacy_hal::frame_info& legacy_frame,
+ WifiDebugPacketFateFrameInfo* hidl_frame) {
+ if (!hidl_frame) {
+ return false;
+ }
+ *hidl_frame = {};
+ hidl_frame->frameType = convertLegacyDebugPacketFateFrameTypeToHidl(legacy_frame.payload_type);
+ hidl_frame->frameLen = legacy_frame.frame_len;
+ hidl_frame->driverTimestampUsec = legacy_frame.driver_timestamp_usec;
+ hidl_frame->firmwareTimestampUsec = legacy_frame.firmware_timestamp_usec;
+ const uint8_t* frame_begin =
+ reinterpret_cast<const uint8_t*>(legacy_frame.frame_content.ethernet_ii_bytes);
+ hidl_frame->frameContent =
+ std::vector<uint8_t>(frame_begin, frame_begin + legacy_frame.frame_len);
+ return true;
+}
+
+bool convertLegacyDebugTxPacketFateToHidl(const legacy_hal::wifi_tx_report& legacy_fate,
+ WifiDebugTxPacketFateReport* hidl_fate) {
+ if (!hidl_fate) {
+ return false;
+ }
+ *hidl_fate = {};
+ hidl_fate->fate = convertLegacyDebugTxPacketFateToHidl(legacy_fate.fate);
+ return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo);
+}
+
+bool convertLegacyVectorOfDebugTxPacketFateToHidl(
+ const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
+ std::vector<WifiDebugTxPacketFateReport>* hidl_fates) {
+ if (!hidl_fates) {
+ return false;
+ }
+ *hidl_fates = {};
+ for (const auto& legacy_fate : legacy_fates) {
+ WifiDebugTxPacketFateReport hidl_fate;
+ if (!convertLegacyDebugTxPacketFateToHidl(legacy_fate, &hidl_fate)) {
+ return false;
+ }
+ hidl_fates->push_back(hidl_fate);
+ }
+ return true;
+}
+
+bool convertLegacyDebugRxPacketFateToHidl(const legacy_hal::wifi_rx_report& legacy_fate,
+ WifiDebugRxPacketFateReport* hidl_fate) {
+ if (!hidl_fate) {
+ return false;
+ }
+ *hidl_fate = {};
+ hidl_fate->fate = convertLegacyDebugRxPacketFateToHidl(legacy_fate.fate);
+ return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo);
+}
+
+bool convertLegacyVectorOfDebugRxPacketFateToHidl(
+ const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
+ std::vector<WifiDebugRxPacketFateReport>* hidl_fates) {
+ if (!hidl_fates) {
+ return false;
+ }
+ *hidl_fates = {};
+ for (const auto& legacy_fate : legacy_fates) {
+ WifiDebugRxPacketFateReport hidl_fate;
+ if (!convertLegacyDebugRxPacketFateToHidl(legacy_fate, &hidl_fate)) {
+ return false;
+ }
+ hidl_fates->push_back(hidl_fate);
+ }
+ return true;
+}
+
+bool convertLegacyLinkLayerRadioStatsToHidl(
+ const legacy_hal::LinkLayerRadioStats& legacy_radio_stat,
+ V1_6::StaLinkLayerRadioStats* hidl_radio_stat) {
+ if (!hidl_radio_stat) {
+ return false;
+ }
+ *hidl_radio_stat = {};
+
+ hidl_radio_stat->radioId = legacy_radio_stat.stats.radio;
+ hidl_radio_stat->V1_0.onTimeInMs = legacy_radio_stat.stats.on_time;
+ hidl_radio_stat->V1_0.txTimeInMs = legacy_radio_stat.stats.tx_time;
+ hidl_radio_stat->V1_0.rxTimeInMs = legacy_radio_stat.stats.rx_time;
+ hidl_radio_stat->V1_0.onTimeInMsForScan = legacy_radio_stat.stats.on_time_scan;
+ hidl_radio_stat->V1_0.txTimeInMsPerLevel = legacy_radio_stat.tx_time_per_levels;
+ hidl_radio_stat->onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd;
+ hidl_radio_stat->onTimeInMsForBgScan = legacy_radio_stat.stats.on_time_gscan;
+ hidl_radio_stat->onTimeInMsForRoamScan = legacy_radio_stat.stats.on_time_roam_scan;
+ hidl_radio_stat->onTimeInMsForPnoScan = legacy_radio_stat.stats.on_time_pno_scan;
+ hidl_radio_stat->onTimeInMsForHs20Scan = legacy_radio_stat.stats.on_time_hs20;
+
+ std::vector<V1_6::WifiChannelStats> hidl_channel_stats;
+
+ for (const auto& channel_stat : legacy_radio_stat.channel_stats) {
+ V1_6::WifiChannelStats hidl_channel_stat;
+ hidl_channel_stat.onTimeInMs = channel_stat.on_time;
+ hidl_channel_stat.ccaBusyTimeInMs = channel_stat.cca_busy_time;
+ /*
+ * TODO once b/119142899 is fixed,
+ * replace below code with convertLegacyWifiChannelInfoToHidl()
+ */
+ hidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20;
+ hidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq;
+ hidl_channel_stat.channel.centerFreq0 = channel_stat.channel.center_freq0;
+ hidl_channel_stat.channel.centerFreq1 = channel_stat.channel.center_freq1;
+ hidl_channel_stats.push_back(hidl_channel_stat);
+ }
+
+ hidl_radio_stat->channelStats = hidl_channel_stats;
+
+ return true;
+}
+
+bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats,
+ V1_6::StaLinkLayerStats* hidl_stats) {
+ if (!hidl_stats) {
+ return false;
+ }
+ *hidl_stats = {};
+ // iface legacy_stats conversion.
+ hidl_stats->iface.V1_0.beaconRx = legacy_stats.iface.beacon_rx;
+ hidl_stats->iface.V1_0.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
+ hidl_stats->iface.V1_0.wmeBePktStats.rxMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
+ hidl_stats->iface.V1_0.wmeBePktStats.txMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
+ hidl_stats->iface.V1_0.wmeBePktStats.lostMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
+ hidl_stats->iface.V1_0.wmeBePktStats.retries =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
+ hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMinInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
+ hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
+ hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
+ hidl_stats->iface.wmeBeContentionTimeStats.contentionNumSamples =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
+ hidl_stats->iface.V1_0.wmeBkPktStats.rxMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
+ hidl_stats->iface.V1_0.wmeBkPktStats.txMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
+ hidl_stats->iface.V1_0.wmeBkPktStats.lostMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
+ hidl_stats->iface.V1_0.wmeBkPktStats.retries =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
+ hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMinInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
+ hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
+ hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
+ hidl_stats->iface.wmeBkContentionTimeStats.contentionNumSamples =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
+ hidl_stats->iface.V1_0.wmeViPktStats.rxMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
+ hidl_stats->iface.V1_0.wmeViPktStats.txMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
+ hidl_stats->iface.V1_0.wmeViPktStats.lostMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
+ hidl_stats->iface.V1_0.wmeViPktStats.retries =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
+ hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMinInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
+ hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMaxInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
+ hidl_stats->iface.wmeViContentionTimeStats.contentionTimeAvgInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
+ hidl_stats->iface.wmeViContentionTimeStats.contentionNumSamples =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
+ hidl_stats->iface.V1_0.wmeVoPktStats.rxMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
+ hidl_stats->iface.V1_0.wmeVoPktStats.txMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
+ hidl_stats->iface.V1_0.wmeVoPktStats.lostMpdu =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
+ hidl_stats->iface.V1_0.wmeVoPktStats.retries =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
+ hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMinInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
+ hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
+ hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
+ hidl_stats->iface.wmeVoContentionTimeStats.contentionNumSamples =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
+ hidl_stats->iface.timeSliceDutyCycleInPercent =
+ legacy_stats.iface.info.time_slicing_duty_cycle_percent;
+ // peer info legacy_stats conversion.
+ std::vector<V1_6::StaPeerInfo> hidl_peers_info_stats;
+ for (const auto& legacy_peer_info_stats : legacy_stats.peers) {
+ V1_6::StaPeerInfo hidl_peer_info_stats;
+ if (!convertLegacyPeerInfoStatsToHidl(legacy_peer_info_stats, &hidl_peer_info_stats)) {
+ return false;
+ }
+ hidl_peers_info_stats.push_back(hidl_peer_info_stats);
+ }
+ hidl_stats->iface.peers = hidl_peers_info_stats;
+ // radio legacy_stats conversion.
+ std::vector<V1_6::StaLinkLayerRadioStats> hidl_radios_stats;
+ for (const auto& legacy_radio_stats : legacy_stats.radios) {
+ V1_6::StaLinkLayerRadioStats hidl_radio_stats;
+ if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats, &hidl_radio_stats)) {
+ return false;
+ }
+ hidl_radios_stats.push_back(hidl_radio_stats);
+ }
+ hidl_stats->radios = hidl_radios_stats;
+ // Timestamp in the HAL wrapper here since it's not provided in the legacy
+ // HAL API.
+ hidl_stats->timeStampInMs = uptimeMillis();
+ return true;
+}
+
+bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+ V1_6::StaPeerInfo* hidl_peer_info_stats) {
+ if (!hidl_peer_info_stats) {
+ return false;
+ }
+ *hidl_peer_info_stats = {};
+ hidl_peer_info_stats->staCount = legacy_peer_info_stats.peer_info.bssload.sta_count;
+ hidl_peer_info_stats->chanUtil = legacy_peer_info_stats.peer_info.bssload.chan_util;
+
+ std::vector<V1_6::StaRateStat> hidlRateStats;
+ for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) {
+ V1_6::StaRateStat rateStat;
+ if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate, &rateStat.rateInfo)) {
+ return false;
+ }
+ rateStat.txMpdu = legacy_rate_stats.tx_mpdu;
+ rateStat.rxMpdu = legacy_rate_stats.rx_mpdu;
+ rateStat.mpduLost = legacy_rate_stats.mpdu_lost;
+ rateStat.retries = legacy_rate_stats.retries;
+ hidlRateStats.push_back(rateStat);
+ }
+ hidl_peer_info_stats->rateStats = hidlRateStats;
+ return true;
+}
+
+bool convertLegacyRoamingCapabilitiesToHidl(
+ const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+ StaRoamingCapabilities* hidl_caps) {
+ if (!hidl_caps) {
+ return false;
+ }
+ *hidl_caps = {};
+ hidl_caps->maxBlacklistSize = legacy_caps.max_blacklist_size;
+ hidl_caps->maxWhitelistSize = legacy_caps.max_whitelist_size;
+ return true;
+}
+
+bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config,
+ legacy_hal::wifi_roaming_config* legacy_config) {
+ if (!legacy_config) {
+ return false;
+ }
+ *legacy_config = {};
+ if (hidl_config.bssidBlacklist.size() > MAX_BLACKLIST_BSSID ||
+ hidl_config.ssidWhitelist.size() > MAX_WHITELIST_SSID) {
+ return false;
+ }
+ legacy_config->num_blacklist_bssid = hidl_config.bssidBlacklist.size();
+ uint32_t i = 0;
+ for (const auto& bssid : hidl_config.bssidBlacklist) {
+ CHECK(bssid.size() == sizeof(legacy_hal::mac_addr));
+ memcpy(legacy_config->blacklist_bssid[i++], bssid.data(), bssid.size());
+ }
+ legacy_config->num_whitelist_ssid = hidl_config.ssidWhitelist.size();
+ i = 0;
+ for (const auto& ssid : hidl_config.ssidWhitelist) {
+ CHECK(ssid.size() <= sizeof(legacy_hal::ssid_t::ssid_str));
+ legacy_config->whitelist_ssid[i].length = ssid.size();
+ memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data(), ssid.size());
+ i++;
+ }
+ return true;
+}
+
+legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state) {
+ switch (state) {
+ case StaRoamingState::ENABLED:
+ return legacy_hal::ROAMING_ENABLE;
+ case StaRoamingState::DISABLED:
+ return legacy_hal::ROAMING_DISABLE;
+ };
+ CHECK(false);
+}
+
+legacy_hal::NanMatchAlg convertHidlNanMatchAlgToLegacy(NanMatchAlg type) {
+ switch (type) {
+ case NanMatchAlg::MATCH_ONCE:
+ return legacy_hal::NAN_MATCH_ALG_MATCH_ONCE;
+ case NanMatchAlg::MATCH_CONTINUOUS:
+ return legacy_hal::NAN_MATCH_ALG_MATCH_CONTINUOUS;
+ case NanMatchAlg::MATCH_NEVER:
+ return legacy_hal::NAN_MATCH_ALG_MATCH_NEVER;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy(NanPublishType type) {
+ switch (type) {
+ case NanPublishType::UNSOLICITED:
+ return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED;
+ case NanPublishType::SOLICITED:
+ return legacy_hal::NAN_PUBLISH_TYPE_SOLICITED;
+ case NanPublishType::UNSOLICITED_SOLICITED:
+ return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanTxType convertHidlNanTxTypeToLegacy(NanTxType type) {
+ switch (type) {
+ case NanTxType::BROADCAST:
+ return legacy_hal::NAN_TX_TYPE_BROADCAST;
+ case NanTxType::UNICAST:
+ return legacy_hal::NAN_TX_TYPE_UNICAST;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy(NanSubscribeType type) {
+ switch (type) {
+ case NanSubscribeType::PASSIVE:
+ return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE;
+ case NanSubscribeType::ACTIVE:
+ return legacy_hal::NAN_SUBSCRIBE_TYPE_ACTIVE;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanSRFType convertHidlNanSrfTypeToLegacy(NanSrfType type) {
+ switch (type) {
+ case NanSrfType::BLOOM_FILTER:
+ return legacy_hal::NAN_SRF_ATTR_BLOOM_FILTER;
+ case NanSrfType::PARTIAL_MAC_ADDR:
+ return legacy_hal::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanDataPathChannelCfg convertHidlNanDataPathChannelCfgToLegacy(
+ NanDataPathChannelCfg type) {
+ switch (type) {
+ case NanDataPathChannelCfg::CHANNEL_NOT_REQUESTED:
+ return legacy_hal::NAN_DP_CHANNEL_NOT_REQUESTED;
+ case NanDataPathChannelCfg::REQUEST_CHANNEL_SETUP:
+ return legacy_hal::NAN_DP_REQUEST_CHANNEL_SETUP;
+ case NanDataPathChannelCfg::FORCE_CHANNEL_SETUP:
+ return legacy_hal::NAN_DP_FORCE_CHANNEL_SETUP;
+ }
+ CHECK(false);
+}
+
+NanStatusType convertLegacyNanStatusTypeToHidl(legacy_hal::NanStatusType type) {
+ switch (type) {
+ case legacy_hal::NAN_STATUS_SUCCESS:
+ return NanStatusType::SUCCESS;
+ case legacy_hal::NAN_STATUS_INTERNAL_FAILURE:
+ return NanStatusType::INTERNAL_FAILURE;
+ case legacy_hal::NAN_STATUS_PROTOCOL_FAILURE:
+ return NanStatusType::PROTOCOL_FAILURE;
+ case legacy_hal::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID:
+ return NanStatusType::INVALID_SESSION_ID;
+ case legacy_hal::NAN_STATUS_NO_RESOURCE_AVAILABLE:
+ return NanStatusType::NO_RESOURCES_AVAILABLE;
+ case legacy_hal::NAN_STATUS_INVALID_PARAM:
+ return NanStatusType::INVALID_ARGS;
+ case legacy_hal::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID:
+ return NanStatusType::INVALID_PEER_ID;
+ case legacy_hal::NAN_STATUS_INVALID_NDP_ID:
+ return NanStatusType::INVALID_NDP_ID;
+ case legacy_hal::NAN_STATUS_NAN_NOT_ALLOWED:
+ return NanStatusType::NAN_NOT_ALLOWED;
+ case legacy_hal::NAN_STATUS_NO_OTA_ACK:
+ return NanStatusType::NO_OTA_ACK;
+ case legacy_hal::NAN_STATUS_ALREADY_ENABLED:
+ return NanStatusType::ALREADY_ENABLED;
+ case legacy_hal::NAN_STATUS_FOLLOWUP_QUEUE_FULL:
+ return NanStatusType::FOLLOWUP_TX_QUEUE_FULL;
+ case legacy_hal::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
+ return NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
+ }
+ CHECK(false);
+}
+
+void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+ WifiNanStatus* wifiNanStatus) {
+ wifiNanStatus->status = convertLegacyNanStatusTypeToHidl(type);
+ wifiNanStatus->description = safeConvertChar(str, max_len);
+}
+
+bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request,
+ legacy_hal::NanEnableRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: null legacy_request";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->config_2dot4g_support = 1;
+ legacy_request->support_2dot4g_val =
+ hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+ legacy_request->config_support_5g = 1;
+ legacy_request->support_5g_val =
+ hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+ legacy_request->config_hop_count_limit = 1;
+ legacy_request->hop_count_limit_val = hidl_request.hopCountMax;
+ legacy_request->master_pref = hidl_request.configParams.masterPref;
+ legacy_request->discovery_indication_cfg = 0;
+ legacy_request->discovery_indication_cfg |=
+ hidl_request.configParams.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
+ legacy_request->discovery_indication_cfg |=
+ hidl_request.configParams.disableStartedClusterIndication ? 0x2 : 0x0;
+ legacy_request->discovery_indication_cfg |=
+ hidl_request.configParams.disableJoinedClusterIndication ? 0x4 : 0x0;
+ legacy_request->config_sid_beacon = 1;
+ if (hidl_request.configParams.numberOfPublishServiceIdsInBeacon > 127) {
+ LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
+ "numberOfPublishServiceIdsInBeacon > 127";
+ return false;
+ }
+ legacy_request->sid_beacon_val =
+ (hidl_request.configParams.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
+ (hidl_request.configParams.numberOfPublishServiceIdsInBeacon << 1);
+ legacy_request->config_subscribe_sid_beacon = 1;
+ if (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon > 127) {
+ LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
+ "numberOfSubscribeServiceIdsInBeacon > 127";
+ return false;
+ }
+ legacy_request->subscribe_sid_beacon_val =
+ (hidl_request.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
+ (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon << 1);
+ legacy_request->config_rssi_window_size = 1;
+ legacy_request->rssi_window_size_val = hidl_request.configParams.rssiWindowSize;
+ legacy_request->config_disc_mac_addr_randomization = 1;
+ legacy_request->disc_mac_addr_rand_interval_sec =
+ hidl_request.configParams.macAddressRandomizationIntervalSec;
+ legacy_request->config_2dot4g_rssi_close = 1;
+ if (hidl_request.configParams.bandSpecificConfig.size() != 3) {
+ LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
+ "bandSpecificConfig.size() != 3";
+ return false;
+ }
+ legacy_request->rssi_close_2dot4g_val =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .rssiClose;
+ legacy_request->config_2dot4g_rssi_middle = 1;
+ legacy_request->rssi_middle_2dot4g_val =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .rssiMiddle;
+ legacy_request->config_2dot4g_rssi_proximity = 1;
+ legacy_request->rssi_proximity_2dot4g_val =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .rssiCloseProximity;
+ legacy_request->config_scan_params = 1;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .scanPeriodSec;
+ legacy_request->config_dw.config_2dot4g_dw_band =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal;
+ legacy_request->config_dw.dw_2dot4g_interval_val =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .discoveryWindowIntervalVal;
+ legacy_request->config_5g_rssi_close = 1;
+ legacy_request->rssi_close_5g_val =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .rssiClose;
+ legacy_request->config_5g_rssi_middle = 1;
+ legacy_request->rssi_middle_5g_val =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .rssiMiddle;
+ legacy_request->config_5g_rssi_close_proximity = 1;
+ legacy_request->rssi_close_proximity_5g_val =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .rssiCloseProximity;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .scanPeriodSec;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .scanPeriodSec;
+ legacy_request->config_dw.config_5g_dw_band =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal;
+ legacy_request->config_dw.dw_5g_interval_val =
+ hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal;
+ if (hidl_request.debugConfigs.validClusterIdVals) {
+ legacy_request->cluster_low = hidl_request.debugConfigs.clusterIdBottomRangeVal;
+ legacy_request->cluster_high = hidl_request.debugConfigs.clusterIdTopRangeVal;
+ } else { // need 'else' since not configurable in legacy HAL
+ legacy_request->cluster_low = 0x0000;
+ legacy_request->cluster_high = 0xFFFF;
+ }
+ legacy_request->config_intf_addr = hidl_request.debugConfigs.validIntfAddrVal;
+ memcpy(legacy_request->intf_addr_val, hidl_request.debugConfigs.intfAddrVal.data(), 6);
+ legacy_request->config_oui = hidl_request.debugConfigs.validOuiVal;
+ legacy_request->oui_val = hidl_request.debugConfigs.ouiVal;
+ legacy_request->config_random_factor_force =
+ hidl_request.debugConfigs.validRandomFactorForceVal;
+ legacy_request->random_factor_force_val = hidl_request.debugConfigs.randomFactorForceVal;
+ legacy_request->config_hop_count_force = hidl_request.debugConfigs.validHopCountForceVal;
+ legacy_request->hop_count_force_val = hidl_request.debugConfigs.hopCountForceVal;
+ legacy_request->config_24g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal;
+ legacy_request->channel_24g_val =
+ hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+ legacy_request->config_5g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal;
+ legacy_request->channel_5g_val =
+ hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+ legacy_request->config_2dot4g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal;
+ legacy_request->beacon_2dot4g_val =
+ hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+ legacy_request->config_5g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal;
+ legacy_request->beacon_5g_val =
+ hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+ legacy_request->config_2dot4g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal;
+ legacy_request->sdf_2dot4g_val =
+ hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+ legacy_request->config_5g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal;
+ legacy_request->sdf_5g_val =
+ hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+
+ /* TODO: b/145609058
+ * Missing updates needed to legacy_hal::NanEnableRequest and conversion to
+ * it for 6GHz band */
+
+ return true;
+}
+
+bool convertHidlNanEnableRequest_1_6ToLegacy(const V1_4::NanEnableRequest& hidl_request1,
+ const NanConfigRequestSupplemental& hidl_request2,
+ legacy_hal::NanEnableRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanEnableRequest_1_6ToLegacy: null legacy_request";
+ return false;
+ }
+
+ *legacy_request = {};
+ if (!convertHidlNanEnableRequestToLegacy(hidl_request1, legacy_request)) {
+ return false;
+ }
+
+ legacy_request->config_discovery_beacon_int = 1;
+ legacy_request->discovery_beacon_interval = hidl_request2.V1_5.V1_2.discoveryBeaconIntervalMs;
+ legacy_request->config_nss = 1;
+ legacy_request->nss = hidl_request2.V1_5.V1_2.numberOfSpatialStreamsInDiscovery;
+ legacy_request->config_dw_early_termination = 1;
+ legacy_request->enable_dw_termination =
+ hidl_request2.V1_5.V1_2.enableDiscoveryWindowEarlyTermination;
+ legacy_request->config_enable_ranging = 1;
+ legacy_request->enable_ranging = hidl_request2.V1_5.V1_2.enableRanging;
+
+ legacy_request->config_enable_instant_mode = 1;
+ legacy_request->enable_instant_mode = hidl_request2.V1_5.enableInstantCommunicationMode;
+ legacy_request->config_instant_mode_channel = 1;
+ legacy_request->instant_mode_channel = hidl_request2.instantModeChannel;
+
+ return true;
+}
+
+bool convertHidlNanConfigRequest_1_6ToLegacy(const V1_4::NanConfigRequest& hidl_request1,
+ const NanConfigRequestSupplemental& hidl_request2,
+ legacy_hal::NanConfigRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanConfigRequest_1_6ToLegacy: null legacy_request";
+ return false;
+ }
+
+ *legacy_request = {};
+ if (!convertHidlNanConfigRequestToLegacy(hidl_request1, legacy_request)) {
+ return false;
+ }
+
+ legacy_request->config_discovery_beacon_int = 1;
+ legacy_request->discovery_beacon_interval = hidl_request2.V1_5.V1_2.discoveryBeaconIntervalMs;
+ legacy_request->config_nss = 1;
+ legacy_request->nss = hidl_request2.V1_5.V1_2.numberOfSpatialStreamsInDiscovery;
+ legacy_request->config_dw_early_termination = 1;
+ legacy_request->enable_dw_termination =
+ hidl_request2.V1_5.V1_2.enableDiscoveryWindowEarlyTermination;
+ legacy_request->config_enable_ranging = 1;
+ legacy_request->enable_ranging = hidl_request2.V1_5.V1_2.enableRanging;
+
+ legacy_request->config_enable_instant_mode = 1;
+ legacy_request->enable_instant_mode = hidl_request2.V1_5.enableInstantCommunicationMode;
+ legacy_request->config_instant_mode_channel = 1;
+ legacy_request->instant_mode_channel = hidl_request2.instantModeChannel;
+
+ return true;
+}
+
+bool convertHidlNanPublishRequestToLegacy(const V1_6::NanPublishRequest& hidl_request,
+ legacy_hal::NanPublishRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: null legacy_request";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->publish_id = hidl_request.baseConfigs.sessionId;
+ legacy_request->ttl = hidl_request.baseConfigs.ttlSec;
+ legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod;
+ legacy_request->publish_count = hidl_request.baseConfigs.discoveryCount;
+ legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: service_name_len "
+ "too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
+ legacy_request->service_name_len);
+ legacy_request->publish_match_indicator =
+ convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator);
+ legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
+ if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
+ "service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_specific_info,
+ hidl_request.baseConfigs.serviceSpecificInfo.data(),
+ legacy_request->service_specific_info_len);
+ legacy_request->sdea_service_specific_info_len =
+ hidl_request.baseConfigs.extendedServiceSpecificInfo.size();
+ if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
+ "sdea_service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->sdea_service_specific_info,
+ hidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
+ legacy_request->sdea_service_specific_info_len);
+ legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size();
+ if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
+ "rx_match_filter_len too large";
+ return false;
+ }
+ memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(),
+ legacy_request->rx_match_filter_len);
+ legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size();
+ if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
+ "tx_match_filter_len too large";
+ return false;
+ }
+ memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(),
+ legacy_request->tx_match_filter_len);
+ legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold;
+ legacy_request->recv_indication_cfg = 0;
+ legacy_request->recv_indication_cfg |=
+ hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
+ legacy_request->recv_indication_cfg |=
+ hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
+ legacy_request->recv_indication_cfg |=
+ hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
+ legacy_request->recv_indication_cfg |= 0x8;
+ legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType;
+
+ legacy_request->scid_len = hidl_request.baseConfigs.securityConfig.scid.size();
+ if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: scid_len too large";
+ return false;
+ }
+ memcpy(legacy_request->scid, hidl_request.baseConfigs.securityConfig.scid.data(),
+ legacy_request->scid_len);
+
+ if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len =
+ hidl_request.baseConfigs.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk,
+ hidl_request.baseConfigs.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (hidl_request.baseConfigs.securityConfig.securityType ==
+ NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ hidl_request.baseConfigs.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ hidl_request.baseConfigs.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->sdea_params.security_cfg =
+ (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+
+ legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired
+ ? legacy_hal::NAN_RANGING_ENABLE
+ : legacy_hal::NAN_RANGING_DISABLE;
+ legacy_request->ranging_cfg.ranging_interval_msec =
+ hidl_request.baseConfigs.rangingIntervalMsec;
+ legacy_request->ranging_cfg.config_ranging_indications =
+ hidl_request.baseConfigs.configRangingIndications;
+ legacy_request->ranging_cfg.distance_ingress_mm =
+ hidl_request.baseConfigs.distanceIngressCm * 10;
+ legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10;
+ legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired
+ ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
+ : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+ legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
+ legacy_request->publish_type = convertHidlNanPublishTypeToLegacy(hidl_request.publishType);
+ legacy_request->tx_type = convertHidlNanTxTypeToLegacy(hidl_request.txType);
+ legacy_request->service_responder_policy = hidl_request.autoAcceptDataPathRequests
+ ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL
+ : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE;
+
+ return true;
+}
+
+bool convertHidlNanSubscribeRequestToLegacy(const V1_0::NanSubscribeRequest& hidl_request,
+ legacy_hal::NanSubscribeRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->subscribe_id = hidl_request.baseConfigs.sessionId;
+ legacy_request->ttl = hidl_request.baseConfigs.ttlSec;
+ legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod;
+ legacy_request->subscribe_count = hidl_request.baseConfigs.discoveryCount;
+ legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
+ "service_name_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
+ legacy_request->service_name_len);
+ legacy_request->subscribe_match_indicator =
+ convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator);
+ legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
+ if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
+ "service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_specific_info,
+ hidl_request.baseConfigs.serviceSpecificInfo.data(),
+ legacy_request->service_specific_info_len);
+ legacy_request->sdea_service_specific_info_len =
+ hidl_request.baseConfigs.extendedServiceSpecificInfo.size();
+ if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
+ "sdea_service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->sdea_service_specific_info,
+ hidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
+ legacy_request->sdea_service_specific_info_len);
+ legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size();
+ if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
+ "rx_match_filter_len too large";
+ return false;
+ }
+ memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(),
+ legacy_request->rx_match_filter_len);
+ legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size();
+ if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
+ "tx_match_filter_len too large";
+ return false;
+ }
+ memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(),
+ legacy_request->tx_match_filter_len);
+ legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold;
+ legacy_request->recv_indication_cfg = 0;
+ legacy_request->recv_indication_cfg |=
+ hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
+ legacy_request->recv_indication_cfg |=
+ hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
+ legacy_request->recv_indication_cfg |=
+ hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
+ legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType;
+ if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len =
+ hidl_request.baseConfigs.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk,
+ hidl_request.baseConfigs.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (hidl_request.baseConfigs.securityConfig.securityType ==
+ NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ hidl_request.baseConfigs.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ hidl_request.baseConfigs.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->sdea_params.security_cfg =
+ (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+ legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired
+ ? legacy_hal::NAN_RANGING_ENABLE
+ : legacy_hal::NAN_RANGING_DISABLE;
+ legacy_request->ranging_cfg.ranging_interval_msec =
+ hidl_request.baseConfigs.rangingIntervalMsec;
+ legacy_request->ranging_cfg.config_ranging_indications =
+ hidl_request.baseConfigs.configRangingIndications;
+ legacy_request->ranging_cfg.distance_ingress_mm =
+ hidl_request.baseConfigs.distanceIngressCm * 10;
+ legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10;
+ legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired
+ ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
+ : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+ legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
+ legacy_request->subscribe_type =
+ convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType);
+ legacy_request->serviceResponseFilter = convertHidlNanSrfTypeToLegacy(hidl_request.srfType);
+ legacy_request->serviceResponseInclude = hidl_request.srfRespondIfInAddressSet
+ ? legacy_hal::NAN_SRF_INCLUDE_RESPOND
+ : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
+ legacy_request->useServiceResponseFilter =
+ hidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF : legacy_hal::NAN_DO_NOT_USE_SRF;
+ legacy_request->ssiRequiredForMatchIndication =
+ hidl_request.isSsiRequiredForMatch ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND
+ : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
+ legacy_request->num_intf_addr_present = hidl_request.intfAddr.size();
+ if (legacy_request->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) {
+ LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
+ "num_intf_addr_present - too many";
+ return false;
+ }
+ for (int i = 0; i < legacy_request->num_intf_addr_present; i++) {
+ memcpy(legacy_request->intf_addr[i], hidl_request.intfAddr[i].data(), 6);
+ }
+
+ return true;
+}
+
+bool convertHidlNanTransmitFollowupRequestToLegacy(
+ const NanTransmitFollowupRequest& hidl_request,
+ legacy_hal::NanTransmitFollowupRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->publish_subscribe_id = hidl_request.discoverySessionId;
+ legacy_request->requestor_instance_id = hidl_request.peerId;
+ memcpy(legacy_request->addr, hidl_request.addr.data(), 6);
+ legacy_request->priority = hidl_request.isHighPriority ? legacy_hal::NAN_TX_PRIORITY_HIGH
+ : legacy_hal::NAN_TX_PRIORITY_NORMAL;
+ legacy_request->dw_or_faw = hidl_request.shouldUseDiscoveryWindow
+ ? legacy_hal::NAN_TRANSMIT_IN_DW
+ : legacy_hal::NAN_TRANSMIT_IN_FAW;
+ legacy_request->service_specific_info_len = hidl_request.serviceSpecificInfo.size();
+ if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: "
+ "service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_specific_info, hidl_request.serviceSpecificInfo.data(),
+ legacy_request->service_specific_info_len);
+ legacy_request->sdea_service_specific_info_len =
+ hidl_request.extendedServiceSpecificInfo.size();
+ if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: "
+ "sdea_service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->sdea_service_specific_info,
+ hidl_request.extendedServiceSpecificInfo.data(),
+ legacy_request->sdea_service_specific_info_len);
+ legacy_request->recv_indication_cfg = hidl_request.disableFollowupResultIndication ? 0x1 : 0x0;
+
+ return true;
+}
+
+bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request,
+ legacy_hal::NanConfigRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ // TODO: b/34059183 tracks missing configurations in legacy HAL or uknown
+ // defaults
+ legacy_request->master_pref = hidl_request.masterPref;
+ legacy_request->discovery_indication_cfg = 0;
+ legacy_request->discovery_indication_cfg |=
+ hidl_request.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
+ legacy_request->discovery_indication_cfg |=
+ hidl_request.disableStartedClusterIndication ? 0x2 : 0x0;
+ legacy_request->discovery_indication_cfg |=
+ hidl_request.disableJoinedClusterIndication ? 0x4 : 0x0;
+ legacy_request->config_sid_beacon = 1;
+ if (hidl_request.numberOfPublishServiceIdsInBeacon > 127) {
+ LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: "
+ "numberOfPublishServiceIdsInBeacon > 127";
+ return false;
+ }
+ legacy_request->sid_beacon = (hidl_request.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
+ (hidl_request.numberOfPublishServiceIdsInBeacon << 1);
+ legacy_request->config_subscribe_sid_beacon = 1;
+ if (hidl_request.numberOfSubscribeServiceIdsInBeacon > 127) {
+ LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: "
+ "numberOfSubscribeServiceIdsInBeacon > 127";
+ return false;
+ }
+ legacy_request->subscribe_sid_beacon_val =
+ (hidl_request.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
+ (hidl_request.numberOfSubscribeServiceIdsInBeacon << 1);
+ legacy_request->config_rssi_window_size = 1;
+ legacy_request->rssi_window_size_val = hidl_request.rssiWindowSize;
+ legacy_request->config_disc_mac_addr_randomization = 1;
+ legacy_request->disc_mac_addr_rand_interval_sec =
+ hidl_request.macAddressRandomizationIntervalSec;
+ /* TODO : missing
+ legacy_request->config_2dot4g_rssi_close = 1;
+ legacy_request->rssi_close_2dot4g_val =
+ hidl_request.bandSpecificConfig[
+ (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiClose;
+ legacy_request->config_2dot4g_rssi_middle = 1;
+ legacy_request->rssi_middle_2dot4g_val =
+ hidl_request.bandSpecificConfig[
+ (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiMiddle;
+ legacy_request->config_2dot4g_rssi_proximity = 1;
+ legacy_request->rssi_proximity_2dot4g_val =
+ hidl_request.bandSpecificConfig[
+ (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiCloseProximity;
+ */
+ legacy_request->config_scan_params = 1;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].scanPeriodSec;
+ legacy_request->config_dw.config_2dot4g_dw_band =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal;
+ legacy_request->config_dw.dw_2dot4g_interval_val =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .discoveryWindowIntervalVal;
+ /* TODO: missing
+ legacy_request->config_5g_rssi_close = 1;
+ legacy_request->rssi_close_5g_val =
+ hidl_request.bandSpecificConfig[
+ (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiClose;
+ legacy_request->config_5g_rssi_middle = 1;
+ legacy_request->rssi_middle_5g_val =
+ hidl_request.bandSpecificConfig[
+ (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiMiddle;
+ */
+ legacy_request->config_5g_rssi_close_proximity = 1;
+ legacy_request->rssi_close_proximity_5g_val =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].rssiCloseProximity;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
+ legacy_request->config_dw.config_5g_dw_band =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal;
+ legacy_request->config_dw.dw_5g_interval_val =
+ hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal;
+ /* TODO: b/145609058
+ * Missing updates needed to legacy_hal::NanConfigRequest and conversion to
+ * it for 6GHz band */
+
+ return true;
+}
+
+bool convertHidlNanDataPathInitiatorRequestToLegacy(
+ const V1_0::NanInitiateDataPathRequest& hidl_request,
+ legacy_hal::NanDataPathInitiatorRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->requestor_instance_id = hidl_request.peerId;
+ memcpy(legacy_request->peer_disc_mac_addr, hidl_request.peerDiscMacAddr.data(), 6);
+ legacy_request->channel_request_type =
+ convertHidlNanDataPathChannelCfgToLegacy(hidl_request.channelRequestType);
+ legacy_request->channel = hidl_request.channel;
+ if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strlcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
+ legacy_request->ndp_cfg.security_cfg =
+ (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+ legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
+ if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
+ "ndp_app_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
+ legacy_request->app_info.ndp_app_info_len);
+ legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
+ if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
+ "invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ hidl_request.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ hidl_request.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
+ "service_name_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
+ legacy_request->service_name_len);
+
+ return true;
+}
+
+bool convertHidlNanDataPathInitiatorRequest_1_6ToLegacy(
+ const V1_6::NanInitiateDataPathRequest& hidl_request,
+ legacy_hal::NanDataPathInitiatorRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->requestor_instance_id = hidl_request.peerId;
+ memcpy(legacy_request->peer_disc_mac_addr, hidl_request.peerDiscMacAddr.data(), 6);
+ legacy_request->channel_request_type =
+ convertHidlNanDataPathChannelCfgToLegacy(hidl_request.channelRequestType);
+ legacy_request->channel = hidl_request.channel;
+ if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strlcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
+ legacy_request->ndp_cfg.security_cfg =
+ (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+ legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
+ if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
+ "ndp_app_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
+ legacy_request->app_info.ndp_app_info_len);
+ legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
+ if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
+ "invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ hidl_request.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ hidl_request.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
+ "service_name_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
+ legacy_request->service_name_len);
+ legacy_request->scid_len = hidl_request.securityConfig.scid.size();
+ if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: scid_len too large";
+ return false;
+ }
+ memcpy(legacy_request->scid, hidl_request.securityConfig.scid.data(), legacy_request->scid_len);
+
+ return true;
+}
+
+bool convertHidlNanDataPathIndicationResponseToLegacy(
+ const V1_0::NanRespondToDataPathIndicationRequest& hidl_request,
+ legacy_hal::NanDataPathIndicationResponse* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->rsp_code = hidl_request.acceptRequest ? legacy_hal::NAN_DP_REQUEST_ACCEPT
+ : legacy_hal::NAN_DP_REQUEST_REJECT;
+ legacy_request->ndp_instance_id = hidl_request.ndpInstanceId;
+ if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strlcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
+ legacy_request->ndp_cfg.security_cfg =
+ (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+ legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
+ if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
+ "ndp_app_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
+ legacy_request->app_info.ndp_app_info_len);
+ legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
+ if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
+ "invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ hidl_request.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ hidl_request.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
+ "service_name_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
+ legacy_request->service_name_len);
+
+ return true;
+}
+
+bool convertHidlNanDataPathIndicationResponse_1_6ToLegacy(
+ const V1_6::NanRespondToDataPathIndicationRequest& hidl_request,
+ legacy_hal::NanDataPathIndicationResponse* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->rsp_code = hidl_request.acceptRequest ? legacy_hal::NAN_DP_REQUEST_ACCEPT
+ : legacy_hal::NAN_DP_REQUEST_REJECT;
+ legacy_request->ndp_instance_id = hidl_request.ndpInstanceId;
+ if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strlcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
+ legacy_request->ndp_cfg.security_cfg =
+ (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+ legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
+ if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
+ "ndp_app_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
+ legacy_request->app_info.ndp_app_info_len);
+ legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
+ if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
+ "invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ hidl_request.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ hidl_request.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
+ "service_name_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
+ legacy_request->service_name_len);
+ legacy_request->scid_len = hidl_request.securityConfig.scid.size();
+ if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
+ LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: scid_len too large";
+ return false;
+ }
+ memcpy(legacy_request->scid, hidl_request.securityConfig.scid.data(), legacy_request->scid_len);
+
+ return true;
+}
+
+bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response,
+ WifiNanStatus* wifiNanStatus) {
+ if (!wifiNanStatus) {
+ LOG(ERROR) << "convertLegacyNanResponseHeaderToHidl: wifiNanStatus is null";
+ return false;
+ }
+ *wifiNanStatus = {};
+
+ convertToWifiNanStatus(legacy_response.status, legacy_response.nan_error,
+ sizeof(legacy_response.nan_error), wifiNanStatus);
+ return true;
+}
+
+bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response,
+ V1_6::NanCapabilities* hidl_response) {
+ if (!hidl_response) {
+ LOG(ERROR) << "convertLegacyNanCapabilitiesResponseToHidl: "
+ "hidl_response is null";
+ return false;
+ }
+ *hidl_response = {};
+
+ hidl_response->maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters;
+ hidl_response->maxPublishes = legacy_response.max_publishes;
+ hidl_response->maxSubscribes = legacy_response.max_subscribes;
+ hidl_response->maxServiceNameLen = legacy_response.max_service_name_len;
+ hidl_response->maxMatchFilterLen = legacy_response.max_match_filter_len;
+ hidl_response->maxTotalMatchFilterLen = legacy_response.max_total_match_filter_len;
+ hidl_response->maxServiceSpecificInfoLen = legacy_response.max_service_specific_info_len;
+ hidl_response->maxExtendedServiceSpecificInfoLen =
+ legacy_response.max_sdea_service_specific_info_len;
+ hidl_response->maxNdiInterfaces = legacy_response.max_ndi_interfaces;
+ hidl_response->maxNdpSessions = legacy_response.max_ndp_sessions;
+ hidl_response->maxAppInfoLen = legacy_response.max_app_info_len;
+ hidl_response->maxQueuedTransmitFollowupMsgs =
+ legacy_response.max_queued_transmit_followup_msgs;
+ hidl_response->maxSubscribeInterfaceAddresses = legacy_response.max_subscribe_address;
+ hidl_response->supportedCipherSuites = legacy_response.cipher_suites_supported;
+ hidl_response->instantCommunicationModeSupportFlag = legacy_response.is_instant_mode_supported;
+
+ return true;
+}
+
+bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind,
+ V1_6::NanMatchInd* hidl_ind) {
+ if (!hidl_ind) {
+ LOG(ERROR) << "convertLegacyNanMatchIndToHidl: hidl_ind is null";
+ return false;
+ }
+ *hidl_ind = {};
+
+ hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+ hidl_ind->peerId = legacy_ind.requestor_instance_id;
+ hidl_ind->addr = hidl_array<uint8_t, 6>(legacy_ind.addr);
+ hidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
+ legacy_ind.service_specific_info,
+ legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
+ hidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
+ legacy_ind.sdea_service_specific_info,
+ legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
+ hidl_ind->matchFilter =
+ std::vector<uint8_t>(legacy_ind.sdf_match_filter,
+ legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len);
+ hidl_ind->matchOccuredInBeaconFlag = legacy_ind.match_occured_flag == 1;
+ hidl_ind->outOfResourceFlag = legacy_ind.out_of_resource_flag == 1;
+ hidl_ind->rssiValue = legacy_ind.rssi_value;
+ hidl_ind->peerCipherType = (V1_6::NanCipherSuiteType)legacy_ind.peer_cipher_type;
+ hidl_ind->peerRequiresSecurityEnabledInNdp =
+ legacy_ind.peer_sdea_params.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
+ hidl_ind->peerRequiresRanging =
+ legacy_ind.peer_sdea_params.ranging_state == legacy_hal::NAN_RANGING_ENABLE;
+ hidl_ind->rangingMeasurementInMm = legacy_ind.range_info.range_measurement_mm;
+ hidl_ind->rangingIndicationType = legacy_ind.range_info.ranging_event_type;
+ hidl_ind->scid = std::vector<uint8_t>(legacy_ind.scid, legacy_ind.scid + legacy_ind.scid_len);
+ return true;
+}
+
+bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind,
+ NanFollowupReceivedInd* hidl_ind) {
+ if (!hidl_ind) {
+ LOG(ERROR) << "convertLegacyNanFollowupIndToHidl: hidl_ind is null";
+ return false;
+ }
+ *hidl_ind = {};
+
+ hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+ hidl_ind->peerId = legacy_ind.requestor_instance_id;
+ hidl_ind->addr = hidl_array<uint8_t, 6>(legacy_ind.addr);
+ hidl_ind->receivedInFaw = legacy_ind.dw_or_faw == 1;
+ hidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
+ legacy_ind.service_specific_info,
+ legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
+ hidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
+ legacy_ind.sdea_service_specific_info,
+ legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
+
+ return true;
+}
+
+bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
+ NanDataPathRequestInd* hidl_ind) {
+ if (!hidl_ind) {
+ LOG(ERROR) << "convertLegacyNanDataPathRequestIndToHidl: hidl_ind is null";
+ return false;
+ }
+ *hidl_ind = {};
+
+ hidl_ind->discoverySessionId = legacy_ind.service_instance_id;
+ hidl_ind->peerDiscMacAddr = hidl_array<uint8_t, 6>(legacy_ind.peer_disc_mac_addr);
+ hidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id;
+ hidl_ind->securityRequired =
+ legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
+ hidl_ind->appInfo = std::vector<uint8_t>(
+ legacy_ind.app_info.ndp_app_info,
+ legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
+
+ return true;
+}
+
+bool convertLegacyNdpChannelInfoToHidl(const legacy_hal::NanChannelInfo& legacy_struct,
+ V1_6::NanDataPathChannelInfo* hidl_struct) {
+ if (!hidl_struct) {
+ LOG(ERROR) << "convertLegacyNdpChannelInfoToHidl: hidl_struct is null";
+ return false;
+ }
+ *hidl_struct = {};
+
+ hidl_struct->channelFreq = legacy_struct.channel;
+ hidl_struct->channelBandwidth = convertLegacyWifiChannelWidthToHidl(
+ (legacy_hal::wifi_channel_width)legacy_struct.bandwidth);
+ hidl_struct->numSpatialStreams = legacy_struct.nss;
+
+ return true;
+}
+
+bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
+ V1_6::NanDataPathConfirmInd* hidl_ind) {
+ if (!hidl_ind) {
+ LOG(ERROR) << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null";
+ return false;
+ }
+ *hidl_ind = {};
+
+ hidl_ind->V1_0.ndpInstanceId = legacy_ind.ndp_instance_id;
+ hidl_ind->V1_0.dataPathSetupSuccess = legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT;
+ hidl_ind->V1_0.peerNdiMacAddr = hidl_array<uint8_t, 6>(legacy_ind.peer_ndi_mac_addr);
+ hidl_ind->V1_0.appInfo = std::vector<uint8_t>(
+ legacy_ind.app_info.ndp_app_info,
+ legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
+ hidl_ind->V1_0.status.status = convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code);
+ hidl_ind->V1_0.status.description = ""; // TODO: b/34059183
+
+ std::vector<V1_6::NanDataPathChannelInfo> channelInfo;
+ for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
+ V1_6::NanDataPathChannelInfo hidl_struct;
+ if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) {
+ return false;
+ }
+ channelInfo.push_back(hidl_struct);
+ }
+ hidl_ind->channelInfo = channelInfo;
+
+ return true;
+}
+
+bool convertLegacyNanDataPathScheduleUpdateIndToHidl(
+ const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
+ V1_6::NanDataPathScheduleUpdateInd* hidl_ind) {
+ if (!hidl_ind) {
+ LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToHidl: "
+ "hidl_ind is null";
+ return false;
+ }
+ *hidl_ind = {};
+
+ hidl_ind->peerDiscoveryAddress = hidl_array<uint8_t, 6>(legacy_ind.peer_mac_addr);
+ std::vector<V1_6::NanDataPathChannelInfo> channelInfo;
+ for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
+ V1_6::NanDataPathChannelInfo hidl_struct;
+ if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) {
+ return false;
+ }
+ channelInfo.push_back(hidl_struct);
+ }
+ hidl_ind->channelInfo = channelInfo;
+ std::vector<uint32_t> ndpInstanceIds;
+ for (unsigned int i = 0; i < legacy_ind.num_ndp_instances; ++i) {
+ ndpInstanceIds.push_back(legacy_ind.ndp_instance_id[i]);
+ }
+ hidl_ind->ndpInstanceIds = ndpInstanceIds;
+
+ return true;
+}
+
+legacy_hal::wifi_rtt_type convertHidlRttTypeToLegacy(RttType type) {
+ switch (type) {
+ case RttType::ONE_SIDED:
+ return legacy_hal::RTT_TYPE_1_SIDED;
+ case RttType::TWO_SIDED:
+ return legacy_hal::RTT_TYPE_2_SIDED;
+ };
+ CHECK(false);
+}
+
+RttType convertLegacyRttTypeToHidl(legacy_hal::wifi_rtt_type type) {
+ switch (type) {
+ case legacy_hal::RTT_TYPE_1_SIDED:
+ return RttType::ONE_SIDED;
+ case legacy_hal::RTT_TYPE_2_SIDED:
+ return RttType::TWO_SIDED;
+ };
+ CHECK(false) << "Unknown legacy type: " << type;
+}
+
+legacy_hal::rtt_peer_type convertHidlRttPeerTypeToLegacy(RttPeerType type) {
+ switch (type) {
+ case RttPeerType::AP:
+ return legacy_hal::RTT_PEER_AP;
+ case RttPeerType::STA:
+ return legacy_hal::RTT_PEER_STA;
+ case RttPeerType::P2P_GO:
+ return legacy_hal::RTT_PEER_P2P_GO;
+ case RttPeerType::P2P_CLIENT:
+ return legacy_hal::RTT_PEER_P2P_CLIENT;
+ case RttPeerType::NAN:
+ return legacy_hal::RTT_PEER_NAN;
+ };
+ CHECK(false);
+}
+
+legacy_hal::wifi_channel_width convertHidlWifiChannelWidthToLegacy(WifiChannelWidthInMhz type) {
+ switch (type) {
+ case WifiChannelWidthInMhz::WIDTH_20:
+ return legacy_hal::WIFI_CHAN_WIDTH_20;
+ case WifiChannelWidthInMhz::WIDTH_40:
+ return legacy_hal::WIFI_CHAN_WIDTH_40;
+ case WifiChannelWidthInMhz::WIDTH_80:
+ return legacy_hal::WIFI_CHAN_WIDTH_80;
+ case WifiChannelWidthInMhz::WIDTH_160:
+ return legacy_hal::WIFI_CHAN_WIDTH_160;
+ case WifiChannelWidthInMhz::WIDTH_80P80:
+ return legacy_hal::WIFI_CHAN_WIDTH_80P80;
+ case WifiChannelWidthInMhz::WIDTH_5:
+ return legacy_hal::WIFI_CHAN_WIDTH_5;
+ case WifiChannelWidthInMhz::WIDTH_10:
+ return legacy_hal::WIFI_CHAN_WIDTH_10;
+ case V1_6::WifiChannelWidthInMhz::WIDTH_320:
+ return legacy_hal::WIFI_CHAN_WIDTH_320;
+ case WifiChannelWidthInMhz::WIDTH_INVALID:
+ return legacy_hal::WIFI_CHAN_WIDTH_INVALID;
+ };
+ CHECK(false);
+}
+
+V1_6::WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(
+ legacy_hal::wifi_channel_width type) {
+ switch (type) {
+ case legacy_hal::WIFI_CHAN_WIDTH_20:
+ return WifiChannelWidthInMhz::WIDTH_20;
+ case legacy_hal::WIFI_CHAN_WIDTH_40:
+ return WifiChannelWidthInMhz::WIDTH_40;
+ case legacy_hal::WIFI_CHAN_WIDTH_80:
+ return WifiChannelWidthInMhz::WIDTH_80;
+ case legacy_hal::WIFI_CHAN_WIDTH_160:
+ return WifiChannelWidthInMhz::WIDTH_160;
+ case legacy_hal::WIFI_CHAN_WIDTH_80P80:
+ return WifiChannelWidthInMhz::WIDTH_80P80;
+ case legacy_hal::WIFI_CHAN_WIDTH_5:
+ return WifiChannelWidthInMhz::WIDTH_5;
+ case legacy_hal::WIFI_CHAN_WIDTH_10:
+ return WifiChannelWidthInMhz::WIDTH_10;
+ case legacy_hal::WIFI_CHAN_WIDTH_320:
+ return V1_6::WifiChannelWidthInMhz::WIDTH_320;
+ default:
+ return WifiChannelWidthInMhz::WIDTH_INVALID;
+ };
+}
+
+legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy(V1_6::RttPreamble type) {
+ switch (type) {
+ case V1_6::RttPreamble::LEGACY:
+ return legacy_hal::WIFI_RTT_PREAMBLE_LEGACY;
+ case V1_6::RttPreamble::HT:
+ return legacy_hal::WIFI_RTT_PREAMBLE_HT;
+ case V1_6::RttPreamble::VHT:
+ return legacy_hal::WIFI_RTT_PREAMBLE_VHT;
+ case V1_6::RttPreamble::HE:
+ return legacy_hal::WIFI_RTT_PREAMBLE_HE;
+ case V1_6::RttPreamble::EHT:
+ return legacy_hal::WIFI_RTT_PREAMBLE_EHT;
+ };
+ CHECK(false);
+}
+
+V1_6::RttPreamble convertLegacyRttPreambleToHidl(legacy_hal::wifi_rtt_preamble type) {
+ switch (type) {
+ case legacy_hal::WIFI_RTT_PREAMBLE_LEGACY:
+ return V1_6::RttPreamble::LEGACY;
+ case legacy_hal::WIFI_RTT_PREAMBLE_HT:
+ return V1_6::RttPreamble::HT;
+ case legacy_hal::WIFI_RTT_PREAMBLE_VHT:
+ return V1_6::RttPreamble::VHT;
+ case legacy_hal::WIFI_RTT_PREAMBLE_HE:
+ return V1_6::RttPreamble::HE;
+ case legacy_hal::WIFI_RTT_PREAMBLE_EHT:
+ return V1_6::RttPreamble::EHT;
+ };
+ CHECK(false) << "Unknown legacy type: " << type;
+}
+
+legacy_hal::wifi_rtt_bw convertHidlRttBwToLegacy(RttBw type) {
+ switch (type) {
+ case RttBw::BW_5MHZ:
+ return legacy_hal::WIFI_RTT_BW_5;
+ case RttBw::BW_10MHZ:
+ return legacy_hal::WIFI_RTT_BW_10;
+ case RttBw::BW_20MHZ:
+ return legacy_hal::WIFI_RTT_BW_20;
+ case RttBw::BW_40MHZ:
+ return legacy_hal::WIFI_RTT_BW_40;
+ case RttBw::BW_80MHZ:
+ return legacy_hal::WIFI_RTT_BW_80;
+ case RttBw::BW_160MHZ:
+ return legacy_hal::WIFI_RTT_BW_160;
+ case RttBw::BW_320MHZ:
+ return legacy_hal::WIFI_RTT_BW_320;
+ };
+ CHECK(false);
+}
+
+RttBw convertLegacyRttBwToHidl(legacy_hal::wifi_rtt_bw type) {
+ switch (type) {
+ case legacy_hal::WIFI_RTT_BW_5:
+ return RttBw::BW_5MHZ;
+ case legacy_hal::WIFI_RTT_BW_10:
+ return RttBw::BW_10MHZ;
+ case legacy_hal::WIFI_RTT_BW_20:
+ return RttBw::BW_20MHZ;
+ case legacy_hal::WIFI_RTT_BW_40:
+ return RttBw::BW_40MHZ;
+ case legacy_hal::WIFI_RTT_BW_80:
+ return RttBw::BW_80MHZ;
+ case legacy_hal::WIFI_RTT_BW_160:
+ return RttBw::BW_160MHZ;
+ case legacy_hal::WIFI_RTT_BW_320:
+ return RttBw::BW_320MHZ;
+ };
+ CHECK(false) << "Unknown legacy type: " << type;
+}
+
+legacy_hal::wifi_motion_pattern convertHidlRttMotionPatternToLegacy(RttMotionPattern type) {
+ switch (type) {
+ case RttMotionPattern::NOT_EXPECTED:
+ return legacy_hal::WIFI_MOTION_NOT_EXPECTED;
+ case RttMotionPattern::EXPECTED:
+ return legacy_hal::WIFI_MOTION_EXPECTED;
+ case RttMotionPattern::UNKNOWN:
+ return legacy_hal::WIFI_MOTION_UNKNOWN;
+ };
+ CHECK(false);
+}
+
+V1_6::WifiRatePreamble convertLegacyWifiRatePreambleToHidl(uint8_t preamble) {
+ switch (preamble) {
+ case 0:
+ return V1_6::WifiRatePreamble::OFDM;
+ case 1:
+ return V1_6::WifiRatePreamble::CCK;
+ case 2:
+ return V1_6::WifiRatePreamble::HT;
+ case 3:
+ return V1_6::WifiRatePreamble::VHT;
+ case 4:
+ return V1_6::WifiRatePreamble::HE;
+ case 5:
+ return V1_6::WifiRatePreamble::EHT;
+ default:
+ return V1_6::WifiRatePreamble::RESERVED;
+ };
+ CHECK(false) << "Unknown legacy preamble: " << preamble;
+}
+
+WifiRateNss convertLegacyWifiRateNssToHidl(uint8_t nss) {
+ switch (nss) {
+ case 0:
+ return WifiRateNss::NSS_1x1;
+ case 1:
+ return WifiRateNss::NSS_2x2;
+ case 2:
+ return WifiRateNss::NSS_3x3;
+ case 3:
+ return WifiRateNss::NSS_4x4;
+ };
+ CHECK(false) << "Unknown legacy nss: " << nss;
+ return {};
+}
+
+RttStatus convertLegacyRttStatusToHidl(legacy_hal::wifi_rtt_status status) {
+ switch (status) {
+ case legacy_hal::RTT_STATUS_SUCCESS:
+ return RttStatus::SUCCESS;
+ case legacy_hal::RTT_STATUS_FAILURE:
+ return RttStatus::FAILURE;
+ case legacy_hal::RTT_STATUS_FAIL_NO_RSP:
+ return RttStatus::FAIL_NO_RSP;
+ case legacy_hal::RTT_STATUS_FAIL_REJECTED:
+ return RttStatus::FAIL_REJECTED;
+ case legacy_hal::RTT_STATUS_FAIL_NOT_SCHEDULED_YET:
+ return RttStatus::FAIL_NOT_SCHEDULED_YET;
+ case legacy_hal::RTT_STATUS_FAIL_TM_TIMEOUT:
+ return RttStatus::FAIL_TM_TIMEOUT;
+ case legacy_hal::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL:
+ return RttStatus::FAIL_AP_ON_DIFF_CHANNEL;
+ case legacy_hal::RTT_STATUS_FAIL_NO_CAPABILITY:
+ return RttStatus::FAIL_NO_CAPABILITY;
+ case legacy_hal::RTT_STATUS_ABORTED:
+ return RttStatus::ABORTED;
+ case legacy_hal::RTT_STATUS_FAIL_INVALID_TS:
+ return RttStatus::FAIL_INVALID_TS;
+ case legacy_hal::RTT_STATUS_FAIL_PROTOCOL:
+ return RttStatus::FAIL_PROTOCOL;
+ case legacy_hal::RTT_STATUS_FAIL_SCHEDULE:
+ return RttStatus::FAIL_SCHEDULE;
+ case legacy_hal::RTT_STATUS_FAIL_BUSY_TRY_LATER:
+ return RttStatus::FAIL_BUSY_TRY_LATER;
+ case legacy_hal::RTT_STATUS_INVALID_REQ:
+ return RttStatus::INVALID_REQ;
+ case legacy_hal::RTT_STATUS_NO_WIFI:
+ return RttStatus::NO_WIFI;
+ case legacy_hal::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE:
+ return RttStatus::FAIL_FTM_PARAM_OVERRIDE;
+ case legacy_hal::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE:
+ return RttStatus::FAILURE; // TODO: add HIDL enumeration
+ case legacy_hal::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED:
+ return RttStatus::FAILURE; // TODO: add HIDL enumeration
+ };
+ CHECK(false) << "Unknown legacy status: " << status;
+}
+
+bool convertHidlWifiChannelInfoToLegacy(const WifiChannelInfo& hidl_info,
+ legacy_hal::wifi_channel_info* legacy_info) {
+ if (!legacy_info) {
+ return false;
+ }
+ *legacy_info = {};
+ legacy_info->width = convertHidlWifiChannelWidthToLegacy(hidl_info.width);
+ legacy_info->center_freq = hidl_info.centerFreq;
+ legacy_info->center_freq0 = hidl_info.centerFreq0;
+ legacy_info->center_freq1 = hidl_info.centerFreq1;
+ return true;
+}
+
+bool convertLegacyWifiChannelInfoToHidl(const legacy_hal::wifi_channel_info& legacy_info,
+ WifiChannelInfo* hidl_info) {
+ if (!hidl_info) {
+ return false;
+ }
+ *hidl_info = {};
+ hidl_info->width = convertLegacyWifiChannelWidthToHidl(legacy_info.width);
+ hidl_info->centerFreq = legacy_info.center_freq;
+ hidl_info->centerFreq0 = legacy_info.center_freq0;
+ hidl_info->centerFreq1 = legacy_info.center_freq1;
+ return true;
+}
+
+bool convertHidlRttConfigToLegacy(const V1_6::RttConfig& hidl_config,
+ legacy_hal::wifi_rtt_config* legacy_config) {
+ if (!legacy_config) {
+ return false;
+ }
+ *legacy_config = {};
+ CHECK(hidl_config.addr.size() == sizeof(legacy_config->addr));
+ memcpy(legacy_config->addr, hidl_config.addr.data(), hidl_config.addr.size());
+ legacy_config->type = convertHidlRttTypeToLegacy(hidl_config.type);
+ legacy_config->peer = convertHidlRttPeerTypeToLegacy(hidl_config.peer);
+ if (!convertHidlWifiChannelInfoToLegacy(hidl_config.channel, &legacy_config->channel)) {
+ return false;
+ }
+ legacy_config->burst_period = hidl_config.burstPeriod;
+ legacy_config->num_burst = hidl_config.numBurst;
+ legacy_config->num_frames_per_burst = hidl_config.numFramesPerBurst;
+ legacy_config->num_retries_per_rtt_frame = hidl_config.numRetriesPerRttFrame;
+ legacy_config->num_retries_per_ftmr = hidl_config.numRetriesPerFtmr;
+ legacy_config->LCI_request = hidl_config.mustRequestLci;
+ legacy_config->LCR_request = hidl_config.mustRequestLcr;
+ legacy_config->burst_duration = hidl_config.burstDuration;
+ legacy_config->preamble = convertHidlRttPreambleToLegacy(hidl_config.preamble);
+ legacy_config->bw = convertHidlRttBwToLegacy(hidl_config.bw);
+ return true;
+}
+
+bool convertHidlVectorOfRttConfigToLegacy(
+ const std::vector<V1_6::RttConfig>& hidl_configs,
+ std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) {
+ if (!legacy_configs) {
+ return false;
+ }
+ *legacy_configs = {};
+ for (const auto& hidl_config : hidl_configs) {
+ legacy_hal::wifi_rtt_config legacy_config;
+ if (!convertHidlRttConfigToLegacy(hidl_config, &legacy_config)) {
+ return false;
+ }
+ legacy_configs->push_back(legacy_config);
+ }
+ return true;
+}
+
+bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info,
+ legacy_hal::wifi_lci_information* legacy_info) {
+ if (!legacy_info) {
+ return false;
+ }
+ *legacy_info = {};
+ legacy_info->latitude = hidl_info.latitude;
+ legacy_info->longitude = hidl_info.longitude;
+ legacy_info->altitude = hidl_info.altitude;
+ legacy_info->latitude_unc = hidl_info.latitudeUnc;
+ legacy_info->longitude_unc = hidl_info.longitudeUnc;
+ legacy_info->altitude_unc = hidl_info.altitudeUnc;
+ legacy_info->motion_pattern = convertHidlRttMotionPatternToLegacy(hidl_info.motionPattern);
+ legacy_info->floor = hidl_info.floor;
+ legacy_info->height_above_floor = hidl_info.heightAboveFloor;
+ legacy_info->height_unc = hidl_info.heightUnc;
+ return true;
+}
+
+bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info,
+ legacy_hal::wifi_lcr_information* legacy_info) {
+ if (!legacy_info) {
+ return false;
+ }
+ *legacy_info = {};
+ CHECK(hidl_info.countryCode.size() == sizeof(legacy_info->country_code));
+ memcpy(legacy_info->country_code, hidl_info.countryCode.data(), hidl_info.countryCode.size());
+ if (hidl_info.civicInfo.size() > sizeof(legacy_info->civic_info)) {
+ return false;
+ }
+ legacy_info->length = hidl_info.civicInfo.size();
+ memcpy(legacy_info->civic_info, hidl_info.civicInfo.c_str(), hidl_info.civicInfo.size());
+ return true;
+}
+
+bool convertHidlRttResponderToLegacy(const V1_6::RttResponder& hidl_responder,
+ legacy_hal::wifi_rtt_responder* legacy_responder) {
+ if (!legacy_responder) {
+ return false;
+ }
+ *legacy_responder = {};
+ if (!convertHidlWifiChannelInfoToLegacy(hidl_responder.channel, &legacy_responder->channel)) {
+ return false;
+ }
+ legacy_responder->preamble = convertHidlRttPreambleToLegacy(hidl_responder.preamble);
+ return true;
+}
+
+bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
+ V1_6::RttResponder* hidl_responder) {
+ if (!hidl_responder) {
+ return false;
+ }
+ *hidl_responder = {};
+ if (!convertLegacyWifiChannelInfoToHidl(legacy_responder.channel, &hidl_responder->channel)) {
+ return false;
+ }
+ hidl_responder->preamble = convertLegacyRttPreambleToHidl(legacy_responder.preamble);
+ return true;
+}
+
+bool convertLegacyRttCapabilitiesToHidl(
+ const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
+ V1_6::RttCapabilities* hidl_capabilities) {
+ if (!hidl_capabilities) {
+ return false;
+ }
+ *hidl_capabilities = {};
+ hidl_capabilities->rttOneSidedSupported = legacy_capabilities.rtt_one_sided_supported;
+ hidl_capabilities->rttFtmSupported = legacy_capabilities.rtt_ftm_supported;
+ hidl_capabilities->lciSupported = legacy_capabilities.lci_support;
+ hidl_capabilities->lcrSupported = legacy_capabilities.lcr_support;
+ hidl_capabilities->responderSupported = legacy_capabilities.responder_supported;
+ hidl_capabilities->preambleSupport = 0;
+ for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT,
+ legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE,
+ legacy_hal::WIFI_RTT_PREAMBLE_EHT}) {
+ if (legacy_capabilities.preamble_support & flag) {
+ hidl_capabilities->preambleSupport |=
+ static_cast<std::underlying_type<V1_6::RttPreamble>::type>(
+ convertLegacyRttPreambleToHidl(flag));
+ }
+ }
+ hidl_capabilities->bwSupport = 0;
+ for (const auto flag :
+ {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20,
+ legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160,
+ legacy_hal::WIFI_RTT_BW_320}) {
+ if (legacy_capabilities.bw_support & flag) {
+ hidl_capabilities->bwSupport |=
+ static_cast<std::underlying_type<RttBw>::type>(convertLegacyRttBwToHidl(flag));
+ }
+ }
+ hidl_capabilities->mcVersion = legacy_capabilities.mc_version;
+ return true;
+}
+
+bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate,
+ V1_6::WifiRateInfo* hidl_rate) {
+ if (!hidl_rate) {
+ return false;
+ }
+ *hidl_rate = {};
+ hidl_rate->preamble = convertLegacyWifiRatePreambleToHidl(legacy_rate.preamble);
+ hidl_rate->nss = convertLegacyWifiRateNssToHidl(legacy_rate.nss);
+ hidl_rate->bw = convertLegacyWifiChannelWidthToHidl(
+ static_cast<legacy_hal::wifi_channel_width>(legacy_rate.bw));
+ hidl_rate->rateMcsIdx = legacy_rate.rateMcsIdx;
+ hidl_rate->bitRateInKbps = legacy_rate.bitrate;
+ return true;
+}
+
+bool convertLegacyRttResultToHidl(const legacy_hal::wifi_rtt_result& legacy_result,
+ V1_6::RttResult* hidl_result) {
+ if (!hidl_result) {
+ return false;
+ }
+ *hidl_result = {};
+ CHECK(sizeof(legacy_result.addr) == hidl_result->addr.size());
+ memcpy(hidl_result->addr.data(), legacy_result.addr, sizeof(legacy_result.addr));
+ hidl_result->burstNum = legacy_result.burst_num;
+ hidl_result->measurementNumber = legacy_result.measurement_number;
+ hidl_result->successNumber = legacy_result.success_number;
+ hidl_result->numberPerBurstPeer = legacy_result.number_per_burst_peer;
+ hidl_result->status = convertLegacyRttStatusToHidl(legacy_result.status);
+ hidl_result->retryAfterDuration = legacy_result.retry_after_duration;
+ hidl_result->type = convertLegacyRttTypeToHidl(legacy_result.type);
+ hidl_result->rssi = legacy_result.rssi;
+ hidl_result->rssiSpread = legacy_result.rssi_spread;
+ if (!convertLegacyWifiRateInfoToHidl(legacy_result.tx_rate, &hidl_result->txRate)) {
+ return false;
+ }
+ if (!convertLegacyWifiRateInfoToHidl(legacy_result.rx_rate, &hidl_result->rxRate)) {
+ return false;
+ }
+ hidl_result->rtt = legacy_result.rtt;
+ hidl_result->rttSd = legacy_result.rtt_sd;
+ hidl_result->rttSpread = legacy_result.rtt_spread;
+ hidl_result->distanceInMm = legacy_result.distance_mm;
+ hidl_result->distanceSdInMm = legacy_result.distance_sd_mm;
+ hidl_result->distanceSpreadInMm = legacy_result.distance_spread_mm;
+ hidl_result->timeStampInUs = legacy_result.ts;
+ hidl_result->burstDurationInMs = legacy_result.burst_duration;
+ hidl_result->negotiatedBurstNum = legacy_result.negotiated_burst_num;
+ if (legacy_result.LCI && !convertLegacyIeToHidl(*legacy_result.LCI, &hidl_result->lci)) {
+ return false;
+ }
+ if (legacy_result.LCR && !convertLegacyIeToHidl(*legacy_result.LCR, &hidl_result->lcr)) {
+ return false;
+ }
+ return true;
+}
+
+bool convertLegacyVectorOfRttResultToHidl(
+ const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
+ std::vector<V1_6::RttResult>* hidl_results) {
+ if (!hidl_results) {
+ return false;
+ }
+ *hidl_results = {};
+ for (const auto legacy_result : legacy_results) {
+ V1_6::RttResult hidl_result;
+ if (!convertLegacyRttResultToHidl(*legacy_result, &hidl_result)) {
+ return false;
+ }
+ hidl_results->push_back(hidl_result);
+ }
+ return true;
+}
+
+legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type) {
+ switch (hidl_interface_type) {
+ case IfaceType::STA:
+ return legacy_hal::WIFI_INTERFACE_TYPE_STA;
+ case IfaceType::AP:
+ return legacy_hal::WIFI_INTERFACE_TYPE_AP;
+ case IfaceType::P2P:
+ return legacy_hal::WIFI_INTERFACE_TYPE_P2P;
+ case IfaceType::NAN:
+ return legacy_hal::WIFI_INTERFACE_TYPE_NAN;
+ }
+ CHECK(false);
+}
+
+legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
+ V1_5::IWifiChip::MultiStaUseCase use_case) {
+ switch (use_case) {
+ case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY:
+ return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+ case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED:
+ return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
+ }
+ CHECK(false);
+}
+
+bool convertHidlCoexUnsafeChannelToLegacy(
+ const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
+ legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) {
+ if (!legacy_unsafe_channel) {
+ return false;
+ }
+ *legacy_unsafe_channel = {};
+ switch (hidl_unsafe_channel.band) {
+ case V1_5::WifiBand::BAND_24GHZ:
+ legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND;
+ break;
+ case V1_5::WifiBand::BAND_5GHZ:
+ legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND;
+ break;
+ default:
+ return false;
+ };
+ legacy_unsafe_channel->channel = hidl_unsafe_channel.channel;
+ legacy_unsafe_channel->power_cap_dbm = hidl_unsafe_channel.powerCapDbm;
+ return true;
+}
+
+bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
+ const std::vector<V1_5::IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
+ std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) {
+ if (!legacy_unsafe_channels) {
+ return false;
+ }
+ *legacy_unsafe_channels = {};
+ for (const auto& hidl_unsafe_channel : hidl_unsafe_channels) {
+ legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel;
+ if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy(hidl_unsafe_channel,
+ &legacy_unsafe_channel)) {
+ return false;
+ }
+ legacy_unsafe_channels->push_back(legacy_unsafe_channel);
+ }
+ return true;
+}
+
+V1_6::WifiAntennaMode convertLegacyAntennaConfigurationToHidl(uint32_t antenna_cfg) {
+ switch (antenna_cfg) {
+ case legacy_hal::WIFI_ANTENNA_1X1:
+ return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_1X1;
+ case legacy_hal::WIFI_ANTENNA_2X2:
+ return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_2X2;
+ case legacy_hal::WIFI_ANTENNA_3X3:
+ return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_3X3;
+ case legacy_hal::WIFI_ANTENNA_4X4:
+ return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_4X4;
+ default:
+ return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_UNSPECIFIED;
+ }
+}
+
+bool convertLegacyWifiRadioConfigurationToHidl(
+ legacy_hal::wifi_radio_configuration* radio_configuration,
+ V1_6::WifiRadioConfiguration* hidl_radio_configuration) {
+ if (!hidl_radio_configuration) {
+ return false;
+ }
+ *hidl_radio_configuration = {};
+ hidl_radio_configuration->bandInfo =
+ hidl_struct_util::convertLegacyMacBandToHidlWifiBand(radio_configuration->band);
+ if (hidl_radio_configuration->bandInfo == V1_5::WifiBand::BAND_UNSPECIFIED) {
+ LOG(ERROR) << "Unspecified band";
+ return false;
+ }
+ hidl_radio_configuration->antennaMode =
+ hidl_struct_util::convertLegacyAntennaConfigurationToHidl(
+ radio_configuration->antenna_cfg);
+ return true;
+}
+
+bool convertLegacyRadioCombinationsMatrixToHidl(
+ legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
+ WifiRadioCombinationMatrix* hidl_matrix) {
+ if (!hidl_matrix || !legacy_matrix) {
+ return false;
+ }
+ *hidl_matrix = {};
+
+ int num_combinations = legacy_matrix->num_radio_combinations;
+ std::vector<V1_6::WifiRadioCombination> radio_combinations_vec;
+ if (!num_combinations) {
+ LOG(ERROR) << "zero radio combinations";
+ return false;
+ }
+ wifi_radio_combination* l_radio_combinations_ptr = legacy_matrix->radio_combinations;
+ for (int i = 0; i < num_combinations; i++) {
+ int num_configurations = l_radio_combinations_ptr->num_radio_configurations;
+ WifiRadioCombination radioCombination;
+ std::vector<V1_6::WifiRadioConfiguration> radio_configurations_vec;
+ if (!num_configurations) {
+ LOG(ERROR) << "zero radio configurations";
+ return false;
+ }
+ for (int j = 0; j < num_configurations; j++) {
+ WifiRadioConfiguration radioConfiguration;
+ wifi_radio_configuration* l_radio_configurations_ptr =
+ &l_radio_combinations_ptr->radio_configurations[j];
+ if (!hidl_struct_util::convertLegacyWifiRadioConfigurationToHidl(
+ l_radio_configurations_ptr, &radioConfiguration)) {
+ LOG(ERROR) << "Error converting wifi radio configuration";
+ return false;
+ }
+ radio_configurations_vec.push_back(radioConfiguration);
+ }
+ radioCombination.radioConfigurations = radio_configurations_vec;
+ radio_combinations_vec.push_back(radioCombination);
+ l_radio_combinations_ptr =
+ (wifi_radio_combination*)((u8*)l_radio_combinations_ptr +
+ sizeof(wifi_radio_combination) +
+ (sizeof(wifi_radio_configuration) * num_configurations));
+ }
+ hidl_matrix->radioCombinations = radio_combinations_vec;
+ return true;
+}
+
+} // namespace hidl_struct_util
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hidl_struct_util.h b/wifi/wifi_legacy_service/1.0-legacy/hidl_struct_util.h
new file mode 100644
index 0000000..2d4a5f1
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hidl_struct_util.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HIDL_STRUCT_UTIL_H_
+#define HIDL_STRUCT_UTIL_H_
+
+#include <vector>
+
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.0/types.h>
+#include <android/hardware/wifi/1.2/types.h>
+#include <android/hardware/wifi/1.3/types.h>
+#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
+#include <android/hardware/wifi/1.4/types.h>
+#include <android/hardware/wifi/1.6/IWifiChip.h>
+#include <android/hardware/wifi/1.6/types.h>
+
+#include "wifi_legacy_hal.h"
+
+/**
+ * This file contains a bunch of functions to convert structs from the legacy
+ * HAL to HIDL and vice versa.
+ * TODO(b/32093047): Add unit tests for these conversion methods in the VTS test
+ * suite.
+ */
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace hidl_struct_util {
+using namespace android::hardware::wifi::V1_0;
+
+// Chip conversion methods.
+bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set,
+ uint32_t legacy_logger_feature_set,
+ uint32_t* hidl_caps);
+bool convertLegacyDebugRingBufferStatusToHidl(
+ const legacy_hal::wifi_ring_buffer_status& legacy_status,
+ WifiDebugRingBufferStatus* hidl_status);
+bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
+ const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
+ std::vector<WifiDebugRingBufferStatus>* hidl_status_vec);
+bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats,
+ WifiDebugHostWakeReasonStats* hidl_stats);
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
+ V1_1::IWifiChip::TxPowerScenario hidl_scenario);
+legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy(
+ V1_3::IWifiChip::LatencyMode hidl_latency_mode);
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2(
+ V1_2::IWifiChip::TxPowerScenario hidl_scenario);
+bool convertLegacyWifiMacInfosToHidl(
+ const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+ std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos);
+legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type);
+legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
+ V1_5::IWifiChip::MultiStaUseCase use_case);
+bool convertHidlCoexUnsafeChannelToLegacy(
+ const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
+ legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel);
+bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
+ const std::vector<V1_5::IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
+ std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);
+bool convertLegacyRadioCombinationsMatrixToHidl(
+ legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
+ V1_6::WifiRadioCombinationMatrix* hidl_matrix);
+V1_5::WifiBand convertLegacyMacBandToHidlWifiBand(uint32_t band);
+V1_6::WifiAntennaMode convertLegacyAntennaConfigurationToHidl(uint32_t antenna_cfg);
+
+// STA iface conversion methods.
+bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set,
+ uint32_t legacy_logger_feature_set,
+ uint32_t* hidl_caps);
+bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
+ StaApfPacketFilterCapabilities* hidl_caps);
+bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
+ StaBackgroundScanCapabilities* hidl_caps);
+legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band);
+bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params,
+ legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
+// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11
+// Information Elements (IEs)
+bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
+ bool has_ie_data, StaScanResult* hidl_scan_result);
+// |cached_results| is assumed to not include IEs.
+bool convertLegacyVectorOfCachedGscanResultsToHidl(
+ const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
+ std::vector<StaScanData>* hidl_scan_datas);
+bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats,
+ V1_6::StaLinkLayerStats* hidl_stats);
+bool convertLegacyRoamingCapabilitiesToHidl(
+ const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+ StaRoamingCapabilities* hidl_caps);
+bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config,
+ legacy_hal::wifi_roaming_config* legacy_config);
+legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state);
+bool convertLegacyVectorOfDebugTxPacketFateToHidl(
+ const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
+ std::vector<WifiDebugTxPacketFateReport>* hidl_fates);
+bool convertLegacyVectorOfDebugRxPacketFateToHidl(
+ const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
+ std::vector<WifiDebugRxPacketFateReport>* hidl_fates);
+
+// NAN iface conversion methods.
+void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+ WifiNanStatus* wifiNanStatus);
+bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request,
+ legacy_hal::NanEnableRequest* legacy_request);
+bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request,
+ legacy_hal::NanConfigRequest* legacy_request);
+bool convertHidlNanEnableRequest_1_6ToLegacy(
+ const V1_4::NanEnableRequest& hidl_request1,
+ const V1_6::NanConfigRequestSupplemental& hidl_request2,
+ legacy_hal::NanEnableRequest* legacy_request);
+bool convertHidlNanConfigRequest_1_6ToLegacy(
+ const V1_4::NanConfigRequest& hidl_request1,
+ const V1_6::NanConfigRequestSupplemental& hidl_request2,
+ legacy_hal::NanConfigRequest* legacy_request);
+bool convertHidlNanPublishRequestToLegacy(const V1_6::NanPublishRequest& hidl_request,
+ legacy_hal::NanPublishRequest* legacy_request);
+bool convertHidlNanSubscribeRequestToLegacy(const V1_0::NanSubscribeRequest& hidl_request,
+ legacy_hal::NanSubscribeRequest* legacy_request);
+bool convertHidlNanTransmitFollowupRequestToLegacy(
+ const NanTransmitFollowupRequest& hidl_request,
+ legacy_hal::NanTransmitFollowupRequest* legacy_request);
+bool convertHidlNanDataPathInitiatorRequestToLegacy(
+ const V1_0::NanInitiateDataPathRequest& hidl_request,
+ legacy_hal::NanDataPathInitiatorRequest* legacy_request);
+bool convertHidlNanDataPathIndicationResponseToLegacy(
+ const V1_0::NanRespondToDataPathIndicationRequest& hidl_response,
+ legacy_hal::NanDataPathIndicationResponse* legacy_response);
+bool convertHidlNanDataPathInitiatorRequest_1_6ToLegacy(
+ const V1_6::NanInitiateDataPathRequest& hidl_request,
+ legacy_hal::NanDataPathInitiatorRequest* legacy_request);
+bool convertHidlNanDataPathIndicationResponse_1_6ToLegacy(
+ const V1_6::NanRespondToDataPathIndicationRequest& hidl_response,
+ legacy_hal::NanDataPathIndicationResponse* legacy_response);
+
+bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response,
+ WifiNanStatus* wifiNanStatus);
+bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response,
+ V1_6::NanCapabilities* hidl_response);
+bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind,
+ V1_6::NanMatchInd* hidl_ind);
+bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind,
+ NanFollowupReceivedInd* hidl_ind);
+bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
+ NanDataPathRequestInd* hidl_ind);
+bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
+ V1_6::NanDataPathConfirmInd* hidl_ind);
+bool convertLegacyNanDataPathScheduleUpdateIndToHidl(
+ const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
+ V1_6::NanDataPathScheduleUpdateInd* hidl_ind);
+
+// RTT controller conversion methods.
+bool convertHidlVectorOfRttConfigToLegacy(const std::vector<V1_6::RttConfig>& hidl_configs,
+ std::vector<legacy_hal::wifi_rtt_config>* legacy_configs);
+bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info,
+ legacy_hal::wifi_lci_information* legacy_info);
+bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info,
+ legacy_hal::wifi_lcr_information* legacy_info);
+bool convertHidlRttResponderToLegacy(const V1_6::RttResponder& hidl_responder,
+ legacy_hal::wifi_rtt_responder* legacy_responder);
+bool convertHidlWifiChannelInfoToLegacy(const V1_6::WifiChannelInfo& hidl_info,
+ legacy_hal::wifi_channel_info* legacy_info);
+bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
+ V1_6::RttResponder* hidl_responder);
+bool convertLegacyRttCapabilitiesToHidl(
+ const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
+ V1_6::RttCapabilities* hidl_capabilities);
+bool convertLegacyVectorOfRttResultToHidl(
+ const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
+ std::vector<V1_6::RttResult>* hidl_results);
+uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band);
+uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask);
+uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask);
+bool convertLegacyWifiUsableChannelsToHidl(
+ const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+ std::vector<V1_6::WifiUsableChannel>* hidl_usable_channels);
+bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+ V1_6::StaPeerInfo* hidl_peer_info_stats);
+bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate,
+ V1_6::WifiRateInfo* hidl_rate);
+} // namespace hidl_struct_util
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // HIDL_STRUCT_UTIL_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hidl_sync_util.cpp b/wifi/wifi_legacy_service/1.0-legacy/hidl_sync_util.cpp
new file mode 100644
index 0000000..358d95e
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hidl_sync_util.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hidl_sync_util.h"
+
+namespace {
+std::recursive_mutex g_mutex;
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace hidl_sync_util {
+
+std::unique_lock<std::recursive_mutex> acquireGlobalLock() {
+ return std::unique_lock<std::recursive_mutex>{g_mutex};
+}
+
+} // namespace hidl_sync_util
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/hidl_sync_util.h b/wifi/wifi_legacy_service/1.0-legacy/hidl_sync_util.h
new file mode 100644
index 0000000..2c1c37b
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/hidl_sync_util.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HIDL_SYNC_UTIL_H_
+#define HIDL_SYNC_UTIL_H_
+
+#include <mutex>
+
+// Utility that provides a global lock to synchronize access between
+// the HIDL thread and the legacy HAL's event loop.
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace hidl_sync_util {
+std::unique_lock<std::recursive_mutex> acquireGlobalLock();
+} // namespace hidl_sync_util
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+#endif // HIDL_SYNC_UTIL_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/ringbuffer.cpp b/wifi/wifi_legacy_service/1.0-legacy/ringbuffer.cpp
new file mode 100644
index 0000000..981bf7b
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/ringbuffer.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include "ringbuffer.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+
+Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {}
+
+enum Ringbuffer::AppendStatus Ringbuffer::append(const std::vector<uint8_t>& input) {
+ if (input.size() == 0) {
+ return AppendStatus::FAIL_IP_BUFFER_ZERO;
+ }
+ if (input.size() > maxSize_) {
+ LOG(INFO) << "Oversized message of " << input.size() << " bytes is dropped";
+ return AppendStatus::FAIL_IP_BUFFER_EXCEEDED_MAXSIZE;
+ }
+ data_.push_back(input);
+ size_ += input.size() * sizeof(input[0]);
+ while (size_ > maxSize_) {
+ if (data_.front().size() <= 0 || data_.front().size() > maxSize_) {
+ LOG(ERROR) << "First buffer in the ring buffer is Invalid. Size: "
+ << data_.front().size();
+ return AppendStatus::FAIL_RING_BUFFER_CORRUPTED;
+ }
+ size_ -= data_.front().size() * sizeof(data_.front()[0]);
+ data_.pop_front();
+ }
+ return AppendStatus::SUCCESS;
+}
+
+const std::list<std::vector<uint8_t>>& Ringbuffer::getData() const {
+ return data_;
+}
+
+void Ringbuffer::clear() {
+ data_.clear();
+ size_ = 0;
+}
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/ringbuffer.h b/wifi/wifi_legacy_service/1.0-legacy/ringbuffer.h
new file mode 100644
index 0000000..c6a1e4c
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/ringbuffer.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RINGBUFFER_H_
+#define RINGBUFFER_H_
+
+#include <list>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+
+/**
+ * Ringbuffer object used to store debug data.
+ */
+class Ringbuffer {
+ public:
+ // Error codes for the append ring buffer operation
+ enum AppendStatus {
+ SUCCESS,
+ FAIL_GENERIC,
+ FAIL_IP_BUFFER_ZERO,
+ FAIL_IP_BUFFER_EXCEEDED_MAXSIZE,
+ FAIL_RING_BUFFER_CORRUPTED
+ };
+ explicit Ringbuffer(size_t maxSize);
+
+ // Appends the data buffer and deletes from the front until buffer is
+ // within |maxSize_|.
+ enum AppendStatus append(const std::vector<uint8_t>& input);
+ const std::list<std::vector<uint8_t>>& getData() const;
+ void clear();
+
+ private:
+ std::list<std::vector<uint8_t>> data_;
+ size_t size_;
+ size_t maxSize_;
+};
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // RINGBUFFER_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/service.cpp b/wifi/wifi_legacy_service/1.0-legacy/service.cpp
new file mode 100644
index 0000000..c874d8b
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/service.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <hidl/HidlLazyUtils.h>
+#include <hidl/HidlTransportSupport.h>
+#include <signal.h>
+#include <utils/Looper.h>
+#include <utils/StrongPointer.h>
+
+#include "wifi.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_legacy_hal_factory.h"
+#include "wifi_mode_controller.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::LazyServiceRegistrar;
+using android::hardware::wifi::V1_6::implementation::feature_flags::WifiFeatureFlags;
+using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHal;
+using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHalFactory;
+using android::hardware::wifi::V1_6::implementation::mode_controller::WifiModeController;
+
+#ifdef LAZY_SERVICE
+const bool kLazyService = true;
+#else
+const bool kLazyService = false;
+#endif
+
+int main(int /*argc*/, char** argv) {
+ signal(SIGPIPE, SIG_IGN);
+ android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
+ LOG(INFO) << "Wifi Hal is booting up...";
+
+ configureRpcThreadpool(1, true /* callerWillJoin */);
+
+ const auto iface_tool = std::make_shared<android::wifi_system::InterfaceTool>();
+ const auto legacy_hal_factory = std::make_shared<WifiLegacyHalFactory>(iface_tool);
+
+ // Setup hwbinder service
+ android::sp<android::hardware::wifi::V1_6::IWifi> service =
+ new android::hardware::wifi::V1_6::implementation::Wifi(
+ iface_tool, legacy_hal_factory, std::make_shared<WifiModeController>(),
+ std::make_shared<WifiFeatureFlags>());
+ if (kLazyService) {
+ auto registrar = LazyServiceRegistrar::getInstance();
+ CHECK_EQ(registrar.registerService(service), android::NO_ERROR)
+ << "Failed to register wifi HAL";
+ } else {
+ CHECK_EQ(service->registerAsService(), android::NO_ERROR) << "Failed to register wifi HAL";
+ }
+
+ joinRpcThreadpool();
+
+ LOG(INFO) << "Wifi Hal is terminating...";
+ return 0;
+}
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi.cpp
new file mode 100644
index 0000000..c302ce2
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include "hidl_return_util.h"
+#include "wifi.h"
+#include "wifi_status_util.h"
+
+namespace {
+// Starting Chip ID, will be assigned to primary chip
+static constexpr android::hardware::wifi::V1_0::ChipId kPrimaryChipId = 0;
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+using hidl_return_util::validateAndCallWithLock;
+
+Wifi::Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
+ const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
+ const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
+ : iface_tool_(iface_tool),
+ legacy_hal_factory_(legacy_hal_factory),
+ mode_controller_(mode_controller),
+ feature_flags_(feature_flags),
+ run_state_(RunState::STOPPED) {}
+
+bool Wifi::isValid() {
+ // This object is always valid.
+ return true;
+}
+
+Return<void> Wifi::registerEventCallback(const sp<V1_0::IWifiEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
+ &Wifi::registerEventCallbackInternal, hidl_status_cb, event_callback);
+}
+
+Return<void> Wifi::registerEventCallback_1_5(const sp<V1_5::IWifiEventCallback>& event_callback,
+ registerEventCallback_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
+ &Wifi::registerEventCallbackInternal_1_5, hidl_status_cb,
+ event_callback);
+}
+
+Return<bool> Wifi::isStarted() {
+ return run_state_ != RunState::STOPPED;
+}
+
+Return<void> Wifi::start(start_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal,
+ hidl_status_cb);
+}
+
+Return<void> Wifi::stop(stop_cb hidl_status_cb) {
+ return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal,
+ hidl_status_cb);
+}
+
+Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipIdsInternal,
+ hidl_status_cb);
+}
+
+Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipInternal,
+ hidl_status_cb, chip_id);
+}
+
+Return<void> Wifi::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
+ LOG(INFO) << "-----------Debug is called----------------";
+ if (chips_.size() == 0) {
+ return Void();
+ }
+
+ for (sp<WifiChip> chip : chips_) {
+ if (!chip.get()) continue;
+
+ chip->debug(handle, {});
+ }
+ return Void();
+}
+
+WifiStatus Wifi::registerEventCallbackInternal(
+ const sp<V1_0::IWifiEventCallback>& event_callback __unused) {
+ // Deprecated support for this callback.
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus Wifi::registerEventCallbackInternal_1_5(
+ const sp<V1_5::IWifiEventCallback>& event_callback) {
+ if (!event_cb_handler_.addCallback(event_callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus Wifi::startInternal() {
+ if (run_state_ == RunState::STARTED) {
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+ } else if (run_state_ == RunState::STOPPING) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
+ }
+ WifiStatus wifi_status = initializeModeControllerAndLegacyHal();
+ if (wifi_status.code == WifiStatusCode::SUCCESS) {
+ // Register the callback for subsystem restart
+ const auto& on_subsystem_restart_callback = [this](const std::string& error) {
+ WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ LOG(INFO) << "Attempting to invoke onSubsystemRestart "
+ "callback";
+ if (!callback->onSubsystemRestart(wifi_status).isOk()) {
+ LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
+ } else {
+ LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
+ "callback";
+ }
+ }
+ };
+
+ // Create the chip instance once the HAL is started.
+ android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId;
+ for (auto& hal : legacy_hals_) {
+ chips_.push_back(
+ new WifiChip(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
+ std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
+ feature_flags_, on_subsystem_restart_callback));
+ chipId++;
+ }
+ run_state_ = RunState::STARTED;
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onStart().isOk()) {
+ LOG(ERROR) << "Failed to invoke onStart callback";
+ };
+ }
+ LOG(INFO) << "Wifi HAL started";
+ } else {
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onFailure(wifi_status).isOk()) {
+ LOG(ERROR) << "Failed to invoke onFailure callback";
+ }
+ }
+ LOG(ERROR) << "Wifi HAL start failed";
+ // Clear the event callback objects since the HAL start failed.
+ event_cb_handler_.invalidate();
+ }
+ return wifi_status;
+}
+
+WifiStatus Wifi::stopInternal(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
+ if (run_state_ == RunState::STOPPED) {
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+ } else if (run_state_ == RunState::STOPPING) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
+ }
+ // Clear the chip object and its child objects since the HAL is now
+ // stopped.
+ for (auto& chip : chips_) {
+ if (chip.get()) {
+ chip->invalidate();
+ chip.clear();
+ }
+ }
+ chips_.clear();
+ WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock);
+ if (wifi_status.code == WifiStatusCode::SUCCESS) {
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onStop().isOk()) {
+ LOG(ERROR) << "Failed to invoke onStop callback";
+ };
+ }
+ LOG(INFO) << "Wifi HAL stopped";
+ } else {
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onFailure(wifi_status).isOk()) {
+ LOG(ERROR) << "Failed to invoke onFailure callback";
+ }
+ }
+ LOG(ERROR) << "Wifi HAL stop failed";
+ }
+ // Clear the event callback objects since the HAL is now stopped.
+ event_cb_handler_.invalidate();
+ return wifi_status;
+}
+
+std::pair<WifiStatus, std::vector<ChipId>> Wifi::getChipIdsInternal() {
+ std::vector<ChipId> chip_ids;
+
+ for (auto& chip : chips_) {
+ ChipId chip_id = getChipIdFromWifiChip(chip);
+ if (chip_id != UINT32_MAX) chip_ids.emplace_back(chip_id);
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)};
+}
+
+std::pair<WifiStatus, sp<V1_4::IWifiChip>> Wifi::getChipInternal(ChipId chip_id) {
+ for (auto& chip : chips_) {
+ ChipId cand_id = getChipIdFromWifiChip(chip);
+ if ((cand_id != UINT32_MAX) && (cand_id == chip_id))
+ return {createWifiStatus(WifiStatusCode::SUCCESS), chip};
+ }
+
+ return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+}
+
+WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
+ if (!mode_controller_->initialize()) {
+ LOG(ERROR) << "Failed to initialize firmware mode controller";
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+
+ legacy_hals_ = legacy_hal_factory_->getHals();
+ if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ int index = 0; // for failure log
+ for (auto& hal : legacy_hals_) {
+ legacy_hal::wifi_error legacy_status = hal->initialize();
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ // Currently WifiLegacyHal::initialize does not allocate extra mem,
+ // only initializes the function table. If this changes, need to
+ // implement WifiLegacyHal::deinitialize and deinitalize the
+ // HALs already initialized
+ LOG(ERROR) << "Failed to initialize legacy HAL index: " << index
+ << " error: " << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ index++;
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
+ legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS;
+ int index = 0;
+
+ run_state_ = RunState::STOPPING;
+ for (auto& hal : legacy_hals_) {
+ legacy_hal::wifi_error tmp = hal->stop(lock, [&]() {});
+ if (tmp != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to stop legacy HAL index: " << index
+ << " error: " << legacyErrorToString(legacy_status);
+ legacy_status = tmp;
+ }
+ index++;
+ }
+ run_state_ = RunState::STOPPED;
+
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "One or more legacy HALs failed to stop";
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ if (!mode_controller_->deinitialize()) {
+ LOG(ERROR) << "Failed to deinitialize firmware mode controller";
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+ChipId Wifi::getChipIdFromWifiChip(sp<WifiChip>& chip) {
+ ChipId chip_id = UINT32_MAX;
+ if (chip.get()) {
+ chip->getId([&](WifiStatus status, uint32_t id) {
+ if (status.code == WifiStatusCode::SUCCESS) {
+ chip_id = id;
+ }
+ });
+ }
+
+ return chip_id;
+}
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi.h b/wifi/wifi_legacy_service/1.0-legacy/wifi.h
new file mode 100644
index 0000000..435358e
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_H_
+#define WIFI_H_
+
+// HACK: NAN is a macro defined in math.h, which can be included in various
+// headers. This wifi HAL uses an enum called NAN, which does not compile when
+// the macro is defined. Undefine NAN to work around it.
+#undef NAN
+#include <android/hardware/wifi/1.6/IWifi.h>
+
+#include <android-base/macros.h>
+#include <utils/Looper.h>
+#include <functional>
+
+#include "hidl_callback_util.h"
+#include "wifi_chip.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_legacy_hal_factory.h"
+#include "wifi_mode_controller.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+
+/**
+ * Root HIDL interface object used to control the Wifi HAL.
+ */
+class Wifi : public V1_6::IWifi {
+ public:
+ Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
+ const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
+ const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
+
+ bool isValid();
+
+ // HIDL methods exposed.
+ Return<void> registerEventCallback(const sp<V1_0::IWifiEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_5(const sp<V1_5::IWifiEventCallback>& event_callback,
+ registerEventCallback_1_5_cb hidl_status_cb) override;
+ Return<bool> isStarted() override;
+ Return<void> start(start_cb hidl_status_cb) override;
+ Return<void> stop(stop_cb hidl_status_cb) override;
+ Return<void> getChipIds(getChipIds_cb hidl_status_cb) override;
+ Return<void> getChip(ChipId chip_id, getChip_cb hidl_status_cb) override;
+ Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override;
+
+ private:
+ enum class RunState { STOPPED, STARTED, STOPPING };
+
+ // Corresponding worker functions for the HIDL methods.
+ WifiStatus registerEventCallbackInternal(
+ const sp<V1_0::IWifiEventCallback>& event_callback __unused);
+ WifiStatus registerEventCallbackInternal_1_5(
+ const sp<V1_5::IWifiEventCallback>& event_callback);
+ WifiStatus startInternal();
+ WifiStatus stopInternal(std::unique_lock<std::recursive_mutex>* lock);
+ std::pair<WifiStatus, std::vector<ChipId>> getChipIdsInternal();
+ std::pair<WifiStatus, sp<V1_4::IWifiChip>> getChipInternal(ChipId chip_id);
+
+ WifiStatus initializeModeControllerAndLegacyHal();
+ WifiStatus stopLegacyHalAndDeinitializeModeController(
+ std::unique_lock<std::recursive_mutex>* lock);
+ ChipId getChipIdFromWifiChip(sp<WifiChip>& chip);
+
+ // Instance is created in this root level |IWifi| HIDL interface object
+ // and shared with all the child HIDL interface objects.
+ std::shared_ptr<wifi_system::InterfaceTool> iface_tool_;
+ std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory_;
+ std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
+ std::vector<std::shared_ptr<legacy_hal::WifiLegacyHal>> legacy_hals_;
+ std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
+ RunState run_state_;
+ std::vector<sp<WifiChip>> chips_;
+ hidl_callback_util::HidlCallbackHandler<V1_5::IWifiEventCallback> event_cb_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(Wifi);
+};
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_ap_iface.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_ap_iface.cpp
new file mode 100644
index 0000000..b2957db
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_ap_iface.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include "hidl_return_util.h"
+#include "hidl_struct_util.h"
+#include "wifi_ap_iface.h"
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+
+WifiApIface::WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+ : ifname_(ifname),
+ instances_(instances),
+ legacy_hal_(legacy_hal),
+ iface_util_(iface_util),
+ is_valid_(true) {}
+
+void WifiApIface::invalidate() {
+ legacy_hal_.reset();
+ is_valid_ = false;
+}
+
+bool WifiApIface::isValid() {
+ return is_valid_;
+}
+
+std::string WifiApIface::getName() {
+ return ifname_;
+}
+
+void WifiApIface::removeInstance(std::string instance) {
+ instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end());
+}
+
+Return<void> WifiApIface::getName(getName_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::getNameInternal, hidl_status_cb);
+}
+
+Return<void> WifiApIface::getType(getType_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::getTypeInternal, hidl_status_cb);
+}
+
+Return<void> WifiApIface::setCountryCode(const hidl_array<int8_t, 2>& code,
+ setCountryCode_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::setCountryCodeInternal, hidl_status_cb, code);
+}
+
+Return<void> WifiApIface::getValidFrequenciesForBand(V1_0::WifiBand band,
+ getValidFrequenciesForBand_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::getValidFrequenciesForBandInternal, hidl_status_cb, band);
+}
+
+Return<void> WifiApIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
+ setMacAddress_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::setMacAddressInternal, hidl_status_cb, mac);
+}
+
+Return<void> WifiApIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::getFactoryMacAddressInternal, hidl_status_cb,
+ instances_.size() > 0 ? instances_[0] : ifname_);
+}
+
+Return<void> WifiApIface::resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::resetToFactoryMacAddressInternal, hidl_status_cb);
+}
+
+Return<void> WifiApIface::getBridgedInstances(getBridgedInstances_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::getBridgedInstancesInternal, hidl_status_cb);
+}
+
+std::pair<WifiStatus, std::string> WifiApIface::getNameInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
+}
+
+std::pair<WifiStatus, IfaceType> WifiApIface::getTypeInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::AP};
+}
+
+WifiStatus WifiApIface::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode(
+ instances_.size() > 0 ? instances_[0] : ifname_, code);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
+WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
+ static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch");
+ legacy_hal::wifi_error legacy_status;
+ std::vector<uint32_t> valid_frequencies;
+ std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand(
+ instances_.size() > 0 ? instances_[0] : ifname_,
+ hidl_struct_util::convertHidlWifiBandToLegacy(band));
+ return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
+}
+
+WifiStatus WifiApIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
+ // Support random MAC up to 2 interfaces
+ if (instances_.size() == 2) {
+ int rbyte = 1;
+ for (auto const& intf : instances_) {
+ std::array<uint8_t, 6> rmac = mac;
+ // reverse the bits to avoid collision
+ rmac[rbyte] = 0xff - rmac[rbyte];
+ if (!iface_util_.lock()->setMacAddress(intf, rmac)) {
+ LOG(INFO) << "Failed to set random mac address on " << intf;
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ rbyte++;
+ }
+ }
+ // It also needs to set mac address for bridged interface, otherwise the mac
+ // address of bridged interface will be changed after one of instance
+ // down.
+ if (!iface_util_.lock()->setMacAddress(ifname_, mac)) {
+ LOG(ERROR) << "Fail to config MAC for interface " << ifname_;
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, std::array<uint8_t, 6>> WifiApIface::getFactoryMacAddressInternal(
+ const std::string& ifaceName) {
+ std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifaceName);
+ if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
+}
+
+WifiStatus WifiApIface::resetToFactoryMacAddressInternal() {
+ std::pair<WifiStatus, std::array<uint8_t, 6>> getMacResult;
+ if (instances_.size() == 2) {
+ for (auto const& intf : instances_) {
+ getMacResult = getFactoryMacAddressInternal(intf);
+ LOG(DEBUG) << "Reset MAC to factory MAC on " << intf;
+ if (getMacResult.first.code != WifiStatusCode::SUCCESS ||
+ !iface_util_.lock()->setMacAddress(intf, getMacResult.second)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ }
+ // It needs to set mac address for bridged interface, otherwise the mac
+ // address of the bridged interface will be changed after one of the
+ // instance down. Thus we are generating a random MAC address for the
+ // bridged interface even if we got the request to reset the Factory
+ // MAC. Since the bridged interface is an internal interface for the
+ // operation of bpf and others networking operation.
+ if (!iface_util_.lock()->setMacAddress(ifname_,
+ iface_util_.lock()->createRandomMacAddress())) {
+ LOG(ERROR) << "Fail to config MAC for bridged interface " << ifname_;
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ } else {
+ getMacResult = getFactoryMacAddressInternal(ifname_);
+ LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_;
+ if (getMacResult.first.code != WifiStatusCode::SUCCESS ||
+ !iface_util_.lock()->setMacAddress(ifname_, getMacResult.second)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, std::vector<hidl_string>> WifiApIface::getBridgedInstancesInternal() {
+ std::vector<hidl_string> instances;
+ for (const auto& instance_name : instances_) {
+ instances.push_back(instance_name);
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), instances};
+}
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_ap_iface.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_ap_iface.h
new file mode 100644
index 0000000..d1c0642
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_ap_iface.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_AP_IFACE_H_
+#define WIFI_AP_IFACE_H_
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.5/IWifiApIface.h>
+
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+
+/**
+ * HIDL interface object used to control a AP Iface instance.
+ */
+class WifiApIface : public V1_5::IWifiApIface {
+ public:
+ WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::string getName();
+ void removeInstance(std::string instance);
+
+ // HIDL methods exposed.
+ Return<void> getName(getName_cb hidl_status_cb) override;
+ Return<void> getType(getType_cb hidl_status_cb) override;
+ Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
+ setCountryCode_cb hidl_status_cb) override;
+ Return<void> getValidFrequenciesForBand(V1_0::WifiBand band,
+ getValidFrequenciesForBand_cb hidl_status_cb) override;
+ Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
+ setMacAddress_cb hidl_status_cb) override;
+ Return<void> getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override;
+ Return<void> resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) override;
+
+ Return<void> getBridgedInstances(getBridgedInstances_cb hidl_status_cb) override;
+
+ private:
+ // Corresponding worker functions for the HIDL methods.
+ std::pair<WifiStatus, std::string> getNameInternal();
+ std::pair<WifiStatus, IfaceType> getTypeInternal();
+ WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
+ std::pair<WifiStatus, std::vector<WifiChannelInMhz>> getValidFrequenciesForBandInternal(
+ V1_0::WifiBand band);
+ WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
+ std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal(
+ const std::string& ifaceName);
+ WifiStatus resetToFactoryMacAddressInternal();
+ std::pair<WifiStatus, std::vector<hidl_string>> getBridgedInstancesInternal();
+
+ std::string ifname_;
+ std::vector<std::string> instances_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+ bool is_valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiApIface);
+};
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_AP_IFACE_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_chip.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_chip.cpp
new file mode 100644
index 0000000..08ef368
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_chip.cpp
@@ -0,0 +1,2109 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <cutils/properties.h>
+#include <net/if.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+
+#include "hidl_return_util.h"
+#include "hidl_struct_util.h"
+#include "wifi_chip.h"
+#include "wifi_status_util.h"
+
+#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
+
+namespace {
+using android::sp;
+using android::base::unique_fd;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::wifi::V1_0::ChipModeId;
+using android::hardware::wifi::V1_0::IfaceType;
+using android::hardware::wifi::V1_0::IWifiChip;
+
+constexpr char kCpioMagic[] = "070701";
+constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
+constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
+constexpr uint32_t kMaxRingBufferFileNum = 20;
+constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
+constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
+constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
+constexpr unsigned kMaxWlanIfaces = 5;
+constexpr char kApBridgeIfacePrefix[] = "ap_br_";
+
+template <typename Iface>
+void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
+ iface->invalidate();
+ ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end());
+}
+
+template <typename Iface>
+void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
+ for (const auto& iface : ifaces) {
+ iface->invalidate();
+ }
+ ifaces.clear();
+}
+
+template <typename Iface>
+std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
+ std::vector<hidl_string> names;
+ for (const auto& iface : ifaces) {
+ names.emplace_back(iface->getName());
+ }
+ return names;
+}
+
+template <typename Iface>
+sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces, const std::string& name) {
+ std::vector<hidl_string> names;
+ for (const auto& iface : ifaces) {
+ if (name == iface->getName()) {
+ return iface;
+ }
+ }
+ return nullptr;
+}
+
+std::string getWlanIfaceName(unsigned idx) {
+ if (idx >= kMaxWlanIfaces) {
+ CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
+ return {};
+ }
+
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ if (idx == 0 || idx == 1) {
+ const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
+ auto res = property_get(altPropName, buffer.data(), nullptr);
+ if (res > 0) return buffer.data();
+ }
+ std::string propName = "wifi.interface." + std::to_string(idx);
+ auto res = property_get(propName.c_str(), buffer.data(), nullptr);
+ if (res > 0) return buffer.data();
+
+ return "wlan" + std::to_string(idx);
+}
+
+// Returns the dedicated iface name if defined.
+// Returns two ifaces in bridged mode.
+std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
+ std::vector<std::string> ifnames;
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ buffer.fill(0);
+ if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) {
+ return ifnames;
+ }
+ ifnames.push_back(buffer.data());
+ if (is_bridged) {
+ buffer.fill(0);
+ if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) {
+ return ifnames;
+ }
+ ifnames.push_back(buffer.data());
+ }
+ return ifnames;
+}
+
+std::string getPredefinedP2pIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
+ char p2pParentIfname[100];
+ std::string p2pDevIfName = "";
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ property_get("wifi.direct.interface", buffer.data(), "p2p0");
+ if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+ /* Get the p2p parent interface name from p2p device interface name set
+ * in property */
+ strlcpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
+ strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
+ if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) {
+ return buffer.data();
+ }
+ /* Check if the parent interface derived from p2p device interface name
+ * is active */
+ if (strncmp(p2pParentIfname, primaryIfaceName.data(),
+ strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) {
+ /*
+ * Update the predefined p2p device interface parent interface name
+ * with current active wlan interface
+ */
+ p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
+ p2pDevIfName += primaryIfaceName.data();
+ LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str();
+ return p2pDevIfName;
+ }
+ }
+ return buffer.data();
+}
+
+// Returns the dedicated iface name if one is defined.
+std::string getPredefinedNanIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
+ return {};
+ }
+ return buffer.data();
+}
+
+void setActiveWlanIfaceNameProperty(const std::string& ifname) {
+ auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
+ if (res != 0) {
+ PLOG(ERROR) << "Failed to set active wlan iface name property";
+ }
+}
+
+// delete files that meet either conditions:
+// 1. older than a predefined time in the wifi tombstone dir.
+// 2. Files in excess to a predefined amount, starting from the oldest ones
+bool removeOldFilesInternal() {
+ time_t now = time(0);
+ const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
+ std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir);
+ if (!dir_dump) {
+ PLOG(ERROR) << "Failed to open directory";
+ return false;
+ }
+ struct dirent* dp;
+ bool success = true;
+ std::list<std::pair<const time_t, std::string>> valid_files;
+ while ((dp = readdir(dir_dump.get()))) {
+ if (dp->d_type != DT_REG) {
+ continue;
+ }
+ std::string cur_file_name(dp->d_name);
+ struct stat cur_file_stat;
+ std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
+ if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
+ PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
+ success = false;
+ continue;
+ }
+ const time_t cur_file_time = cur_file_stat.st_mtime;
+ valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
+ }
+ valid_files.sort(); // sort the list of files by last modified time from
+ // small to big.
+ uint32_t cur_file_count = valid_files.size();
+ for (auto cur_file : valid_files) {
+ if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) {
+ if (unlink(cur_file.second.c_str()) != 0) {
+ PLOG(ERROR) << "Error deleting file";
+ success = false;
+ }
+ cur_file_count--;
+ } else {
+ break;
+ }
+ }
+ return success;
+}
+
+// Helper function for |cpioArchiveFilesInDir|
+bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) {
+ const int buf_size = 32 * 1024;
+ std::array<char, buf_size> read_buf;
+ ssize_t llen = snprintf(
+ read_buf.data(), buf_size, "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
+ kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, st.st_gid,
+ static_cast<int>(st.st_nlink), static_cast<int>(st.st_mtime),
+ static_cast<int>(st.st_size), major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
+ minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
+ if (write(out_fd, read_buf.data(), llen < buf_size ? llen : buf_size - 1) == -1) {
+ PLOG(ERROR) << "Error writing cpio header to file " << file_name;
+ return false;
+ }
+ if (write(out_fd, file_name, file_name_len) == -1) {
+ PLOG(ERROR) << "Error writing filename to file " << file_name;
+ return false;
+ }
+
+ // NUL Pad header up to 4 multiple bytes.
+ llen = (llen + file_name_len) % 4;
+ if (llen != 0) {
+ const uint32_t zero = 0;
+ if (write(out_fd, &zero, 4 - llen) == -1) {
+ PLOG(ERROR) << "Error padding 0s to file " << file_name;
+ return false;
+ }
+ }
+ return true;
+}
+
+// Helper function for |cpioArchiveFilesInDir|
+size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) {
+ // writing content of file
+ std::array<char, 32 * 1024> read_buf;
+ ssize_t llen = st.st_size;
+ size_t n_error = 0;
+ while (llen > 0) {
+ ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
+ if (bytes_read == -1) {
+ PLOG(ERROR) << "Error reading file";
+ return ++n_error;
+ }
+ llen -= bytes_read;
+ if (write(out_fd, read_buf.data(), bytes_read) == -1) {
+ PLOG(ERROR) << "Error writing data to file";
+ return ++n_error;
+ }
+ if (bytes_read == 0) { // this should never happen, but just in case
+ // to unstuck from while loop
+ PLOG(ERROR) << "Unexpected read result";
+ n_error++;
+ break;
+ }
+ }
+ llen = st.st_size % 4;
+ if (llen != 0) {
+ const uint32_t zero = 0;
+ if (write(out_fd, &zero, 4 - llen) == -1) {
+ PLOG(ERROR) << "Error padding 0s to file";
+ return ++n_error;
+ }
+ }
+ return n_error;
+}
+
+// Helper function for |cpioArchiveFilesInDir|
+bool cpioWriteFileTrailer(int out_fd) {
+ const int buf_size = 4096;
+ std::array<char, buf_size> read_buf;
+ read_buf.fill(0);
+ ssize_t llen = snprintf(read_buf.data(), 4096, "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0);
+ if (write(out_fd, read_buf.data(), (llen < buf_size ? llen : buf_size - 1) + 4) == -1) {
+ PLOG(ERROR) << "Error writing trailing bytes";
+ return false;
+ }
+ return true;
+}
+
+// Archives all files in |input_dir| and writes result into |out_fd|
+// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
+// portion
+size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
+ struct dirent* dp;
+ size_t n_error = 0;
+ std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), closedir);
+ if (!dir_dump) {
+ PLOG(ERROR) << "Failed to open directory";
+ return ++n_error;
+ }
+ while ((dp = readdir(dir_dump.get()))) {
+ if (dp->d_type != DT_REG) {
+ continue;
+ }
+ std::string cur_file_name(dp->d_name);
+ struct stat st;
+ const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
+ if (stat(cur_file_path.c_str(), &st) == -1) {
+ PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
+ n_error++;
+ continue;
+ }
+ const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
+ if (fd_read == -1) {
+ PLOG(ERROR) << "Failed to open file " << cur_file_path;
+ n_error++;
+ continue;
+ }
+ std::string file_name_with_last_modified_time =
+ cur_file_name + "-" + std::to_string(st.st_mtime);
+ // string.size() does not include the null terminator. The cpio FreeBSD
+ // file header expects the null character to be included in the length.
+ const size_t file_name_len = file_name_with_last_modified_time.size() + 1;
+ unique_fd file_auto_closer(fd_read);
+ if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(),
+ file_name_len)) {
+ return ++n_error;
+ }
+ size_t write_error = cpioWriteFileContent(fd_read, out_fd, st);
+ if (write_error) {
+ return n_error + write_error;
+ }
+ }
+ if (!cpioWriteFileTrailer(out_fd)) {
+ return ++n_error;
+ }
+ return n_error;
+}
+
+// Helper function to create a non-const char*.
+std::vector<char> makeCharVec(const std::string& str) {
+ std::vector<char> vec(str.size() + 1);
+ vec.assign(str.begin(), str.end());
+ vec.push_back('\0');
+ return vec;
+}
+
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+using hidl_return_util::validateAndCallWithLock;
+
+WifiChip::WifiChip(ChipId chip_id, bool is_primary,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+ const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+ const std::function<void(const std::string&)>& handler)
+ : chip_id_(chip_id),
+ legacy_hal_(legacy_hal),
+ mode_controller_(mode_controller),
+ iface_util_(iface_util),
+ is_valid_(true),
+ current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
+ modes_(feature_flags.lock()->getChipModes(is_primary)),
+ debug_ring_buffer_cb_registered_(false),
+ subsystemCallbackHandler_(handler) {
+ setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
+}
+
+void WifiChip::invalidate() {
+ if (!writeRingbufferFilesInternal()) {
+ LOG(ERROR) << "Error writing files to flash";
+ }
+ invalidateAndRemoveAllIfaces();
+ setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
+ legacy_hal_.reset();
+ event_cb_handler_.invalidate();
+ is_valid_ = false;
+}
+
+bool WifiChip::isValid() {
+ return is_valid_;
+}
+
+std::set<sp<V1_4::IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
+ return event_cb_handler_.getCallbacks();
+}
+
+Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal,
+ hidl_status_cb);
+}
+
+// Deprecated support for this callback
+Return<void> WifiChip::registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::registerEventCallbackInternal, hidl_status_cb,
+ event_callback);
+}
+
+Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getAvailableModesInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) {
+ return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
+}
+
+Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getModeInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::requestChipDebugInfoInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::requestDriverDebugDumpInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::requestFirmwareDebugDumpInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createApIfaceInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::createBridgedApIface(createBridgedApIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createBridgedApIfaceInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getApIfaceInternal, hidl_status_cb, ifname);
+}
+
+Return<void> WifiChip::removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeApIfaceInternal, hidl_status_cb, ifname);
+}
+
+Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface(
+ const hidl_string& ifname, const hidl_string& ifInstanceName,
+ removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, hidl_status_cb,
+ ifname, ifInstanceName);
+}
+
+Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createNanIfaceInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getNanIfaceInternal, hidl_status_cb, ifname);
+}
+
+Return<void> WifiChip::removeNanIface(const hidl_string& ifname, removeNanIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeNanIfaceInternal, hidl_status_cb, ifname);
+}
+
+Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createP2pIfaceInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getP2pIfaceInternal, hidl_status_cb, ifname);
+}
+
+Return<void> WifiChip::removeP2pIface(const hidl_string& ifname, removeP2pIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeP2pIfaceInternal, hidl_status_cb, ifname);
+}
+
+Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createStaIfaceInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getStaIfaceInternal, hidl_status_cb, ifname);
+}
+
+Return<void> WifiChip::removeStaIface(const hidl_string& ifname, removeStaIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeStaIfaceInternal, hidl_status_cb, ifname);
+}
+
+Return<void> WifiChip::createRttController(const sp<IWifiIface>& bound_iface,
+ createRttController_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createRttControllerInternal, hidl_status_cb, bound_iface);
+}
+
+Return<void> WifiChip::getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getDebugRingBuffersStatusInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::startLoggingToDebugRingBuffer(
+ const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+ uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
+ startLoggingToDebugRingBuffer_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::startLoggingToDebugRingBufferInternal, hidl_status_cb,
+ ring_name, verbose_level, max_interval_in_sec, min_data_size_in_bytes);
+}
+
+Return<void> WifiChip::forceDumpToDebugRingBuffer(const hidl_string& ring_name,
+ forceDumpToDebugRingBuffer_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::forceDumpToDebugRingBufferInternal, hidl_status_cb,
+ ring_name);
+}
+
+Return<void> WifiChip::flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::flushRingBufferToFileInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::stopLoggingToDebugRingBuffer(
+ stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::stopLoggingToDebugRingBufferInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getDebugHostWakeReasonStatsInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::enableDebugErrorAlerts(bool enable,
+ enableDebugErrorAlerts_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::enableDebugErrorAlertsInternal, hidl_status_cb, enable);
+}
+
+Return<void> WifiChip::selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,
+ selectTxPowerScenario_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::selectTxPowerScenarioInternal, hidl_status_cb, scenario);
+}
+
+Return<void> WifiChip::resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::resetTxPowerScenarioInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setLatencyModeInternal, hidl_status_cb, mode);
+}
+
+Return<void> WifiChip::registerEventCallback_1_2(
+ const sp<V1_2::IWifiChipEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::registerEventCallbackInternal_1_2, hidl_status_cb,
+ event_callback);
+}
+
+Return<void> WifiChip::selectTxPowerScenario_1_2(TxPowerScenario scenario,
+ selectTxPowerScenario_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::selectTxPowerScenarioInternal_1_2, hidl_status_cb, scenario);
+}
+
+Return<void> WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getCapabilitiesInternal_1_3, hidl_status_cb);
+}
+
+Return<void> WifiChip::getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getCapabilitiesInternal_1_5, hidl_status_cb);
+}
+
+Return<void> WifiChip::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
+ if (handle != nullptr && handle->numFds >= 1) {
+ {
+ std::unique_lock<std::mutex> lk(lock_t);
+ for (const auto& item : ringbuffer_map_) {
+ forceDumpToDebugRingBufferInternal(item.first);
+ }
+ // unique_lock unlocked here
+ }
+ usleep(100 * 1000); // sleep for 100 milliseconds to wait for
+ // ringbuffer updates.
+ int fd = handle->data[0];
+ if (!writeRingbufferFilesInternal()) {
+ LOG(ERROR) << "Error writing files to flash";
+ }
+ uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath);
+ if (n_error != 0) {
+ LOG(ERROR) << n_error << " errors occured in cpio function";
+ }
+ fsync(fd);
+ } else {
+ LOG(ERROR) << "File handle error";
+ }
+ return Void();
+}
+
+Return<void> WifiChip::createRttController_1_4(const sp<IWifiIface>& bound_iface,
+ createRttController_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createRttControllerInternal_1_4, hidl_status_cb, bound_iface);
+}
+
+Return<void> WifiChip::registerEventCallback_1_4(
+ const sp<V1_4::IWifiChipEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::registerEventCallbackInternal_1_4, hidl_status_cb,
+ event_callback);
+}
+
+Return<void> WifiChip::setMultiStaPrimaryConnection(
+ const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setMultiStaPrimaryConnectionInternal, hidl_status_cb, ifname);
+}
+
+Return<void> WifiChip::setMultiStaUseCase(MultiStaUseCase use_case,
+ setMultiStaUseCase_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setMultiStaUseCaseInternal, hidl_status_cb, use_case);
+}
+
+Return<void> WifiChip::setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel>& unsafeChannels,
+ hidl_bitfield<CoexRestriction> restrictions,
+ setCoexUnsafeChannels_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setCoexUnsafeChannelsInternal, hidl_status_cb, unsafeChannels,
+ restrictions);
+}
+
+Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code,
+ setCountryCode_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiChip::setCountryCodeInternal, hidl_status_cb, code);
+}
+
+Return<void> WifiChip::getUsableChannels(
+ WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
+ hidl_bitfield<V1_5::IWifiChip::UsableChannelFilter> filterMask,
+ getUsableChannels_cb _hidl_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getUsableChannelsInternal, _hidl_cb, band, ifaceModeMask,
+ filterMask);
+}
+
+Return<void> WifiChip::triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::triggerSubsystemRestartInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::createRttController_1_6(const sp<IWifiIface>& bound_iface,
+ createRttController_1_6_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createRttControllerInternal_1_6, hidl_status_cb, bound_iface);
+}
+
+Return<void> WifiChip::getUsableChannels_1_6(
+ WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
+ hidl_bitfield<V1_6::IWifiChip::UsableChannelFilter> filterMask,
+ getUsableChannels_1_6_cb _hidl_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getUsableChannelsInternal_1_6, _hidl_cb, band, ifaceModeMask,
+ filterMask);
+}
+
+Return<void> WifiChip::getSupportedRadioCombinationsMatrix(
+ getSupportedRadioCombinationsMatrix_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getSupportedRadioCombinationsMatrixInternal, hidl_status_cb);
+}
+
+Return<void> WifiChip::getAvailableModes_1_6(getAvailableModes_1_6_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getAvailableModesInternal_1_6, hidl_status_cb);
+}
+
+void WifiChip::QcRemoveAndClearDynamicIfaces() {
+ for (const auto& iface : created_ap_ifaces_) {
+ std::string ifname = iface->getName();
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->deleteVirtualInterface(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to remove interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ }
+ }
+
+ for (const auto& iface : created_sta_ifaces_) {
+ std::string ifname = iface->getName();
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->deleteVirtualInterface(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to remove interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ }
+ }
+
+ // created_ap/sta_ifaces are also part of sta/ap_ifaces.
+ // Do no invalidate here.
+
+ created_ap_ifaces_.clear();
+ created_sta_ifaces_.clear();
+}
+
+void WifiChip::invalidateAndRemoveAllIfaces() {
+ QcRemoveAndClearDynamicIfaces();
+ invalidateAndClearBridgedApAll();
+ invalidateAndClearAll(ap_ifaces_);
+ invalidateAndClearAll(nan_ifaces_);
+ invalidateAndClearAll(p2p_ifaces_);
+ invalidateAndClearAll(sta_ifaces_);
+ // Since all the ifaces are invalid now, all RTT controller objects
+ // using those ifaces also need to be invalidated.
+ for (const auto& rtt : rtt_controllers_) {
+ rtt->invalidate();
+ }
+ rtt_controllers_.clear();
+}
+
+void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) {
+ for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
+ auto nan_iface = *it;
+ if (nan_iface->getName() == removed_iface_name) {
+ nan_iface->invalidate();
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::NAN, removed_iface_name).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+ }
+ }
+ it = nan_ifaces_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+
+ for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
+ auto rtt = *it;
+ if (rtt->getIfaceName() == removed_iface_name) {
+ rtt->invalidate();
+ it = rtt_controllers_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
+}
+
+WifiStatus WifiChip::registerEventCallbackInternal(
+ const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
+ // Deprecated support for this callback.
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
+ // Deprecated support for this callback.
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
+}
+
+std::pair<WifiStatus, std::vector<V1_0::IWifiChip::ChipMode>>
+WifiChip::getAvailableModesInternal() {
+ // Deprecated support -- use getAvailableModes_1_6 for more granular concurrency combinations.
+ std::vector<V1_0::IWifiChip::ChipMode> modes_1_0 = {};
+ for (const auto& mode_1_6 : modes_) {
+ std::vector<V1_0::IWifiChip::ChipIfaceCombination> combos_1_0;
+ for (const auto& combo_1_6 : mode_1_6.availableCombinations) {
+ std::vector<V1_0::IWifiChip::ChipIfaceCombinationLimit> limits_1_0;
+ for (const auto& limit_1_6 : combo_1_6.limits) {
+ std::vector<IfaceType> types_1_0;
+ for (IfaceConcurrencyType type_1_6 : limit_1_6.types) {
+ switch (type_1_6) {
+ case IfaceConcurrencyType::STA:
+ types_1_0.push_back(IfaceType::STA);
+ break;
+ case IfaceConcurrencyType::AP:
+ types_1_0.push_back(IfaceType::AP);
+ break;
+ case IfaceConcurrencyType::AP_BRIDGED:
+ // Ignore AP_BRIDGED
+ break;
+ case IfaceConcurrencyType::P2P:
+ types_1_0.push_back(IfaceType::P2P);
+ break;
+ case IfaceConcurrencyType::NAN:
+ types_1_0.push_back(IfaceType::NAN);
+ break;
+ }
+ }
+ if (types_1_0.empty()) {
+ continue;
+ }
+ V1_0::IWifiChip::ChipIfaceCombinationLimit limit_1_0;
+ limit_1_0.types = hidl_vec(types_1_0);
+ limit_1_0.maxIfaces = limit_1_6.maxIfaces;
+ limits_1_0.push_back(limit_1_0);
+ }
+ if (limits_1_0.empty()) {
+ continue;
+ }
+ V1_0::IWifiChip::ChipIfaceCombination combo_1_0;
+ combo_1_0.limits = hidl_vec(limits_1_0);
+ combos_1_0.push_back(combo_1_0);
+ }
+ if (combos_1_0.empty()) {
+ continue;
+ }
+ V1_0::IWifiChip::ChipMode mode_1_0;
+ mode_1_0.id = mode_1_6.id;
+ mode_1_0.availableCombinations = hidl_vec(combos_1_0);
+ modes_1_0.push_back(mode_1_0);
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), modes_1_0};
+}
+
+WifiStatus WifiChip::configureChipInternal(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
+ if (!isValidModeId(mode_id)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ if (mode_id == current_mode_id_) {
+ LOG(DEBUG) << "Already in the specified mode " << mode_id;
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+ }
+ WifiStatus status = handleChipConfiguration(lock, mode_id);
+ if (status.code != WifiStatusCode::SUCCESS) {
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onChipReconfigureFailure(status).isOk()) {
+ LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
+ }
+ }
+ return status;
+ }
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onChipReconfigured(mode_id).isOk()) {
+ LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
+ }
+ }
+ current_mode_id_ = mode_id;
+ LOG(INFO) << "Configured chip in mode " << mode_id;
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+
+ legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_);
+
+ return status;
+}
+
+std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
+ if (!isValidModeId(current_mode_id_)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), current_mode_id_};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
+}
+
+std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> WifiChip::requestChipDebugInfoInternal() {
+ V1_4::IWifiChip::ChipDebugInfo result;
+ legacy_hal::wifi_error legacy_status;
+ std::string driver_desc;
+ const auto ifname = getFirstActiveWlanIfaceName();
+ std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status);
+ WifiStatus status =
+ createWifiStatusFromLegacyError(legacy_status, "failed to get driver version");
+ return {status, result};
+ }
+ result.driverDescription = driver_desc.c_str();
+
+ std::string firmware_desc;
+ std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status);
+ WifiStatus status =
+ createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version");
+ return {status, result};
+ }
+ result.firmwareDescription = firmware_desc.c_str();
+
+ return {createWifiStatus(WifiStatusCode::SUCCESS), result};
+}
+
+std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestDriverDebugDumpInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<uint8_t> driver_dump;
+ std::tie(legacy_status, driver_dump) =
+ legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName());
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status);
+ return {createWifiStatusFromLegacyError(legacy_status), std::vector<uint8_t>()};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
+}
+
+std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestFirmwareDebugDumpInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<uint8_t> firmware_dump;
+ std::tie(legacy_status, firmware_dump) =
+ legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName());
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status);
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
+}
+
+WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
+ legacy_hal::wifi_error legacy_status;
+ legacy_status = legacy_hal_.lock()->createVirtualInterface(
+ apVirtIf, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
+ << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
+ std::vector<std::string> ap_instances;
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == ifname) {
+ ap_instances = it.second;
+ }
+ }
+ sp<WifiApIface> iface = new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_);
+ ap_ifaces_.push_back(iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+ return iface;
+}
+
+std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createApIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ bool iface_created = false;
+ std::string ifname = allocateApIfaceName();
+ if (!if_nametoindex(ifname.c_str())) {
+ WifiStatus status = createVirtualApInterface(ifname);
+ if (status.code != WifiStatusCode::SUCCESS) {
+ return {status, {}};
+ }
+ iface_created = true;
+ }
+ sp<WifiApIface> iface = newWifiApIface(ifname);
+ if (iface_created) created_ap_ifaces_.push_back(iface);
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createBridgedApIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
+ if (ap_instances.size() < 2) {
+ LOG(ERROR) << "Fail to allocate two instances";
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
+ for (int i = 0; i < 2; i++) {
+ WifiStatus status = createVirtualApInterface(ap_instances[i]);
+ if (status.code != WifiStatusCode::SUCCESS) {
+ if (i != 0) { // The failure happened when creating second virtual
+ // iface.
+ legacy_hal_.lock()->deleteVirtualInterface(
+ ap_instances.front()); // Remove the first virtual iface.
+ }
+ return {status, {}};
+ }
+ }
+ br_ifaces_ap_instances_[br_ifname] = ap_instances;
+ if (!iface_util_->createBridge(br_ifname)) {
+ LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
+ deleteApIface(br_ifname);
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ for (auto const& instance : ap_instances) {
+ // Bind ap instance interface to AP bridge
+ if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
+ LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
+ deleteApIface(br_ifname);
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ }
+ sp<WifiApIface> iface = newWifiApIface(br_ifname);
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getApIfaceNamesInternal() {
+ if (ap_ifaces_.empty()) {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
+}
+
+std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::getApIfaceInternal(
+ const std::string& ifname) {
+ const auto iface = findUsingName(ap_ifaces_, ifname);
+ if (!iface.get()) {
+ return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
+ const auto iface = findUsingName(ap_ifaces_, ifname);
+ if (!iface.get()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ // Invalidate & remove any dependent objects first.
+ // Note: This is probably not required because we never create
+ // nan/rtt objects over AP iface. But, there is no harm to do it
+ // here and not make that assumption all over the place.
+ invalidateAndRemoveDependencies(ifname);
+ if (findUsingName(created_ap_ifaces_, ifname) != nullptr) {
+ invalidateAndClear(created_ap_ifaces_, iface);
+ }
+ invalidateAndClear(ap_ifaces_, iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+ }
+ }
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
+ const std::string& ifname, const std::string& ifInstanceName) {
+ const auto iface = findUsingName(ap_ifaces_, ifname);
+ if (!iface.get() || ifInstanceName.empty()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ // Requires to remove one of the instance in bridge mode
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == ifname) {
+ std::vector<std::string> ap_instances = it.second;
+ for (auto const& iface : ap_instances) {
+ if (iface == ifInstanceName) {
+ if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
+ LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
+ << ifname;
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->deleteVirtualInterface(iface);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to del interface: " << iface << " "
+ << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ ap_instances.erase(
+ std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
+ ap_instances.end());
+ br_ifaces_ap_instances_[ifname] = ap_instances;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ iface->removeInstance(ifInstanceName);
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::createNanIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::NAN)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ bool is_dedicated_iface = true;
+ std::string ifname = getPredefinedNanIfaceName();
+ if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
+ // Use the first shared STA iface (wlan0) if a dedicated aware iface is
+ // not defined.
+ ifname = getFirstActiveWlanIfaceName();
+ is_dedicated_iface = false;
+ }
+ sp<WifiNanIface> iface = new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
+ nan_ifaces_.push_back(iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getNanIfaceNamesInternal() {
+ if (nan_ifaces_.empty()) {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
+}
+
+std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::getNanIfaceInternal(
+ const std::string& ifname) {
+ const auto iface = findUsingName(nan_ifaces_, ifname);
+ if (!iface.get()) {
+ return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
+ const auto iface = findUsingName(nan_ifaces_, ifname);
+ if (!iface.get()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ invalidateAndClear(nan_ifaces_, iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::P2P)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ std::string ifname = getPredefinedP2pIfaceName();
+ sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
+ p2p_ifaces_.push_back(iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getP2pIfaceNamesInternal() {
+ if (p2p_ifaces_.empty()) {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
+}
+
+std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(const std::string& ifname) {
+ const auto iface = findUsingName(p2p_ifaces_, ifname);
+ if (!iface.get()) {
+ return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
+ const auto iface = findUsingName(p2p_ifaces_, ifname);
+ if (!iface.get()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ invalidateAndClear(p2p_ifaces_, iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+ }
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> WifiChip::createStaIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ bool iface_created = false;
+ std::string ifname = allocateStaIfaceName();
+ if (!if_nametoindex(ifname.c_str())) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->createVirtualInterface(
+ ifname,
+ hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to add interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ iface_created = true;
+ }
+ sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
+ sta_ifaces_.push_back(iface);
+ if (iface_created) created_sta_ifaces_.push_back(iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getStaIfaceNamesInternal() {
+ if (sta_ifaces_.empty()) {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
+}
+
+std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> WifiChip::getStaIfaceInternal(
+ const std::string& ifname) {
+ const auto iface = findUsingName(sta_ifaces_, ifname);
+ if (!iface.get()) {
+ return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
+}
+
+WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
+ const auto iface = findUsingName(sta_ifaces_, ifname);
+ if (!iface.get()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ // Invalidate & remove any dependent objects first.
+ invalidateAndRemoveDependencies(ifname);
+ if (findUsingName(created_sta_ifaces_, ifname) != nullptr) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->deleteVirtualInterface(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to remove interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ }
+ invalidateAndClear(created_sta_ifaces_, iface);
+ }
+ invalidateAndClear(sta_ifaces_, iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+ }
+ }
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, sp<V1_0::IWifiRttController>> WifiChip::createRttControllerInternal(
+ const sp<IWifiIface>& /*bound_iface*/) {
+ LOG(ERROR) << "createRttController is not supported on this HAL";
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
+WifiChip::getDebugRingBuffersStatusInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec;
+ std::tie(legacy_status, legacy_ring_buffer_status_vec) =
+ legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
+ if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
+ legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_ring_buffer_status_vec};
+}
+
+WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
+ const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+ uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
+ WifiStatus status = registerDebugRingBufferCallback();
+ if (status.code != WifiStatusCode::SUCCESS) {
+ return status;
+ }
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging(
+ getFirstActiveWlanIfaceName(), ring_name,
+ static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level),
+ max_interval_in_sec, min_data_size_in_bytes);
+ ringbuffer_map_.insert(
+ std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes)));
+ // if verbose logging enabled, turn up HAL daemon logging as well.
+ if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
+ android::base::SetMinimumLogSeverity(android::base::DEBUG);
+ } else {
+ android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+ }
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(const hidl_string& ring_name) {
+ WifiStatus status = registerDebugRingBufferCallback();
+ if (status.code != WifiStatusCode::SUCCESS) {
+ return status;
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name);
+
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::flushRingBufferToFileInternal() {
+ if (!writeRingbufferFilesInternal()) {
+ LOG(ERROR) << "Error writing files to flash";
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName());
+ if (legacy_status == legacy_hal::WIFI_SUCCESS) {
+ debug_ring_buffer_cb_registered_ = false;
+ }
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
+WifiChip::getDebugHostWakeReasonStatsInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::WakeReasonStats legacy_stats;
+ std::tie(legacy_status, legacy_stats) =
+ legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ WifiDebugHostWakeReasonStats hidl_stats;
+ if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, &hidl_stats)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
+}
+
+WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
+ legacy_hal::wifi_error legacy_status;
+ if (enable) {
+ android::wp<WifiChip> weak_ptr_this(this);
+ const auto& on_alert_callback = [weak_ptr_this](int32_t error_code,
+ std::vector<uint8_t> debug_data) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
+ LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
+ }
+ }
+ };
+ legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
+ getFirstActiveWlanIfaceName(), on_alert_callback);
+ } else {
+ legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
+ getFirstActiveWlanIfaceName());
+ }
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario) {
+ auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
+ getFirstActiveWlanIfaceName(),
+ hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::resetTxPowerScenarioInternal() {
+ auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
+ auto legacy_status = legacy_hal_.lock()->setLatencyMode(
+ getFirstActiveWlanIfaceName(), hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::registerEventCallbackInternal_1_2(
+ const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
+ // Deprecated support for this callback.
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario) {
+ auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
+ getFirstActiveWlanIfaceName(),
+ hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
+ // Deprecated support for this callback.
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
+}
+
+std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_5() {
+ legacy_hal::wifi_error legacy_status;
+ uint64_t legacy_feature_set;
+ uint32_t legacy_logger_feature_set;
+ const auto ifname = getFirstActiveWlanIfaceName();
+ std::tie(legacy_status, legacy_feature_set) =
+ legacy_hal_.lock()->getSupportedFeatureSet(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), 0};
+ }
+ std::tie(legacy_status, legacy_logger_feature_set) =
+ legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ // some devices don't support querying logger feature set
+ legacy_logger_feature_set = 0;
+ }
+ uint32_t hidl_caps;
+ if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
+ legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+std::pair<WifiStatus, sp<V1_4::IWifiRttController>> WifiChip::createRttControllerInternal_1_4(
+ const sp<IWifiIface>& /*bound_iface*/) {
+ LOG(ERROR) << "createRttController_1_4 is not supported on this HAL";
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+WifiStatus WifiChip::registerEventCallbackInternal_1_4(
+ const sp<V1_4::IWifiChipEventCallback>& event_callback) {
+ if (!event_cb_handler_.addCallback(event_callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) {
+ auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) {
+ auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
+ hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,
+ uint32_t restrictions) {
+ std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
+ if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels,
+ &legacy_unsafe_channels)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ uint32_t legacy_restrictions = 0;
+ if (restrictions & CoexRestriction::WIFI_DIRECT) {
+ legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
+ }
+ if (restrictions & CoexRestriction::SOFTAP) {
+ legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
+ }
+ if (restrictions & CoexRestriction::WIFI_AWARE) {
+ legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
+ }
+ auto legacy_status =
+ legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
+ auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, std::vector<V1_5::WifiUsableChannel>> WifiChip::getUsableChannelsInternal(
+ WifiBand /*band*/, uint32_t /*ifaceModeMask*/, uint32_t /*filterMask*/) {
+ LOG(ERROR) << "getUsableChannels is not supported on this HAL";
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+WifiStatus WifiChip::triggerSubsystemRestartInternal() {
+ auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, sp<V1_6::IWifiRttController>> WifiChip::createRttControllerInternal_1_6(
+ const sp<IWifiIface>& bound_iface) {
+ if (sta_ifaces_.size() == 0 &&
+ !canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
+ LOG(ERROR) << "createRttControllerInternal_1_6: Chip cannot support STAs "
+ "(and RTT by extension)";
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+ }
+ sp<WifiRttController> rtt =
+ new WifiRttController(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
+ rtt_controllers_.emplace_back(rtt);
+ return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
+}
+
+std::pair<WifiStatus, std::vector<V1_6::WifiUsableChannel>> WifiChip::getUsableChannelsInternal_1_6(
+ WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask) {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
+ std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels(
+ hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band),
+ hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask),
+ hidl_struct_util::convertHidlUsableChannelFilterToLegacy(filterMask));
+
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ std::vector<V1_6::WifiUsableChannel> hidl_usable_channels;
+ if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(legacy_usable_channels,
+ &hidl_usable_channels)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
+}
+
+std::pair<WifiStatus, V1_6::WifiRadioCombinationMatrix>
+WifiChip::getSupportedRadioCombinationsMatrixInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_radio_combination_matrix* legacy_matrix;
+
+ std::tie(legacy_status, legacy_matrix) =
+ legacy_hal_.lock()->getSupportedRadioCombinationsMatrix();
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get SupportedRadioCombinations matrix from legacy HAL: "
+ << legacyErrorToString(legacy_status);
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+
+ V1_6::WifiRadioCombinationMatrix hidl_matrix;
+ if (!hidl_struct_util::convertLegacyRadioCombinationsMatrixToHidl(legacy_matrix,
+ &hidl_matrix)) {
+ LOG(ERROR) << "Failed convertLegacyRadioCombinationsMatrixToHidl() ";
+ return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_matrix};
+}
+
+std::pair<WifiStatus, std::vector<V1_6::IWifiChip::ChipMode>>
+WifiChip::getAvailableModesInternal_1_6() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
+}
+
+WifiStatus WifiChip::handleChipConfiguration(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
+ // If the chip is already configured in a different mode, stop
+ // the legacy HAL and then start it after firmware mode change.
+ if (isValidModeId(current_mode_id_)) {
+ LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id;
+ invalidateAndRemoveAllIfaces();
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {});
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ }
+ // Firmware mode change not needed for V2 devices.
+ bool success = true;
+ if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
+ success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
+ } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
+ success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
+ }
+ if (!success) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ // Every time the HAL is restarted, we need to register the
+ // radio mode change callback.
+ WifiStatus status = registerRadioModeChangeCallback();
+ if (status.code != WifiStatusCode::SUCCESS) {
+ // This probably is not a critical failure?
+ LOG(ERROR) << "Failed to register radio mode change callback";
+ }
+ // Extract and save the version information into property.
+ std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> version_info;
+ version_info = WifiChip::requestChipDebugInfoInternal();
+ if (WifiStatusCode::SUCCESS == version_info.first.code) {
+ property_set("vendor.wlan.firmware.version",
+ version_info.second.firmwareDescription.c_str());
+ property_set("vendor.wlan.driver.version", version_info.second.driverDescription.c_str());
+ }
+
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiChip::registerDebugRingBufferCallback() {
+ if (debug_ring_buffer_cb_registered_) {
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+ }
+
+ android::wp<WifiChip> weak_ptr_this(this);
+ const auto& on_ring_buffer_data_callback =
+ [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data,
+ const legacy_hal::wifi_ring_buffer_status& status) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ WifiDebugRingBufferStatus hidl_status;
+ Ringbuffer::AppendStatus appendstatus;
+ if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(status,
+ &hidl_status)) {
+ LOG(ERROR) << "Error converting ring buffer status";
+ return;
+ }
+ {
+ std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
+ const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
+ if (target != shared_ptr_this->ringbuffer_map_.end()) {
+ Ringbuffer& cur_buffer = target->second;
+ appendstatus = cur_buffer.append(data);
+ } else {
+ LOG(ERROR) << "Ringname " << name << " not found";
+ return;
+ }
+ // unique_lock unlocked here
+ }
+ if (appendstatus == Ringbuffer::AppendStatus::FAIL_RING_BUFFER_CORRUPTED) {
+ LOG(ERROR) << "Ringname " << name << " is corrupted. Clear the ring buffer";
+ shared_ptr_this->writeRingbufferFilesInternal();
+ return;
+ }
+
+ };
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler(
+ getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
+
+ if (legacy_status == legacy_hal::WIFI_SUCCESS) {
+ debug_ring_buffer_cb_registered_ = true;
+ }
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiChip::registerRadioModeChangeCallback() {
+ android::wp<WifiChip> weak_ptr_this(this);
+ const auto& on_radio_mode_change_callback =
+ [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
+ if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(mac_infos,
+ &hidl_radio_mode_infos)) {
+ LOG(ERROR) << "Error converting wifi mac info";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos).isOk()) {
+ LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
+ << " callback on: " << toString(callback);
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
+ getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::vector<V1_6::IWifiChip::ChipConcurrencyCombination>
+WifiChip::getCurrentModeConcurrencyCombinations() {
+ if (!isValidModeId(current_mode_id_)) {
+ LOG(ERROR) << "Chip not configured in a mode yet";
+ return {};
+ }
+ for (const auto& mode : modes_) {
+ if (mode.id == current_mode_id_) {
+ return mode.availableCombinations;
+ }
+ }
+ CHECK(0) << "Expected to find concurrency combinations for current mode!";
+ return {};
+}
+
+// Returns a map indexed by IfaceConcurrencyType with the number of ifaces currently
+// created of the corresponding concurrency type.
+std::map<IfaceConcurrencyType, size_t> WifiChip::getCurrentConcurrencyCombination() {
+ std::map<IfaceConcurrencyType, size_t> iface_counts;
+ uint32_t num_ap = 0;
+ uint32_t num_ap_bridged = 0;
+ for (const auto& ap_iface : ap_ifaces_) {
+ std::string ap_iface_name = ap_iface->getName();
+ if (br_ifaces_ap_instances_.count(ap_iface_name) > 0 &&
+ br_ifaces_ap_instances_[ap_iface_name].size() > 1) {
+ num_ap_bridged++;
+ } else {
+ num_ap++;
+ }
+ }
+ iface_counts[IfaceConcurrencyType::AP] = num_ap;
+ iface_counts[IfaceConcurrencyType::AP_BRIDGED] = num_ap_bridged;
+ iface_counts[IfaceConcurrencyType::NAN] = nan_ifaces_.size();
+ iface_counts[IfaceConcurrencyType::P2P] = p2p_ifaces_.size();
+ iface_counts[IfaceConcurrencyType::STA] = sta_ifaces_.size();
+ return iface_counts;
+}
+
+// This expands the provided concurrency combinations to a more parseable
+// form. Returns a vector of available combinations possible with the number
+// of each concurrency type in the combination.
+// This method is a port of HalDeviceManager.expandConcurrencyCombos() from framework.
+std::vector<std::map<IfaceConcurrencyType, size_t>> WifiChip::expandConcurrencyCombinations(
+ const V1_6::IWifiChip::ChipConcurrencyCombination& combination) {
+ uint32_t num_expanded_combos = 1;
+ for (const auto& limit : combination.limits) {
+ for (uint32_t i = 0; i < limit.maxIfaces; i++) {
+ num_expanded_combos *= limit.types.size();
+ }
+ }
+
+ // Allocate the vector of expanded combos and reset all concurrency type counts to 0
+ // in each combo.
+ std::vector<std::map<IfaceConcurrencyType, size_t>> expanded_combos;
+ expanded_combos.resize(num_expanded_combos);
+ for (auto& expanded_combo : expanded_combos) {
+ for (const auto type :
+ {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
+ IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
+ expanded_combo[type] = 0;
+ }
+ }
+ uint32_t span = num_expanded_combos;
+ for (const auto& limit : combination.limits) {
+ for (uint32_t i = 0; i < limit.maxIfaces; i++) {
+ span /= limit.types.size();
+ for (uint32_t k = 0; k < num_expanded_combos; ++k) {
+ const auto iface_type = limit.types[(k / span) % limit.types.size()];
+ expanded_combos[k][iface_type]++;
+ }
+ }
+ }
+ return expanded_combos;
+}
+
+bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
+ const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+ IfaceConcurrencyType requested_type) {
+ const auto current_combo = getCurrentConcurrencyCombination();
+
+ // Check if we have space for 1 more iface of |type| in this combo
+ for (const auto type :
+ {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
+ IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
+ size_t num_ifaces_needed = current_combo.at(type);
+ if (type == requested_type) {
+ num_ifaces_needed++;
+ }
+ size_t num_ifaces_allowed = expanded_combo.at(type);
+ if (num_ifaces_needed > num_ifaces_allowed) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// This method does the following:
+// a) Enumerate all possible concurrency combos by expanding the current
+// ChipConcurrencyCombination.
+// b) Check if the requested concurrency type can be added to the current mode
+// with the concurrency combination that is already active.
+bool WifiChip::canCurrentModeSupportConcurrencyTypeWithCurrentTypes(
+ IfaceConcurrencyType requested_type) {
+ if (!isValidModeId(current_mode_id_)) {
+ LOG(ERROR) << "Chip not configured in a mode yet";
+ return false;
+ }
+ const auto combinations = getCurrentModeConcurrencyCombinations();
+ for (const auto& combination : combinations) {
+ const auto expanded_combos = expandConcurrencyCombinations(combination);
+ for (const auto& expanded_combo : expanded_combos) {
+ if (canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(expanded_combo,
+ requested_type)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// Note: This does not consider concurrency types already active. It only checks if the
+// provided expanded concurrency combination can support the requested combo.
+bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyCombo(
+ const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+ const std::map<IfaceConcurrencyType, size_t>& req_combo) {
+ // Check if we have space for 1 more |type| in this combo
+ for (const auto type :
+ {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
+ IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
+ if (req_combo.count(type) == 0) {
+ // Concurrency type not in the req_combo.
+ continue;
+ }
+ size_t num_ifaces_needed = req_combo.at(type);
+ size_t num_ifaces_allowed = expanded_combo.at(type);
+ if (num_ifaces_needed > num_ifaces_allowed) {
+ return false;
+ }
+ }
+ return true;
+}
+// This method does the following:
+// a) Enumerate all possible concurrency combos by expanding the current
+// ChipConcurrencyCombination.
+// b) Check if the requested concurrency combo can be added to the current mode.
+// Note: This does not consider concurrency types already active. It only checks if the
+// current mode can support the requested combo.
+bool WifiChip::canCurrentModeSupportConcurrencyCombo(
+ const std::map<IfaceConcurrencyType, size_t>& req_combo) {
+ if (!isValidModeId(current_mode_id_)) {
+ LOG(ERROR) << "Chip not configured in a mode yet";
+ return false;
+ }
+ const auto combinations = getCurrentModeConcurrencyCombinations();
+ for (const auto& combination : combinations) {
+ const auto expanded_combos = expandConcurrencyCombinations(combination);
+ for (const auto& expanded_combo : expanded_combos) {
+ if (canExpandedConcurrencyComboSupportConcurrencyCombo(expanded_combo, req_combo)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// This method does the following:
+// a) Enumerate all possible concurrency combos by expanding the current
+// ChipConcurrencyCombination.
+// b) Check if the requested concurrency type can be added to the current mode.
+bool WifiChip::canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type) {
+ // Check if we can support at least 1 of the requested concurrency type.
+ std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+ req_iface_combo[requested_type] = 1;
+ return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
+}
+
+bool WifiChip::isValidModeId(ChipModeId mode_id) {
+ for (const auto& mode : modes_) {
+ if (mode.id == mode_id) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
+ // Check if we can support at least 1 STA & 1 AP concurrently.
+ std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+ req_iface_combo[IfaceConcurrencyType::STA] = 1;
+ req_iface_combo[IfaceConcurrencyType::AP] = 1;
+ return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
+}
+
+bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
+ // Check if we can support at least 2 STA concurrently.
+ std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+ req_iface_combo[IfaceConcurrencyType::STA] = 2;
+ return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
+}
+
+std::string WifiChip::getFirstActiveWlanIfaceName() {
+ if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
+ if (ap_ifaces_.size() > 0) {
+ // If the first active wlan iface is bridged iface.
+ // Return first instance name.
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == ap_ifaces_[0]->getName()) {
+ return it.second[0];
+ }
+ }
+ return ap_ifaces_[0]->getName();
+ }
+ // This could happen if the chip call is made before any STA/AP
+ // iface is created. Default to wlan0 for such cases.
+ LOG(WARNING) << "No active wlan interfaces in use! Using default";
+ return getWlanIfaceNameWithType(IfaceType::STA, 0);
+}
+
+// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
+// not already in use.
+// Note: This doesn't check the actual presence of these interfaces.
+std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) {
+ for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
+ const auto ifname = getWlanIfaceNameWithType(type, idx);
+ if (findUsingNameFromBridgedApInstances(ifname)) continue;
+ if (findUsingName(ap_ifaces_, ifname)) continue;
+ if (findUsingName(sta_ifaces_, ifname)) continue;
+ return ifname;
+ }
+ // This should never happen. We screwed up somewhere if it did.
+ CHECK(false) << "All wlan interfaces in use already!";
+ return {};
+}
+
+uint32_t WifiChip::startIdxOfApIface() {
+ if (isDualStaConcurrencyAllowedInCurrentMode()) {
+ // When the HAL support dual STAs, AP should start with idx 2.
+ return 2;
+ } else if (isStaApConcurrencyAllowedInCurrentMode()) {
+ // When the HAL support STA + AP but it doesn't support dual STAs.
+ // AP should start with idx 1.
+ return 1;
+ }
+ // No concurrency support.
+ return 0;
+}
+
+// AP iface names start with idx 1 for modes supporting
+// concurrent STA, else start with idx 0.
+std::string WifiChip::allocateApIfaceName() {
+ // Check if we have a dedicated iface for AP.
+ std::vector<std::string> ifnames = getPredefinedApIfaceNames(true);
+ for (auto const& ifname : ifnames) {
+ if (findUsingName(ap_ifaces_, ifname)) continue;
+ return ifname;
+ }
+ return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
+}
+
+std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
+ // Check if we have a dedicated iface for AP.
+ std::vector<std::string> instances = getPredefinedApIfaceNames(true);
+ if (instances.size() == 2) {
+ return instances;
+ } else {
+ int num_ifaces_need_to_allocate = 2 - instances.size();
+ for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
+ std::string instance_name =
+ allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i);
+ if (!instance_name.empty()) {
+ instances.push_back(instance_name);
+ }
+ }
+ }
+ return instances;
+}
+
+// STA iface names start with idx 0.
+// Primary STA iface will always be 0.
+std::string WifiChip::allocateStaIfaceName() {
+ return allocateApOrStaIfaceName(IfaceType::STA, 0);
+}
+
+bool WifiChip::writeRingbufferFilesInternal() {
+ if (!removeOldFilesInternal()) {
+ LOG(ERROR) << "Error occurred while deleting old tombstone files";
+ return false;
+ }
+ // write ringbuffers to file
+ {
+ std::unique_lock<std::mutex> lk(lock_t);
+ for (auto& item : ringbuffer_map_) {
+ Ringbuffer& cur_buffer = item.second;
+ if (cur_buffer.getData().empty()) {
+ continue;
+ }
+ const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX";
+ const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
+ if (dump_fd == -1) {
+ PLOG(ERROR) << "create file failed";
+ return false;
+ }
+ unique_fd file_auto_closer(dump_fd);
+ for (const auto& cur_block : cur_buffer.getData()) {
+ if (cur_block.size() <= 0 || cur_block.size() > kMaxBufferSizeBytes) {
+ PLOG(ERROR) << "Ring buffer: " << item.first
+ << " is corrupted. Invalid block size: " << cur_block.size();
+ break;
+ }
+ if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) ==
+ -1) {
+ PLOG(ERROR) << "Error writing to file";
+ }
+ }
+ cur_buffer.clear();
+ }
+ // unique_lock unlocked here
+ }
+ return true;
+}
+
+std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
+ std::string ifname;
+
+ // let the legacy hal override the interface name
+ legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
+ if (err == legacy_hal::WIFI_SUCCESS) return ifname;
+
+ return getWlanIfaceName(idx);
+}
+
+void WifiChip::invalidateAndClearBridgedApAll() {
+ for (auto const& it : br_ifaces_ap_instances_) {
+ for (auto const& iface : it.second) {
+ iface_util_->removeIfaceFromBridge(it.first, iface);
+ legacy_hal_.lock()->deleteVirtualInterface(iface);
+ }
+ iface_util_->deleteBridge(it.first);
+ }
+ br_ifaces_ap_instances_.clear();
+}
+
+void WifiChip::deleteApIface(const std::string& if_name) {
+ if (if_name.empty()) return;
+ // delete bridged interfaces if have
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == if_name) {
+ for (auto const& iface : it.second) {
+ iface_util_->removeIfaceFromBridge(if_name, iface);
+ legacy_hal_.lock()->deleteVirtualInterface(iface);
+ }
+ iface_util_->deleteBridge(if_name);
+ br_ifaces_ap_instances_.erase(if_name);
+ // ifname is bridged AP, return here.
+ return;
+ }
+ }
+
+ // No bridged AP case, delete AP iface
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(if_name);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to remove interface: " << if_name << " "
+ << legacyErrorToString(legacy_status);
+ }
+}
+
+bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == name) {
+ return true;
+ }
+ for (auto const& iface : it.second) {
+ if (iface == name) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_chip.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_chip.h
new file mode 100644
index 0000000..27baf3d
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_chip.h
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_CHIP_H_
+#define WIFI_CHIP_H_
+
+// HACK: NAN is a macro defined in math.h, which can be included in various
+// headers. This wifi HAL uses an enum called NAN, which does not compile when
+// the macro is defined. Undefine NAN to work around it.
+#undef NAN
+
+#include <list>
+#include <map>
+#include <mutex>
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.6/IWifiChip.h>
+#include <android/hardware/wifi/1.6/IWifiRttController.h>
+#include <android/hardware/wifi/1.6/IWifiStaIface.h>
+
+#include "hidl_callback_util.h"
+#include "ringbuffer.h"
+#include "wifi_ap_iface.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_mode_controller.h"
+#include "wifi_nan_iface.h"
+#include "wifi_p2p_iface.h"
+#include "wifi_rtt_controller.h"
+#include "wifi_sta_iface.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+using V1_5::WifiBand;
+
+/**
+ * HIDL interface object used to control a Wifi HAL chip instance.
+ * Since there is only a single chip instance used today, there is no
+ * identifying handle information stored here.
+ */
+class WifiChip : public V1_6::IWifiChip {
+ public:
+ WifiChip(ChipId chip_id, bool is_primary,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+ const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+ const std::function<void(const std::string&)>& subsystemCallbackHandler);
+ // HIDL does not provide a built-in mechanism to let the server invalidate
+ // a HIDL interface object after creation. If any client process holds onto
+ // a reference to the object in their context, any method calls on that
+ // reference will continue to be directed to the server.
+ //
+ // However Wifi HAL needs to control the lifetime of these objects. So, add
+ // a public |invalidate| method to |WifiChip| and it's child objects. This
+ // will be used to mark an object invalid when either:
+ // a) Wifi HAL is stopped, or
+ // b) Wifi Chip is reconfigured.
+ //
+ // All HIDL method implementations should check if the object is still
+ // marked valid before processing them.
+ void invalidate();
+ bool isValid();
+ std::set<sp<V1_4::IWifiChipEventCallback>> getEventCallbacks();
+
+ // HIDL methods exposed.
+ Return<void> getId(getId_cb hidl_status_cb) override;
+ // Deprecated support for this callback
+ Return<void> registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) override;
+ Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
+ Return<void> getAvailableModes(getAvailableModes_cb hidl_status_cb) override;
+ Return<void> configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) override;
+ Return<void> getMode(getMode_cb hidl_status_cb) override;
+ Return<void> requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) override;
+ Return<void> requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) override;
+ Return<void> requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) override;
+ Return<void> createApIface(createApIface_cb hidl_status_cb) override;
+ Return<void> createBridgedApIface(createBridgedApIface_cb hidl_status_cb) override;
+ Return<void> getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override;
+ Return<void> getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) override;
+ Return<void> removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) override;
+ Return<void> removeIfaceInstanceFromBridgedApIface(
+ const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName,
+ removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override;
+ Return<void> createNanIface(createNanIface_cb hidl_status_cb) override;
+ Return<void> getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override;
+ Return<void> getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) override;
+ Return<void> removeNanIface(const hidl_string& ifname,
+ removeNanIface_cb hidl_status_cb) override;
+ Return<void> createP2pIface(createP2pIface_cb hidl_status_cb) override;
+ Return<void> getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) override;
+ Return<void> getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) override;
+ Return<void> removeP2pIface(const hidl_string& ifname,
+ removeP2pIface_cb hidl_status_cb) override;
+ Return<void> createStaIface(createStaIface_cb hidl_status_cb) override;
+ Return<void> getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) override;
+ Return<void> getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) override;
+ Return<void> removeStaIface(const hidl_string& ifname,
+ removeStaIface_cb hidl_status_cb) override;
+ Return<void> createRttController(const sp<IWifiIface>& bound_iface,
+ createRttController_cb hidl_status_cb) override;
+ Return<void> getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) override;
+ Return<void> startLoggingToDebugRingBuffer(
+ const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+ uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
+ startLoggingToDebugRingBuffer_cb hidl_status_cb) override;
+ Return<void> forceDumpToDebugRingBuffer(const hidl_string& ring_name,
+ forceDumpToDebugRingBuffer_cb hidl_status_cb) override;
+ Return<void> flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) override;
+ Return<void> stopLoggingToDebugRingBuffer(
+ stopLoggingToDebugRingBuffer_cb hidl_status_cb) override;
+ Return<void> getDebugHostWakeReasonStats(
+ getDebugHostWakeReasonStats_cb hidl_status_cb) override;
+ Return<void> enableDebugErrorAlerts(bool enable,
+ enableDebugErrorAlerts_cb hidl_status_cb) override;
+ Return<void> selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,
+ selectTxPowerScenario_cb hidl_status_cb) override;
+ Return<void> resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) override;
+ Return<void> setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_2(const sp<V1_2::IWifiChipEventCallback>& event_callback,
+ registerEventCallback_1_2_cb hidl_status_cb) override;
+ Return<void> selectTxPowerScenario_1_2(TxPowerScenario scenario,
+ selectTxPowerScenario_cb hidl_status_cb) override;
+ Return<void> getCapabilities_1_3(getCapabilities_cb hidl_status_cb) override;
+ Return<void> getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) override;
+ Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override;
+ Return<void> createRttController_1_4(const sp<IWifiIface>& bound_iface,
+ createRttController_1_4_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_4(const sp<V1_4::IWifiChipEventCallback>& event_callback,
+ registerEventCallback_1_4_cb hidl_status_cb) override;
+ Return<void> setMultiStaPrimaryConnection(
+ const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) override;
+ Return<void> setMultiStaUseCase(MultiStaUseCase use_case,
+ setMultiStaUseCase_cb hidl_status_cb) override;
+ Return<void> setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel>& unsafe_channels,
+ hidl_bitfield<IfaceType> restrictions,
+ setCoexUnsafeChannels_cb hidl_status_cb) override;
+ Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
+ setCountryCode_cb _hidl_cb) override;
+ Return<void> getUsableChannels(WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
+ hidl_bitfield<V1_5::IWifiChip::UsableChannelFilter> filterMask,
+ getUsableChannels_cb _hidl_cb) override;
+ Return<void> triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) override;
+ Return<void> createRttController_1_6(const sp<IWifiIface>& bound_iface,
+ createRttController_1_6_cb hidl_status_cb) override;
+ Return<void> getUsableChannels_1_6(WifiBand band,
+ hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
+ hidl_bitfield<UsableChannelFilter> filterMask,
+ getUsableChannels_1_6_cb _hidl_cb) override;
+ Return<void> getSupportedRadioCombinationsMatrix(
+ getSupportedRadioCombinationsMatrix_cb hidl_status_cb) override;
+ Return<void> getAvailableModes_1_6(getAvailableModes_1_6_cb hidl_status_cb) override;
+
+ private:
+ void invalidateAndRemoveAllIfaces();
+ // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
+ // invalidated & removed.
+ void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
+
+ // Corresponding worker functions for the HIDL methods.
+ std::pair<WifiStatus, ChipId> getIdInternal();
+ // Deprecated support for this callback
+ WifiStatus registerEventCallbackInternal(
+ const sp<V1_0::IWifiChipEventCallback>& event_callback);
+ std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
+ std::pair<WifiStatus, std::vector<V1_0::IWifiChip::ChipMode>> getAvailableModesInternal();
+ WifiStatus configureChipInternal(std::unique_lock<std::recursive_mutex>* lock,
+ ChipModeId mode_id);
+ std::pair<WifiStatus, uint32_t> getModeInternal();
+ std::pair<WifiStatus, IWifiChip::ChipDebugInfo> requestChipDebugInfoInternal();
+ std::pair<WifiStatus, std::vector<uint8_t>> requestDriverDebugDumpInternal();
+ std::pair<WifiStatus, std::vector<uint8_t>> requestFirmwareDebugDumpInternal();
+ sp<WifiApIface> newWifiApIface(std::string& ifname);
+ WifiStatus createVirtualApInterface(const std::string& apVirtIf);
+ std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createApIfaceInternal();
+ std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createBridgedApIfaceInternal();
+ std::pair<WifiStatus, std::vector<hidl_string>> getApIfaceNamesInternal();
+ std::pair<WifiStatus, sp<V1_5::IWifiApIface>> getApIfaceInternal(const std::string& ifname);
+ WifiStatus removeApIfaceInternal(const std::string& ifname);
+ WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal(const std::string& brIfaceName,
+ const std::string& ifInstanceName);
+ std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> createNanIfaceInternal();
+ std::pair<WifiStatus, std::vector<hidl_string>> getNanIfaceNamesInternal();
+ std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> getNanIfaceInternal(const std::string& ifname);
+ WifiStatus removeNanIfaceInternal(const std::string& ifname);
+ std::pair<WifiStatus, sp<IWifiP2pIface>> createP2pIfaceInternal();
+ std::pair<WifiStatus, std::vector<hidl_string>> getP2pIfaceNamesInternal();
+ std::pair<WifiStatus, sp<IWifiP2pIface>> getP2pIfaceInternal(const std::string& ifname);
+ WifiStatus removeP2pIfaceInternal(const std::string& ifname);
+ std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> createStaIfaceInternal();
+ std::pair<WifiStatus, std::vector<hidl_string>> getStaIfaceNamesInternal();
+ std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> getStaIfaceInternal(const std::string& ifname);
+ WifiStatus removeStaIfaceInternal(const std::string& ifname);
+ std::pair<WifiStatus, sp<V1_0::IWifiRttController>> createRttControllerInternal(
+ const sp<IWifiIface>& bound_iface);
+ std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
+ getDebugRingBuffersStatusInternal();
+ WifiStatus startLoggingToDebugRingBufferInternal(const hidl_string& ring_name,
+ WifiDebugRingBufferVerboseLevel verbose_level,
+ uint32_t max_interval_in_sec,
+ uint32_t min_data_size_in_bytes);
+ WifiStatus forceDumpToDebugRingBufferInternal(const hidl_string& ring_name);
+ WifiStatus flushRingBufferToFileInternal();
+ WifiStatus stopLoggingToDebugRingBufferInternal();
+ std::pair<WifiStatus, WifiDebugHostWakeReasonStats> getDebugHostWakeReasonStatsInternal();
+ WifiStatus enableDebugErrorAlertsInternal(bool enable);
+ WifiStatus selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario);
+ WifiStatus resetTxPowerScenarioInternal();
+ WifiStatus setLatencyModeInternal(LatencyMode mode);
+ WifiStatus registerEventCallbackInternal_1_2(
+ const sp<V1_2::IWifiChipEventCallback>& event_callback);
+ WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario);
+ std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_3();
+ std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_5();
+ std::pair<WifiStatus, sp<V1_4::IWifiRttController>> createRttControllerInternal_1_4(
+ const sp<IWifiIface>& bound_iface);
+ WifiStatus registerEventCallbackInternal_1_4(
+ const sp<V1_4::IWifiChipEventCallback>& event_callback);
+ WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
+ WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case);
+ WifiStatus setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,
+ uint32_t restrictions);
+ WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
+ std::pair<WifiStatus, std::vector<V1_5::WifiUsableChannel>> getUsableChannelsInternal(
+ WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask);
+ WifiStatus handleChipConfiguration(std::unique_lock<std::recursive_mutex>* lock,
+ ChipModeId mode_id);
+ WifiStatus registerDebugRingBufferCallback();
+ WifiStatus registerRadioModeChangeCallback();
+ std::vector<V1_6::IWifiChip::ChipConcurrencyCombination>
+ getCurrentModeConcurrencyCombinations();
+ std::map<IfaceConcurrencyType, size_t> getCurrentConcurrencyCombination();
+ std::vector<std::map<IfaceConcurrencyType, size_t>> expandConcurrencyCombinations(
+ const V1_6::IWifiChip::ChipConcurrencyCombination& combination);
+ bool canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
+ const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+ IfaceConcurrencyType requested_type);
+ bool canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType requested_type);
+ bool canExpandedConcurrencyComboSupportConcurrencyCombo(
+ const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+ const std::map<IfaceConcurrencyType, size_t>& req_combo);
+ bool canCurrentModeSupportConcurrencyCombo(
+ const std::map<IfaceConcurrencyType, size_t>& req_combo);
+ bool canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type);
+ bool isValidModeId(ChipModeId mode_id);
+ bool isStaApConcurrencyAllowedInCurrentMode();
+ bool isDualStaConcurrencyAllowedInCurrentMode();
+ uint32_t startIdxOfApIface();
+ std::string getFirstActiveWlanIfaceName();
+ std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx);
+ std::string allocateApIfaceName();
+ std::vector<std::string> allocateBridgedApInstanceNames();
+ std::string allocateStaIfaceName();
+ bool writeRingbufferFilesInternal();
+ std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx);
+ void invalidateAndClearBridgedApAll();
+ void deleteApIface(const std::string& if_name);
+ bool findUsingNameFromBridgedApInstances(const std::string& name);
+ WifiStatus triggerSubsystemRestartInternal();
+ void QcRemoveAndClearDynamicIfaces();
+ std::pair<WifiStatus, sp<V1_6::IWifiRttController>> createRttControllerInternal_1_6(
+ const sp<IWifiIface>& bound_iface);
+ std::pair<WifiStatus, std::vector<V1_6::WifiUsableChannel>> getUsableChannelsInternal_1_6(
+ WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask);
+ std::pair<WifiStatus, WifiRadioCombinationMatrix> getSupportedRadioCombinationsMatrixInternal();
+ std::pair<WifiStatus, std::vector<V1_6::IWifiChip::ChipMode>> getAvailableModesInternal_1_6();
+
+ ChipId chip_id_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
+ std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
+ std::vector<sp<WifiApIface>> ap_ifaces_;
+ std::vector<sp<WifiNanIface>> nan_ifaces_;
+ std::vector<sp<WifiP2pIface>> p2p_ifaces_;
+ std::vector<sp<WifiStaIface>> sta_ifaces_;
+ std::vector<sp<WifiRttController>> rtt_controllers_;
+ std::map<std::string, Ringbuffer> ringbuffer_map_;
+ bool is_valid_;
+ // Members pertaining to chip configuration.
+ uint32_t current_mode_id_;
+ std::mutex lock_t;
+ std::vector<V1_6::IWifiChip::ChipMode> modes_;
+ // The legacy ring buffer callback API has only a global callback
+ // registration mechanism. Use this to check if we have already
+ // registered a callback.
+ bool debug_ring_buffer_cb_registered_;
+ hidl_callback_util::HidlCallbackHandler<V1_4::IWifiChipEventCallback> event_cb_handler_;
+
+ const std::function<void(const std::string&)> subsystemCallbackHandler_;
+ std::map<std::string, std::vector<std::string>> br_ifaces_ap_instances_;
+
+ std::vector<sp<WifiApIface>> created_ap_ifaces_;
+ std::vector<sp<WifiStaIface>> created_sta_ifaces_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiChip);
+};
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_CHIP_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_feature_flags.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_feature_flags.cpp
new file mode 100644
index 0000000..e80a3cd
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_feature_flags.cpp
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include "wifi_feature_flags.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace feature_flags {
+
+using V1_0::ChipModeId;
+using V1_0::IWifiChip;
+using V1_6::IfaceConcurrencyType;
+
+/* The chip may either have a single mode supporting any number of combinations,
+ * or a fixed dual-mode (so it involves firmware loading to switch between
+ * modes) setting. If there is a need to support more modes, it needs to be
+ * implemented manually in WiFi HAL (see changeFirmwareMode in
+ * WifiChip::handleChipConfiguration).
+ *
+ * Supported combinations are defined in device's makefile, for example:
+ * WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}},
+ * WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}}
+ * What means:
+ * Interface concurrency combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface
+ * operations.
+ * Interface concurrency combination 2: 1 STA and 2 AP concurrent iface operations.
+ *
+ * For backward compatibility, the following makefile flags can be used to
+ * generate combinations list:
+ * - WIFI_HIDL_FEATURE_DUAL_INTERFACE
+ * - WIFI_HIDL_FEATURE_DISABLE_AP
+ * - WIFI_HIDL_FEATURE_AWARE
+ * However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided.
+ * With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with
+ * two concurrency combinations:
+ * Interface Concurrency Combination 1: Will support 1 STA and 1 P2P or NAN (optional)
+ * concurrent iface operations.
+ * Interface Concurrency Combination 2: Will support 1 STA and 1 AP concurrent
+ * iface operations.
+ *
+ * The only dual-mode configuration supported is for alternating STA and AP
+ * mode, that may involve firmware reloading. In such case, there are 2 separate
+ * modes of operation with 1 concurrency combination each:
+ * Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional)
+ * concurrent iface operations.
+ * Mode 2 (AP mode): Will support 1 AP iface operation.
+ *
+ * If Aware is enabled, the concurrency combination will be modified to support either
+ * P2P or NAN in place of just P2P.
+ */
+// clang-format off
+#ifdef WIFI_HAL_INTERFACE_COMBINATIONS
+constexpr ChipModeId kMainModeId = chip_mode_ids::kV3;
+#elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE)
+// former V2 (fixed dual interface) setup expressed as V3
+constexpr ChipModeId kMainModeId = chip_mode_ids::kV3;
+# ifdef WIFI_HIDL_FEATURE_DISABLE_AP
+# ifdef WIFI_HIDL_FEATURE_AWARE
+// 1 STA + 1 of (P2P or NAN)
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
+# else
+// 1 STA + 1 P2P
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
+# endif
+# else
+# ifdef WIFI_HIDL_FEATURE_AWARE
+// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
+ {{{STA}, 1}, {{P2P, NAN}, 1}}
+# else
+// (1 STA + 1 AP) or (1 STA + 1 P2P)
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
+ {{{STA}, 1}, {{P2P}, 1}}
+# endif
+# endif
+#else
+// V1 (fixed single interface, dual-mode chip)
+constexpr ChipModeId kMainModeId = chip_mode_ids::kV1Sta;
+# ifdef WIFI_HIDL_FEATURE_AWARE
+// 1 STA + 1 of (P2P or NAN)
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
+# else
+// 1 STA + 1 P2P
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
+# endif
+
+# ifndef WIFI_HIDL_FEATURE_DISABLE_AP
+# define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}}
+# endif
+#endif
+// clang-format on
+
+/**
+ * Helper class to convert a collection of combination limits to a combination.
+ *
+ * The main point here is to simplify the syntax required by
+ * WIFI_HAL_INTERFACE_COMBINATIONS.
+ */
+struct ChipConcurrencyCombination
+ : public hidl_vec<V1_6::IWifiChip::ChipConcurrencyCombinationLimit> {
+ ChipConcurrencyCombination(
+ const std::initializer_list<V1_6::IWifiChip::ChipConcurrencyCombinationLimit> list)
+ : hidl_vec(list) {}
+
+ operator V1_6::IWifiChip::ChipConcurrencyCombination() const { return {*this}; }
+
+ static hidl_vec<V1_6::IWifiChip::ChipConcurrencyCombination> make_vec(
+ const std::initializer_list<ChipConcurrencyCombination> list) {
+ return hidl_vec<V1_6::IWifiChip::ChipConcurrencyCombination>( //
+ std::begin(list), std::end(list));
+ }
+};
+
+#define STA IfaceConcurrencyType::STA
+#define AP IfaceConcurrencyType::AP
+#define AP_BRIDGED IfaceConcurrencyType::AP_BRIDGED
+#define P2P IfaceConcurrencyType::P2P
+#define NAN IfaceConcurrencyType::NAN
+static const std::vector<V1_6::IWifiChip::ChipMode> kChipModesPrimary{
+ {kMainModeId, ChipConcurrencyCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})},
+#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
+ {chip_mode_ids::kV1Ap,
+ ChipConcurrencyCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
+#endif
+};
+
+static const std::vector<V1_6::IWifiChip::ChipMode> kChipModesSecondary{
+#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
+ {chip_mode_ids::kV3,
+ ChipConcurrencyCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
+#endif
+};
+
+constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
+ "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
+// List of pre-defined concurrency combinations that can be enabled at runtime via
+// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
+// corresponding index value.
+static const std::vector<std::pair<std::string, std::vector<V1_6::IWifiChip::ChipMode>>>
+ kDebugChipModes{// Legacy combination - No STA/AP concurrencies.
+ // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
+ {"No STA/AP Concurrency",
+ {{kMainModeId, ChipConcurrencyCombination::make_vec(
+ {{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + AP concurrency
+ // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+ {"STA + AP Concurrency",
+ {{kMainModeId,
+ ChipConcurrencyCombination::make_vec(
+ {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + STA concurrency
+ // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
+ {"Dual STA Concurrency",
+ {{kMainModeId,
+ ChipConcurrencyCombination::make_vec(
+ {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+ // AP + AP + STA concurrency
+ // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
+ {"Dual AP Concurrency",
+ {{kMainModeId,
+ ChipConcurrencyCombination::make_vec(
+ {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + STA concurrency and AP + AP + STA concurrency
+ // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
+ {"Dual STA & Dual AP Concurrency",
+ {{kMainModeId,
+ ChipConcurrencyCombination::make_vec(
+ {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + STA concurrency
+ // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
+ {"Dual STA or STA plus single other interface",
+ {{kMainModeId, ChipConcurrencyCombination::make_vec(
+ {{{{STA}, 1}, {{P2P, NAN, AP, AP_BRIDGED}, 1}},
+ {{{STA}, 2}}})}}}};
+
+#undef STA
+#undef AP
+#undef P2P
+#undef NAN
+
+#ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
+#pragma message \
+ "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
+ "'config_wifi_ap_randomization_supported' in " \
+ "frameworks/base/core/res/res/values/config.xml in the device overlay " \
+ "instead"
+#endif // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
+
+WifiFeatureFlags::WifiFeatureFlags() {}
+
+std::vector<V1_6::IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
+ // Debug property not set, use the device preset concurrency combination.
+ if (res <= 0) return kChipModesPrimary;
+
+ // Debug property set, use one of the debug preset concurrency combination.
+ unsigned long idx = std::stoul(buffer.data());
+ if (idx >= kDebugChipModes.size()) {
+ LOG(ERROR) << "Invalid index set in property: "
+ << kDebugPresetInterfaceCombinationIdxProperty;
+ return kChipModesPrimary;
+ }
+ std::string name;
+ std::vector<V1_6::IWifiChip::ChipMode> chip_modes;
+ std::tie(name, chip_modes) = kDebugChipModes[idx];
+ LOG(INFO) << "Using debug chip mode: <" << name
+ << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
+ return chip_modes;
+}
+
+std::vector<V1_6::IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
+ return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
+}
+
+} // namespace feature_flags
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_feature_flags.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_feature_flags.h
new file mode 100644
index 0000000..1635341
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_feature_flags.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_FEATURE_FLAGS_H_
+#define WIFI_FEATURE_FLAGS_H_
+
+#include <android/hardware/wifi/1.6/IWifiChip.h>
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace feature_flags {
+
+namespace chip_mode_ids {
+// These mode ID's should be unique (even across combo versions). Refer to
+// handleChipConfiguration() for it's usage.
+constexpr V1_0::ChipModeId kInvalid = UINT32_MAX;
+// Mode ID's for V1
+constexpr V1_0::ChipModeId kV1Sta = 0;
+constexpr V1_0::ChipModeId kV1Ap = 1;
+// Mode ID for V3
+constexpr V1_0::ChipModeId kV3 = 3;
+} // namespace chip_mode_ids
+
+class WifiFeatureFlags {
+ public:
+ WifiFeatureFlags();
+ virtual ~WifiFeatureFlags() = default;
+
+ virtual std::vector<V1_6::IWifiChip::ChipMode> getChipModes(bool is_primary);
+
+ private:
+ std::vector<V1_6::IWifiChip::ChipMode> getChipModesForPrimary();
+};
+
+} // namespace feature_flags
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_FEATURE_FLAGS_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_iface_util.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_iface_util.cpp
new file mode 100644
index 0000000..d55e4f8
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_iface_util.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <net/if.h>
+#include <cstddef>
+#include <iostream>
+#include <limits>
+#include <random>
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <private/android_filesystem_config.h>
+
+#undef NAN
+#include "wifi_iface_util.h"
+
+namespace {
+// Constants to set the local bit & clear the multicast bit.
+constexpr uint8_t kMacAddressMulticastMask = 0x01;
+constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02;
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace iface_util {
+
+WifiIfaceUtil::WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+ : iface_tool_(iface_tool),
+ legacy_hal_(legacy_hal),
+ random_mac_address_(nullptr),
+ event_handlers_map_() {}
+
+std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(const std::string& iface_name) {
+ return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str());
+}
+
+bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
+ const std::array<uint8_t, 6>& mac) {
+#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+ legacy_hal::wifi_error legacy_status;
+ uint64_t legacy_feature_set;
+ std::tie(legacy_status, legacy_feature_set) =
+ legacy_hal_.lock()->getSupportedFeatureSet(iface_name);
+
+ if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
+ !iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) {
+ LOG(ERROR) << "SetUpState(false) failed.";
+ return false;
+ }
+#endif
+ bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac);
+#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+ if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
+ !iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
+ LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready.";
+ // Wait for driver ready and try to set iface UP again
+ if (legacy_hal_.lock()->waitForDriverReady() != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "SetUpState(true) wait for driver ready failed.";
+ return false;
+ }
+ if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
+ LOG(ERROR) << "SetUpState(true) failed after retry.";
+ return false;
+ }
+ }
+#endif
+ IfaceEventHandlers event_handlers = {};
+ const auto it = event_handlers_map_.find(iface_name);
+ if (it != event_handlers_map_.end()) {
+ event_handlers = it->second;
+ }
+ if (event_handlers.on_state_toggle_off_on != nullptr) {
+ event_handlers.on_state_toggle_off_on(iface_name);
+ }
+ if (!success) {
+ LOG(ERROR) << "SetMacAddress failed on " << iface_name;
+ } else {
+ LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name;
+ }
+ return success;
+}
+
+std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
+ if (random_mac_address_) {
+ return *random_mac_address_.get();
+ }
+ random_mac_address_ = std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress());
+ return *random_mac_address_.get();
+}
+
+void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
+ IfaceEventHandlers handlers) {
+ event_handlers_map_[iface_name] = handlers;
+}
+
+void WifiIfaceUtil::unregisterIfaceEventHandlers(const std::string& iface_name) {
+ event_handlers_map_.erase(iface_name);
+}
+
+std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
+ std::array<uint8_t, 6> address = {};
+ std::random_device rd;
+ std::default_random_engine engine(rd());
+ std::uniform_int_distribution<uint8_t> dist(std::numeric_limits<uint8_t>::min(),
+ std::numeric_limits<uint8_t>::max());
+ for (size_t i = 0; i < address.size(); i++) {
+ address[i] = dist(engine);
+ }
+ // Set the local bit and clear the multicast bit.
+ address[0] |= kMacAddressLocallyAssignedMask;
+ address[0] &= ~kMacAddressMulticastMask;
+ return address;
+}
+
+bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) {
+ if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) {
+ LOG(ERROR) << "SetUpState to " << request_up << " failed";
+ return false;
+ }
+ return true;
+}
+
+unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) {
+ return if_nametoindex(iface_name.c_str());
+}
+
+bool WifiIfaceUtil::createBridge(const std::string& br_name) {
+ if (!iface_tool_.lock()->createBridge(br_name)) {
+ return false;
+ }
+
+ if (!iface_tool_.lock()->SetUpState(br_name.c_str(), true)) {
+ LOG(ERROR) << "bridge SetUpState(true) failed.";
+ }
+ return true;
+}
+
+bool WifiIfaceUtil::deleteBridge(const std::string& br_name) {
+ if (!iface_tool_.lock()->SetUpState(br_name.c_str(), false)) {
+ LOG(INFO) << "SetUpState(false) failed for bridge=" << br_name.c_str();
+ }
+
+ return iface_tool_.lock()->deleteBridge(br_name);
+}
+
+bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, const std::string& if_name) {
+ return iface_tool_.lock()->addIfaceToBridge(br_name, if_name);
+}
+
+bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, const std::string& if_name) {
+ return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name);
+}
+
+} // namespace iface_util
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_iface_util.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_iface_util.h
new file mode 100644
index 0000000..c5db5de
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_iface_util.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_IFACE_UTIL_H_
+#define WIFI_IFACE_UTIL_H_
+
+#include <wifi_system/interface_tool.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace iface_util {
+
+// Iface event handlers.
+struct IfaceEventHandlers {
+ // Callback to be invoked when the iface is set down & up for MAC address
+ // change.
+ std::function<void(const std::string& iface_name)> on_state_toggle_off_on;
+};
+
+/**
+ * Util class for common iface operations.
+ */
+class WifiIfaceUtil {
+ public:
+ WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+ virtual ~WifiIfaceUtil() = default;
+
+ virtual std::array<uint8_t, 6> getFactoryMacAddress(const std::string& iface_name);
+ virtual bool setMacAddress(const std::string& iface_name, const std::array<uint8_t, 6>& mac);
+ // Get or create a random MAC address. The MAC address returned from
+ // this method will remain the same throughout the lifetime of the HAL
+ // daemon. (So, changes on every reboot)
+ virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress();
+
+ // Register for any iface event callbacks for the provided interface.
+ virtual void registerIfaceEventHandlers(const std::string& iface_name,
+ IfaceEventHandlers handlers);
+ virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
+ virtual bool setUpState(const std::string& iface_name, bool request_up);
+ virtual unsigned ifNameToIndex(const std::string& iface_name);
+
+ virtual bool createBridge(const std::string& br_name);
+
+ virtual bool deleteBridge(const std::string& br_name);
+
+ virtual bool addIfaceToBridge(const std::string& br_name, const std::string& if_name);
+
+ virtual bool removeIfaceFromBridge(const std::string& br_name, const std::string& if_name);
+ // Get a random MAC address.
+ virtual std::array<uint8_t, 6> createRandomMacAddress();
+
+ private:
+ std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
+ std::map<std::string, IfaceEventHandlers> event_handlers_map_;
+};
+
+} // namespace iface_util
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_IFACE_UTIL_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal.cpp
new file mode 100644
index 0000000..43cb7c4
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal.cpp
@@ -0,0 +1,1654 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <array>
+#include <chrono>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+#include <net/if.h>
+
+#include "hidl_sync_util.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_legacy_hal_stubs.h"
+
+namespace {
+// Constants ported over from the legacy HAL calling code
+// (com_android_server_wifi_WifiNative.cpp). This will all be thrown
+// away when this shim layer is replaced by the real vendor
+// implementation.
+static constexpr uint32_t kMaxVersionStringLength = 256;
+static constexpr uint32_t kMaxCachedGscanResults = 64;
+static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
+static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
+static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
+static constexpr uint32_t kMaxRingBuffers = 10;
+static constexpr uint32_t kMaxWifiUsableChannels = 256;
+static constexpr uint32_t kMaxSupportedRadioCombinationsMatrixLength = 256;
+// need a long timeout (1000ms) for chips that unload their driver.
+static constexpr uint32_t kMaxStopCompleteWaitMs = 1000;
+static constexpr char kDriverPropName[] = "wlan.driver.status";
+
+// Helper function to create a non-const char* for legacy Hal API's.
+std::vector<char> makeCharVec(const std::string& str) {
+ std::vector<char> vec(str.size() + 1);
+ vec.assign(str.begin(), str.end());
+ vec.push_back('\0');
+ return vec;
+}
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace legacy_hal {
+
+// Legacy HAL functions accept "C" style function pointers, so use global
+// functions to pass to the legacy HAL function and store the corresponding
+// std::function methods to be invoked.
+//
+// Callback to be invoked once |stop| is complete
+std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
+void onAsyncStopComplete(wifi_handle handle) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_stop_complete_internal_callback) {
+ on_stop_complete_internal_callback(handle);
+ // Invalidate this callback since we don't want this firing again.
+ on_stop_complete_internal_callback = nullptr;
+ }
+}
+
+// Callback to be invoked for driver dump.
+std::function<void(char*, int)> on_driver_memory_dump_internal_callback;
+void onSyncDriverMemoryDump(char* buffer, int buffer_size) {
+ if (on_driver_memory_dump_internal_callback) {
+ on_driver_memory_dump_internal_callback(buffer, buffer_size);
+ }
+}
+
+// Callback to be invoked for firmware dump.
+std::function<void(char*, int)> on_firmware_memory_dump_internal_callback;
+void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) {
+ if (on_firmware_memory_dump_internal_callback) {
+ on_firmware_memory_dump_internal_callback(buffer, buffer_size);
+ }
+}
+
+// Callback to be invoked for Gscan events.
+std::function<void(wifi_request_id, wifi_scan_event)> on_gscan_event_internal_callback;
+void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_gscan_event_internal_callback) {
+ on_gscan_event_internal_callback(id, event);
+ }
+}
+
+// Callback to be invoked for Gscan full results.
+std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
+ on_gscan_full_result_internal_callback;
+void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result,
+ uint32_t buckets_scanned) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_gscan_full_result_internal_callback) {
+ on_gscan_full_result_internal_callback(id, result, buckets_scanned);
+ }
+}
+
+// Callback to be invoked for link layer stats results.
+std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
+ on_link_layer_stats_result_internal_callback;
+void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios,
+ wifi_radio_stat* radio_stat) {
+ if (on_link_layer_stats_result_internal_callback) {
+ on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, radio_stat);
+ }
+}
+
+// Callback to be invoked for rssi threshold breach.
+std::function<void((wifi_request_id, uint8_t*, int8_t))>
+ on_rssi_threshold_breached_internal_callback;
+void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, int8_t rssi) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_rssi_threshold_breached_internal_callback) {
+ on_rssi_threshold_breached_internal_callback(id, bssid, rssi);
+ }
+}
+
+// Callback to be invoked for ring buffer data indication.
+std::function<void(char*, char*, int, wifi_ring_buffer_status*)>
+ on_ring_buffer_data_internal_callback;
+void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size,
+ wifi_ring_buffer_status* status) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_ring_buffer_data_internal_callback) {
+ on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, status);
+ }
+}
+
+// Callback to be invoked for error alert indication.
+std::function<void(wifi_request_id, char*, int, int)> on_error_alert_internal_callback;
+void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, int err_code) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_error_alert_internal_callback) {
+ on_error_alert_internal_callback(id, buffer, buffer_size, err_code);
+ }
+}
+
+// Callback to be invoked for radio mode change indication.
+std::function<void(wifi_request_id, uint32_t, wifi_mac_info*)>
+ on_radio_mode_change_internal_callback;
+void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, wifi_mac_info* mac_infos) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_radio_mode_change_internal_callback) {
+ on_radio_mode_change_internal_callback(id, num_macs, mac_infos);
+ }
+}
+
+// Callback to be invoked to report subsystem restart
+std::function<void(const char*)> on_subsystem_restart_internal_callback;
+void onAsyncSubsystemRestart(const char* error) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_subsystem_restart_internal_callback) {
+ on_subsystem_restart_internal_callback(error);
+ }
+}
+
+// Callback to be invoked for rtt results results.
+std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result* rtt_results[])>
+ on_rtt_results_internal_callback;
+void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_rtt_results_internal_callback) {
+ on_rtt_results_internal_callback(id, num_results, rtt_results);
+ on_rtt_results_internal_callback = nullptr;
+ }
+}
+
+// Callbacks for the various NAN operations.
+// NOTE: These have very little conversions to perform before invoking the user
+// callbacks.
+// So, handle all of them here directly to avoid adding an unnecessary layer.
+std::function<void(transaction_id, const NanResponseMsg&)> on_nan_notify_response_user_callback;
+void onAysncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_notify_response_user_callback && msg) {
+ on_nan_notify_response_user_callback(id, *msg);
+ }
+}
+
+std::function<void(const NanPublishRepliedInd&)> on_nan_event_publish_replied_user_callback;
+void onAysncNanEventPublishReplied(NanPublishRepliedInd* /* event */) {
+ LOG(ERROR) << "onAysncNanEventPublishReplied triggered";
+}
+
+std::function<void(const NanPublishTerminatedInd&)> on_nan_event_publish_terminated_user_callback;
+void onAysncNanEventPublishTerminated(NanPublishTerminatedInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_publish_terminated_user_callback && event) {
+ on_nan_event_publish_terminated_user_callback(*event);
+ }
+}
+
+std::function<void(const NanMatchInd&)> on_nan_event_match_user_callback;
+void onAysncNanEventMatch(NanMatchInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_match_user_callback && event) {
+ on_nan_event_match_user_callback(*event);
+ }
+}
+
+std::function<void(const NanMatchExpiredInd&)> on_nan_event_match_expired_user_callback;
+void onAysncNanEventMatchExpired(NanMatchExpiredInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_match_expired_user_callback && event) {
+ on_nan_event_match_expired_user_callback(*event);
+ }
+}
+
+std::function<void(const NanSubscribeTerminatedInd&)>
+ on_nan_event_subscribe_terminated_user_callback;
+void onAysncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_subscribe_terminated_user_callback && event) {
+ on_nan_event_subscribe_terminated_user_callback(*event);
+ }
+}
+
+std::function<void(const NanFollowupInd&)> on_nan_event_followup_user_callback;
+void onAysncNanEventFollowup(NanFollowupInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_followup_user_callback && event) {
+ on_nan_event_followup_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDiscEngEventInd&)> on_nan_event_disc_eng_event_user_callback;
+void onAysncNanEventDiscEngEvent(NanDiscEngEventInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_disc_eng_event_user_callback && event) {
+ on_nan_event_disc_eng_event_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDisabledInd&)> on_nan_event_disabled_user_callback;
+void onAysncNanEventDisabled(NanDisabledInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_disabled_user_callback && event) {
+ on_nan_event_disabled_user_callback(*event);
+ }
+}
+
+std::function<void(const NanTCAInd&)> on_nan_event_tca_user_callback;
+void onAysncNanEventTca(NanTCAInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_tca_user_callback && event) {
+ on_nan_event_tca_user_callback(*event);
+ }
+}
+
+std::function<void(const NanBeaconSdfPayloadInd&)> on_nan_event_beacon_sdf_payload_user_callback;
+void onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_beacon_sdf_payload_user_callback && event) {
+ on_nan_event_beacon_sdf_payload_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDataPathRequestInd&)> on_nan_event_data_path_request_user_callback;
+void onAysncNanEventDataPathRequest(NanDataPathRequestInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_data_path_request_user_callback && event) {
+ on_nan_event_data_path_request_user_callback(*event);
+ }
+}
+std::function<void(const NanDataPathConfirmInd&)> on_nan_event_data_path_confirm_user_callback;
+void onAysncNanEventDataPathConfirm(NanDataPathConfirmInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_data_path_confirm_user_callback && event) {
+ on_nan_event_data_path_confirm_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDataPathEndInd&)> on_nan_event_data_path_end_user_callback;
+void onAysncNanEventDataPathEnd(NanDataPathEndInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_data_path_end_user_callback && event) {
+ on_nan_event_data_path_end_user_callback(*event);
+ }
+}
+
+std::function<void(const NanTransmitFollowupInd&)> on_nan_event_transmit_follow_up_user_callback;
+void onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_transmit_follow_up_user_callback && event) {
+ on_nan_event_transmit_follow_up_user_callback(*event);
+ }
+}
+
+std::function<void(const NanRangeRequestInd&)> on_nan_event_range_request_user_callback;
+void onAysncNanEventRangeRequest(NanRangeRequestInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_range_request_user_callback && event) {
+ on_nan_event_range_request_user_callback(*event);
+ }
+}
+
+std::function<void(const NanRangeReportInd&)> on_nan_event_range_report_user_callback;
+void onAysncNanEventRangeReport(NanRangeReportInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_range_report_user_callback && event) {
+ on_nan_event_range_report_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDataPathScheduleUpdateInd&)> on_nan_event_schedule_update_user_callback;
+void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_schedule_update_user_callback && event) {
+ on_nan_event_schedule_update_user_callback(*event);
+ }
+}
+
+// Callbacks for the various TWT operations.
+std::function<void(const TwtSetupResponse&)> on_twt_event_setup_response_callback;
+void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_twt_event_setup_response_callback && event) {
+ on_twt_event_setup_response_callback(*event);
+ }
+}
+
+std::function<void(const TwtTeardownCompletion&)> on_twt_event_teardown_completion_callback;
+void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_twt_event_teardown_completion_callback && event) {
+ on_twt_event_teardown_completion_callback(*event);
+ }
+}
+
+std::function<void(const TwtInfoFrameReceived&)> on_twt_event_info_frame_received_callback;
+void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_twt_event_info_frame_received_callback && event) {
+ on_twt_event_info_frame_received_callback(*event);
+ }
+}
+
+std::function<void(const TwtDeviceNotify&)> on_twt_event_device_notify_callback;
+void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_twt_event_device_notify_callback && event) {
+ on_twt_event_device_notify_callback(*event);
+ }
+}
+
+// Callback to report current CHRE NAN state
+std::function<void(chre_nan_rtt_state)> on_chre_nan_rtt_internal_callback;
+void onAsyncChreNanRttState(chre_nan_rtt_state state) {
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (on_chre_nan_rtt_internal_callback) {
+ on_chre_nan_rtt_internal_callback(state);
+ }
+}
+
+// Callback to report cached scan results
+std::function<void(wifi_cached_scan_report*)> on_cached_scan_results_internal_callback;
+void onSyncCachedScanResults(wifi_cached_scan_report* cache_report) {
+ if (on_cached_scan_results_internal_callback) {
+ on_cached_scan_results_internal_callback(cache_report);
+ }
+}
+
+// End of the free-standing "C" style callbacks.
+
+WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+ const wifi_hal_fn& fn, bool is_primary)
+ : global_func_table_(fn),
+ global_handle_(nullptr),
+ awaiting_event_loop_termination_(false),
+ is_started_(false),
+ iface_tool_(iface_tool),
+ is_primary_(is_primary) {}
+
+wifi_error WifiLegacyHal::initialize() {
+ LOG(DEBUG) << "Initialize legacy HAL";
+ // this now does nothing, since HAL function table is provided
+ // to the constructor
+ return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::start() {
+ // Ensure that we're starting in a good state.
+ CHECK(global_func_table_.wifi_initialize && !global_handle_ && iface_name_to_handle_.empty() &&
+ !awaiting_event_loop_termination_);
+ if (is_started_) {
+ LOG(DEBUG) << "Legacy HAL already started";
+ return WIFI_SUCCESS;
+ }
+ LOG(DEBUG) << "Waiting for the driver ready";
+ wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
+ if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) {
+ LOG(ERROR) << "Failed or timed out awaiting driver ready";
+ return status;
+ }
+
+ if (is_primary_) {
+ property_set(kDriverPropName, "ok");
+
+ if (!iface_tool_.lock()->SetWifiUpState(true)) {
+ LOG(ERROR) << "Failed to set WiFi interface up";
+ return WIFI_ERROR_UNKNOWN;
+ }
+ }
+
+ LOG(DEBUG) << "Starting legacy HAL";
+ status = global_func_table_.wifi_initialize(&global_handle_);
+ if (status != WIFI_SUCCESS || !global_handle_) {
+ LOG(ERROR) << "Failed to retrieve global handle";
+ return status;
+ }
+ std::thread(&WifiLegacyHal::runEventLoop, this).detach();
+ status = retrieveIfaceHandles();
+ if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) {
+ LOG(ERROR) << "Failed to retrieve wlan interface handle";
+ return status;
+ }
+ LOG(DEBUG) << "Legacy HAL start complete";
+ is_started_ = true;
+ return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::stop(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
+ const std::function<void()>& on_stop_complete_user_callback) {
+ if (!is_started_) {
+ LOG(DEBUG) << "Legacy HAL already stopped";
+ on_stop_complete_user_callback();
+ return WIFI_SUCCESS;
+ }
+ LOG(DEBUG) << "Stopping legacy HAL";
+ on_stop_complete_internal_callback = [on_stop_complete_user_callback,
+ this](wifi_handle handle) {
+ CHECK_EQ(global_handle_, handle) << "Handle mismatch";
+ LOG(INFO) << "Legacy HAL stop complete callback received";
+ // Invalidate all the internal pointers now that the HAL is
+ // stopped.
+ invalidate();
+ if (is_primary_) iface_tool_.lock()->SetWifiUpState(false);
+ on_stop_complete_user_callback();
+ is_started_ = false;
+ };
+ awaiting_event_loop_termination_ = true;
+ global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
+ const auto status =
+ stop_wait_cv_.wait_for(*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
+ [this] { return !awaiting_event_loop_termination_; });
+ if (!status) {
+ LOG(ERROR) << "Legacy HAL stop failed or timed out";
+ return WIFI_ERROR_UNKNOWN;
+ }
+ LOG(DEBUG) << "Legacy HAL stop complete";
+ return WIFI_SUCCESS;
+}
+
+bool WifiLegacyHal::isStarted() {
+ return is_started_;
+}
+
+wifi_error WifiLegacyHal::waitForDriverReady() {
+ return global_func_table_.wifi_wait_for_driver_ready();
+}
+
+std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(const std::string& iface_name) {
+ std::array<char, kMaxVersionStringLength> buffer;
+ buffer.fill(0);
+ wifi_error status = global_func_table_.wifi_get_driver_version(getIfaceHandle(iface_name),
+ buffer.data(), buffer.size());
+ return {status, buffer.data()};
+}
+
+std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion(
+ const std::string& iface_name) {
+ std::array<char, kMaxVersionStringLength> buffer;
+ buffer.fill(0);
+ wifi_error status = global_func_table_.wifi_get_firmware_version(getIfaceHandle(iface_name),
+ buffer.data(), buffer.size());
+ return {status, buffer.data()};
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestDriverMemoryDump(
+ const std::string& iface_name) {
+ std::vector<uint8_t> driver_dump;
+ on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, int buffer_size) {
+ driver_dump.insert(driver_dump.end(), reinterpret_cast<uint8_t*>(buffer),
+ reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+ };
+ wifi_error status = global_func_table_.wifi_get_driver_memory_dump(getIfaceHandle(iface_name),
+ {onSyncDriverMemoryDump});
+ on_driver_memory_dump_internal_callback = nullptr;
+ return {status, std::move(driver_dump)};
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestFirmwareMemoryDump(
+ const std::string& iface_name) {
+ std::vector<uint8_t> firmware_dump;
+ on_firmware_memory_dump_internal_callback = [&firmware_dump](char* buffer, int buffer_size) {
+ firmware_dump.insert(firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer),
+ reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+ };
+ wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
+ getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump});
+ on_firmware_memory_dump_internal_callback = nullptr;
+ return {status, std::move(firmware_dump)};
+}
+
+std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet(
+ const std::string& iface_name) {
+ feature_set set = 0, chip_set = 0;
+ wifi_error status = WIFI_SUCCESS;
+
+ static_assert(sizeof(set) == sizeof(uint64_t),
+ "Some feature_flags can not be represented in output");
+ wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
+
+ global_func_table_.wifi_get_chip_feature_set(
+ global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */
+
+ if (iface_handle) {
+ status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set);
+ }
+ return {status, static_cast<uint64_t>(set | chip_set)};
+}
+
+std::pair<wifi_error, PacketFilterCapabilities> WifiLegacyHal::getPacketFilterCapabilities(
+ const std::string& iface_name) {
+ PacketFilterCapabilities caps;
+ wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
+ getIfaceHandle(iface_name), &caps.version, &caps.max_len);
+ return {status, caps};
+}
+
+wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name,
+ const std::vector<uint8_t>& program) {
+ return global_func_table_.wifi_set_packet_filter(getIfaceHandle(iface_name), program.data(),
+ program.size());
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::readApfPacketFilterData(
+ const std::string& iface_name) {
+ PacketFilterCapabilities caps;
+ wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
+ getIfaceHandle(iface_name), &caps.version, &caps.max_len);
+ if (status != WIFI_SUCCESS) {
+ return {status, {}};
+ }
+
+ // Size the buffer to read the entire program & work memory.
+ std::vector<uint8_t> buffer(caps.max_len);
+
+ status = global_func_table_.wifi_read_packet_filter(
+ getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), buffer.size());
+ return {status, std::move(buffer)};
+}
+
+std::pair<wifi_error, wifi_gscan_capabilities> WifiLegacyHal::getGscanCapabilities(
+ const std::string& iface_name) {
+ wifi_gscan_capabilities caps;
+ wifi_error status =
+ global_func_table_.wifi_get_gscan_capabilities(getIfaceHandle(iface_name), &caps);
+ return {status, caps};
+}
+
+wifi_error WifiLegacyHal::startGscan(
+ const std::string& iface_name, wifi_request_id id, const wifi_scan_cmd_params& params,
+ const std::function<void(wifi_request_id)>& on_failure_user_callback,
+ const on_gscan_results_callback& on_results_user_callback,
+ const on_gscan_full_result_callback& on_full_result_user_callback) {
+ // If there is already an ongoing background scan, reject new scan requests.
+ if (on_gscan_event_internal_callback || on_gscan_full_result_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ // This callback will be used to either trigger |on_results_user_callback|
+ // or |on_failure_user_callback|.
+ on_gscan_event_internal_callback = [iface_name, on_failure_user_callback,
+ on_results_user_callback,
+ this](wifi_request_id id, wifi_scan_event event) {
+ switch (event) {
+ case WIFI_SCAN_RESULTS_AVAILABLE:
+ case WIFI_SCAN_THRESHOLD_NUM_SCANS:
+ case WIFI_SCAN_THRESHOLD_PERCENT: {
+ wifi_error status;
+ std::vector<wifi_cached_scan_results> cached_scan_results;
+ std::tie(status, cached_scan_results) = getGscanCachedResults(iface_name);
+ if (status == WIFI_SUCCESS) {
+ on_results_user_callback(id, cached_scan_results);
+ return;
+ }
+ FALLTHROUGH_INTENDED;
+ }
+ // Fall through if failed. Failure to retrieve cached scan
+ // results should trigger a background scan failure.
+ case WIFI_SCAN_FAILED:
+ on_failure_user_callback(id);
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ return;
+ }
+ LOG(FATAL) << "Unexpected gscan event received: " << event;
+ };
+
+ on_gscan_full_result_internal_callback = [on_full_result_user_callback](
+ wifi_request_id id, wifi_scan_result* result,
+ uint32_t buckets_scanned) {
+ if (result) {
+ on_full_result_user_callback(id, result, buckets_scanned);
+ }
+ };
+
+ wifi_scan_result_handler handler = {onAsyncGscanFullResult, onAsyncGscanEvent};
+ wifi_error status =
+ global_func_table_.wifi_start_gscan(id, getIfaceHandle(iface_name), params, handler);
+ if (status != WIFI_SUCCESS) {
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, wifi_request_id id) {
+ // If there is no an ongoing background scan, reject stop requests.
+ // TODO(b/32337212): This needs to be handled by the HIDL object because we
+ // need to return the NOT_STARTED error code.
+ if (!on_gscan_event_internal_callback && !on_gscan_full_result_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ wifi_error status = global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name));
+ // If the request Id is wrong, don't stop the ongoing background scan. Any
+ // other error should be treated as the end of background scan.
+ if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ }
+ return status;
+}
+
+std::pair<wifi_error, std::vector<uint32_t>> WifiLegacyHal::getValidFrequenciesForBand(
+ const std::string& iface_name, wifi_band band) {
+ static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
+ "Wifi Channel cannot be represented in output");
+ std::vector<uint32_t> freqs;
+ freqs.resize(kMaxGscanFrequenciesForBand);
+ int32_t num_freqs = 0;
+ wifi_error status = global_func_table_.wifi_get_valid_channels(
+ getIfaceHandle(iface_name), band, freqs.size(),
+ reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs);
+ CHECK(num_freqs >= 0 && static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
+ freqs.resize(num_freqs);
+ return {status, std::move(freqs)};
+}
+
+wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, bool dfs_on) {
+ return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), dfs_on ? 0 : 1);
+}
+
+wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, bool debug) {
+ wifi_link_layer_params params;
+ params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
+ params.aggressive_statistics_gathering = debug;
+ return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), params);
+}
+
+wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) {
+ // TODO: Do we care about these responses?
+ uint32_t clear_mask_rsp;
+ uint8_t stop_rsp;
+ return global_func_table_.wifi_clear_link_stats(getIfaceHandle(iface_name), 0xFFFFFFFF,
+ &clear_mask_rsp, 1, &stop_rsp);
+}
+
+std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats(
+ const std::string& iface_name) {
+ LinkLayerStats link_stats{};
+ LinkLayerStats* link_stats_ptr = &link_stats;
+
+ on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
+ wifi_request_id /* id */,
+ wifi_iface_stat* iface_stats_ptr,
+ int num_radios,
+ wifi_radio_stat* radio_stats_ptr) {
+ wifi_radio_stat* l_radio_stats_ptr;
+ wifi_peer_info* l_peer_info_stats_ptr;
+
+ if (iface_stats_ptr != nullptr) {
+ link_stats_ptr->iface = *iface_stats_ptr;
+ l_peer_info_stats_ptr = iface_stats_ptr->peer_info;
+ for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) {
+ WifiPeerInfo peer;
+ peer.peer_info = *l_peer_info_stats_ptr;
+ if (l_peer_info_stats_ptr->num_rate > 0) {
+ /* Copy the rate stats */
+ peer.rate_stats.assign(
+ l_peer_info_stats_ptr->rate_stats,
+ l_peer_info_stats_ptr->rate_stats + l_peer_info_stats_ptr->num_rate);
+ }
+ peer.peer_info.num_rate = 0;
+ link_stats_ptr->peers.push_back(peer);
+ l_peer_info_stats_ptr =
+ (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + sizeof(wifi_peer_info) +
+ (sizeof(wifi_rate_stat) *
+ l_peer_info_stats_ptr->num_rate));
+ }
+ link_stats_ptr->iface.num_peers = 0;
+ } else {
+ LOG(ERROR) << "Invalid iface stats in link layer stats";
+ }
+ if (num_radios <= 0 || radio_stats_ptr == nullptr) {
+ LOG(ERROR) << "Invalid radio stats in link layer stats";
+ return;
+ }
+ l_radio_stats_ptr = radio_stats_ptr;
+ for (int i = 0; i < num_radios; i++) {
+ LinkLayerRadioStats radio;
+
+ radio.stats = *l_radio_stats_ptr;
+ // Copy over the tx level array to the separate vector.
+ if (l_radio_stats_ptr->num_tx_levels > 0 &&
+ l_radio_stats_ptr->tx_time_per_levels != nullptr) {
+ radio.tx_time_per_levels.assign(
+ l_radio_stats_ptr->tx_time_per_levels,
+ l_radio_stats_ptr->tx_time_per_levels + l_radio_stats_ptr->num_tx_levels);
+ }
+ radio.stats.num_tx_levels = 0;
+ radio.stats.tx_time_per_levels = nullptr;
+ /* Copy over the channel stat to separate vector */
+ if (l_radio_stats_ptr->num_channels > 0) {
+ /* Copy the channel stats */
+ radio.channel_stats.assign(
+ l_radio_stats_ptr->channels,
+ l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
+ }
+ link_stats_ptr->radios.push_back(radio);
+ l_radio_stats_ptr =
+ (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
+ (sizeof(wifi_channel_stat) *
+ l_radio_stats_ptr->num_channels));
+ }
+ };
+
+ wifi_error status = global_func_table_.wifi_get_link_stats(0, getIfaceHandle(iface_name),
+ {onSyncLinkLayerStatsResult});
+ on_link_layer_stats_result_internal_callback = nullptr;
+ return {status, link_stats};
+}
+
+wifi_error WifiLegacyHal::startRssiMonitoring(
+ const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
+ const on_rssi_threshold_breached_callback& on_threshold_breached_user_callback) {
+ if (on_rssi_threshold_breached_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_rssi_threshold_breached_internal_callback = [on_threshold_breached_user_callback](
+ wifi_request_id id, uint8_t* bssid_ptr,
+ int8_t rssi) {
+ if (!bssid_ptr) {
+ return;
+ }
+ std::array<uint8_t, 6> bssid_arr;
+ // |bssid_ptr| pointer is assumed to have 6 bytes for the mac
+ // address.
+ std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
+ on_threshold_breached_user_callback(id, bssid_arr, rssi);
+ };
+ wifi_error status = global_func_table_.wifi_start_rssi_monitoring(
+ id, getIfaceHandle(iface_name), max_rssi, min_rssi, {onAsyncRssiThresholdBreached});
+ if (status != WIFI_SUCCESS) {
+ on_rssi_threshold_breached_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, wifi_request_id id) {
+ if (!on_rssi_threshold_breached_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ wifi_error status =
+ global_func_table_.wifi_stop_rssi_monitoring(id, getIfaceHandle(iface_name));
+ // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
+ // other error should be treated as the end of background scan.
+ if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+ on_rssi_threshold_breached_internal_callback = nullptr;
+ }
+ return status;
+}
+
+std::pair<wifi_error, wifi_roaming_capabilities> WifiLegacyHal::getRoamingCapabilities(
+ const std::string& iface_name) {
+ wifi_roaming_capabilities caps;
+ wifi_error status =
+ global_func_table_.wifi_get_roaming_capabilities(getIfaceHandle(iface_name), &caps);
+ return {status, caps};
+}
+
+wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name,
+ const wifi_roaming_config& config) {
+ wifi_roaming_config config_internal = config;
+ return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), &config_internal);
+}
+
+wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name,
+ fw_roaming_state_t state) {
+ return global_func_table_.wifi_enable_firmware_roaming(getIfaceHandle(iface_name), state);
+}
+
+wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, bool enable) {
+ return global_func_table_.wifi_configure_nd_offload(getIfaceHandle(iface_name), enable);
+}
+
+wifi_error WifiLegacyHal::startSendingOffloadedPacket(const std::string& iface_name,
+ uint32_t cmd_id, uint16_t ether_type,
+ const std::vector<uint8_t>& ip_packet_data,
+ const std::array<uint8_t, 6>& src_address,
+ const std::array<uint8_t, 6>& dst_address,
+ uint32_t period_in_ms) {
+ std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
+ std::vector<uint8_t> src_address_internal(src_address.data(),
+ src_address.data() + src_address.size());
+ std::vector<uint8_t> dst_address_internal(dst_address.data(),
+ dst_address.data() + dst_address.size());
+ return global_func_table_.wifi_start_sending_offloaded_packet(
+ cmd_id, getIfaceHandle(iface_name), ether_type, ip_packet_data_internal.data(),
+ ip_packet_data_internal.size(), src_address_internal.data(),
+ dst_address_internal.data(), period_in_ms);
+}
+
+wifi_error WifiLegacyHal::stopSendingOffloadedPacket(const std::string& iface_name,
+ uint32_t cmd_id) {
+ return global_func_table_.wifi_stop_sending_offloaded_packet(cmd_id,
+ getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
+ wifi_power_scenario scenario) {
+ return global_func_table_.wifi_select_tx_power_scenario(getIfaceHandle(iface_name), scenario);
+}
+
+wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) {
+ return global_func_table_.wifi_reset_tx_power_scenario(getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, wifi_latency_mode mode) {
+ return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), mode);
+}
+
+wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode,
+ uint32_t completion_window) {
+ return global_func_table_.wifi_set_thermal_mitigation_mode(global_handle_, mode,
+ completion_window);
+}
+
+wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
+ uint32_t access_category) {
+ return global_func_table_.wifi_map_dscp_access_category(global_handle_, start, end,
+ access_category);
+}
+
+wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() {
+ return global_func_table_.wifi_reset_dscp_mapping(global_handle_);
+}
+
+std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet(
+ const std::string& iface_name) {
+ uint32_t supported_feature_flags = 0;
+ wifi_error status = WIFI_SUCCESS;
+
+ wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
+
+ if (iface_handle) {
+ status = global_func_table_.wifi_get_logger_supported_feature_set(iface_handle,
+ &supported_feature_flags);
+ }
+ return {status, supported_feature_flags};
+}
+
+wifi_error WifiLegacyHal::startPktFateMonitoring(const std::string& iface_name) {
+ return global_func_table_.wifi_start_pkt_fate_monitoring(getIfaceHandle(iface_name));
+}
+
+std::pair<wifi_error, std::vector<wifi_tx_report>> WifiLegacyHal::getTxPktFates(
+ const std::string& iface_name) {
+ std::vector<wifi_tx_report> tx_pkt_fates;
+ tx_pkt_fates.resize(MAX_FATE_LOG_LEN);
+ size_t num_fates = 0;
+ wifi_error status = global_func_table_.wifi_get_tx_pkt_fates(
+ getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), &num_fates);
+ CHECK(num_fates <= MAX_FATE_LOG_LEN);
+ tx_pkt_fates.resize(num_fates);
+ return {status, std::move(tx_pkt_fates)};
+}
+
+std::pair<wifi_error, std::vector<wifi_rx_report>> WifiLegacyHal::getRxPktFates(
+ const std::string& iface_name) {
+ std::vector<wifi_rx_report> rx_pkt_fates;
+ rx_pkt_fates.resize(MAX_FATE_LOG_LEN);
+ size_t num_fates = 0;
+ wifi_error status = global_func_table_.wifi_get_rx_pkt_fates(
+ getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), &num_fates);
+ CHECK(num_fates <= MAX_FATE_LOG_LEN);
+ rx_pkt_fates.resize(num_fates);
+ return {status, std::move(rx_pkt_fates)};
+}
+
+std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats(
+ const std::string& iface_name) {
+ WakeReasonStats stats;
+ stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
+ stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
+
+ // This legacy struct needs separate memory to store the variable sized wake
+ // reason types.
+ stats.wake_reason_cnt.cmd_event_wake_cnt =
+ reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data());
+ stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size();
+ stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0;
+ stats.wake_reason_cnt.driver_fw_local_wake_cnt =
+ reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data());
+ stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = stats.driver_fw_local_wake_cnt.size();
+ stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0;
+
+ wifi_error status = global_func_table_.wifi_get_wake_reason_stats(getIfaceHandle(iface_name),
+ &stats.wake_reason_cnt);
+
+ CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 &&
+ static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <=
+ kMaxWakeReasonStatsArraySize);
+ stats.cmd_event_wake_cnt.resize(stats.wake_reason_cnt.cmd_event_wake_cnt_used);
+ stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr;
+
+ CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 &&
+ static_cast<uint32_t>(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <=
+ kMaxWakeReasonStatsArraySize);
+ stats.driver_fw_local_wake_cnt.resize(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used);
+ stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr;
+
+ return {status, stats};
+}
+
+wifi_error WifiLegacyHal::registerRingBufferCallbackHandler(
+ const std::string& iface_name, const on_ring_buffer_data_callback& on_user_data_callback) {
+ if (on_ring_buffer_data_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_ring_buffer_data_internal_callback = [on_user_data_callback](
+ char* ring_name, char* buffer, int buffer_size,
+ wifi_ring_buffer_status* status) {
+ if (status && buffer) {
+ std::vector<uint8_t> buffer_vector(reinterpret_cast<uint8_t*>(buffer),
+ reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+ on_user_data_callback(ring_name, buffer_vector, *status);
+ }
+ };
+ wifi_error status = global_func_table_.wifi_set_log_handler(0, getIfaceHandle(iface_name),
+ {onAsyncRingBufferData});
+ if (status != WIFI_SUCCESS) {
+ on_ring_buffer_data_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(const std::string& iface_name) {
+ if (!on_ring_buffer_data_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_ring_buffer_data_internal_callback = nullptr;
+ return global_func_table_.wifi_reset_log_handler(0, getIfaceHandle(iface_name));
+}
+
+std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> WifiLegacyHal::getRingBuffersStatus(
+ const std::string& iface_name) {
+ std::vector<wifi_ring_buffer_status> ring_buffers_status;
+ ring_buffers_status.resize(kMaxRingBuffers);
+ uint32_t num_rings = kMaxRingBuffers;
+ wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
+ getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data());
+ CHECK(num_rings <= kMaxRingBuffers);
+ ring_buffers_status.resize(num_rings);
+ return {status, std::move(ring_buffers_status)};
+}
+
+wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name,
+ const std::string& ring_name,
+ uint32_t verbose_level, uint32_t max_interval_sec,
+ uint32_t min_data_size) {
+ return global_func_table_.wifi_start_logging(getIfaceHandle(iface_name), verbose_level, 0,
+ max_interval_sec, min_data_size,
+ makeCharVec(ring_name).data());
+}
+
+wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name,
+ const std::string& ring_name) {
+ return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name),
+ makeCharVec(ring_name).data());
+}
+
+wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
+ const std::string& iface_name, const on_error_alert_callback& on_user_alert_callback) {
+ if (on_error_alert_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_error_alert_internal_callback = [on_user_alert_callback](wifi_request_id id, char* buffer,
+ int buffer_size, int err_code) {
+ if (buffer) {
+ CHECK(id == 0);
+ on_user_alert_callback(
+ err_code,
+ std::vector<uint8_t>(reinterpret_cast<uint8_t*>(buffer),
+ reinterpret_cast<uint8_t*>(buffer) + buffer_size));
+ }
+ };
+ wifi_error status = global_func_table_.wifi_set_alert_handler(0, getIfaceHandle(iface_name),
+ {onAsyncErrorAlert});
+ if (status != WIFI_SUCCESS) {
+ on_error_alert_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(const std::string& iface_name) {
+ if (!on_error_alert_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_error_alert_internal_callback = nullptr;
+ return global_func_table_.wifi_reset_alert_handler(0, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
+ const std::string& iface_name,
+ const on_radio_mode_change_callback& on_user_change_callback) {
+ if (on_radio_mode_change_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_radio_mode_change_internal_callback = [on_user_change_callback](
+ wifi_request_id /* id */, uint32_t num_macs,
+ wifi_mac_info* mac_infos_arr) {
+ if (num_macs > 0 && mac_infos_arr) {
+ std::vector<WifiMacInfo> mac_infos_vec;
+ for (uint32_t i = 0; i < num_macs; i++) {
+ WifiMacInfo mac_info;
+ mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id;
+ mac_info.mac_band = mac_infos_arr[i].mac_band;
+ for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) {
+ WifiIfaceInfo iface_info;
+ iface_info.name = mac_infos_arr[i].iface_info[j].iface_name;
+ iface_info.channel = mac_infos_arr[i].iface_info[j].channel;
+ mac_info.iface_infos.push_back(iface_info);
+ }
+ mac_infos_vec.push_back(mac_info);
+ }
+ on_user_change_callback(mac_infos_vec);
+ }
+ };
+ wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler(
+ 0, getIfaceHandle(iface_name), {onAsyncRadioModeChange});
+ if (status != WIFI_SUCCESS) {
+ on_radio_mode_change_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler(
+ const on_subsystem_restart_callback& on_restart_callback) {
+ if (on_subsystem_restart_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_subsystem_restart_internal_callback = [on_restart_callback](const char* error) {
+ on_restart_callback(error);
+ };
+ wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler(
+ global_handle_, {onAsyncSubsystemRestart});
+ if (status != WIFI_SUCCESS) {
+ on_subsystem_restart_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::startRttRangeRequest(
+ const std::string& iface_name, wifi_request_id id,
+ const std::vector<wifi_rtt_config>& rtt_configs,
+ const on_rtt_results_callback& on_results_user_callback) {
+ if (on_rtt_results_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ on_rtt_results_internal_callback = [on_results_user_callback](wifi_request_id id,
+ unsigned num_results,
+ wifi_rtt_result* rtt_results[]) {
+ if (num_results > 0 && !rtt_results) {
+ LOG(ERROR) << "Unexpected nullptr in RTT results";
+ return;
+ }
+ std::vector<const wifi_rtt_result*> rtt_results_vec;
+ std::copy_if(rtt_results, rtt_results + num_results, back_inserter(rtt_results_vec),
+ [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; });
+ on_results_user_callback(id, rtt_results_vec);
+ };
+
+ std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs);
+ wifi_error status = global_func_table_.wifi_rtt_range_request(
+ id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
+ {onAsyncRttResults});
+ if (status != WIFI_SUCCESS) {
+ on_rtt_results_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::cancelRttRangeRequest(
+ const std::string& iface_name, wifi_request_id id,
+ const std::vector<std::array<uint8_t, 6>>& mac_addrs) {
+ if (!on_rtt_results_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, 6>), "MAC address size mismatch");
+ // TODO: How do we handle partial cancels (i.e only a subset of enabled mac
+ // addressed are cancelled).
+ std::vector<std::array<uint8_t, 6>> mac_addrs_internal(mac_addrs);
+ wifi_error status = global_func_table_.wifi_rtt_range_cancel(
+ id, getIfaceHandle(iface_name), mac_addrs.size(),
+ reinterpret_cast<mac_addr*>(mac_addrs_internal.data()));
+ // If the request Id is wrong, don't stop the ongoing range request. Any
+ // other error should be treated as the end of rtt ranging.
+ if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+ on_rtt_results_internal_callback = nullptr;
+ }
+ return status;
+}
+
+std::pair<wifi_error, wifi_rtt_capabilities> WifiLegacyHal::getRttCapabilities(
+ const std::string& iface_name) {
+ wifi_rtt_capabilities rtt_caps;
+ wifi_error status =
+ global_func_table_.wifi_get_rtt_capabilities(getIfaceHandle(iface_name), &rtt_caps);
+ return {status, rtt_caps};
+}
+
+std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
+ const std::string& iface_name) {
+ wifi_rtt_responder rtt_responder;
+ wifi_error status = global_func_table_.wifi_rtt_get_responder_info(getIfaceHandle(iface_name),
+ &rtt_responder);
+ return {status, rtt_responder};
+}
+
+wifi_error WifiLegacyHal::enableRttResponder(const std::string& iface_name, wifi_request_id id,
+ const wifi_channel_info& channel_hint,
+ uint32_t max_duration_secs,
+ const wifi_rtt_responder& info) {
+ wifi_rtt_responder info_internal(info);
+ return global_func_table_.wifi_enable_responder(id, getIfaceHandle(iface_name), channel_hint,
+ max_duration_secs, &info_internal);
+}
+
+wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, wifi_request_id id) {
+ return global_func_table_.wifi_disable_responder(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, wifi_request_id id,
+ const wifi_lci_information& info) {
+ wifi_lci_information info_internal(info);
+ return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), &info_internal);
+}
+
+wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, wifi_request_id id,
+ const wifi_lcr_information& info) {
+ wifi_lcr_information info_internal(info);
+ return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), &info_internal);
+}
+
+wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(const std::string& iface_name,
+ const NanCallbackHandlers& user_callbacks) {
+ on_nan_notify_response_user_callback = user_callbacks.on_notify_response;
+ on_nan_event_publish_terminated_user_callback = user_callbacks.on_event_publish_terminated;
+ on_nan_event_match_user_callback = user_callbacks.on_event_match;
+ on_nan_event_match_expired_user_callback = user_callbacks.on_event_match_expired;
+ on_nan_event_subscribe_terminated_user_callback = user_callbacks.on_event_subscribe_terminated;
+ on_nan_event_followup_user_callback = user_callbacks.on_event_followup;
+ on_nan_event_disc_eng_event_user_callback = user_callbacks.on_event_disc_eng_event;
+ on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled;
+ on_nan_event_tca_user_callback = user_callbacks.on_event_tca;
+ on_nan_event_beacon_sdf_payload_user_callback = user_callbacks.on_event_beacon_sdf_payload;
+ on_nan_event_data_path_request_user_callback = user_callbacks.on_event_data_path_request;
+ on_nan_event_data_path_confirm_user_callback = user_callbacks.on_event_data_path_confirm;
+ on_nan_event_data_path_end_user_callback = user_callbacks.on_event_data_path_end;
+ on_nan_event_transmit_follow_up_user_callback = user_callbacks.on_event_transmit_follow_up;
+ on_nan_event_range_request_user_callback = user_callbacks.on_event_range_request;
+ on_nan_event_range_report_user_callback = user_callbacks.on_event_range_report;
+ on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update;
+
+ return global_func_table_.wifi_nan_register_handler(
+ getIfaceHandle(iface_name),
+ {onAysncNanNotifyResponse, onAysncNanEventPublishReplied,
+ onAysncNanEventPublishTerminated, onAysncNanEventMatch, onAysncNanEventMatchExpired,
+ onAysncNanEventSubscribeTerminated, onAysncNanEventFollowup,
+ onAysncNanEventDiscEngEvent, onAysncNanEventDisabled, onAysncNanEventTca,
+ onAysncNanEventBeaconSdfPayload, onAysncNanEventDataPathRequest,
+ onAysncNanEventDataPathConfirm, onAysncNanEventDataPathEnd,
+ onAysncNanEventTransmitFollowUp, onAysncNanEventRangeRequest,
+ onAysncNanEventRangeReport, onAsyncNanEventScheduleUpdate});
+}
+
+wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id,
+ const NanEnableRequest& msg) {
+ NanEnableRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_enable_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, transaction_id id) {
+ return global_func_table_.wifi_nan_disable_request(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, transaction_id id,
+ const NanPublishRequest& msg) {
+ NanPublishRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_publish_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
+ const NanPublishCancelRequest& msg) {
+ NanPublishCancelRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_publish_cancel_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, transaction_id id,
+ const NanSubscribeRequest& msg) {
+ NanSubscribeRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_subscribe_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanSubscribeCancelRequest(const std::string& iface_name,
+ transaction_id id,
+ const NanSubscribeCancelRequest& msg) {
+ NanSubscribeCancelRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_subscribe_cancel_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanTransmitFollowupRequest(const std::string& iface_name,
+ transaction_id id,
+ const NanTransmitFollowupRequest& msg) {
+ NanTransmitFollowupRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_transmit_followup_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, transaction_id id,
+ const NanStatsRequest& msg) {
+ NanStatsRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_stats_request(id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, transaction_id id,
+ const NanConfigRequest& msg) {
+ NanConfigRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_config_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, transaction_id id,
+ const NanTCARequest& msg) {
+ NanTCARequest msg_internal(msg);
+ return global_func_table_.wifi_nan_tca_request(id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(const std::string& iface_name,
+ transaction_id id,
+ const NanBeaconSdfPayloadRequest& msg) {
+ NanBeaconSdfPayloadRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_beacon_sdf_payload_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() {
+ NanVersion version;
+ wifi_error status = global_func_table_.wifi_nan_get_version(global_handle_, &version);
+ return {status, version};
+}
+
+wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, transaction_id id) {
+ return global_func_table_.wifi_nan_get_capabilities(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
+ const std::string& data_iface_name) {
+ return global_func_table_.wifi_nan_data_interface_create(id, getIfaceHandle(iface_name),
+ makeCharVec(data_iface_name).data());
+}
+
+wifi_error WifiLegacyHal::nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
+ const std::string& data_iface_name) {
+ return global_func_table_.wifi_nan_data_interface_delete(id, getIfaceHandle(iface_name),
+ makeCharVec(data_iface_name).data());
+}
+
+wifi_error WifiLegacyHal::nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
+ const NanDataPathInitiatorRequest& msg) {
+ NanDataPathInitiatorRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_data_request_initiator(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanDataIndicationResponse(const std::string& iface_name,
+ transaction_id id,
+ const NanDataPathIndicationResponse& msg) {
+ NanDataPathIndicationResponse msg_internal(msg);
+ return global_func_table_.wifi_nan_data_indication_response(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+typedef struct {
+ u8 num_ndp_instances;
+ NanDataPathId ndp_instance_id;
+} NanDataPathEndSingleNdpIdRequest;
+
+wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, transaction_id id,
+ uint32_t ndpInstanceId) {
+ NanDataPathEndSingleNdpIdRequest msg;
+ msg.num_ndp_instances = 1;
+ msg.ndp_instance_id = ndpInstanceId;
+ wifi_error status = global_func_table_.wifi_nan_data_end(id, getIfaceHandle(iface_name),
+ (NanDataPathEndRequest*)&msg);
+ return status;
+}
+
+wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name,
+ std::array<int8_t, 2> code) {
+ std::string code_str(code.data(), code.data() + code.size());
+ return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), code_str.c_str());
+}
+
+wifi_error WifiLegacyHal::retrieveIfaceHandles() {
+ wifi_interface_handle* iface_handles = nullptr;
+ int num_iface_handles = 0;
+ wifi_error status =
+ global_func_table_.wifi_get_ifaces(global_handle_, &num_iface_handles, &iface_handles);
+ if (status != WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to enumerate interface handles";
+ return status;
+ }
+ iface_name_to_handle_.clear();
+ for (int i = 0; i < num_iface_handles; ++i) {
+ std::array<char, IFNAMSIZ> iface_name_arr = {};
+ status = global_func_table_.wifi_get_iface_name(iface_handles[i], iface_name_arr.data(),
+ iface_name_arr.size());
+ if (status != WIFI_SUCCESS) {
+ LOG(WARNING) << "Failed to get interface handle name";
+ continue;
+ }
+ // Assuming the interface name is null terminated since the legacy HAL
+ // API does not return a size.
+ std::string iface_name(iface_name_arr.data());
+ LOG(INFO) << "Adding interface handle for " << iface_name;
+ iface_name_to_handle_[iface_name] = iface_handles[i];
+ }
+ return WIFI_SUCCESS;
+}
+
+wifi_interface_handle WifiLegacyHal::getIfaceHandle(const std::string& iface_name) {
+ const auto iface_handle_iter = iface_name_to_handle_.find(iface_name);
+ if (iface_handle_iter == iface_name_to_handle_.end()) {
+ LOG(ERROR) << "Unknown iface name: " << iface_name;
+ return nullptr;
+ }
+ return iface_handle_iter->second;
+}
+
+void WifiLegacyHal::runEventLoop() {
+ LOG(DEBUG) << "Starting legacy HAL event loop";
+ global_func_table_.wifi_event_loop(global_handle_);
+ const auto lock = hidl_sync_util::acquireGlobalLock();
+ if (!awaiting_event_loop_termination_) {
+ LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
+ }
+ LOG(DEBUG) << "Legacy HAL event loop terminated";
+ awaiting_event_loop_termination_ = false;
+ stop_wait_cv_.notify_one();
+}
+
+std::pair<wifi_error, std::vector<wifi_cached_scan_results>> WifiLegacyHal::getGscanCachedResults(
+ const std::string& iface_name) {
+ std::vector<wifi_cached_scan_results> cached_scan_results;
+ cached_scan_results.resize(kMaxCachedGscanResults);
+ int32_t num_results = 0;
+ wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
+ getIfaceHandle(iface_name), true /* always flush */, cached_scan_results.size(),
+ cached_scan_results.data(), &num_results);
+ CHECK(num_results >= 0 && static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
+ cached_scan_results.resize(num_results);
+ // Check for invalid IE lengths in these cached scan results and correct it.
+ for (auto& cached_scan_result : cached_scan_results) {
+ int num_scan_results = cached_scan_result.num_results;
+ for (int i = 0; i < num_scan_results; i++) {
+ auto& scan_result = cached_scan_result.results[i];
+ if (scan_result.ie_length > 0) {
+ LOG(DEBUG) << "Cached scan result has non-zero IE length " << scan_result.ie_length;
+ scan_result.ie_length = 0;
+ }
+ }
+ }
+ return {status, std::move(cached_scan_results)};
+}
+
+wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname,
+ wifi_interface_type iftype) {
+ // Create the interface if it doesn't exist. If interface already exist,
+ // Vendor Hal should return WIFI_SUCCESS.
+ wifi_error status = global_func_table_.wifi_virtual_interface_create(global_handle_,
+ ifname.c_str(), iftype);
+ return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
+}
+
+wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) {
+ // Delete the interface if it was created dynamically.
+ wifi_error status =
+ global_func_table_.wifi_virtual_interface_delete(global_handle_, ifname.c_str());
+ return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
+}
+
+wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
+ wifi_error status) {
+ if (status == WIFI_SUCCESS) {
+ // refresh list of handlers now.
+ status = retrieveIfaceHandles();
+ } else if (status == WIFI_ERROR_NOT_SUPPORTED) {
+ // Vendor hal does not implement this API. Such vendor implementations
+ // are expected to create / delete interface by other means.
+
+ // check if interface exists.
+ if (if_nametoindex(ifname.c_str())) {
+ status = retrieveIfaceHandles();
+ }
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, std::string& ifname) {
+ std::array<char, IFNAMSIZ> buffer;
+
+ wifi_error res = global_func_table_.wifi_get_supported_iface_name(
+ global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size());
+ if (res == WIFI_SUCCESS) ifname = buffer.data();
+
+ return res;
+}
+
+wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(const std::string& ifname) {
+ return global_func_table_.wifi_multi_sta_set_primary_connection(global_handle_,
+ getIfaceHandle(ifname));
+}
+
+wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) {
+ return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, use_case);
+}
+
+wifi_error WifiLegacyHal::setCoexUnsafeChannels(
+ std::vector<wifi_coex_unsafe_channel> unsafe_channels, uint32_t restrictions) {
+ return global_func_table_.wifi_set_coex_unsafe_channels(global_handle_, unsafe_channels.size(),
+ unsafe_channels.data(), restrictions);
+}
+
+wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, wifi_voip_mode mode) {
+ return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode);
+}
+
+wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name,
+ const TwtCallbackHandlers& user_callbacks) {
+ on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
+ on_twt_event_teardown_completion_callback = user_callbacks.on_teardown_completion;
+ on_twt_event_info_frame_received_callback = user_callbacks.on_info_frame_received;
+ on_twt_event_device_notify_callback = user_callbacks.on_device_notify;
+
+ return global_func_table_.wifi_twt_register_handler(
+ getIfaceHandle(iface_name),
+ {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion,
+ onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify});
+}
+
+std::pair<wifi_error, TwtCapabilitySet> WifiLegacyHal::twtGetCapability(
+ const std::string& iface_name) {
+ TwtCapabilitySet capSet;
+ wifi_error status =
+ global_func_table_.wifi_twt_get_capability(getIfaceHandle(iface_name), &capSet);
+ return {status, capSet};
+}
+
+wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name,
+ const TwtSetupRequest& msg) {
+ TwtSetupRequest msgInternal(msg);
+ return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name,
+ const TwtTeardownRequest& msg) {
+ TwtTeardownRequest msgInternal(msg);
+ return global_func_table_.wifi_twt_teardown_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name,
+ const TwtInfoFrameRequest& msg) {
+ TwtInfoFrameRequest msgInternal(msg);
+ return global_func_table_.wifi_twt_info_frame_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats(const std::string& iface_name,
+ uint8_t configId) {
+ TwtStats stats;
+ wifi_error status =
+ global_func_table_.wifi_twt_get_stats(getIfaceHandle(iface_name), configId, &stats);
+ return {status, stats};
+}
+
+wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, uint8_t configId) {
+ return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), configId);
+}
+
+wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) {
+ return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), multiplier);
+}
+
+std::pair<wifi_error, std::vector<wifi_usable_channel>> WifiLegacyHal::getUsableChannels(
+ uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask) {
+ std::vector<wifi_usable_channel> channels;
+ channels.resize(kMaxWifiUsableChannels);
+ uint32_t size = 0;
+ wifi_error status = global_func_table_.wifi_get_usable_channels(
+ global_handle_, band_mask, iface_mode_mask, filter_mask, channels.size(), &size,
+ reinterpret_cast<wifi_usable_channel*>(channels.data()));
+ CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
+ channels.resize(size);
+ return {status, std::move(channels)};
+}
+
+wifi_error WifiLegacyHal::triggerSubsystemRestart() {
+ return global_func_table_.wifi_trigger_subsystem_restart(global_handle_);
+}
+
+wifi_error WifiLegacyHal::setIndoorState(bool isIndoor) {
+ return global_func_table_.wifi_set_indoor_state(global_handle_, isIndoor);
+}
+
+std::pair<wifi_error, wifi_radio_combination_matrix*>
+WifiLegacyHal::getSupportedRadioCombinationsMatrix() {
+ char* buffer = new char[kMaxSupportedRadioCombinationsMatrixLength];
+ std::fill(buffer, buffer + kMaxSupportedRadioCombinationsMatrixLength, 0);
+ uint32_t size = 0;
+ wifi_radio_combination_matrix* radio_combination_matrix_ptr =
+ reinterpret_cast<wifi_radio_combination_matrix*>(buffer);
+ wifi_error status = global_func_table_.wifi_get_supported_radio_combinations_matrix(
+ global_handle_, kMaxSupportedRadioCombinationsMatrixLength, &size,
+ radio_combination_matrix_ptr);
+ CHECK(size >= 0 && size <= kMaxSupportedRadioCombinationsMatrixLength);
+ return {status, radio_combination_matrix_ptr};
+}
+
+wifi_error WifiLegacyHal::chreNanRttRequest(const std::string& iface_name, bool enable) {
+ if (enable)
+ return global_func_table_.wifi_nan_rtt_chre_enable_request(0, getIfaceHandle(iface_name),
+ NULL);
+ else
+ return global_func_table_.wifi_nan_rtt_chre_disable_request(0, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::chreRegisterHandler(const std::string& iface_name,
+ const ChreCallbackHandlers& handler) {
+ if (on_chre_nan_rtt_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ on_chre_nan_rtt_internal_callback = handler.on_wifi_chre_nan_rtt_state;
+
+ wifi_error status = global_func_table_.wifi_chre_register_handler(getIfaceHandle(iface_name),
+ {onAsyncChreNanRttState});
+ if (status != WIFI_SUCCESS) {
+ on_chre_nan_rtt_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::enableWifiTxPowerLimits(const std::string& iface_name, bool enable) {
+ return global_func_table_.wifi_enable_tx_power_limits(getIfaceHandle(iface_name), enable);
+}
+
+wifi_error WifiLegacyHal::getWifiCachedScanResults(
+ const std::string& iface_name, const CachedScanResultsCallbackHandlers& handler) {
+ on_cached_scan_results_internal_callback = handler.on_cached_scan_results;
+
+ wifi_error status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
+ {onSyncCachedScanResults});
+
+ on_cached_scan_results_internal_callback = nullptr;
+ return status;
+}
+
+void WifiLegacyHal::invalidate() {
+ global_handle_ = nullptr;
+ iface_name_to_handle_.clear();
+ on_driver_memory_dump_internal_callback = nullptr;
+ on_firmware_memory_dump_internal_callback = nullptr;
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ on_link_layer_stats_result_internal_callback = nullptr;
+ on_rssi_threshold_breached_internal_callback = nullptr;
+ on_ring_buffer_data_internal_callback = nullptr;
+ on_error_alert_internal_callback = nullptr;
+ on_radio_mode_change_internal_callback = nullptr;
+ on_subsystem_restart_internal_callback = nullptr;
+ on_rtt_results_internal_callback = nullptr;
+ on_nan_notify_response_user_callback = nullptr;
+ on_nan_event_publish_terminated_user_callback = nullptr;
+ on_nan_event_match_user_callback = nullptr;
+ on_nan_event_match_expired_user_callback = nullptr;
+ on_nan_event_subscribe_terminated_user_callback = nullptr;
+ on_nan_event_followup_user_callback = nullptr;
+ on_nan_event_disc_eng_event_user_callback = nullptr;
+ on_nan_event_disabled_user_callback = nullptr;
+ on_nan_event_tca_user_callback = nullptr;
+ on_nan_event_beacon_sdf_payload_user_callback = nullptr;
+ on_nan_event_data_path_request_user_callback = nullptr;
+ on_nan_event_data_path_confirm_user_callback = nullptr;
+ on_nan_event_data_path_end_user_callback = nullptr;
+ on_nan_event_transmit_follow_up_user_callback = nullptr;
+ on_nan_event_range_request_user_callback = nullptr;
+ on_nan_event_range_report_user_callback = nullptr;
+ on_nan_event_schedule_update_user_callback = nullptr;
+ on_twt_event_setup_response_callback = nullptr;
+ on_twt_event_teardown_completion_callback = nullptr;
+ on_twt_event_info_frame_received_callback = nullptr;
+ on_twt_event_device_notify_callback = nullptr;
+ on_chre_nan_rtt_internal_callback = nullptr;
+}
+
+} // namespace legacy_hal
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal.h
new file mode 100644
index 0000000..b6bd5ea
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal.h
@@ -0,0 +1,739 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_LEGACY_HAL_H_
+#define WIFI_LEGACY_HAL_H_
+
+#include <condition_variable>
+#include <functional>
+#include <map>
+#include <thread>
+#include <vector>
+
+#include <hal_legacy/wifi_hal.h>
+#include <wifi_system/interface_tool.h>
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+// This is in a separate namespace to prevent typename conflicts between
+// the legacy HAL types and the HIDL interface types.
+namespace legacy_hal {
+// Import all the types defined inside the legacy HAL header files into this
+// namespace.
+using ::chre_nan_rtt_state;
+using ::frame_info;
+using ::frame_type;
+using ::FRAME_TYPE_80211_MGMT;
+using ::FRAME_TYPE_ETHERNET_II;
+using ::FRAME_TYPE_UNKNOWN;
+using ::fw_roaming_state_t;
+using ::mac_addr;
+using ::NAN_CHANNEL_24G_BAND;
+using ::NAN_CHANNEL_5G_BAND_HIGH;
+using ::NAN_CHANNEL_5G_BAND_LOW;
+using ::NAN_DISABLE_RANGE_REPORT;
+using ::NAN_DO_NOT_USE_SRF;
+using ::NAN_DP_CHANNEL_NOT_REQUESTED;
+using ::NAN_DP_CONFIG_NO_SECURITY;
+using ::NAN_DP_CONFIG_SECURITY;
+using ::NAN_DP_END;
+using ::NAN_DP_FORCE_CHANNEL_SETUP;
+using ::NAN_DP_INITIATOR_RESPONSE;
+using ::NAN_DP_INTERFACE_CREATE;
+using ::NAN_DP_INTERFACE_DELETE;
+using ::NAN_DP_REQUEST_ACCEPT;
+using ::NAN_DP_REQUEST_CHANNEL_SETUP;
+using ::NAN_DP_REQUEST_REJECT;
+using ::NAN_DP_RESPONDER_RESPONSE;
+using ::NAN_GET_CAPABILITIES;
+using ::NAN_MATCH_ALG_MATCH_CONTINUOUS;
+using ::NAN_MATCH_ALG_MATCH_NEVER;
+using ::NAN_MATCH_ALG_MATCH_ONCE;
+using ::NAN_PUBLISH_TYPE_SOLICITED;
+using ::NAN_PUBLISH_TYPE_UNSOLICITED;
+using ::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
+using ::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+using ::NAN_RANGING_AUTO_RESPONSE_ENABLE;
+using ::NAN_RANGING_DISABLE;
+using ::NAN_RANGING_ENABLE;
+using ::NAN_RESPONSE_BEACON_SDF_PAYLOAD;
+using ::NAN_RESPONSE_CONFIG;
+using ::NAN_RESPONSE_DISABLED;
+using ::NAN_RESPONSE_ENABLED;
+using ::NAN_RESPONSE_ERROR;
+using ::NAN_RESPONSE_PUBLISH;
+using ::NAN_RESPONSE_PUBLISH_CANCEL;
+using ::NAN_RESPONSE_STATS;
+using ::NAN_RESPONSE_SUBSCRIBE;
+using ::NAN_RESPONSE_SUBSCRIBE_CANCEL;
+using ::NAN_RESPONSE_TCA;
+using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP;
+using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+using ::NAN_SECURITY_KEY_INPUT_PMK;
+using ::NAN_SERVICE_ACCEPT_POLICY_ALL;
+using ::NAN_SERVICE_ACCEPT_POLICY_NONE;
+using ::NAN_SRF_ATTR_BLOOM_FILTER;
+using ::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
+using ::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
+using ::NAN_SRF_INCLUDE_RESPOND;
+using ::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
+using ::NAN_SSI_REQUIRED_IN_MATCH_IND;
+using ::NAN_STATUS_ALREADY_ENABLED;
+using ::NAN_STATUS_FOLLOWUP_QUEUE_FULL;
+using ::NAN_STATUS_INTERNAL_FAILURE;
+using ::NAN_STATUS_INVALID_NDP_ID;
+using ::NAN_STATUS_INVALID_PARAM;
+using ::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
+using ::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID;
+using ::NAN_STATUS_NAN_NOT_ALLOWED;
+using ::NAN_STATUS_NO_OTA_ACK;
+using ::NAN_STATUS_NO_RESOURCE_AVAILABLE;
+using ::NAN_STATUS_PROTOCOL_FAILURE;
+using ::NAN_STATUS_SUCCESS;
+using ::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
+using ::NAN_SUBSCRIBE_TYPE_ACTIVE;
+using ::NAN_SUBSCRIBE_TYPE_PASSIVE;
+using ::NAN_TRANSMIT_IN_DW;
+using ::NAN_TRANSMIT_IN_FAW;
+using ::NAN_TX_PRIORITY_HIGH;
+using ::NAN_TX_PRIORITY_NORMAL;
+using ::NAN_TX_TYPE_BROADCAST;
+using ::NAN_TX_TYPE_UNICAST;
+using ::NAN_USE_SRF;
+using ::NanBeaconSdfPayloadInd;
+using ::NanCapabilities;
+using ::NanChannelInfo;
+using ::NanConfigRequest;
+using ::NanDataPathChannelCfg;
+using ::NanDataPathConfirmInd;
+using ::NanDataPathEndInd;
+using ::NanDataPathIndicationResponse;
+using ::NanDataPathInitiatorRequest;
+using ::NanDataPathRequestInd;
+using ::NanDataPathScheduleUpdateInd;
+using ::NanDisabledInd;
+using ::NanDiscEngEventInd;
+using ::NanEnableRequest;
+using ::NanFollowupInd;
+using ::NanMatchAlg;
+using ::NanMatchExpiredInd;
+using ::NanMatchInd;
+using ::NanPublishCancelRequest;
+using ::NanPublishRequest;
+using ::NanPublishTerminatedInd;
+using ::NanPublishType;
+using ::NanRangeReportInd;
+using ::NanRangeRequestInd;
+using ::NanResponseMsg;
+using ::NanSRFType;
+using ::NanStatusType;
+using ::NanSubscribeCancelRequest;
+using ::NanSubscribeRequest;
+using ::NanSubscribeTerminatedInd;
+using ::NanSubscribeType;
+using ::NanTransmitFollowupInd;
+using ::NanTransmitFollowupRequest;
+using ::NanTxType;
+using ::ROAMING_DISABLE;
+using ::ROAMING_ENABLE;
+using ::RTT_PEER_AP;
+using ::RTT_PEER_NAN;
+using ::RTT_PEER_P2P_CLIENT;
+using ::RTT_PEER_P2P_GO;
+using ::RTT_PEER_STA;
+using ::rtt_peer_type;
+using ::RTT_STATUS_ABORTED;
+using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
+using ::RTT_STATUS_FAIL_BUSY_TRY_LATER;
+using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
+using ::RTT_STATUS_FAIL_INVALID_TS;
+using ::RTT_STATUS_FAIL_NO_CAPABILITY;
+using ::RTT_STATUS_FAIL_NO_RSP;
+using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
+using ::RTT_STATUS_FAIL_PROTOCOL;
+using ::RTT_STATUS_FAIL_REJECTED;
+using ::RTT_STATUS_FAIL_SCHEDULE;
+using ::RTT_STATUS_FAIL_TM_TIMEOUT;
+using ::RTT_STATUS_FAILURE;
+using ::RTT_STATUS_INVALID_REQ;
+using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
+using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE;
+using ::RTT_STATUS_NO_WIFI;
+using ::RTT_STATUS_SUCCESS;
+using ::RTT_TYPE_1_SIDED;
+using ::RTT_TYPE_2_SIDED;
+using ::RX_PKT_FATE_DRV_DROP_FILTER;
+using ::RX_PKT_FATE_DRV_DROP_INVALID;
+using ::RX_PKT_FATE_DRV_DROP_NOBUFS;
+using ::RX_PKT_FATE_DRV_DROP_OTHER;
+using ::RX_PKT_FATE_DRV_QUEUED;
+using ::RX_PKT_FATE_FW_DROP_FILTER;
+using ::RX_PKT_FATE_FW_DROP_INVALID;
+using ::RX_PKT_FATE_FW_DROP_NOBUFS;
+using ::RX_PKT_FATE_FW_DROP_OTHER;
+using ::RX_PKT_FATE_FW_QUEUED;
+using ::RX_PKT_FATE_SUCCESS;
+using ::ssid_t;
+using ::transaction_id;
+using ::TX_PKT_FATE_ACKED;
+using ::TX_PKT_FATE_DRV_DROP_INVALID;
+using ::TX_PKT_FATE_DRV_DROP_NOBUFS;
+using ::TX_PKT_FATE_DRV_DROP_OTHER;
+using ::TX_PKT_FATE_DRV_QUEUED;
+using ::TX_PKT_FATE_FW_DROP_INVALID;
+using ::TX_PKT_FATE_FW_DROP_NOBUFS;
+using ::TX_PKT_FATE_FW_DROP_OTHER;
+using ::TX_PKT_FATE_FW_QUEUED;
+using ::TX_PKT_FATE_SENT;
+using ::WIFI_AC_BE;
+using ::WIFI_AC_BK;
+using ::WIFI_AC_VI;
+using ::WIFI_AC_VO;
+using ::WIFI_ANTENNA_1X1;
+using ::WIFI_ANTENNA_2X2;
+using ::WIFI_ANTENNA_3X3;
+using ::WIFI_ANTENNA_4X4;
+using ::WIFI_ANTENNA_UNSPECIFIED;
+using ::wifi_band;
+using ::WIFI_BAND_A;
+using ::WIFI_BAND_A_DFS;
+using ::WIFI_BAND_A_WITH_DFS;
+using ::WIFI_BAND_ABG;
+using ::WIFI_BAND_ABG_WITH_DFS;
+using ::WIFI_BAND_BG;
+using ::WIFI_BAND_UNSPECIFIED;
+using ::wifi_cached_scan_report;
+using ::wifi_cached_scan_results;
+using ::WIFI_CHAN_WIDTH_10;
+using ::WIFI_CHAN_WIDTH_160;
+using ::WIFI_CHAN_WIDTH_20;
+using ::WIFI_CHAN_WIDTH_320;
+using ::WIFI_CHAN_WIDTH_40;
+using ::WIFI_CHAN_WIDTH_5;
+using ::WIFI_CHAN_WIDTH_80;
+using ::WIFI_CHAN_WIDTH_80P80;
+using ::WIFI_CHAN_WIDTH_INVALID;
+using ::wifi_channel_info;
+using ::wifi_channel_stat;
+using ::wifi_channel_width;
+using ::wifi_coex_restriction;
+using ::wifi_coex_unsafe_channel;
+using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
+using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+using ::wifi_error;
+using ::WIFI_ERROR_BUSY;
+using ::WIFI_ERROR_INVALID_ARGS;
+using ::WIFI_ERROR_INVALID_REQUEST_ID;
+using ::WIFI_ERROR_NONE;
+using ::WIFI_ERROR_NOT_AVAILABLE;
+using ::WIFI_ERROR_NOT_SUPPORTED;
+using ::WIFI_ERROR_OUT_OF_MEMORY;
+using ::WIFI_ERROR_TIMED_OUT;
+using ::WIFI_ERROR_TOO_MANY_REQUESTS;
+using ::WIFI_ERROR_UNINITIALIZED;
+using ::WIFI_ERROR_UNKNOWN;
+using ::wifi_gscan_capabilities;
+using ::wifi_hal_fn;
+using ::wifi_information_element;
+using ::WIFI_INTERFACE_IBSS;
+using ::WIFI_INTERFACE_MESH;
+using ::wifi_interface_mode;
+using ::WIFI_INTERFACE_NAN;
+using ::WIFI_INTERFACE_P2P_CLIENT;
+using ::WIFI_INTERFACE_P2P_GO;
+using ::WIFI_INTERFACE_SOFTAP;
+using ::WIFI_INTERFACE_STA;
+using ::WIFI_INTERFACE_TDLS;
+using ::wifi_interface_type;
+using ::WIFI_INTERFACE_TYPE_AP;
+using ::WIFI_INTERFACE_TYPE_NAN;
+using ::WIFI_INTERFACE_TYPE_P2P;
+using ::WIFI_INTERFACE_TYPE_STA;
+using ::WIFI_INTERFACE_UNKNOWN;
+using ::wifi_latency_mode;
+using ::WIFI_LATENCY_MODE_LOW;
+using ::WIFI_LATENCY_MODE_NORMAL;
+using ::wifi_lci_information;
+using ::wifi_lcr_information;
+using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
+using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
+using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
+using ::WIFI_LOGGER_PACKET_FATE_SUPPORTED;
+using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED;
+using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
+using ::WIFI_MOTION_EXPECTED;
+using ::WIFI_MOTION_NOT_EXPECTED;
+using ::wifi_motion_pattern;
+using ::WIFI_MOTION_UNKNOWN;
+using ::wifi_multi_sta_use_case;
+using ::wifi_power_scenario;
+using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
+using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
+using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
+using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
+using ::WIFI_POWER_SCENARIO_VOICE_CALL;
+using ::wifi_radio_combination;
+using ::wifi_radio_combination_matrix;
+using ::wifi_radio_configuration;
+using ::wifi_rate;
+using ::wifi_request_id;
+using ::wifi_ring_buffer_status;
+using ::wifi_roaming_capabilities;
+using ::wifi_roaming_config;
+using ::wifi_rtt_bw;
+using ::WIFI_RTT_BW_10;
+using ::WIFI_RTT_BW_160;
+using ::WIFI_RTT_BW_20;
+using ::WIFI_RTT_BW_320;
+using ::WIFI_RTT_BW_40;
+using ::WIFI_RTT_BW_5;
+using ::WIFI_RTT_BW_80;
+using ::wifi_rtt_capabilities;
+using ::wifi_rtt_config;
+using ::wifi_rtt_preamble;
+using ::WIFI_RTT_PREAMBLE_EHT;
+using ::WIFI_RTT_PREAMBLE_HE;
+using ::WIFI_RTT_PREAMBLE_HT;
+using ::WIFI_RTT_PREAMBLE_LEGACY;
+using ::WIFI_RTT_PREAMBLE_VHT;
+using ::wifi_rtt_responder;
+using ::wifi_rtt_result;
+using ::wifi_rtt_status;
+using ::wifi_rtt_type;
+using ::wifi_rx_packet_fate;
+using ::wifi_rx_report;
+using ::wifi_scan_bucket_spec;
+using ::wifi_scan_cmd_params;
+using ::WIFI_SCAN_FLAG_INTERRUPTED;
+using ::wifi_scan_result;
+using ::WIFI_SUCCESS;
+using ::wifi_tx_packet_fate;
+using ::wifi_tx_report;
+using ::wifi_usable_channel;
+using ::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
+using ::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
+using ::WLAN_MAC_2_4_BAND;
+using ::WLAN_MAC_5_0_BAND;
+using ::WLAN_MAC_60_0_BAND;
+using ::WLAN_MAC_6_0_BAND;
+
+// APF capabilities supported by the iface.
+struct PacketFilterCapabilities {
+ uint32_t version;
+ uint32_t max_len;
+};
+
+// WARNING: We don't care about the variable sized members of either
+// |wifi_iface_stat|, |wifi_radio_stat| structures. So, using the pragma
+// to escape the compiler warnings regarding this.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
+// The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in
+// |wifi_radio_stat| structure in the legacy HAL API. Separate that out
+// into a separate return element to avoid passing pointers around.
+struct LinkLayerRadioStats {
+ wifi_radio_stat stats;
+ std::vector<uint32_t> tx_time_per_levels;
+ std::vector<wifi_channel_stat> channel_stats;
+};
+
+struct WifiPeerInfo {
+ wifi_peer_info peer_info;
+ std::vector<wifi_rate_stat> rate_stats;
+};
+
+struct LinkLayerStats {
+ wifi_iface_stat iface;
+ std::vector<LinkLayerRadioStats> radios;
+ std::vector<WifiPeerInfo> peers;
+};
+#pragma GCC diagnostic pop
+
+// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
+// |WLAN_DRIVER_WAKE_REASON_CNT.driver_fw_local_wake_cnt| stats is provided
+// as a pointer in |WLAN_DRIVER_WAKE_REASON_CNT| structure in the legacy HAL
+// API. Separate that out into a separate return elements to avoid passing
+// pointers around.
+struct WakeReasonStats {
+ WLAN_DRIVER_WAKE_REASON_CNT wake_reason_cnt;
+ std::vector<uint32_t> cmd_event_wake_cnt;
+ std::vector<uint32_t> driver_fw_local_wake_cnt;
+};
+
+// NAN response and event callbacks struct.
+struct NanCallbackHandlers {
+ // NotifyResponse invoked to notify the status of the Request.
+ std::function<void(transaction_id, const NanResponseMsg&)> on_notify_response;
+ // Various event callbacks.
+ std::function<void(const NanPublishTerminatedInd&)> on_event_publish_terminated;
+ std::function<void(const NanMatchInd&)> on_event_match;
+ std::function<void(const NanMatchExpiredInd&)> on_event_match_expired;
+ std::function<void(const NanSubscribeTerminatedInd&)> on_event_subscribe_terminated;
+ std::function<void(const NanFollowupInd&)> on_event_followup;
+ std::function<void(const NanDiscEngEventInd&)> on_event_disc_eng_event;
+ std::function<void(const NanDisabledInd&)> on_event_disabled;
+ std::function<void(const NanTCAInd&)> on_event_tca;
+ std::function<void(const NanBeaconSdfPayloadInd&)> on_event_beacon_sdf_payload;
+ std::function<void(const NanDataPathRequestInd&)> on_event_data_path_request;
+ std::function<void(const NanDataPathConfirmInd&)> on_event_data_path_confirm;
+ std::function<void(const NanDataPathEndInd&)> on_event_data_path_end;
+ std::function<void(const NanTransmitFollowupInd&)> on_event_transmit_follow_up;
+ std::function<void(const NanRangeRequestInd&)> on_event_range_request;
+ std::function<void(const NanRangeReportInd&)> on_event_range_report;
+ std::function<void(const NanDataPathScheduleUpdateInd&)> on_event_schedule_update;
+};
+
+// Full scan results contain IE info and are hence passed by reference, to
+// preserve the variable length array member |ie_data|. Callee must not retain
+// the pointer.
+using on_gscan_full_result_callback =
+ std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>;
+// These scan results don't contain any IE info, so no need to pass by
+// reference.
+using on_gscan_results_callback =
+ std::function<void(wifi_request_id, const std::vector<wifi_cached_scan_results>&)>;
+
+// Invoked when the rssi value breaches the thresholds set.
+using on_rssi_threshold_breached_callback =
+ std::function<void(wifi_request_id, std::array<uint8_t, 6>, int8_t)>;
+
+// Callback for RTT range request results.
+// Rtt results contain IE info and are hence passed by reference, to
+// preserve the |LCI| and |LCR| pointers. Callee must not retain
+// the pointer.
+using on_rtt_results_callback =
+ std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result*>&)>;
+
+// Callback for ring buffer data.
+using on_ring_buffer_data_callback = std::function<void(
+ const std::string&, const std::vector<uint8_t>&, const wifi_ring_buffer_status&)>;
+
+// Callback for alerts.
+using on_error_alert_callback = std::function<void(int32_t, const std::vector<uint8_t>&)>;
+
+// Callback for subsystem restart
+using on_subsystem_restart_callback = std::function<void(const std::string&)>;
+
+// Struct for the mac info from the legacy HAL. This is a cleaner version
+// of the |wifi_mac_info| & |wifi_iface_info|.
+typedef struct {
+ std::string name;
+ wifi_channel channel;
+} WifiIfaceInfo;
+
+typedef struct {
+ uint32_t wlan_mac_id;
+ /* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */
+ uint32_t mac_band;
+ /* Represents the connected Wi-Fi interfaces associated with each MAC */
+ std::vector<WifiIfaceInfo> iface_infos;
+} WifiMacInfo;
+
+// Callback for radio mode change
+using on_radio_mode_change_callback = std::function<void(const std::vector<WifiMacInfo>&)>;
+
+// TWT response and event callbacks struct.
+struct TwtCallbackHandlers {
+ // Callback for TWT setup response
+ std::function<void(const TwtSetupResponse&)> on_setup_response;
+ // Callback for TWT teardown completion
+ std::function<void(const TwtTeardownCompletion&)> on_teardown_completion;
+ // Callback for TWT info frame received event
+ std::function<void(const TwtInfoFrameReceived&)> on_info_frame_received;
+ // Callback for TWT notification from the device
+ std::function<void(const TwtDeviceNotify&)> on_device_notify;
+};
+
+// CHRE response and event callbacks struct.
+struct ChreCallbackHandlers {
+ // Callback for CHRE NAN RTT
+ std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
+};
+
+// Cached Scan Results response and event callbacks struct.
+struct CachedScanResultsCallbackHandlers {
+ // Callback for Cached Scan Results
+ std::function<void(wifi_cached_scan_report*)> on_cached_scan_results;
+};
+
+/**
+ * Class that encapsulates all legacy HAL interactions.
+ * This class manages the lifetime of the event loop thread used by legacy HAL.
+ *
+ * Note: There will only be a single instance of this class created in the Wifi
+ * object and will be valid for the lifetime of the process.
+ */
+class WifiLegacyHal {
+ public:
+ WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, const wifi_hal_fn& fn,
+ bool is_primary);
+ virtual ~WifiLegacyHal() = default;
+
+ // Initialize the legacy HAL function table.
+ virtual wifi_error initialize();
+ // Start the legacy HAL and the event looper thread.
+ virtual wifi_error start();
+ // Deinitialize the legacy HAL and wait for the event loop thread to exit
+ // using a predefined timeout.
+ virtual wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
+ const std::function<void()>& on_complete_callback);
+ virtual wifi_error waitForDriverReady();
+ // Checks if legacy HAL has successfully started
+ bool isStarted();
+ // Wrappers for all the functions in the legacy HAL function table.
+ virtual std::pair<wifi_error, std::string> getDriverVersion(const std::string& iface_name);
+ virtual std::pair<wifi_error, std::string> getFirmwareVersion(const std::string& iface_name);
+ std::pair<wifi_error, std::vector<uint8_t>> requestDriverMemoryDump(
+ const std::string& iface_name);
+ std::pair<wifi_error, std::vector<uint8_t>> requestFirmwareMemoryDump(
+ const std::string& iface_name);
+ virtual std::pair<wifi_error, uint64_t> getSupportedFeatureSet(const std::string& iface_name);
+ // APF functions.
+ std::pair<wifi_error, PacketFilterCapabilities> getPacketFilterCapabilities(
+ const std::string& iface_name);
+ wifi_error setPacketFilter(const std::string& iface_name, const std::vector<uint8_t>& program);
+ std::pair<wifi_error, std::vector<uint8_t>> readApfPacketFilterData(
+ const std::string& iface_name);
+ // Gscan functions.
+ std::pair<wifi_error, wifi_gscan_capabilities> getGscanCapabilities(
+ const std::string& iface_name);
+ // These API's provides a simplified interface over the legacy Gscan API's:
+ // a) All scan events from the legacy HAL API other than the
+ // |WIFI_SCAN_FAILED| are treated as notification of results.
+ // This method then retrieves the cached scan results from the legacy
+ // HAL API and triggers the externally provided
+ // |on_results_user_callback| on success.
+ // b) |WIFI_SCAN_FAILED| scan event or failure to retrieve cached scan
+ // results
+ // triggers the externally provided |on_failure_user_callback|.
+ // c) Full scan result event triggers the externally provided
+ // |on_full_result_user_callback|.
+ wifi_error startGscan(const std::string& iface_name, wifi_request_id id,
+ const wifi_scan_cmd_params& params,
+ const std::function<void(wifi_request_id)>& on_failure_callback,
+ const on_gscan_results_callback& on_results_callback,
+ const on_gscan_full_result_callback& on_full_result_callback);
+ wifi_error stopGscan(const std::string& iface_name, wifi_request_id id);
+ std::pair<wifi_error, std::vector<uint32_t>> getValidFrequenciesForBand(
+ const std::string& iface_name, wifi_band band);
+ virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on);
+ // Link layer stats functions.
+ wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug);
+ wifi_error disableLinkLayerStats(const std::string& iface_name);
+ std::pair<wifi_error, LinkLayerStats> getLinkLayerStats(const std::string& iface_name);
+ // RSSI monitor functions.
+ wifi_error startRssiMonitoring(
+ const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
+ const on_rssi_threshold_breached_callback& on_threshold_breached_callback);
+ wifi_error stopRssiMonitoring(const std::string& iface_name, wifi_request_id id);
+ std::pair<wifi_error, wifi_roaming_capabilities> getRoamingCapabilities(
+ const std::string& iface_name);
+ wifi_error configureRoaming(const std::string& iface_name, const wifi_roaming_config& config);
+ wifi_error enableFirmwareRoaming(const std::string& iface_name, fw_roaming_state_t state);
+ wifi_error configureNdOffload(const std::string& iface_name, bool enable);
+ wifi_error startSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id,
+ uint16_t ether_type,
+ const std::vector<uint8_t>& ip_packet_data,
+ const std::array<uint8_t, 6>& src_address,
+ const std::array<uint8_t, 6>& dst_address,
+ uint32_t period_in_ms);
+ wifi_error stopSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id);
+ virtual wifi_error selectTxPowerScenario(const std::string& iface_name,
+ wifi_power_scenario scenario);
+ virtual wifi_error resetTxPowerScenario(const std::string& iface_name);
+ wifi_error setLatencyMode(const std::string& iface_name, wifi_latency_mode mode);
+ wifi_error setThermalMitigationMode(wifi_thermal_mode mode, uint32_t completion_window);
+ wifi_error setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
+ uint32_t access_category);
+ wifi_error resetDscpToAccessCategoryMapping();
+ // Logger/debug functions.
+ std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet(const std::string& iface_name);
+ wifi_error startPktFateMonitoring(const std::string& iface_name);
+ std::pair<wifi_error, std::vector<wifi_tx_report>> getTxPktFates(const std::string& iface_name);
+ std::pair<wifi_error, std::vector<wifi_rx_report>> getRxPktFates(const std::string& iface_name);
+ std::pair<wifi_error, WakeReasonStats> getWakeReasonStats(const std::string& iface_name);
+ wifi_error registerRingBufferCallbackHandler(
+ const std::string& iface_name, const on_ring_buffer_data_callback& on_data_callback);
+ wifi_error deregisterRingBufferCallbackHandler(const std::string& iface_name);
+ virtual wifi_error registerSubsystemRestartCallbackHandler(
+ const on_subsystem_restart_callback& on_restart_callback);
+ std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> getRingBuffersStatus(
+ const std::string& iface_name);
+ wifi_error startRingBufferLogging(const std::string& iface_name, const std::string& ring_name,
+ uint32_t verbose_level, uint32_t max_interval_sec,
+ uint32_t min_data_size);
+ wifi_error getRingBufferData(const std::string& iface_name, const std::string& ring_name);
+ wifi_error registerErrorAlertCallbackHandler(const std::string& iface_name,
+ const on_error_alert_callback& on_alert_callback);
+ wifi_error deregisterErrorAlertCallbackHandler(const std::string& iface_name);
+ // Radio mode functions.
+ virtual wifi_error registerRadioModeChangeCallbackHandler(
+ const std::string& iface_name,
+ const on_radio_mode_change_callback& on_user_change_callback);
+ // RTT functions.
+ wifi_error startRttRangeRequest(const std::string& iface_name, wifi_request_id id,
+ const std::vector<wifi_rtt_config>& rtt_configs,
+ const on_rtt_results_callback& on_results_callback);
+ wifi_error cancelRttRangeRequest(const std::string& iface_name, wifi_request_id id,
+ const std::vector<std::array<uint8_t, 6>>& mac_addrs);
+ std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities(const std::string& iface_name);
+ std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo(const std::string& iface_name);
+ wifi_error enableRttResponder(const std::string& iface_name, wifi_request_id id,
+ const wifi_channel_info& channel_hint, uint32_t max_duration_secs,
+ const wifi_rtt_responder& info);
+ wifi_error disableRttResponder(const std::string& iface_name, wifi_request_id id);
+ wifi_error setRttLci(const std::string& iface_name, wifi_request_id id,
+ const wifi_lci_information& info);
+ wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id,
+ const wifi_lcr_information& info);
+ // NAN functions.
+ virtual wifi_error nanRegisterCallbackHandlers(const std::string& iface_name,
+ const NanCallbackHandlers& callbacks);
+ wifi_error nanEnableRequest(const std::string& iface_name, transaction_id id,
+ const NanEnableRequest& msg);
+ virtual wifi_error nanDisableRequest(const std::string& iface_name, transaction_id id);
+ wifi_error nanPublishRequest(const std::string& iface_name, transaction_id id,
+ const NanPublishRequest& msg);
+ wifi_error nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
+ const NanPublishCancelRequest& msg);
+ wifi_error nanSubscribeRequest(const std::string& iface_name, transaction_id id,
+ const NanSubscribeRequest& msg);
+ wifi_error nanSubscribeCancelRequest(const std::string& iface_name, transaction_id id,
+ const NanSubscribeCancelRequest& msg);
+ wifi_error nanTransmitFollowupRequest(const std::string& iface_name, transaction_id id,
+ const NanTransmitFollowupRequest& msg);
+ wifi_error nanStatsRequest(const std::string& iface_name, transaction_id id,
+ const NanStatsRequest& msg);
+ wifi_error nanConfigRequest(const std::string& iface_name, transaction_id id,
+ const NanConfigRequest& msg);
+ wifi_error nanTcaRequest(const std::string& iface_name, transaction_id id,
+ const NanTCARequest& msg);
+ wifi_error nanBeaconSdfPayloadRequest(const std::string& iface_name, transaction_id id,
+ const NanBeaconSdfPayloadRequest& msg);
+ std::pair<wifi_error, NanVersion> nanGetVersion();
+ wifi_error nanGetCapabilities(const std::string& iface_name, transaction_id id);
+ wifi_error nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
+ const std::string& data_iface_name);
+ virtual wifi_error nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
+ const std::string& data_iface_name);
+ wifi_error nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
+ const NanDataPathInitiatorRequest& msg);
+ wifi_error nanDataIndicationResponse(const std::string& iface_name, transaction_id id,
+ const NanDataPathIndicationResponse& msg);
+ wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, uint32_t ndpInstanceId);
+ // AP functions.
+ wifi_error setCountryCode(const std::string& iface_name, std::array<int8_t, 2> code);
+
+ // interface functions.
+ virtual wifi_error createVirtualInterface(const std::string& ifname,
+ wifi_interface_type iftype);
+ virtual wifi_error deleteVirtualInterface(const std::string& ifname);
+ virtual wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname);
+
+ // STA + STA functions
+ virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname);
+ virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case);
+
+ // Coex functions.
+ virtual wifi_error setCoexUnsafeChannels(std::vector<wifi_coex_unsafe_channel> unsafe_channels,
+ uint32_t restrictions);
+
+ wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode);
+
+ wifi_error twtRegisterHandler(const std::string& iface_name,
+ const TwtCallbackHandlers& handler);
+
+ std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(const std::string& iface_name);
+
+ wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg);
+
+ wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg);
+
+ wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg);
+
+ std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, uint8_t configId);
+
+ wifi_error twtClearStats(const std::string& iface_name, uint8_t configId);
+
+ wifi_error setDtimConfig(const std::string& iface_name, uint32_t multiplier);
+
+ // Retrieve the list of usable channels in the requested bands
+ // for the requested modes
+ std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels(
+ uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask);
+
+ wifi_error triggerSubsystemRestart();
+
+ wifi_error setIndoorState(bool isIndoor);
+
+ std::pair<wifi_error, wifi_radio_combination_matrix*> getSupportedRadioCombinationsMatrix();
+
+ // CHRE NAN RTT function
+ wifi_error chreNanRttRequest(const std::string& iface_name, bool enable);
+
+ wifi_error chreRegisterHandler(const std::string& iface_name,
+ const ChreCallbackHandlers& handler);
+
+ wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
+ wifi_error getWifiCachedScanResults(const std::string& iface_name,
+ const CachedScanResultsCallbackHandlers& handler);
+
+ private:
+ // Retrieve interface handles for all the available interfaces.
+ wifi_error retrieveIfaceHandles();
+ wifi_interface_handle getIfaceHandle(const std::string& iface_name);
+ // Run the legacy HAL event loop thread.
+ void runEventLoop();
+ // Retrieve the cached gscan results to pass the results back to the
+ // external callbacks.
+ std::pair<wifi_error, std::vector<wifi_cached_scan_results>> getGscanCachedResults(
+ const std::string& iface_name);
+ void invalidate();
+ // Handles wifi (error) status of Virtual interface create/delete
+ wifi_error handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
+ wifi_error status);
+
+ // Global function table of legacy HAL.
+ wifi_hal_fn global_func_table_;
+ // Opaque handle to be used for all global operations.
+ wifi_handle global_handle_;
+ // Map of interface name to handle that is to be used for all interface
+ // specific operations.
+ std::map<std::string, wifi_interface_handle> iface_name_to_handle_;
+ // Flag to indicate if we have initiated the cleanup of legacy HAL.
+ std::atomic<bool> awaiting_event_loop_termination_;
+ std::condition_variable_any stop_wait_cv_;
+ // Flag to indicate if the legacy HAL has been started.
+ bool is_started_;
+ std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
+ // flag to indicate if this HAL is for the primary chip. This is used
+ // in order to avoid some hard-coded behavior used with older HALs,
+ // such as bring wlan0 interface up/down on start/stop HAL.
+ // it may be removed once vendor HALs are updated.
+ bool is_primary_;
+};
+
+} // namespace legacy_hal
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_LEGACY_HAL_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_factory.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_factory.cpp
new file mode 100644
index 0000000..147bf4d
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_factory.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <android-base/logging.h>
+#include <dlfcn.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+
+#include "wifi_legacy_hal_factory.h"
+#include "wifi_legacy_hal_stubs.h"
+
+namespace {
+static constexpr char kVendorHalsDescPath[] = "/vendor/etc/wifi/vendor_hals";
+static constexpr char kVendorHalsDescExt[] = ".xml";
+static constexpr uint32_t kVendorHalsDescVersion = 1;
+
+bool isDirectory(struct dirent* entryPtr) {
+ bool isDir = false;
+ if (entryPtr->d_type != DT_UNKNOWN && entryPtr->d_type != DT_LNK) {
+ isDir = (entryPtr->d_type == DT_DIR);
+ } else {
+ struct stat entryStat;
+ stat(entryPtr->d_name, &entryStat);
+ isDir = S_ISDIR(entryStat.st_mode);
+ }
+ return isDir;
+}
+
+bool isFileExtension(const char* name, const char* ext) {
+ if (name == NULL) return false;
+ if (ext == NULL) return false;
+
+ size_t extLen = strlen(ext);
+ size_t nameLen = strlen(name);
+
+ if (extLen > nameLen) return false;
+
+ if (strncmp(name + nameLen - extLen, ext, extLen) != 0) return false;
+
+ return true;
+}
+}; // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace legacy_hal {
+
+WifiLegacyHalFactory::WifiLegacyHalFactory(
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+ : iface_tool_(iface_tool) {}
+
+std::vector<std::shared_ptr<WifiLegacyHal>> WifiLegacyHalFactory::getHals() {
+ if (legacy_hals_.empty()) {
+ if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList();
+ for (auto& desc : descs_) {
+ std::shared_ptr<WifiLegacyHal> hal =
+ std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn, desc.primary);
+ legacy_hals_.push_back(hal);
+ }
+ }
+
+ return legacy_hals_;
+}
+
+bool WifiLegacyHalFactory::initVendorHalDescriptorFromLinked() {
+ wifi_hal_lib_desc desc;
+
+ if (!initLinkedHalFunctionTable(&desc.fn)) return false;
+
+ desc.primary = true;
+ desc.handle = NULL;
+ descs_.push_back(desc);
+ return true;
+}
+
+bool WifiLegacyHalFactory::initLinkedHalFunctionTable(wifi_hal_fn* hal_fn) {
+ init_wifi_vendor_hal_func_table_t initfn;
+
+ initfn = (init_wifi_vendor_hal_func_table_t)dlsym(RTLD_DEFAULT,
+ "init_wifi_vendor_hal_func_table");
+ if (!initfn) {
+ LOG(INFO) << "no vendor HAL library linked, will try dynamic load";
+ return false;
+ }
+
+ if (!initHalFuncTableWithStubs(hal_fn)) {
+ LOG(ERROR) << "Can not initialize the basic function pointer table";
+ return false;
+ }
+
+ if (initfn(hal_fn) != WIFI_SUCCESS) {
+ LOG(ERROR) << "Can not initialize the vendor function pointer table";
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Overall structure of the HAL descriptor XML schema
+ *
+ * <?xml version="1.0" encoding="UTF-8"?>
+ * <WifiVendorHal version="1">
+ * <path>/vendor/lib64/libwifi-hal-qcom.so</path>
+ * <primary>1</primary>
+ * </WifiVendorHal>
+ */
+void WifiLegacyHalFactory::initVendorHalsDescriptorList() {
+ xmlDocPtr xml;
+ xmlNodePtr node, cnode;
+ char* version;
+ std::string path;
+ xmlChar* value;
+ wifi_hal_lib_desc desc;
+
+ LOG(INFO) << "processing vendor HALs descriptions in " << kVendorHalsDescPath;
+ DIR* dirPtr = ::opendir(kVendorHalsDescPath);
+ if (dirPtr == NULL) {
+ LOG(ERROR) << "failed to open " << kVendorHalsDescPath;
+ return;
+ }
+ for (struct dirent* entryPtr = ::readdir(dirPtr); entryPtr != NULL;
+ entryPtr = ::readdir(dirPtr)) {
+ if (isDirectory(entryPtr)) continue;
+
+ if (!isFileExtension(entryPtr->d_name, kVendorHalsDescExt))
+ continue; // only process .xml files
+
+ LOG(INFO) << "processing config file: " << entryPtr->d_name;
+
+ std::string fullPath(kVendorHalsDescPath);
+ fullPath.append("/");
+ fullPath.append(entryPtr->d_name);
+ xml = xmlReadFile(fullPath.c_str(), "UTF-8", XML_PARSE_RECOVER);
+ if (!xml) {
+ LOG(ERROR) << "failed to parse: " << entryPtr->d_name << " skipping...";
+ continue;
+ }
+ node = xmlDocGetRootElement(xml);
+ if (!node) {
+ LOG(ERROR) << "empty config file: " << entryPtr->d_name << " skipping...";
+ goto skip;
+ }
+ if (xmlStrcmp(node->name, BAD_CAST "WifiVendorHal")) {
+ LOG(ERROR) << "bad config, root element not WifiVendorHal: " << entryPtr->d_name
+ << " skipping...";
+ goto skip;
+ }
+ version = (char*)xmlGetProp(node, BAD_CAST "version");
+ if (!version || strtoul(version, NULL, 0) != kVendorHalsDescVersion) {
+ LOG(ERROR) << "conf file: " << entryPtr->d_name
+ << "must have version: " << kVendorHalsDescVersion << ", skipping...";
+ goto skip;
+ }
+ cnode = node->children;
+ path.clear();
+ desc.primary = false;
+ while (cnode) {
+ if (!xmlStrcmp(cnode->name, BAD_CAST "path")) {
+ value = xmlNodeListGetString(xml, cnode->children, 1);
+ if (value) path = (char*)value;
+ xmlFree(value);
+ } else if (!xmlStrcmp(cnode->name, BAD_CAST "primary")) {
+ value = xmlNodeListGetString(xml, cnode->children, 1);
+ desc.primary = !xmlStrcmp(value, BAD_CAST "1");
+ xmlFree(value);
+ }
+ cnode = cnode->next;
+ }
+ if (path.empty()) {
+ LOG(ERROR) << "hal library path not provided in: " << entryPtr->d_name
+ << ", skipping...";
+ goto skip;
+ }
+ if (loadVendorHalLib(path, desc)) {
+ if (desc.primary)
+ descs_.insert(descs_.begin(), desc);
+ else
+ descs_.push_back(desc);
+ }
+ skip:
+ xmlFreeDoc(xml);
+ }
+ ::closedir(dirPtr);
+}
+
+bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc) {
+ void* h = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
+ init_wifi_vendor_hal_func_table_t initfn;
+ wifi_error res;
+
+ if (!h) {
+ LOG(ERROR) << "failed to open vendor hal library: " << path;
+ return false;
+ }
+ initfn = (init_wifi_vendor_hal_func_table_t)dlsym(h, "init_wifi_vendor_hal_func_table");
+ if (!initfn) {
+ LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path;
+ goto out_err;
+ }
+
+ if (!initHalFuncTableWithStubs(&desc.fn)) {
+ LOG(ERROR) << "Can not initialize the basic function pointer table";
+ goto out_err;
+ }
+ res = initfn(&desc.fn);
+ if (res != WIFI_SUCCESS) {
+ LOG(ERROR) << "failed to initialize the vendor func table in: " << path
+ << " error: " << res;
+ goto out_err;
+ }
+
+ res = desc.fn.wifi_early_initialize();
+ // vendor HALs which do not implement early_initialize will return
+ // WIFI_ERROR_NOT_SUPPORTED, treat this as success.
+ if (res != WIFI_SUCCESS && res != WIFI_ERROR_NOT_SUPPORTED) {
+ LOG(ERROR) << "early initialization failed in: " << path << " error: " << res;
+ goto out_err;
+ }
+
+ desc.handle = h;
+ return true;
+out_err:
+ dlclose(h);
+ return false;
+}
+
+} // namespace legacy_hal
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_factory.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_factory.h
new file mode 100644
index 0000000..9f4423e
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_factory.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_LEGACY_HAL_FACTORY_H_
+#define WIFI_LEGACY_HAL_FACTORY_H_
+
+#include <wifi_system/interface_tool.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+// This is in a separate namespace to prevent typename conflicts between
+// the legacy HAL types and the HIDL interface types.
+namespace legacy_hal {
+/**
+ * Class that creates WifiLegacyHal objects for vendor HALs in the system.
+ */
+class WifiLegacyHalFactory {
+ public:
+ WifiLegacyHalFactory(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
+ virtual ~WifiLegacyHalFactory() = default;
+
+ std::vector<std::shared_ptr<WifiLegacyHal>> getHals();
+
+ private:
+ typedef struct {
+ wifi_hal_fn fn;
+ bool primary;
+ void* handle;
+ } wifi_hal_lib_desc;
+
+ bool initVendorHalDescriptorFromLinked();
+ void initVendorHalsDescriptorList();
+ bool initLinkedHalFunctionTable(wifi_hal_fn* hal_fn);
+ bool loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc);
+
+ std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
+ std::vector<wifi_hal_lib_desc> descs_;
+ std::vector<std::shared_ptr<WifiLegacyHal>> legacy_hals_;
+};
+
+} // namespace legacy_hal
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_LEGACY_HAL_FACTORY_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_stubs.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_stubs.cpp
new file mode 100644
index 0000000..8f8527a
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_stubs.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_legacy_hal_stubs.h"
+
+// TODO: Remove these stubs from HalTool in libwifi-system.
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace legacy_hal {
+template <typename>
+struct stubFunction;
+
+template <typename R, typename... Args>
+struct stubFunction<R (*)(Args...)> {
+ static constexpr R invoke(Args...) { return WIFI_ERROR_NOT_SUPPORTED; }
+};
+template <typename... Args>
+struct stubFunction<void (*)(Args...)> {
+ static constexpr void invoke(Args...) {}
+};
+
+template <typename T>
+void populateStubFor(T* val) {
+ *val = &stubFunction<T>::invoke;
+}
+
+bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) {
+ if (hal_fn == nullptr) {
+ return false;
+ }
+ populateStubFor(&hal_fn->wifi_initialize);
+ populateStubFor(&hal_fn->wifi_wait_for_driver_ready);
+ populateStubFor(&hal_fn->wifi_cleanup);
+ populateStubFor(&hal_fn->wifi_event_loop);
+ populateStubFor(&hal_fn->wifi_get_error_info);
+ populateStubFor(&hal_fn->wifi_get_supported_feature_set);
+ populateStubFor(&hal_fn->wifi_get_concurrency_matrix);
+ populateStubFor(&hal_fn->wifi_set_scanning_mac_oui);
+ populateStubFor(&hal_fn->wifi_get_supported_channels);
+ populateStubFor(&hal_fn->wifi_is_epr_supported);
+ populateStubFor(&hal_fn->wifi_get_ifaces);
+ populateStubFor(&hal_fn->wifi_get_iface_name);
+ populateStubFor(&hal_fn->wifi_set_iface_event_handler);
+ populateStubFor(&hal_fn->wifi_reset_iface_event_handler);
+ populateStubFor(&hal_fn->wifi_start_gscan);
+ populateStubFor(&hal_fn->wifi_stop_gscan);
+ populateStubFor(&hal_fn->wifi_get_cached_gscan_results);
+ populateStubFor(&hal_fn->wifi_set_bssid_hotlist);
+ populateStubFor(&hal_fn->wifi_reset_bssid_hotlist);
+ populateStubFor(&hal_fn->wifi_set_significant_change_handler);
+ populateStubFor(&hal_fn->wifi_reset_significant_change_handler);
+ populateStubFor(&hal_fn->wifi_get_gscan_capabilities);
+ populateStubFor(&hal_fn->wifi_set_link_stats);
+ populateStubFor(&hal_fn->wifi_get_link_stats);
+ populateStubFor(&hal_fn->wifi_clear_link_stats);
+ populateStubFor(&hal_fn->wifi_get_valid_channels);
+ populateStubFor(&hal_fn->wifi_rtt_range_request);
+ populateStubFor(&hal_fn->wifi_rtt_range_cancel);
+ populateStubFor(&hal_fn->wifi_get_rtt_capabilities);
+ populateStubFor(&hal_fn->wifi_rtt_get_responder_info);
+ populateStubFor(&hal_fn->wifi_enable_responder);
+ populateStubFor(&hal_fn->wifi_disable_responder);
+ populateStubFor(&hal_fn->wifi_set_nodfs_flag);
+ populateStubFor(&hal_fn->wifi_start_logging);
+ populateStubFor(&hal_fn->wifi_set_epno_list);
+ populateStubFor(&hal_fn->wifi_reset_epno_list);
+ populateStubFor(&hal_fn->wifi_set_country_code);
+ populateStubFor(&hal_fn->wifi_get_firmware_memory_dump);
+ populateStubFor(&hal_fn->wifi_set_log_handler);
+ populateStubFor(&hal_fn->wifi_reset_log_handler);
+ populateStubFor(&hal_fn->wifi_set_alert_handler);
+ populateStubFor(&hal_fn->wifi_reset_alert_handler);
+ populateStubFor(&hal_fn->wifi_get_firmware_version);
+ populateStubFor(&hal_fn->wifi_get_ring_buffers_status);
+ populateStubFor(&hal_fn->wifi_get_logger_supported_feature_set);
+ populateStubFor(&hal_fn->wifi_get_ring_data);
+ populateStubFor(&hal_fn->wifi_enable_tdls);
+ populateStubFor(&hal_fn->wifi_disable_tdls);
+ populateStubFor(&hal_fn->wifi_get_tdls_status);
+ populateStubFor(&hal_fn->wifi_get_tdls_capabilities);
+ populateStubFor(&hal_fn->wifi_get_driver_version);
+ populateStubFor(&hal_fn->wifi_set_passpoint_list);
+ populateStubFor(&hal_fn->wifi_reset_passpoint_list);
+ populateStubFor(&hal_fn->wifi_set_lci);
+ populateStubFor(&hal_fn->wifi_set_lcr);
+ populateStubFor(&hal_fn->wifi_start_sending_offloaded_packet);
+ populateStubFor(&hal_fn->wifi_stop_sending_offloaded_packet);
+ populateStubFor(&hal_fn->wifi_start_rssi_monitoring);
+ populateStubFor(&hal_fn->wifi_stop_rssi_monitoring);
+ populateStubFor(&hal_fn->wifi_get_wake_reason_stats);
+ populateStubFor(&hal_fn->wifi_configure_nd_offload);
+ populateStubFor(&hal_fn->wifi_get_driver_memory_dump);
+ populateStubFor(&hal_fn->wifi_start_pkt_fate_monitoring);
+ populateStubFor(&hal_fn->wifi_get_tx_pkt_fates);
+ populateStubFor(&hal_fn->wifi_get_rx_pkt_fates);
+ populateStubFor(&hal_fn->wifi_nan_enable_request);
+ populateStubFor(&hal_fn->wifi_nan_disable_request);
+ populateStubFor(&hal_fn->wifi_nan_publish_request);
+ populateStubFor(&hal_fn->wifi_nan_publish_cancel_request);
+ populateStubFor(&hal_fn->wifi_nan_subscribe_request);
+ populateStubFor(&hal_fn->wifi_nan_subscribe_cancel_request);
+ populateStubFor(&hal_fn->wifi_nan_transmit_followup_request);
+ populateStubFor(&hal_fn->wifi_nan_stats_request);
+ populateStubFor(&hal_fn->wifi_nan_config_request);
+ populateStubFor(&hal_fn->wifi_nan_tca_request);
+ populateStubFor(&hal_fn->wifi_nan_beacon_sdf_payload_request);
+ populateStubFor(&hal_fn->wifi_nan_register_handler);
+ populateStubFor(&hal_fn->wifi_nan_get_version);
+ populateStubFor(&hal_fn->wifi_nan_get_capabilities);
+ populateStubFor(&hal_fn->wifi_nan_data_interface_create);
+ populateStubFor(&hal_fn->wifi_nan_data_interface_delete);
+ populateStubFor(&hal_fn->wifi_nan_data_request_initiator);
+ populateStubFor(&hal_fn->wifi_nan_data_indication_response);
+ populateStubFor(&hal_fn->wifi_nan_data_end);
+ populateStubFor(&hal_fn->wifi_get_packet_filter_capabilities);
+ populateStubFor(&hal_fn->wifi_set_packet_filter);
+ populateStubFor(&hal_fn->wifi_read_packet_filter);
+ populateStubFor(&hal_fn->wifi_get_roaming_capabilities);
+ populateStubFor(&hal_fn->wifi_enable_firmware_roaming);
+ populateStubFor(&hal_fn->wifi_configure_roaming);
+ populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
+ populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
+ populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler);
+ populateStubFor(&hal_fn->wifi_set_latency_mode);
+ populateStubFor(&hal_fn->wifi_set_thermal_mitigation_mode);
+ populateStubFor(&hal_fn->wifi_virtual_interface_create);
+ populateStubFor(&hal_fn->wifi_virtual_interface_delete);
+ populateStubFor(&hal_fn->wifi_map_dscp_access_category);
+ populateStubFor(&hal_fn->wifi_reset_dscp_mapping);
+ populateStubFor(&hal_fn->wifi_set_subsystem_restart_handler);
+ populateStubFor(&hal_fn->wifi_get_supported_iface_name);
+ populateStubFor(&hal_fn->wifi_early_initialize);
+ populateStubFor(&hal_fn->wifi_get_chip_feature_set);
+ populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection);
+ populateStubFor(&hal_fn->wifi_multi_sta_set_use_case);
+ populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels);
+ populateStubFor(&hal_fn->wifi_set_voip_mode);
+ populateStubFor(&hal_fn->wifi_twt_register_handler);
+ populateStubFor(&hal_fn->wifi_twt_get_capability);
+ populateStubFor(&hal_fn->wifi_twt_setup_request);
+ populateStubFor(&hal_fn->wifi_twt_teardown_request);
+ populateStubFor(&hal_fn->wifi_twt_info_frame_request);
+ populateStubFor(&hal_fn->wifi_twt_get_stats);
+ populateStubFor(&hal_fn->wifi_twt_clear_stats);
+ populateStubFor(&hal_fn->wifi_set_dtim_config);
+ populateStubFor(&hal_fn->wifi_get_usable_channels);
+ populateStubFor(&hal_fn->wifi_trigger_subsystem_restart);
+ populateStubFor(&hal_fn->wifi_set_indoor_state);
+ populateStubFor(&hal_fn->wifi_get_supported_radio_combinations_matrix);
+ populateStubFor(&hal_fn->wifi_nan_rtt_chre_enable_request);
+ populateStubFor(&hal_fn->wifi_nan_rtt_chre_disable_request);
+ populateStubFor(&hal_fn->wifi_chre_register_handler);
+ populateStubFor(&hal_fn->wifi_enable_tx_power_limits);
+ populateStubFor(&hal_fn->wifi_get_cached_scan_results);
+ return true;
+}
+} // namespace legacy_hal
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/gps/android/service.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_stubs.h
index 6b0f602..ebc0347 100644
--- a/gps/android/service.cpp
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_legacy_hal_stubs.h
@@ -1,8 +1,4 @@
/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
- * Not a Contribution
- */
-/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,14 +14,24 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.gnss@1.0-service-qti"
+#ifndef WIFI_LEGACY_HAL_STUBS_H_
+#define WIFI_LEGACY_HAL_STUBS_H_
+
+#include <hal_legacy/wifi_hal.h>
-#include <android/hardware/gnss/1.0/IGnss.h>
-#include <hidl/LegacySupport.h>
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace legacy_hal {
-using android::hardware::gnss::V1_0::IGnss;
-using android::hardware::defaultPassthroughServiceImplementation;
+bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn);
+} // namespace legacy_hal
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
-int main() {
- return defaultPassthroughServiceImplementation<IGnss>();
-}
+#endif // WIFI_LEGACY_HAL_STUBS_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_mode_controller.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_mode_controller.cpp
new file mode 100644
index 0000000..4b8ac7d
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_mode_controller.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <private/android_filesystem_config.h>
+
+#include "wifi_mode_controller.h"
+
+using android::hardware::wifi::V1_0::IfaceType;
+using android::wifi_hal::DriverTool;
+
+namespace {
+int convertIfaceTypeToFirmwareMode(IfaceType type) {
+ int mode;
+ switch (type) {
+ case IfaceType::AP:
+ mode = DriverTool::kFirmwareModeAp;
+ break;
+ case IfaceType::P2P:
+ mode = DriverTool::kFirmwareModeP2p;
+ break;
+ case IfaceType::NAN:
+ // NAN is exposed in STA mode currently.
+ mode = DriverTool::kFirmwareModeSta;
+ break;
+ case IfaceType::STA:
+ mode = DriverTool::kFirmwareModeSta;
+ break;
+ }
+ return mode;
+}
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace mode_controller {
+
+WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {}
+
+bool WifiModeController::isFirmwareModeChangeNeeded(IfaceType type) {
+ return driver_tool_->IsFirmwareModeChangeNeeded(convertIfaceTypeToFirmwareMode(type));
+}
+
+bool WifiModeController::initialize() {
+ if (!driver_tool_->LoadDriver()) {
+ LOG(ERROR) << "Failed to load WiFi driver";
+ return false;
+ }
+ return true;
+}
+
+bool WifiModeController::changeFirmwareMode(IfaceType type) {
+ if (!driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))) {
+ LOG(ERROR) << "Failed to change firmware mode";
+ return false;
+ }
+ return true;
+}
+
+bool WifiModeController::deinitialize() {
+ if (!driver_tool_->UnloadDriver()) {
+ LOG(ERROR) << "Failed to unload WiFi driver";
+ return false;
+ }
+ return true;
+}
+} // namespace mode_controller
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_mode_controller.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_mode_controller.h
new file mode 100644
index 0000000..fee2b66
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_mode_controller.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_MODE_CONTROLLER_H_
+#define WIFI_MODE_CONTROLLER_H_
+
+#include <wifi_hal/driver_tool.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace mode_controller {
+using namespace android::hardware::wifi::V1_0;
+
+/**
+ * Class that encapsulates all firmware mode configuration.
+ * This class will perform the necessary firmware reloads to put the chip in the
+ * required state (essentially a wrapper over DriverTool).
+ */
+class WifiModeController {
+ public:
+ WifiModeController();
+ virtual ~WifiModeController() = default;
+
+ // Checks if a firmware mode change is necessary to support the specified
+ // iface type operations.
+ virtual bool isFirmwareModeChangeNeeded(IfaceType type);
+ virtual bool initialize();
+ // Change the firmware mode to support the specified iface type operations.
+ virtual bool changeFirmwareMode(IfaceType type);
+ // Unload the driver. This should be invoked whenever |IWifi.stop()| is
+ // invoked.
+ virtual bool deinitialize();
+
+ private:
+ std::unique_ptr<wifi_hal::DriverTool> driver_tool_;
+};
+
+} // namespace mode_controller
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_MODE_CONTROLLER_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_nan_iface.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_nan_iface.cpp
new file mode 100644
index 0000000..4c61ba7
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_nan_iface.cpp
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include "hidl_return_util.h"
+#include "hidl_struct_util.h"
+#include "wifi_nan_iface.h"
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+
+WifiNanIface::WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+ : ifname_(ifname),
+ is_dedicated_iface_(is_dedicated_iface),
+ legacy_hal_(legacy_hal),
+ iface_util_(iface_util),
+ is_valid_(true) {
+ if (is_dedicated_iface_) {
+ // If using a dedicated iface, set the iface up first.
+ if (!iface_util_.lock()->setUpState(ifname_, true)) {
+ // Fatal failure, invalidate the iface object.
+ invalidate();
+ return;
+ }
+ }
+ // Register all the callbacks here. these should be valid for the lifetime
+ // of the object. Whenever the mode changes legacy HAL will remove
+ // all of these callbacks.
+ legacy_hal::NanCallbackHandlers callback_handlers;
+ android::wp<WifiNanIface> weak_ptr_this(this);
+
+ // Callback for response.
+ callback_handlers.on_notify_response = [weak_ptr_this](legacy_hal::transaction_id id,
+ const legacy_hal::NanResponseMsg& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ WifiNanStatus wifiNanStatus;
+ if (!hidl_struct_util::convertLegacyNanResponseHeaderToHidl(msg, &wifiNanStatus)) {
+ LOG(ERROR) << "Failed to convert nan response header";
+ return;
+ }
+
+ switch (msg.response_type) {
+ case legacy_hal::NAN_RESPONSE_ENABLED: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyEnableResponse(id, wifiNanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_DISABLED: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyDisableResponse(id, wifiNanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_PUBLISH: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyStartPublishResponse(id, wifiNanStatus,
+ msg.body.publish_response.publish_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyStopPublishResponse(id, wifiNanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyTransmitFollowupResponse(id, wifiNanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_SUBSCRIBE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyStartSubscribeResponse(
+ id, wifiNanStatus,
+ msg.body.subscribe_response.subscribe_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyStopSubscribeResponse(id, wifiNanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_CONFIG: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyConfigResponse(id, wifiNanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_GET_CAPABILITIES: {
+ V1_6::NanCapabilities hidl_struct;
+ if (!hidl_struct_util::convertLegacyNanCapabilitiesResponseToHidl(
+ msg.body.nan_capabilities, &hidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks_1_6()) {
+ if (!callback->notifyCapabilitiesResponse_1_6(id, wifiNanStatus, hidl_struct)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_INTERFACE_CREATE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyCreateDataInterfaceResponse(id, wifiNanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_INTERFACE_DELETE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyDeleteDataInterfaceResponse(id, wifiNanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_INITIATOR_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyInitiateDataPathResponse(
+ id, wifiNanStatus,
+ msg.body.data_request_response.ndp_instance_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_RESPONDER_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyRespondToDataPathIndicationResponse(id, wifiNanStatus)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_END: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyTerminateDataPathResponse(id, wifiNanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD:
+ /* fall through */
+ case legacy_hal::NAN_RESPONSE_TCA:
+ /* fall through */
+ case legacy_hal::NAN_RESPONSE_STATS:
+ /* fall through */
+ case legacy_hal::NAN_RESPONSE_ERROR:
+ /* fall through */
+ default:
+ LOG(ERROR) << "Unknown or unhandled response type: " << msg.response_type;
+ return;
+ }
+ };
+
+ callback_handlers.on_event_disc_eng_event =
+ [weak_ptr_this](const legacy_hal::NanDiscEngEventInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ NanClusterEventInd hidl_struct;
+ // event types defined identically - hence can be cast
+ hidl_struct.eventType = (NanClusterEventType)msg.event_type;
+ hidl_struct.addr = msg.data.mac_addr.addr;
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventClusterEvent(hidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_disabled = [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ WifiNanStatus status;
+ hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
+ &status);
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventDisabled(status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_publish_terminated =
+ [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ WifiNanStatus status;
+ hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason,
+ sizeof(msg.nan_reason), &status);
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventPublishTerminated(msg.publish_id, status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_subscribe_terminated =
+ [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ WifiNanStatus status;
+ hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason,
+ sizeof(msg.nan_reason), &status);
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventSubscribeTerminated(msg.subscribe_id, status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_match = [weak_ptr_this](const legacy_hal::NanMatchInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ V1_6::NanMatchInd hidl_struct;
+ if (!hidl_struct_util::convertLegacyNanMatchIndToHidl(msg, &hidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks_1_6()) {
+ if (!callback->eventMatch_1_6(hidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_match_expired = [weak_ptr_this](
+ const legacy_hal::NanMatchExpiredInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventMatchExpired(msg.publish_subscribe_id, msg.requestor_instance_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_followup = [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ NanFollowupReceivedInd hidl_struct;
+ if (!hidl_struct_util::convertLegacyNanFollowupIndToHidl(msg, &hidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventFollowupReceived(hidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_transmit_follow_up =
+ [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ WifiNanStatus status;
+ hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason,
+ sizeof(msg.nan_reason), &status);
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventTransmitFollowup(msg.id, status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_data_path_request =
+ [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ NanDataPathRequestInd hidl_struct;
+ if (!hidl_struct_util::convertLegacyNanDataPathRequestIndToHidl(msg,
+ &hidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventDataPathRequest(hidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_data_path_confirm =
+ [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ V1_6::NanDataPathConfirmInd hidl_struct;
+ if (!hidl_struct_util::convertLegacyNanDataPathConfirmIndToHidl(msg,
+ &hidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks_1_6()) {
+ if (!callback->eventDataPathConfirm_1_6(hidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_data_path_end =
+ [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ for (int i = 0; i < msg.num_ndp_instances; ++i) {
+ if (!callback->eventDataPathTerminated(msg.ndp_instance_id[i]).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ }
+ };
+
+ callback_handlers.on_event_beacon_sdf_payload =
+ [weak_ptr_this](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) {
+ LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called";
+ };
+
+ callback_handlers.on_event_range_request =
+ [weak_ptr_this](const legacy_hal::NanRangeRequestInd& /* msg */) {
+ LOG(ERROR) << "on_event_range_request - should not be called";
+ };
+
+ callback_handlers.on_event_range_report =
+ [weak_ptr_this](const legacy_hal::NanRangeReportInd& /* msg */) {
+ LOG(ERROR) << "on_event_range_report - should not be called";
+ };
+
+ callback_handlers.on_event_schedule_update =
+ [weak_ptr_this](const legacy_hal::NanDataPathScheduleUpdateInd& msg) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ V1_6::NanDataPathScheduleUpdateInd hidl_struct;
+ if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl(
+ msg, &hidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks_1_6()) {
+ if (!callback->eventDataPathScheduleUpdate_1_6(hidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, callback_handlers);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
+ invalidate();
+ }
+
+ // Register for iface state toggle events.
+ iface_util::IfaceEventHandlers event_handlers = {};
+#ifndef WIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN
+ event_handlers.on_state_toggle_off_on = [weak_ptr_this](const std::string& /* iface_name */) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ // Tell framework that NAN has been disabled.
+ WifiNanStatus status = {NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventDisabled(status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+#endif
+ iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
+}
+
+void WifiNanIface::invalidate() {
+ if (!isValid()) {
+ return;
+ }
+ // send commands to HAL to actually disable and destroy interfaces
+ legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
+ legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
+ legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
+ iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
+ legacy_hal_.reset();
+ event_cb_handler_.invalidate();
+ event_cb_handler_1_2_.invalidate();
+ event_cb_handler_1_5_.invalidate();
+ is_valid_ = false;
+ if (is_dedicated_iface_) {
+ // If using a dedicated iface, set the iface down.
+ iface_util_.lock()->setUpState(ifname_, false);
+ }
+}
+
+bool WifiNanIface::isValid() {
+ return is_valid_;
+}
+
+std::string WifiNanIface::getName() {
+ return ifname_;
+}
+
+std::set<sp<V1_0::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks() {
+ return event_cb_handler_.getCallbacks();
+}
+
+std::set<sp<V1_2::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_2() {
+ return event_cb_handler_1_2_.getCallbacks();
+}
+
+std::set<sp<V1_5::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_5() {
+ return event_cb_handler_1_5_.getCallbacks();
+}
+
+std::set<sp<V1_6::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_6() {
+ return event_cb_handler_1_6_.getCallbacks();
+}
+
+Return<void> WifiNanIface::getName(getName_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::getNameInternal, hidl_status_cb);
+}
+
+Return<void> WifiNanIface::getType(getType_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::getTypeInternal, hidl_status_cb);
+}
+
+Return<void> WifiNanIface::registerEventCallback(
+ const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::registerEventCallbackInternal, hidl_status_cb, callback);
+}
+
+Return<void> WifiNanIface::getCapabilitiesRequest(uint16_t cmd_id,
+ getCapabilitiesRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::getCapabilitiesRequestInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiNanIface::enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg,
+ enableRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::enableRequestInternal, hidl_status_cb, cmd_id, msg);
+}
+
+Return<void> WifiNanIface::configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
+ configRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::configRequestInternal, hidl_status_cb, cmd_id, msg);
+}
+
+Return<void> WifiNanIface::disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::disableRequestInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiNanIface::startPublishRequest(uint16_t cmd_id, const V1_0::NanPublishRequest& msg,
+ startPublishRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::startPublishRequestInternal, hidl_status_cb, cmd_id, msg);
+}
+
+Return<void> WifiNanIface::stopPublishRequest(uint16_t cmd_id, uint8_t sessionId,
+ stopPublishRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::stopPublishRequestInternal, hidl_status_cb, cmd_id,
+ sessionId);
+}
+
+Return<void> WifiNanIface::startSubscribeRequest(uint16_t cmd_id,
+ const V1_0::NanSubscribeRequest& msg,
+ startSubscribeRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::startSubscribeRequestInternal, hidl_status_cb, cmd_id,
+ msg);
+}
+
+Return<void> WifiNanIface::stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId,
+ stopSubscribeRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::stopSubscribeRequestInternal, hidl_status_cb, cmd_id,
+ sessionId);
+}
+
+Return<void> WifiNanIface::transmitFollowupRequest(uint16_t cmd_id,
+ const NanTransmitFollowupRequest& msg,
+ transmitFollowupRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::transmitFollowupRequestInternal, hidl_status_cb, cmd_id,
+ msg);
+}
+
+Return<void> WifiNanIface::createDataInterfaceRequest(
+ uint16_t cmd_id, const hidl_string& iface_name,
+ createDataInterfaceRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::createDataInterfaceRequestInternal, hidl_status_cb,
+ cmd_id, iface_name);
+}
+
+Return<void> WifiNanIface::deleteDataInterfaceRequest(
+ uint16_t cmd_id, const hidl_string& iface_name,
+ deleteDataInterfaceRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::deleteDataInterfaceRequestInternal, hidl_status_cb,
+ cmd_id, iface_name);
+}
+
+Return<void> WifiNanIface::initiateDataPathRequest(uint16_t cmd_id,
+ const V1_0::NanInitiateDataPathRequest& msg,
+ initiateDataPathRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::initiateDataPathRequestInternal, hidl_status_cb, cmd_id,
+ msg);
+}
+
+Return<void> WifiNanIface::respondToDataPathIndicationRequest(
+ uint16_t cmd_id, const V1_0::NanRespondToDataPathIndicationRequest& msg,
+ respondToDataPathIndicationRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::respondToDataPathIndicationRequestInternal,
+ hidl_status_cb, cmd_id, msg);
+}
+
+Return<void> WifiNanIface::terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId,
+ terminateDataPathRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::terminateDataPathRequestInternal, hidl_status_cb, cmd_id,
+ ndpInstanceId);
+}
+
+Return<void> WifiNanIface::registerEventCallback_1_2(
+ const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_1_2_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::registerEventCallback_1_2Internal, hidl_status_cb,
+ callback);
+}
+
+Return<void> WifiNanIface::enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_2_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::enableRequest_1_2Internal, hidl_status_cb, cmd_id, msg1,
+ msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ configRequest_1_2_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::configRequest_1_2Internal, hidl_status_cb, cmd_id, msg1,
+ msg2);
+}
+
+Return<void> WifiNanIface::enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::enableRequest_1_4Internal, hidl_status_cb, cmd_id, msg1,
+ msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ configRequest_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::configRequest_1_4Internal, hidl_status_cb, cmd_id, msg1,
+ msg2);
+}
+
+Return<void> WifiNanIface::registerEventCallback_1_5(
+ const sp<V1_5::IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::registerEventCallback_1_5Internal, hidl_status_cb,
+ callback);
+}
+
+Return<void> WifiNanIface::enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const V1_5::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::enableRequest_1_5Internal, hidl_status_cb, cmd_id, msg1,
+ msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+ const V1_5::NanConfigRequestSupplemental& msg2,
+ configRequest_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::configRequest_1_5Internal, hidl_status_cb, cmd_id, msg1,
+ msg2);
+}
+
+Return<void> WifiNanIface::getCapabilitiesRequest_1_5(
+ uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::getCapabilitiesRequest_1_5Internal, hidl_status_cb,
+ cmd_id);
+}
+
+Return<void> WifiNanIface::enableRequest_1_6(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const V1_6::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::enableRequest_1_6Internal, hidl_status_cb, cmd_id, msg1,
+ msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_6(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+ const V1_6::NanConfigRequestSupplemental& msg2,
+ configRequest_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::configRequest_1_6Internal, hidl_status_cb, cmd_id, msg1,
+ msg2);
+}
+
+Return<void> WifiNanIface::initiateDataPathRequest_1_6(uint16_t cmd_id,
+ const V1_6::NanInitiateDataPathRequest& msg,
+ initiateDataPathRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::initiateDataPathRequest_1_6Internal, hidl_status_cb,
+ cmd_id, msg);
+}
+
+Return<void> WifiNanIface::respondToDataPathIndicationRequest_1_6(
+ uint16_t cmd_id, const V1_6::NanRespondToDataPathIndicationRequest& msg,
+ respondToDataPathIndicationRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::respondToDataPathIndicationRequest_1_6Internal,
+ hidl_status_cb, cmd_id, msg);
+}
+
+Return<void> WifiNanIface::startPublishRequest_1_6(uint16_t cmd_id,
+ const V1_6::NanPublishRequest& msg,
+ startPublishRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::startPublishRequest_1_6Internal, hidl_status_cb, cmd_id,
+ msg);
+}
+
+std::pair<WifiStatus, std::string> WifiNanIface::getNameInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
+}
+
+std::pair<WifiStatus, IfaceType> WifiNanIface::getTypeInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::NAN};
+}
+
+Return<void> WifiNanIface::registerEventCallback_1_6(
+ const sp<V1_6::IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_1_6_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::registerEventCallback_1_6Internal, hidl_status_cb,
+ callback);
+}
+
+WifiStatus WifiNanIface::registerEventCallbackInternal(
+ const sp<V1_0::IWifiNanIfaceEventCallback>& callback) {
+ if (!event_cb_handler_.addCallback(callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::enableRequestInternal(uint16_t /* cmd_id */,
+ const V1_0::NanEnableRequest& /* msg */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequestInternal(uint16_t /* cmd_id */,
+ const V1_0::NanConfigRequest& /* msg */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::disableRequestInternal(uint16_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::startPublishRequestInternal(uint16_t /* cmd_id */,
+ const V1_0::NanPublishRequest& /* msg */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId) {
+ legacy_hal::NanPublishCancelRequest legacy_msg;
+ legacy_msg.publish_id = sessionId;
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::startSubscribeRequestInternal(uint16_t cmd_id,
+ const V1_0::NanSubscribeRequest& msg) {
+ legacy_hal::NanSubscribeRequest legacy_msg;
+ if (!hidl_struct_util::convertHidlNanSubscribeRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId) {
+ legacy_hal::NanSubscribeCancelRequest legacy_msg;
+ legacy_msg.subscribe_id = sessionId;
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::transmitFollowupRequestInternal(uint16_t cmd_id,
+ const NanTransmitFollowupRequest& msg) {
+ legacy_hal::NanTransmitFollowupRequest legacy_msg;
+ if (!hidl_struct_util::convertHidlNanTransmitFollowupRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::createDataInterfaceRequestInternal(uint16_t cmd_id,
+ const std::string& iface_name) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+WifiStatus WifiNanIface::deleteDataInterfaceRequestInternal(uint16_t cmd_id,
+ const std::string& iface_name) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+WifiStatus WifiNanIface::initiateDataPathRequestInternal(
+ uint16_t cmd_id, const V1_0::NanInitiateDataPathRequest& msg) {
+ legacy_hal::NanDataPathInitiatorRequest legacy_msg;
+ if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+WifiStatus WifiNanIface::respondToDataPathIndicationRequestInternal(
+ uint16_t cmd_id, const V1_0::NanRespondToDataPathIndicationRequest& msg) {
+ legacy_hal::NanDataPathIndicationResponse legacy_msg;
+ if (!hidl_struct_util::convertHidlNanDataPathIndicationResponseToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+WifiStatus WifiNanIface::terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::registerEventCallback_1_2Internal(
+ const sp<V1_2::IWifiNanIfaceEventCallback>& callback) {
+ sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
+ if (!event_cb_handler_.addCallback(callback_1_0)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ if (!event_cb_handler_1_2_.addCallback(callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_2Internal(
+ uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequest_1_2Internal(
+ uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_4Internal(
+ uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequest_1_4Internal(
+ uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */,
+ const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::registerEventCallback_1_5Internal(
+ const sp<V1_5::IWifiNanIfaceEventCallback>& callback) {
+ sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
+ if (!event_cb_handler_.addCallback(callback_1_0)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ sp<V1_2::IWifiNanIfaceEventCallback> callback_1_2 = callback;
+ if (!event_cb_handler_1_2_.addCallback(callback_1_2)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ if (!event_cb_handler_1_5_.addCallback(callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_5Internal(
+ uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */,
+ const V1_5::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequest_1_5Internal(
+ uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */,
+ const V1_5::NanConfigRequestSupplemental& /* msg2 */) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_6Internal(uint16_t cmd_id,
+ const V1_4::NanEnableRequest& msg1,
+ const V1_6::NanConfigRequestSupplemental& msg2) {
+ legacy_hal::NanEnableRequest legacy_msg;
+ if (!hidl_struct_util::convertHidlNanEnableRequest_1_6ToLegacy(msg1, msg2, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::configRequest_1_6Internal(uint16_t cmd_id,
+ const V1_4::NanConfigRequest& msg1,
+ const V1_6::NanConfigRequestSupplemental& msg2) {
+ legacy_hal::NanConfigRequest legacy_msg;
+ if (!hidl_struct_util::convertHidlNanConfigRequest_1_6ToLegacy(msg1, msg2, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::initiateDataPathRequest_1_6Internal(
+ uint16_t cmd_id, const V1_6::NanInitiateDataPathRequest& msg) {
+ legacy_hal::NanDataPathInitiatorRequest legacy_msg;
+ if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequest_1_6ToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::respondToDataPathIndicationRequest_1_6Internal(
+ uint16_t cmd_id, const V1_6::NanRespondToDataPathIndicationRequest& msg) {
+ legacy_hal::NanDataPathIndicationResponse legacy_msg;
+ if (!hidl_struct_util::convertHidlNanDataPathIndicationResponse_1_6ToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::startPublishRequest_1_6Internal(uint16_t cmd_id,
+ const V1_6::NanPublishRequest& msg) {
+ legacy_hal::NanPublishRequest legacy_msg;
+ if (!hidl_struct_util::convertHidlNanPublishRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::registerEventCallback_1_6Internal(
+ const sp<V1_6::IWifiNanIfaceEventCallback>& callback) {
+ sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
+ if (!event_cb_handler_.addCallback(callback_1_0)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ sp<V1_2::IWifiNanIfaceEventCallback> callback_1_2 = callback;
+ if (!event_cb_handler_1_2_.addCallback(callback_1_2)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ sp<V1_5::IWifiNanIfaceEventCallback> callback_1_5 = callback;
+ if (!event_cb_handler_1_5_.addCallback(callback_1_5)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ if (!event_cb_handler_1_6_.addCallback(callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_nan_iface.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_nan_iface.h
new file mode 100644
index 0000000..15bf572
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_nan_iface.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_NAN_IFACE_H_
+#define WIFI_NAN_IFACE_H_
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.6/IWifiNanIface.h>
+#include <android/hardware/wifi/1.6/IWifiNanIfaceEventCallback.h>
+
+#include "hidl_callback_util.h"
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+using namespace android::hardware::wifi::V1_2;
+using namespace android::hardware::wifi::V1_4;
+using namespace android::hardware::wifi::V1_6;
+
+/**
+ * HIDL interface object used to control a NAN Iface instance.
+ */
+class WifiNanIface : public V1_6::IWifiNanIface {
+ public:
+ WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::string getName();
+
+ // HIDL methods exposed.
+ Return<void> getName(getName_cb hidl_status_cb) override;
+ Return<void> getType(getType_cb hidl_status_cb) override;
+ Return<void> registerEventCallback(const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_cb hidl_status_cb) override;
+ Return<void> getCapabilitiesRequest(uint16_t cmd_id,
+ getCapabilitiesRequest_cb hidl_status_cb) override;
+ Return<void> enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg,
+ enableRequest_cb hidl_status_cb) override;
+ Return<void> configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
+ configRequest_cb hidl_status_cb) override;
+ Return<void> disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) override;
+ Return<void> startPublishRequest(uint16_t cmd_id, const V1_0::NanPublishRequest& msg,
+ startPublishRequest_cb hidl_status_cb) override;
+ Return<void> stopPublishRequest(uint16_t cmd_id, uint8_t sessionId,
+ stopPublishRequest_cb hidl_status_cb) override;
+ Return<void> startSubscribeRequest(uint16_t cmd_id, const V1_0::NanSubscribeRequest& msg,
+ startSubscribeRequest_cb hidl_status_cb) override;
+ Return<void> stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId,
+ stopSubscribeRequest_cb hidl_status_cb) override;
+ Return<void> transmitFollowupRequest(uint16_t cmd_id, const NanTransmitFollowupRequest& msg,
+ transmitFollowupRequest_cb hidl_status_cb) override;
+ Return<void> createDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name,
+ createDataInterfaceRequest_cb hidl_status_cb) override;
+ Return<void> deleteDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name,
+ deleteDataInterfaceRequest_cb hidl_status_cb) override;
+ Return<void> initiateDataPathRequest(uint16_t cmd_id,
+ const V1_0::NanInitiateDataPathRequest& msg,
+ initiateDataPathRequest_cb hidl_status_cb) override;
+ Return<void> respondToDataPathIndicationRequest(
+ uint16_t cmd_id, const V1_0::NanRespondToDataPathIndicationRequest& msg,
+ respondToDataPathIndicationRequest_cb hidl_status_cb) override;
+ Return<void> terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId,
+ terminateDataPathRequest_cb hidl_status_cb) override;
+
+ Return<void> registerEventCallback_1_2(const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_1_2_cb hidl_status_cb) override;
+ Return<void> enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_2_cb hidl_status_cb) override;
+ Return<void> configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ configRequest_1_2_cb hidl_status_cb) override;
+ Return<void> enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_4_cb hidl_status_cb) override;
+ Return<void> configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2,
+ configRequest_1_4_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_5(const sp<V1_5::IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_1_5_cb hidl_status_cb) override;
+ Return<void> enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const V1_5::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_5_cb hidl_status_cb) override;
+ Return<void> configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+ const V1_5::NanConfigRequestSupplemental& msg2,
+ configRequest_1_5_cb hidl_status_cb) override;
+ Return<void> getCapabilitiesRequest_1_5(uint16_t cmd_id,
+ getCapabilitiesRequest_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_6(const sp<V1_6::IWifiNanIfaceEventCallback>& callback,
+ registerEventCallback_1_6_cb hidl_status_cb) override;
+ Return<void> initiateDataPathRequest_1_6(
+ uint16_t cmd_id, const V1_6::NanInitiateDataPathRequest& msg,
+ initiateDataPathRequest_1_6_cb hidl_status_cb) override;
+ Return<void> respondToDataPathIndicationRequest_1_6(
+ uint16_t cmd_id, const V1_6::NanRespondToDataPathIndicationRequest& msg,
+ respondToDataPathIndicationRequest_1_6_cb hidl_status_cb) override;
+ Return<void> enableRequest_1_6(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const V1_6::NanConfigRequestSupplemental& msg2,
+ enableRequest_1_6_cb hidl_status_cb) override;
+ Return<void> configRequest_1_6(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+ const V1_6::NanConfigRequestSupplemental& msg2,
+ configRequest_1_6_cb hidl_status_cb) override;
+ Return<void> startPublishRequest_1_6(uint16_t cmd_id, const V1_6::NanPublishRequest& msg,
+ startPublishRequest_cb hidl_status_cb) override;
+
+ private:
+ // Corresponding worker functions for the HIDL methods.
+ std::pair<WifiStatus, std::string> getNameInternal();
+ std::pair<WifiStatus, IfaceType> getTypeInternal();
+ WifiStatus registerEventCallbackInternal(const sp<V1_0::IWifiNanIfaceEventCallback>& callback);
+ WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id);
+ WifiStatus enableRequestInternal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg);
+ WifiStatus configRequestInternal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg);
+ WifiStatus disableRequestInternal(uint16_t cmd_id);
+ WifiStatus startPublishRequestInternal(uint16_t cmd_id, const V1_0::NanPublishRequest& msg);
+ WifiStatus stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId);
+ WifiStatus startSubscribeRequestInternal(uint16_t cmd_id, const V1_0::NanSubscribeRequest& msg);
+ WifiStatus stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId);
+ WifiStatus transmitFollowupRequestInternal(uint16_t cmd_id,
+ const NanTransmitFollowupRequest& msg);
+ WifiStatus createDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name);
+ WifiStatus deleteDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name);
+ WifiStatus initiateDataPathRequestInternal(uint16_t cmd_id,
+ const V1_0::NanInitiateDataPathRequest& msg);
+ WifiStatus respondToDataPathIndicationRequestInternal(
+ uint16_t cmd_id, const V1_0::NanRespondToDataPathIndicationRequest& msg);
+ WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId);
+
+ WifiStatus registerEventCallback_1_2Internal(
+ const sp<V1_2::IWifiNanIfaceEventCallback>& callback);
+ WifiStatus enableRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2);
+ WifiStatus configRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
+ const V1_2::NanConfigRequestSupplemental& msg2);
+ WifiStatus enableRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const V1_2::NanConfigRequestSupplemental& msg2);
+ WifiStatus configRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
+ const V1_2::NanConfigRequestSupplemental& msg2);
+ WifiStatus registerEventCallback_1_5Internal(
+ const sp<V1_5::IWifiNanIfaceEventCallback>& callback);
+ WifiStatus enableRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const V1_5::NanConfigRequestSupplemental& msg2);
+ WifiStatus configRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
+ const V1_5::NanConfigRequestSupplemental& msg2);
+ WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id);
+ WifiStatus registerEventCallback_1_6Internal(
+ const sp<V1_6::IWifiNanIfaceEventCallback>& callback);
+
+ WifiStatus enableRequest_1_6Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+ const V1_6::NanConfigRequestSupplemental& msg2);
+ WifiStatus configRequest_1_6Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
+ const V1_6::NanConfigRequestSupplemental& msg2);
+ WifiStatus startPublishRequest_1_6Internal(uint16_t cmd_id, const V1_6::NanPublishRequest& msg);
+ WifiStatus initiateDataPathRequest_1_6Internal(uint16_t cmd_id,
+ const V1_6::NanInitiateDataPathRequest& msg);
+ WifiStatus respondToDataPathIndicationRequest_1_6Internal(
+ uint16_t cmd_id, const V1_6::NanRespondToDataPathIndicationRequest& msg);
+
+ // all 1_0 and descendant callbacks
+ std::set<sp<V1_0::IWifiNanIfaceEventCallback>> getEventCallbacks();
+ // all 1_2 and descendant callbacks
+ std::set<sp<V1_2::IWifiNanIfaceEventCallback>> getEventCallbacks_1_2();
+ // all 1_5 and descendant callbacks
+ std::set<sp<V1_5::IWifiNanIfaceEventCallback>> getEventCallbacks_1_5();
+ // all 1_6 and descendant callbacks
+ std::set<sp<V1_6::IWifiNanIfaceEventCallback>> getEventCallbacks_1_6();
+
+ std::string ifname_;
+ bool is_dedicated_iface_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+ bool is_valid_;
+ hidl_callback_util::HidlCallbackHandler<V1_0::IWifiNanIfaceEventCallback> event_cb_handler_;
+ hidl_callback_util::HidlCallbackHandler<V1_2::IWifiNanIfaceEventCallback> event_cb_handler_1_2_;
+ hidl_callback_util::HidlCallbackHandler<V1_5::IWifiNanIfaceEventCallback> event_cb_handler_1_5_;
+ hidl_callback_util::HidlCallbackHandler<V1_6::IWifiNanIfaceEventCallback> event_cb_handler_1_6_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiNanIface);
+};
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_NAN_IFACE_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_p2p_iface.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_p2p_iface.cpp
new file mode 100644
index 0000000..d4b1fca
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_p2p_iface.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include "hidl_return_util.h"
+#include "wifi_p2p_iface.h"
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+
+WifiP2pIface::WifiP2pIface(const std::string& ifname,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+ : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}
+
+void WifiP2pIface::invalidate() {
+ legacy_hal_.reset();
+ is_valid_ = false;
+}
+
+bool WifiP2pIface::isValid() {
+ return is_valid_;
+}
+
+std::string WifiP2pIface::getName() {
+ return ifname_;
+}
+
+Return<void> WifiP2pIface::getName(getName_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiP2pIface::getNameInternal, hidl_status_cb);
+}
+
+Return<void> WifiP2pIface::getType(getType_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiP2pIface::getTypeInternal, hidl_status_cb);
+}
+
+std::pair<WifiStatus, std::string> WifiP2pIface::getNameInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
+}
+
+std::pair<WifiStatus, IfaceType> WifiP2pIface::getTypeInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::P2P};
+}
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_p2p_iface.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_p2p_iface.h
new file mode 100644
index 0000000..0089443
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_p2p_iface.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_P2P_IFACE_H_
+#define WIFI_P2P_IFACE_H_
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.0/IWifiP2pIface.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+
+/**
+ * HIDL interface object used to control a P2P Iface instance.
+ */
+class WifiP2pIface : public V1_0::IWifiP2pIface {
+ public:
+ WifiP2pIface(const std::string& ifname,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::string getName();
+
+ // HIDL methods exposed.
+ Return<void> getName(getName_cb hidl_status_cb) override;
+ Return<void> getType(getType_cb hidl_status_cb) override;
+
+ private:
+ // Corresponding worker functions for the HIDL methods.
+ std::pair<WifiStatus, std::string> getNameInternal();
+ std::pair<WifiStatus, IfaceType> getTypeInternal();
+
+ std::string ifname_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ bool is_valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiP2pIface);
+};
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_P2P_IFACE_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_rtt_controller.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_rtt_controller.cpp
new file mode 100644
index 0000000..aa9ee2f
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_rtt_controller.cpp
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include "hidl_return_util.h"
+#include "hidl_struct_util.h"
+#include "wifi_rtt_controller.h"
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+
+WifiRttController::WifiRttController(const std::string& iface_name,
+ const sp<IWifiIface>& bound_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+ : ifname_(iface_name), bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {}
+
+void WifiRttController::invalidate() {
+ legacy_hal_.reset();
+ event_callbacks_.clear();
+ is_valid_ = false;
+}
+
+bool WifiRttController::isValid() {
+ return is_valid_;
+}
+
+std::vector<sp<V1_6::IWifiRttControllerEventCallback>> WifiRttController::getEventCallbacks() {
+ return event_callbacks_;
+}
+
+std::string WifiRttController::getIfaceName() {
+ return ifname_;
+}
+
+Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getBoundIfaceInternal, hidl_status_cb);
+}
+
+Return<void> WifiRttController::registerEventCallback(
+ const sp<V1_0::IWifiRttControllerEventCallback>& callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::registerEventCallbackInternal, hidl_status_cb,
+ callback);
+}
+
+Return<void> WifiRttController::rangeRequest(uint32_t cmd_id,
+ const hidl_vec<V1_0::RttConfig>& rtt_configs,
+ rangeRequest_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::rangeRequestInternal, hidl_status_cb, cmd_id,
+ rtt_configs);
+}
+
+Return<void> WifiRttController::rangeCancel(uint32_t cmd_id,
+ const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
+ rangeCancel_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::rangeCancelInternal, hidl_status_cb, cmd_id, addrs);
+}
+
+Return<void> WifiRttController::getCapabilities(getCapabilities_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiRttController::setLci(uint32_t cmd_id, const RttLciInformation& lci,
+ setLci_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::setLciInternal, hidl_status_cb, cmd_id, lci);
+}
+
+Return<void> WifiRttController::setLcr(uint32_t cmd_id, const RttLcrInformation& lcr,
+ setLcr_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::setLcrInternal, hidl_status_cb, cmd_id, lcr);
+}
+
+Return<void> WifiRttController::getResponderInfo(getResponderInfo_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getResponderInfoInternal, hidl_status_cb);
+}
+
+Return<void> WifiRttController::enableResponder(uint32_t cmd_id,
+ const V1_0::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds,
+ const V1_0::RttResponder& info,
+ enableResponder_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::enableResponderInternal, hidl_status_cb, cmd_id,
+ channel_hint, max_duration_seconds, info);
+}
+
+Return<void> WifiRttController::disableResponder(uint32_t cmd_id,
+ disableResponder_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::disableResponderInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiRttController::registerEventCallback_1_4(
+ const sp<V1_4::IWifiRttControllerEventCallback>& callback,
+ registerEventCallback_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::registerEventCallbackInternal_1_4, hidl_status_cb,
+ callback);
+}
+
+Return<void> WifiRttController::rangeRequest_1_4(uint32_t cmd_id,
+ const hidl_vec<V1_4::RttConfig>& rtt_configs,
+ rangeRequest_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::rangeRequestInternal_1_4, hidl_status_cb, cmd_id,
+ rtt_configs);
+}
+
+Return<void> WifiRttController::getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getCapabilitiesInternal_1_4, hidl_status_cb);
+}
+
+Return<void> WifiRttController::getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getResponderInfoInternal_1_4, hidl_status_cb);
+}
+
+Return<void> WifiRttController::enableResponder_1_4(uint32_t cmd_id,
+ const V1_0::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds,
+ const V1_4::RttResponder& info,
+ enableResponder_1_4_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::enableResponderInternal_1_4, hidl_status_cb, cmd_id,
+ channel_hint, max_duration_seconds, info);
+}
+
+Return<void> WifiRttController::registerEventCallback_1_6(
+ const sp<V1_6::IWifiRttControllerEventCallback>& callback,
+ registerEventCallback_1_6_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::registerEventCallbackInternal_1_6, hidl_status_cb,
+ callback);
+}
+
+Return<void> WifiRttController::rangeRequest_1_6(uint32_t cmd_id,
+ const hidl_vec<V1_6::RttConfig>& rtt_configs,
+ rangeRequest_1_6_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::rangeRequestInternal_1_6, hidl_status_cb, cmd_id,
+ rtt_configs);
+}
+
+Return<void> WifiRttController::getCapabilities_1_6(getCapabilities_1_6_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getCapabilitiesInternal_1_6, hidl_status_cb);
+}
+
+Return<void> WifiRttController::getResponderInfo_1_6(getResponderInfo_1_6_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getResponderInfoInternal_1_6, hidl_status_cb);
+}
+
+Return<void> WifiRttController::enableResponder_1_6(uint32_t cmd_id,
+ const V1_6::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds,
+ const V1_6::RttResponder& info,
+ enableResponder_1_6_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::enableResponderInternal_1_6, hidl_status_cb, cmd_id,
+ channel_hint, max_duration_seconds, info);
+}
+
+std::pair<WifiStatus, sp<IWifiIface>> WifiRttController::getBoundIfaceInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_};
+}
+
+WifiStatus WifiRttController::registerEventCallbackInternal(
+ const sp<V1_0::IWifiRttControllerEventCallback>& /* callback */) {
+ // Deprecated support for this api
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiRttController::rangeRequestInternal(
+ uint32_t /* cmd_id */, const std::vector<V1_0::RttConfig>& /* rtt_configs */) {
+ // Deprecated support for this api
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiRttController::rangeCancelInternal(
+ uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs) {
+ std::vector<std::array<uint8_t, 6>> legacy_addrs;
+ for (const auto& addr : addrs) {
+ legacy_addrs.push_back(addr);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, legacy_addrs);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, V1_0::RttCapabilities> WifiRttController::getCapabilitiesInternal() {
+ // Deprecated support for this api
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id, const RttLciInformation& lci) {
+ legacy_hal::wifi_lci_information legacy_lci;
+ if (!hidl_struct_util::convertHidlRttLciInformationToLegacy(lci, &legacy_lci)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiRttController::setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr) {
+ legacy_hal::wifi_lcr_information legacy_lcr;
+ if (!hidl_struct_util::convertHidlRttLcrInformationToLegacy(lcr, &legacy_lcr)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, V1_0::RttResponder> WifiRttController::getResponderInfoInternal() {
+ // Deprecated support for this api
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+WifiStatus WifiRttController::enableResponderInternal(
+ uint32_t /* cmd_id */, const V1_0::WifiChannelInfo& /* channel_hint */,
+ uint32_t /* max_duration_seconds */, const V1_0::RttResponder& /* info */) {
+ // Deprecated support for this api
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)};
+}
+
+WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiRttController::registerEventCallbackInternal_1_4(
+ const sp<V1_4::IWifiRttControllerEventCallback>& /* callback */) {
+ // Deprecated support for this api
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiRttController::rangeRequestInternal_1_4(
+ uint32_t /* cmd_id */, const std::vector<V1_4::RttConfig>& /* rtt_configs */) {
+ // Deprecated support for this api
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+std::pair<WifiStatus, V1_4::RttCapabilities> WifiRttController::getCapabilitiesInternal_1_4() {
+ // Deprecated support for this api
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+std::pair<WifiStatus, V1_4::RttResponder> WifiRttController::getResponderInfoInternal_1_4() {
+ // Deprecated support for this api
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+WifiStatus WifiRttController::enableResponderInternal_1_4(
+ uint32_t /* cmd_id */, const V1_0::WifiChannelInfo& /* channel_hint */,
+ uint32_t /* max_duration_seconds */, const V1_4::RttResponder& /* info */) {
+ // Deprecated support for this api
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)};
+}
+
+WifiStatus WifiRttController::registerEventCallbackInternal_1_6(
+ const sp<V1_6::IWifiRttControllerEventCallback>& callback) {
+ // TODO(b/31632518): remove the callback when the client is destroyed
+ event_callbacks_.emplace_back(callback);
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiRttController::rangeRequestInternal_1_6(
+ uint32_t cmd_id, const std::vector<V1_6::RttConfig>& rtt_configs) {
+ std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
+ if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ android::wp<WifiRttController> weak_ptr_this(this);
+ const auto& on_results_callback =
+ [weak_ptr_this](legacy_hal::wifi_request_id id,
+ const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ std::vector<V1_6::RttResult> hidl_results;
+ if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl(results,
+ &hidl_results)) {
+ LOG(ERROR) << "Failed to convert rtt results to HIDL structs";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onResults_1_6(id, hidl_results).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest(
+ ifname_, cmd_id, legacy_configs, on_results_callback);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, V1_6::RttCapabilities> WifiRttController::getCapabilitiesInternal_1_6() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_rtt_capabilities legacy_caps;
+ std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ V1_6::RttCapabilities hidl_caps;
+ if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+std::pair<WifiStatus, V1_6::RttResponder> WifiRttController::getResponderInfoInternal_1_6() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_rtt_responder legacy_responder;
+ std::tie(legacy_status, legacy_responder) = legacy_hal_.lock()->getRttResponderInfo(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ V1_6::RttResponder hidl_responder;
+ if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder, &hidl_responder)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder};
+}
+
+WifiStatus WifiRttController::enableResponderInternal_1_6(uint32_t cmd_id,
+ const V1_6::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds,
+ const V1_6::RttResponder& info) {
+ legacy_hal::wifi_channel_info legacy_channel_info;
+ if (!hidl_struct_util::convertHidlWifiChannelInfoToLegacy(channel_hint, &legacy_channel_info)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_rtt_responder legacy_responder;
+ if (!hidl_struct_util::convertHidlRttResponderToLegacy(info, &legacy_responder)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder(
+ ifname_, cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_rtt_controller.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_rtt_controller.h
new file mode 100644
index 0000000..fd5f68b
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_rtt_controller.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_RTT_CONTROLLER_H_
+#define WIFI_RTT_CONTROLLER_H_
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.0/IWifiIface.h>
+#include <android/hardware/wifi/1.6/IWifiRttController.h>
+#include <android/hardware/wifi/1.6/IWifiRttControllerEventCallback.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+
+/**
+ * HIDL interface object used to control all RTT operations.
+ */
+class WifiRttController : public V1_6::IWifiRttController {
+ public:
+ WifiRttController(const std::string& iface_name, const sp<IWifiIface>& bound_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::vector<sp<V1_6::IWifiRttControllerEventCallback>> getEventCallbacks();
+ std::string getIfaceName();
+
+ // HIDL methods exposed.
+ Return<void> getBoundIface(getBoundIface_cb hidl_status_cb) override;
+ Return<void> registerEventCallback(const sp<V1_0::IWifiRttControllerEventCallback>& callback,
+ registerEventCallback_cb hidl_status_cb) override;
+ Return<void> rangeRequest(uint32_t cmd_id, const hidl_vec<V1_0::RttConfig>& rtt_configs,
+ rangeRequest_cb hidl_status_cb) override;
+ Return<void> rangeCancel(uint32_t cmd_id, const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
+ rangeCancel_cb hidl_status_cb) override;
+ Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
+ Return<void> setLci(uint32_t cmd_id, const RttLciInformation& lci,
+ setLci_cb hidl_status_cb) override;
+ Return<void> setLcr(uint32_t cmd_id, const RttLcrInformation& lcr,
+ setLcr_cb hidl_status_cb) override;
+ Return<void> getResponderInfo(getResponderInfo_cb hidl_status_cb) override;
+ Return<void> enableResponder(uint32_t cmd_id, const V1_0::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds, const V1_0::RttResponder& info,
+ enableResponder_cb hidl_status_cb) override;
+ Return<void> disableResponder(uint32_t cmd_id, disableResponder_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_4(
+ const sp<V1_4::IWifiRttControllerEventCallback>& callback,
+ registerEventCallback_1_4_cb hidl_status_cb) override;
+ Return<void> rangeRequest_1_4(uint32_t cmd_id, const hidl_vec<V1_4::RttConfig>& rtt_configs,
+ rangeRequest_1_4_cb hidl_status_cb) override;
+ Return<void> getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) override;
+ Return<void> getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) override;
+ Return<void> enableResponder_1_4(uint32_t cmd_id, const V1_0::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds, const V1_4::RttResponder& info,
+ enableResponder_1_4_cb hidl_status_cb) override;
+ Return<void> registerEventCallback_1_6(
+ const sp<V1_6::IWifiRttControllerEventCallback>& callback,
+ registerEventCallback_1_6_cb hidl_status_cb) override;
+ Return<void> rangeRequest_1_6(uint32_t cmd_id, const hidl_vec<V1_6::RttConfig>& rtt_configs,
+ rangeRequest_1_6_cb hidl_status_cb) override;
+ Return<void> getCapabilities_1_6(getCapabilities_1_6_cb hidl_status_cb) override;
+ Return<void> getResponderInfo_1_6(getResponderInfo_1_6_cb hidl_status_cb) override;
+ Return<void> enableResponder_1_6(uint32_t cmd_id, const V1_6::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds, const V1_6::RttResponder& info,
+ enableResponder_1_6_cb hidl_status_cb) override;
+
+ private:
+ // Corresponding worker functions for the HIDL methods.
+ std::pair<WifiStatus, sp<IWifiIface>> getBoundIfaceInternal();
+ WifiStatus registerEventCallbackInternal(
+ const sp<V1_0::IWifiRttControllerEventCallback>& callback);
+ WifiStatus rangeRequestInternal(uint32_t cmd_id,
+ const std::vector<V1_0::RttConfig>& rtt_configs);
+ WifiStatus rangeCancelInternal(uint32_t cmd_id,
+ const std::vector<hidl_array<uint8_t, 6>>& addrs);
+ std::pair<WifiStatus, V1_0::RttCapabilities> getCapabilitiesInternal();
+ WifiStatus setLciInternal(uint32_t cmd_id, const RttLciInformation& lci);
+ WifiStatus setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr);
+ std::pair<WifiStatus, V1_0::RttResponder> getResponderInfoInternal();
+ WifiStatus enableResponderInternal(uint32_t cmd_id, const V1_0::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds,
+ const V1_0::RttResponder& info);
+ WifiStatus disableResponderInternal(uint32_t cmd_id);
+ WifiStatus registerEventCallbackInternal_1_4(
+ const sp<V1_4::IWifiRttControllerEventCallback>& callback);
+ WifiStatus rangeRequestInternal_1_4(uint32_t cmd_id,
+ const std::vector<V1_4::RttConfig>& rtt_configs);
+ std::pair<WifiStatus, V1_4::RttCapabilities> getCapabilitiesInternal_1_4();
+ std::pair<WifiStatus, V1_4::RttResponder> getResponderInfoInternal_1_4();
+ WifiStatus enableResponderInternal_1_4(uint32_t cmd_id,
+ const V1_0::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds,
+ const V1_4::RttResponder& info);
+ WifiStatus registerEventCallbackInternal_1_6(
+ const sp<V1_6::IWifiRttControllerEventCallback>& callback);
+ WifiStatus rangeRequestInternal_1_6(uint32_t cmd_id,
+ const std::vector<V1_6::RttConfig>& rtt_configs);
+ std::pair<WifiStatus, V1_6::RttCapabilities> getCapabilitiesInternal_1_6();
+ std::pair<WifiStatus, V1_6::RttResponder> getResponderInfoInternal_1_6();
+ WifiStatus enableResponderInternal_1_6(uint32_t cmd_id,
+ const V1_6::WifiChannelInfo& channel_hint,
+ uint32_t max_duration_seconds,
+ const V1_6::RttResponder& info);
+
+ std::string ifname_;
+ sp<IWifiIface> bound_iface_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::vector<sp<V1_6::IWifiRttControllerEventCallback>> event_callbacks_;
+ bool is_valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiRttController);
+};
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_RTT_CONTROLLER_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_sta_iface.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_sta_iface.cpp
new file mode 100644
index 0000000..dd11839
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_sta_iface.cpp
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include "hidl_return_util.h"
+#include "hidl_struct_util.h"
+#include "wifi_sta_iface.h"
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+
+WifiStaIface::WifiStaIface(const std::string& ifname,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+ : ifname_(ifname), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) {
+ // Turn on DFS channel usage for STA iface.
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to set DFS flag; DFS channels may be unavailable.";
+ }
+}
+
+void WifiStaIface::invalidate() {
+ legacy_hal_.reset();
+ event_cb_handler_.invalidate();
+ is_valid_ = false;
+}
+
+bool WifiStaIface::isValid() {
+ return is_valid_;
+}
+
+std::string WifiStaIface::getName() {
+ return ifname_;
+}
+
+std::set<sp<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() {
+ return event_cb_handler_.getCallbacks();
+}
+
+Return<void> WifiStaIface::getName(getName_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getNameInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getType(getType_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getTypeInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::registerEventCallback(const sp<IWifiStaIfaceEventCallback>& callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::registerEventCallbackInternal, hidl_status_cb, callback);
+}
+
+Return<void> WifiStaIface::getCapabilities(getCapabilities_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getApfPacketFilterCapabilities(
+ getApfPacketFilterCapabilities_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getApfPacketFilterCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::installApfPacketFilter(uint32_t cmd_id, const hidl_vec<uint8_t>& program,
+ installApfPacketFilter_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::installApfPacketFilterInternal, hidl_status_cb, cmd_id,
+ program);
+}
+
+Return<void> WifiStaIface::readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::readApfPacketFilterDataInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getBackgroundScanCapabilities(
+ getBackgroundScanCapabilities_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getBackgroundScanCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getValidFrequenciesForBand(
+ V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getValidFrequenciesForBandInternal, hidl_status_cb, band);
+}
+
+Return<void> WifiStaIface::startBackgroundScan(uint32_t cmd_id,
+ const StaBackgroundScanParameters& params,
+ startBackgroundScan_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::startBackgroundScanInternal, hidl_status_cb, cmd_id,
+ params);
+}
+
+Return<void> WifiStaIface::stopBackgroundScan(uint32_t cmd_id,
+ stopBackgroundScan_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::stopBackgroundScanInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiStaIface::enableLinkLayerStatsCollection(
+ bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::enableLinkLayerStatsCollectionInternal, hidl_status_cb,
+ debug);
+}
+
+Return<void> WifiStaIface::disableLinkLayerStatsCollection(
+ disableLinkLayerStatsCollection_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::disableLinkLayerStatsCollectionInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getLinkLayerStatsInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getLinkLayerStatsInternal_1_3, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getLinkLayerStatsInternal_1_5, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getLinkLayerStats_1_6(getLinkLayerStats_1_6_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getLinkLayerStatsInternal_1_6, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
+ startRssiMonitoring_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::startRssiMonitoringInternal, hidl_status_cb, cmd_id,
+ max_rssi, min_rssi);
+}
+
+Return<void> WifiStaIface::stopRssiMonitoring(uint32_t cmd_id,
+ stopRssiMonitoring_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::stopRssiMonitoringInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiStaIface::getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getRoamingCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::configureRoaming(const StaRoamingConfig& config,
+ configureRoaming_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::configureRoamingInternal, hidl_status_cb, config);
+}
+
+Return<void> WifiStaIface::setRoamingState(StaRoamingState state,
+ setRoamingState_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::setRoamingStateInternal, hidl_status_cb, state);
+}
+
+Return<void> WifiStaIface::enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::enableNdOffloadInternal, hidl_status_cb, enable);
+}
+
+Return<void> WifiStaIface::startSendingKeepAlivePackets(
+ uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, uint16_t ether_type,
+ const hidl_array<uint8_t, 6>& src_address, const hidl_array<uint8_t, 6>& dst_address,
+ uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::startSendingKeepAlivePacketsInternal, hidl_status_cb,
+ cmd_id, ip_packet_data, ether_type, src_address, dst_address,
+ period_in_ms);
+}
+
+Return<void> WifiStaIface::stopSendingKeepAlivePackets(
+ uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::stopSendingKeepAlivePacketsInternal, hidl_status_cb,
+ cmd_id);
+}
+
+Return<void> WifiStaIface::setScanningMacOui(const hidl_array<uint8_t, 3>& oui,
+ setScanningMacOui_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::setScanningMacOuiInternal, hidl_status_cb, oui);
+}
+
+Return<void> WifiStaIface::startDebugPacketFateMonitoring(
+ startDebugPacketFateMonitoring_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::startDebugPacketFateMonitoringInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getDebugTxPacketFatesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getDebugRxPacketFatesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
+ setMacAddress_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::setMacAddressInternal, hidl_status_cb, mac);
+}
+
+Return<void> WifiStaIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getFactoryMacAddressInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::setScanMode(bool enable, setScanMode_cb hidl_status_cb) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::setScanModeInternal, hidl_status_cb, enable);
+}
+
+std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
+}
+
+std::pair<WifiStatus, IfaceType> WifiStaIface::getTypeInternal() {
+ return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::STA};
+}
+
+WifiStatus WifiStaIface::registerEventCallbackInternal(
+ const sp<IWifiStaIfaceEventCallback>& callback) {
+ if (!event_cb_handler_.addCallback(callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ uint64_t legacy_feature_set;
+ std::tie(legacy_status, legacy_feature_set) =
+ legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), 0};
+ }
+ uint32_t legacy_logger_feature_set;
+ std::tie(legacy_status, legacy_logger_feature_set) =
+ legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ // some devices don't support querying logger feature set
+ legacy_logger_feature_set = 0;
+ }
+ uint32_t hidl_caps;
+ if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
+ legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+std::pair<WifiStatus, StaApfPacketFilterCapabilities>
+WifiStaIface::getApfPacketFilterCapabilitiesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::PacketFilterCapabilities legacy_caps;
+ std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getPacketFilterCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ StaApfPacketFilterCapabilities hidl_caps;
+ if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+WifiStatus WifiStaIface::installApfPacketFilterInternal(uint32_t /* cmd_id */,
+ const std::vector<uint8_t>& program) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setPacketFilter(ifname_, program);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, std::vector<uint8_t>> WifiStaIface::readApfPacketFilterDataInternal() {
+ const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>> legacy_status_and_data =
+ legacy_hal_.lock()->readApfPacketFilterData(ifname_);
+ return {createWifiStatusFromLegacyError(legacy_status_and_data.first),
+ std::move(legacy_status_and_data.second)};
+}
+
+std::pair<WifiStatus, StaBackgroundScanCapabilities>
+WifiStaIface::getBackgroundScanCapabilitiesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_gscan_capabilities legacy_caps;
+ std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getGscanCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ StaBackgroundScanCapabilities hidl_caps;
+ if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
+WifiStaIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
+ static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch");
+ legacy_hal::wifi_error legacy_status;
+ std::vector<uint32_t> valid_frequencies;
+ std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand(
+ ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band));
+ return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
+}
+
+WifiStatus WifiStaIface::startBackgroundScanInternal(uint32_t cmd_id,
+ const StaBackgroundScanParameters& params) {
+ legacy_hal::wifi_scan_cmd_params legacy_params;
+ if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params, &legacy_params)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ android::wp<WifiStaIface> weak_ptr_this(this);
+ const auto& on_failure_callback = [weak_ptr_this](legacy_hal::wifi_request_id id) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onBackgroundScanFailure(id).isOk()) {
+ LOG(ERROR) << "Failed to invoke onBackgroundScanFailure callback";
+ }
+ }
+ };
+ const auto& on_results_callback =
+ [weak_ptr_this](legacy_hal::wifi_request_id id,
+ const std::vector<legacy_hal::wifi_cached_scan_results>& results) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ std::vector<StaScanData> hidl_scan_datas;
+ if (!hidl_struct_util::convertLegacyVectorOfCachedGscanResultsToHidl(
+ results, &hidl_scan_datas)) {
+ LOG(ERROR) << "Failed to convert scan results to HIDL structs";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onBackgroundScanResults(id, hidl_scan_datas).isOk()) {
+ LOG(ERROR) << "Failed to invoke onBackgroundScanResults callback";
+ }
+ }
+ };
+ const auto& on_full_result_callback = [weak_ptr_this](
+ legacy_hal::wifi_request_id id,
+ const legacy_hal::wifi_scan_result* result,
+ uint32_t buckets_scanned) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ StaScanResult hidl_scan_result;
+ if (!hidl_struct_util::convertLegacyGscanResultToHidl(*result, true, &hidl_scan_result)) {
+ LOG(ERROR) << "Failed to convert full scan results to HIDL structs";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onBackgroundFullScanResult(id, buckets_scanned, hidl_scan_result)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke onBackgroundFullScanResult callback";
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->startGscan(ifname_, cmd_id, legacy_params, on_failure_callback,
+ on_results_callback, on_full_result_callback);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::stopBackgroundScanInternal(uint32_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopGscan(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableLinkLayerStats(ifname_);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, V1_0::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal() {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+std::pair<WifiStatus, V1_3::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_3() {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+std::pair<WifiStatus, V1_5::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_5() {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+std::pair<WifiStatus, V1_6::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_6() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::LinkLayerStats legacy_stats;
+ std::tie(legacy_status, legacy_stats) = legacy_hal_.lock()->getLinkLayerStats(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ V1_6::StaLinkLayerStats hidl_stats;
+ if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &hidl_stats)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
+}
+
+WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi,
+ int32_t min_rssi) {
+ android::wp<WifiStaIface> weak_ptr_this(this);
+ const auto& on_threshold_breached_callback = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ std::array<uint8_t, 6> bssid,
+ int8_t rssi) {
+ const auto shared_ptr_this = weak_ptr_this.promote();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onRssiThresholdBreached(id, bssid, rssi).isOk()) {
+ LOG(ERROR) << "Failed to invoke onRssiThresholdBreached callback";
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRssiMonitoring(
+ ifname_, cmd_id, max_rssi, min_rssi, on_threshold_breached_callback);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::stopRssiMonitoringInternal(uint32_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, StaRoamingCapabilities> WifiStaIface::getRoamingCapabilitiesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_roaming_capabilities legacy_caps;
+ std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRoamingCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ StaRoamingCapabilities hidl_caps;
+ if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+WifiStatus WifiStaIface::configureRoamingInternal(const StaRoamingConfig& config) {
+ legacy_hal::wifi_roaming_config legacy_config;
+ if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config, &legacy_config)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->configureRoaming(ifname_, legacy_config);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableFirmwareRoaming(
+ ifname_, hidl_struct_util::convertHidlRoamingStateToLegacy(state));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->configureNdOffload(ifname_, enable);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
+ uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, uint16_t ether_type,
+ const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address,
+ uint32_t period_in_ms) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startSendingOffloadedPacket(
+ ifname_, cmd_id, ether_type, ip_packet_data, src_address, dst_address, period_in_ms);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(uint32_t cmd_id) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::setScanningMacOuiInternal(const std::array<uint8_t, 3>& /* oui */) {
+ // deprecated.
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startPktFateMonitoring(ifname_);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>
+WifiStaIface::getDebugTxPacketFatesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<legacy_hal::wifi_tx_report> legacy_fates;
+ std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getTxPktFates(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ std::vector<WifiDebugTxPacketFateReport> hidl_fates;
+ if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl(legacy_fates,
+ &hidl_fates)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
+}
+
+std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>>
+WifiStaIface::getDebugRxPacketFatesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<legacy_hal::wifi_rx_report> legacy_fates;
+ std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getRxPktFates(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {createWifiStatusFromLegacyError(legacy_status), {}};
+ }
+ std::vector<WifiDebugRxPacketFateReport> hidl_fates;
+ if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl(legacy_fates,
+ &hidl_fates)) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
+}
+
+WifiStatus WifiStaIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
+ bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
+ if (!status) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, std::array<uint8_t, 6>> WifiStaIface::getFactoryMacAddressInternal() {
+ std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifname_);
+ if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
+ return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
+}
+
+WifiStatus WifiStaIface::setScanModeInternal(bool enable) {
+ // OEM's need to implement this on their devices if needed.
+ LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported";
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_sta_iface.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_sta_iface.h
new file mode 100644
index 0000000..c01c50b
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_sta_iface.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_STA_IFACE_H_
+#define WIFI_STA_IFACE_H_
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
+#include <android/hardware/wifi/1.6/IWifiStaIface.h>
+
+#include "hidl_callback_util.h"
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+
+/**
+ * HIDL interface object used to control a STA Iface instance.
+ */
+class WifiStaIface : public V1_6::IWifiStaIface {
+ public:
+ WifiStaIface(const std::string& ifname,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::set<sp<IWifiStaIfaceEventCallback>> getEventCallbacks();
+ std::string getName();
+
+ // HIDL methods exposed.
+ Return<void> getName(getName_cb hidl_status_cb) override;
+ Return<void> getType(getType_cb hidl_status_cb) override;
+ Return<void> registerEventCallback(const sp<IWifiStaIfaceEventCallback>& callback,
+ registerEventCallback_cb hidl_status_cb) override;
+ Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
+ Return<void> getApfPacketFilterCapabilities(
+ getApfPacketFilterCapabilities_cb hidl_status_cb) override;
+ Return<void> installApfPacketFilter(uint32_t cmd_id, const hidl_vec<uint8_t>& program,
+ installApfPacketFilter_cb hidl_status_cb) override;
+ Return<void> readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) override;
+ Return<void> getBackgroundScanCapabilities(
+ getBackgroundScanCapabilities_cb hidl_status_cb) override;
+ Return<void> getValidFrequenciesForBand(V1_0::WifiBand band,
+ getValidFrequenciesForBand_cb hidl_status_cb) override;
+ Return<void> startBackgroundScan(uint32_t cmd_id, const StaBackgroundScanParameters& params,
+ startBackgroundScan_cb hidl_status_cb) override;
+ Return<void> stopBackgroundScan(uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) override;
+ Return<void> enableLinkLayerStatsCollection(
+ bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) override;
+ Return<void> disableLinkLayerStatsCollection(
+ disableLinkLayerStatsCollection_cb hidl_status_cb) override;
+ Return<void> getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) override;
+ Return<void> getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) override;
+ Return<void> getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) override;
+ Return<void> getLinkLayerStats_1_6(getLinkLayerStats_1_6_cb hidl_status_cb) override;
+ Return<void> startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
+ startRssiMonitoring_cb hidl_status_cb) override;
+ Return<void> stopRssiMonitoring(uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override;
+ Return<void> getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) override;
+ Return<void> configureRoaming(const StaRoamingConfig& config,
+ configureRoaming_cb hidl_status_cb) override;
+ Return<void> setRoamingState(StaRoamingState state, setRoamingState_cb hidl_status_cb) override;
+ Return<void> enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) override;
+ Return<void> startSendingKeepAlivePackets(
+ uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, uint16_t ether_type,
+ const hidl_array<uint8_t, 6>& src_address, const hidl_array<uint8_t, 6>& dst_address,
+ uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) override;
+ Return<void> stopSendingKeepAlivePackets(
+ uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) override;
+ Return<void> setScanningMacOui(const hidl_array<uint8_t, 3>& oui,
+ setScanningMacOui_cb hidl_status_cb) override;
+ Return<void> startDebugPacketFateMonitoring(
+ startDebugPacketFateMonitoring_cb hidl_status_cb) override;
+ Return<void> getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) override;
+ Return<void> getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) override;
+ Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
+ setMacAddress_cb hidl_status_cb) override;
+ Return<void> getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override;
+ Return<void> setScanMode(bool enable, setScanMode_cb hidl_status_cb) override;
+
+ private:
+ // Corresponding worker functions for the HIDL methods.
+ std::pair<WifiStatus, std::string> getNameInternal();
+ std::pair<WifiStatus, IfaceType> getTypeInternal();
+ WifiStatus registerEventCallbackInternal(const sp<IWifiStaIfaceEventCallback>& callback);
+ std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
+ std::pair<WifiStatus, StaApfPacketFilterCapabilities> getApfPacketFilterCapabilitiesInternal();
+ WifiStatus installApfPacketFilterInternal(uint32_t cmd_id, const std::vector<uint8_t>& program);
+ std::pair<WifiStatus, std::vector<uint8_t>> readApfPacketFilterDataInternal();
+ std::pair<WifiStatus, StaBackgroundScanCapabilities> getBackgroundScanCapabilitiesInternal();
+ std::pair<WifiStatus, std::vector<WifiChannelInMhz>> getValidFrequenciesForBandInternal(
+ V1_0::WifiBand band);
+ WifiStatus startBackgroundScanInternal(uint32_t cmd_id,
+ const StaBackgroundScanParameters& params);
+ WifiStatus stopBackgroundScanInternal(uint32_t cmd_id);
+ WifiStatus enableLinkLayerStatsCollectionInternal(bool debug);
+ WifiStatus disableLinkLayerStatsCollectionInternal();
+ std::pair<WifiStatus, V1_0::StaLinkLayerStats> getLinkLayerStatsInternal();
+ std::pair<WifiStatus, V1_3::StaLinkLayerStats> getLinkLayerStatsInternal_1_3();
+ std::pair<WifiStatus, V1_5::StaLinkLayerStats> getLinkLayerStatsInternal_1_5();
+ std::pair<WifiStatus, V1_6::StaLinkLayerStats> getLinkLayerStatsInternal_1_6();
+ WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi);
+ WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id);
+ std::pair<WifiStatus, StaRoamingCapabilities> getRoamingCapabilitiesInternal();
+ WifiStatus configureRoamingInternal(const StaRoamingConfig& config);
+ WifiStatus setRoamingStateInternal(StaRoamingState state);
+ WifiStatus enableNdOffloadInternal(bool enable);
+ WifiStatus startSendingKeepAlivePacketsInternal(uint32_t cmd_id,
+ const std::vector<uint8_t>& ip_packet_data,
+ uint16_t ether_type,
+ const std::array<uint8_t, 6>& src_address,
+ const std::array<uint8_t, 6>& dst_address,
+ uint32_t period_in_ms);
+ WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id);
+ WifiStatus setScanningMacOuiInternal(const std::array<uint8_t, 3>& oui);
+ WifiStatus startDebugPacketFateMonitoringInternal();
+ std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>> getDebugTxPacketFatesInternal();
+ std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>> getDebugRxPacketFatesInternal();
+ WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
+ std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal();
+ WifiStatus setScanModeInternal(bool enable);
+
+ std::string ifname_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+ bool is_valid_;
+ hidl_callback_util::HidlCallbackHandler<IWifiStaIfaceEventCallback> event_cb_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
+};
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_STA_IFACE_H_
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_status_util.cpp b/wifi/wifi_legacy_service/1.0-legacy/wifi_status_util.cpp
new file mode 100644
index 0000000..3b18e53
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_status_util.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+
+std::string legacyErrorToString(legacy_hal::wifi_error error) {
+ switch (error) {
+ case legacy_hal::WIFI_SUCCESS:
+ return "SUCCESS";
+ case legacy_hal::WIFI_ERROR_UNINITIALIZED:
+ return "UNINITIALIZED";
+ case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
+ return "NOT_AVAILABLE";
+ case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
+ return "NOT_SUPPORTED";
+ case legacy_hal::WIFI_ERROR_INVALID_ARGS:
+ return "INVALID_ARGS";
+ case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
+ return "INVALID_REQUEST_ID";
+ case legacy_hal::WIFI_ERROR_TIMED_OUT:
+ return "TIMED_OUT";
+ case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
+ return "TOO_MANY_REQUESTS";
+ case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+ case legacy_hal::WIFI_ERROR_BUSY:
+ return "BUSY";
+ case legacy_hal::WIFI_ERROR_UNKNOWN:
+ return "UNKNOWN";
+ default:
+ return "UNKNOWN ERROR";
+ }
+}
+
+WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description) {
+ return {code, description};
+}
+
+WifiStatus createWifiStatus(WifiStatusCode code) {
+ return createWifiStatus(code, "");
+}
+
+WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, const std::string& desc) {
+ switch (error) {
+ case legacy_hal::WIFI_ERROR_UNINITIALIZED:
+ case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, desc);
+
+ case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED, desc);
+
+ case legacy_hal::WIFI_ERROR_INVALID_ARGS:
+ case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS, desc);
+
+ case legacy_hal::WIFI_ERROR_TIMED_OUT:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", timed out");
+
+ case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", too many requests");
+
+ case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", out of memory");
+
+ case legacy_hal::WIFI_ERROR_BUSY:
+ return createWifiStatus(WifiStatusCode::ERROR_BUSY);
+
+ case legacy_hal::WIFI_ERROR_NONE:
+ return createWifiStatus(WifiStatusCode::SUCCESS, desc);
+
+ case legacy_hal::WIFI_ERROR_UNKNOWN:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown");
+
+ default:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown error");
+ }
+}
+
+WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) {
+ return createWifiStatusFromLegacyError(error, "");
+}
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
diff --git a/wifi/wifi_legacy_service/1.0-legacy/wifi_status_util.h b/wifi/wifi_legacy_service/1.0-legacy/wifi_status_util.h
new file mode 100644
index 0000000..ea1c294
--- /dev/null
+++ b/wifi/wifi_legacy_service/1.0-legacy/wifi_status_util.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_STATUS_UTIL_H_
+#define WIFI_STATUS_UTIL_H_
+
+#include <android/hardware/wifi/1.4/IWifi.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+
+std::string legacyErrorToString(legacy_hal::wifi_error error);
+WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description);
+WifiStatus createWifiStatus(WifiStatusCode code);
+WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
+ const std::string& description);
+WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error);
+
+} // namespace implementation
+} // namespace V1_6
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+
+#endif // WIFI_STATUS_UTIL_H_