code:
###################################
#####   ANTENNA INFORMATION   #####
###################################

###################################
# ANTENNA INFO VECTOR SIZE
###################################
# The number of antenna info
# structures in the vector. Each
# entry in this vector is a structure
# with the following elements:
#
# - CARRIER_FREQUENCY
# - PC_OFFSET
# - PC_VARIATION_CORRECTION
# - PC_VARIATION_CORRECTION_UNC
# - SIGNAL_GAIN_CORRECTION
# - SIGNAL_GAIN_CORRECTION_UNC
#
# Notes:
# CARRIER_FREQUENCY
#   The carrier frequency in MHz.
#
# PC = PHASE CENTER
#   PC_OFFSET is a structure with six
#   elements: x, y, z and their associated uncertainties
#   Phase center offset (PCO) is defined with
#   respect to the origin of the Android sensor coordinate system, e.g.,
#   center of primary screen for mobiles
#
# PC_VARIATION_CORRECTION
#   2D vectors representing the phase center variation (PCV) corrections,
#   in millimeters, at regularly spaced azimuthal angle (theta) and zenith angle
#   (phi). The PCV correction is added to the phase measurement to obtain the
#   corrected value.
#   The azimuthal angle, theta, is defined with respect to the X axis of the
#   Android sensor coordinate system, increasing toward the Y axis. The zenith
#   angle, phi, is defined with respect to the Z axis of the Android Sensor
#   coordinate system, increasing toward the X-Y plane.
#   Each row vector (outer vectors) represents a fixed theta. The first row
#   corresponds to a theta angle of 0 degrees. The last row corresponds to a
#   theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular
#   spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows).
#   The columns (inner vectors) represent fixed zenith angles, beginning at 0
#   degrees and ending at 180 degrees. They are separated by deltaPhi, the regular
#   spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1).
#
# PC_VARIATION_CORRECTION_UNC
#   2D vectors of 1-sigma uncertainty in millimeters associated with the PCV
#   correction values.
#
# SIGNAL_GAIN_CORRECTION
#   2D vectors representing the signal gain corrections at regularly spaced
#   azimuthal angle (theta) and zenith angle (phi). The values are calculated or
#   measured at the antenna feed point without considering the radio and receiver
#   noise figure and path loss contribution, in dBi, i.e., decibel over isotropic
#   antenna with the same total power. The signal gain correction is added the
#   signal gain measurement to obtain the corrected value.
#   The azimuthal angle, theta, is defined with respect to the X axis of the
#   Android sensor coordinate system, increasing toward the Y axis. The zenith
#   angle, phi, is defined with respect to the Z axis of the Android Sensor
#   coordinate system, increasing toward the X-Y plane.
#   Each row vector (outer vectors) represents a fixed theta. The first row
#   corresponds to a theta angle of 0 degrees. The last row corresponds to a
#   theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular
#   spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows).
#   The columns (inner vectors) represent fixed zenith angles, beginning at 0
#   degrees and ending at 180 degrees. They are separated by deltaPhi, the regular
#   spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1).
#
# SIGNAL_GAIN_CORRECTION_UNC
#   2D vectors of 1-sigma uncertainty in dBi associated with the signal
#   gain correction values.
#
# The number of rows and columns could be the same for PC variation correction
# and signal gain corrections, or could be different
# If the former then NUMBER_OF_ROWS_ and NUMBER_OF_COLUMNS_ are specified once
# only, if the latter then NUMBER_OF_ROWS_ and NUMBER_OF_COLUMNS_ represent
# the number of rows/columns for PC variation correction and
# NUMBER_OF_ROWS_SGC_ and NUMBER_OF_COLUMNS_SGC_ represent the number of
# rows/columns for signal gain corrections

ANTENNA_INFO_VECTOR_SIZE = 2

CARRIER_FREQUENCY_0 = 1575.42

PC_OFFSET_0 = 1.2 0.1 3.4 0.2 5.6 0.3

NUMBER_OF_ROWS_0 = 3
NUMBER_OF_COLUMNS_0 = 4

PC_VARIATION_CORRECTION_0_ROW_0 = 11.22 33.44 55.66 77.88
PC_VARIATION_CORRECTION_0_ROW_1 = 10.2 30.4 50.6 70.8
PC_VARIATION_CORRECTION_0_ROW_2 = 12.2 34.4 56.6 78.8

PC_VARIATION_CORRECTION_UNC_0_ROW_0 = 0.1 0.2 0.3 0.4
PC_VARIATION_CORRECTION_UNC_0_ROW_1 = 1.1 1.2 1.3 1.4
PC_VARIATION_CORRECTION_UNC_0_ROW_2 = 2.1 2.2 2.3 2.4

SIGNAL_GAIN_CORRECTION_0_ROW_0 = 9.8 8.7 7.6 6.5
SIGNAL_GAIN_CORRECTION_0_ROW_1 = 5.4 4.3 3.2 2.1
SIGNAL_GAIN_CORRECTION_0_ROW_2 = 1.3 2.4 3.5 4.6

SIGNAL_GAIN_CORRECTION_UNC_0_ROW_0 = 0.11 0.22 0.33 0.44
SIGNAL_GAIN_CORRECTION_UNC_0_ROW_1 = 0.55 0.66 0.77 0.88
SIGNAL_GAIN_CORRECTION_UNC_0_ROW_2 = 0.91 0.92 0.93 0.94

CARRIER_FREQUENCY_1 = 1227.6

PC_OFFSET_1 = 3.4 0.2 5.6 0.3 1.2 0.1

NUMBER_OF_ROWS_1 = 4
NUMBER_OF_COLUMNS_1 = 2
NUMBER_OF_ROWS_SGC_1 = 3
NUMBER_OF_COLUMNS_SGC_1 = 4

PC_VARIATION_CORRECTION_1_ROW_0 = 55.66 77.88
PC_VARIATION_CORRECTION_1_ROW_1 = 11.22 33.44
PC_VARIATION_CORRECTION_1_ROW_2 = 56.6 78.8
PC_VARIATION_CORRECTION_1_ROW_3 = 12.2 34.4

PC_VARIATION_CORRECTION_UNC_1_ROW_0 = 0.3 0.4
PC_VARIATION_CORRECTION_UNC_1_ROW_1 = 1.1 1.2
PC_VARIATION_CORRECTION_UNC_1_ROW_2 = 2.1 2.2
PC_VARIATION_CORRECTION_UNC_1_ROW_3 = 0.1 0.2

SIGNAL_GAIN_CORRECTION_1_ROW_0 = 7.6 6.5 5.4 4.3
SIGNAL_GAIN_CORRECTION_1_ROW_1 = 1.3 2.4 9.8 8.7
SIGNAL_GAIN_CORRECTION_1_ROW_2 = 1.4 2.5 3.6 4.7

SIGNAL_GAIN_CORRECTION_UNC_1_ROW_0 = 0.91 0.92 0.55 0.66
SIGNAL_GAIN_CORRECTION_UNC_1_ROW_1 = 0.11 0.22 0.93 0.94
SIGNAL_GAIN_CORRECTION_UNC_1_ROW_2 = 0.95 0.96 0.33 0.44


code:
# Error Estimate
# _SET = 1
# _CLEAR = 0
ERR_ESTIMATE=0

XTRA_TEST_ENABLED = 1
XTRA_THROTTLE_ENABLED = 0

#NTP server
NTP_SERVER=time.xtracloud.net

#XTRA CA path
XTRA_CA_PATH=/usr/lib/ssl-1.1/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=0

# 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=

# 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=5000

################################
##### 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
####################################
# LPP_PROFILE is a bit mask
# 0: Enable RRLP on LTE(Default)
# 0x1: LPP User Plane
# 0x2: LPP Control Plane
# 0x4: LPP User Plane for NR5G
# 0x8: LPP Control Plane for NR5G
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

################################
# NMEA TAG BLOCK GROUPING
################################
# NMEA tag block grouping is only applicable to GSA
# Default is disabled
# 0 - disabled
# 1 - enabled
NMEA_TAG_BLOCK_GROUPING_ENABLED = 0

# Customized NMEA GGA fix quality that can be used to tell
# whether SENSOR contributed to the fix.
#
# When this configuration item is not enabled (set to any value that is not 1),
# GGA fix quality conforms to NMEA standard spec as below:
# PPP/DGNSS/SBAS correction fix w/ or w/o sensor: 2
# RTK fixed fix w/ or w/o sensor: 4
# RTK float fix w/ or w/o sensor: 5
# SPE fix w/ or w/o sensor: 1
# Sensor dead reckoning fix: 6
#
# When this configuration is enabled (set to 1), GGA fix quality
# will be output as below:
# PPP fix w/o sensor: 59,                  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
#
# any value that is not 1 - disabled
# 1 - enabled
CUSTOM_NMEA_GGA_FIX_QUALITY_ENABLED = 0

################################
# NMEA Reporting Rate Config, valid only when NMEA_PROVIDER is set to "0"
################################
# NMEA Reporting Rate
# Set it to "1HZ" for 1Hz NMEA Reporting
# Set it to "NHZ" for NHz NMEA Reporting
#Default : NHZ (overridden by position update rate if set to lower rates)
NMEA_REPORT_RATE=NHZ

# 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

#####################################
# 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
# 2 : Enable PDS API
# This setting use to select between QTI GNSS,
# QCSR SS5 hardware receiver, and PDS API.
# By default QTI GNSS receiver is enabled.
# GNSS_DEPLOYMENT = 0

##################################################
## LOG BUFFER CONFIGURATION
##################################################
#LOG_BUFFER_ENABLED, 1=enable, 0=disable
#*_LEVEL_TIME_DEPTH, maximum time depth of level *
#in log buffer, unit is second
#*_LEVEL_MAX_CAPACITY, maximum numbers of level *
#log print sentences in log buffer
LOG_BUFFER_ENABLED = 0
E_LEVEL_TIME_DEPTH = 600
E_LEVEL_MAX_CAPACITY = 50
W_LEVEL_TIME_DEPTH = 500
W_LEVEL_MAX_CAPACITY = 100
I_LEVEL_TIME_DEPTH = 400
I_LEVEL_MAX_CAPACITY = 200
D_LEVEL_TIME_DEPTH = 30
D_LEVEL_MAX_CAPACITY = 300
V_LEVEL_TIME_DEPTH = 200
V_LEVEL_MAX_CAPACITY = 400

##################################################
# Allow buffer diag log packets when diag memory allocation
# fails during boot up time.
##################################################
BUFFER_DIAG_LOGGING = 1

#######################################
#  NTRIP CLIENT LIBRARY NAME
#######################################
# NTRIP_CLIENT_LIB_NAME =

##################################################
# Correction Data Framework settings
# Default values:
# CDFW_SOURCE_PRIORITY_1 = INTERNAL_1 RTCM
# CDFW_INJECT_DATA_INTERVAL = 600000 //10 mins
# CDFW_RTCM_MESSAGE_INTERVAL = 1000  //1 second
#
# If multiple sources coexist on a PL,
# the prorioty sequence can be set by the integer number.
# PRIORITY_1 is higher than PRIORITY_2, for example,
# CDFW_SOURCE_PRIORITY_1 = INTERNAL_1 RTCM
# CDFW_SOURCE_PRIORITY_2 = CV2X RTCM
##################################################

##################################################
# RF LOSS
# The loss in 0.1 dbHz from the C/N0 at the antenna port
# These values must be configured by OEM if not
# supported in QMI LOC message
# There is one entry for each signal type
##################################################
RF_LOSS_GPS = 0
RF_LOSS_GPS_L5 = 0
RF_LOSS_GLO_LEFT = 0
RF_LOSS_GLO_CENTER = 0
RF_LOSS_GLO_RIGHT = 0
RF_LOSS_BDS = 0
RF_LOSS_BDS_B2A = 0
RF_LOSS_GAL = 0
RF_LOSS_GAL_E5 = 0
RF_LOSS_NAVIC = 0

license: unknown


code:
#########################################
# Log verbosity control for izat modules
#########################################
# OFF = 0, ERROR = 1, WARNING = 2, INFO = 3, DEBUG = 4, VERBOSE = 5
IZAT_DEBUG_LEVEL = 5

##################################################
# 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 = 1
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)
# SDK_WIFI (WWAN provided by legacy Modem)
GTP_MODE=DISABLED

#GTP_WAA valid modes:
# DISABLED
# BASIC
GTP_WAA=DISABLED

#SAP valid modes:
# DISABLED
# BASIC
# PREMIUM
# PREMIUM_ENV_AIDING
# 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

#Values for LOW_RAM_TARGETS:
# ENABLED
# DISABLED
# Property to enable/disable processes for low ram targets. Uses ro.config.low_ram property
# to identify low ram targets.

#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 SOC_IDS can be:
#1. Any valid values obtained from soc_id node separated by single space. For example: 339 386 436
##  soc_id value can be obtained from any one of below node:
##      - /sys/devices/soc0/soc_id
##      - /sys/devices/system/soc/soc0/id
#2. 'all' or 'all exclude' -> for All soc id's
#3. 'all exclude XXXX' -> All soc id's exclude XXXX. For example: all exclude 339 386

#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
SOC_IDS=all
BASEBAND=all
LOW_RAM_TARGETS=ENABLED
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
SOC_IDS=all
BASEBAND=all
LOW_RAM_TARGETS=ENABLED
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
SOC_IDS=all
BASEBAND=all
LOW_RAM_TARGETS=ENABLED
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
SOC_IDS=all exclude 386 436
BASEBAND=all
LOW_RAM_TARGETS=DISABLED
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
SOC_IDS=all
BASEBAND=all
LOW_RAM_TARGETS=ENABLED
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
SOC_IDS=all
BASEBAND=all
LOW_RAM_TARGETS=DISABLED
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 qwes oem_2901 system
PREMIUM_FEATURE=0
IZAT_FEATURE_MASK=0
PLATFORMS=all
SOC_IDS=all
BASEBAND=all
LOW_RAM_TARGETS=DISABLED
HARDWARE_TYPE=all
VENDOR_ENHANCED_PROCESS=1


code:
#*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
#
# LOWI Config file - default
#
# 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 = 2
LOWI_USE_LOWI_LP = 0


code:
################################
# 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=

# 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 = 0
# 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
VN_SPEED_CFG=1:777,0,0,1,3,1,0.002778,0,40,8,32,8
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=50

#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=50

#Vehicle Gear batching value, it can either accept time in milli seconds or sample count
VN_GEAR_CFG_BATCH_VALUE=50

#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

# Vehicle Network Data optimization
# Default value: 0
# Value 0x40000 -  Speed(bit 18 eSLIM_SERVICE_VEHICLE_SPEED)
# Value 0x80000 -  Speed(bit 19 eSLIM_SERVICE_VEHICLE_DWS)
# Value 0x100000 -  Speed(bit 20 eSLIM_SERVICE_VEHICLE_GEAR)
VN_ENABLE_DATA_OPTIMIZATION=0x100000

# Vehicle Network Data Routing time interval
# This is applicable only if VN_ENABLE_DATA_OPTIMIZATION value is set
# Default value: 5000 msec
VN_DATA_ROUTING_TIME_INTERVAL_MSEC=3000

#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


code:
#*******************************************************************************
#  Copyright (c) 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.
#
#******************************************************************************

clone: 1
close: 1
connect: 1
execve: 1
exit_group: 1
exit: 1
faccessat: 1
fcntl: 1
fstat: 1
fstatfs: 1
futex: 1
getpid: 1
getuid: 1
getgid: 1
getegid: 1
getgroups: 1
geteuid: 1
umask: 1
getrandom: 1
mmap: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
mremap: 1
munmap: 1
newfstatat: 1
openat: 1
#prctl: arg0 == PR_SET_VMA || arg0 == PR_SET_NO_NEW_PRIVS || arg0 == PR_GET_DUMPABLE || arg0 == PR_SET_SECCOMP || arg0 == 0x37 /* PR_??? */
prctl: 1
pread64: 1
read: 1
pwrite64: 1
write: 1
writev: 1
readlinkat: 1
restart_syscall: 1
rt_sigaction: 1
rt_sigprocmask: 1
rt_sigreturn: 1
sched_getscheduler: 1
set_tid_address: 1
sigaltstack: 1
unlinkat: 1
lseek: 1
##ioctl: arg1 == _IOC(_IOC_NONE || arg1 == _IOC(_IOC_READ || arg1 == VSOC_MAYBE_SEND_INTERRUPT_TO_HOST
ioctl: 1
clock_gettime: 1

socket: arg0 == AF_INET6 || arg0 == AF_UNIX || arg0 == AF_QIPCRTR
connect: 1
setsockopt: 1
getsockname: 1
socketpair: 1
ppoll: 1
pselect6: 1
accept4: 1
listen: 1
bind: 1
pipe2: 1

recvmsg: 1
sendmsg: 1

sendto: 1
recvfrom: 1

getsockname: 1
nanosleep: 1
clone: 1
setsockopt: 1
getsockopt: 1
madvise: 1

getitimer: 1
setitimer: 1
getpid: 1
bind: 1
listen: 1
getpeername: 1
socketpair: 1
wait4: 1
chown: 1
fchown: 1
lchown: 1
umask: 1
mmap2: 1
fstat64: 1
fstatat64: 1
_llseek: 1
geteuid: 1


code:
#*******************************************************************************
#  Copyright (c) 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.
#
#******************************************************************************
bind: 1
getrlimit: 1

pipe2: 1

sched_getaffinity: 1
timerfd_create: 1
unlinkat: 1
setpriority: 1

epoll_create1: 1
epoll_ctl: 1
epoll_pwait: 1
timerfd_settime: 1

fdatasync: 1
madvise: 1
ftruncate: 1


code:
#*******************************************************************************
#  Copyright (c) 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.
#
#******************************************************************************

fdatasync: 1
getdents64: 1
gettimeofday: 1
ioctl: 1
lseek: 1
madvise: 1
mkdirat: 1
pwrite64: 1

timerfd_create: 1
timerfd_settime: 1
epoll_create1: 1
epoll_pwait: 1
epoll_ctl: 1

sched_getaffinity: 1
gettid: 1
fchown: 1
fchmod: 1
fchmodat: 1
getsockopt: 1
fchownat: 1
fstat: 1
fstatfs: 1
newfstatat: 1
sendmsg: 1
recvmsg: 1
gettimeofday: 1
setsockopt: 1
rt_tgsigqueueinfo: 1
ioctl: 1
mmap: 1
getuid32: 1
getuid: 1
fstat64: 1
fstatat64: 1
mkdir: 1
rmdir: 1
creat: 1
chmod: 1
lseek: 1
geteuid32: 1


code:
#*******************************************************************************
#  Copyright (c) 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.
#
#******************************************************************************

unlinkat: 1
sched_getaffinity: 1
newfstatat: 1
fchmodat: 1
madvise: 1
mmap: 1
getuid: 1
getuid32: 1
fstat64: 1
fstatat64: 1
gettimeofday: 1
getdents64: 1


code:
#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


code:
cc_library_shared {

    name: "libgeofencing",
    vendor: true,

    srcs: [
        "GeofenceAdapter.cpp",
        "location_geofence.cpp",
    ],

    shared_libs: [
        "libutils",
        "libcutils",
        "libgps.utils",
        "liblog",
        "libloc_core",
    ],

    header_libs: [
        "libgps.utils_headers",
        "libloc_core_headers",
        "libloc_pla_headers",
        "liblocation_api_headers",
    ],

    cflags: GNSS_CFLAGS,
}


code:
/* Copyright (c) 2013-2021, 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(LocContext::mLocationHalName),
                   true /*isMaster*/, nullptr, true)
{
    LOC_LOGD("%s]: Constructor", __func__);

    // at last step, let us inform adapater base that we are done
    // with initialization, e.g.: ready to process handleEngineUpEvent
    doneInit();
}

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);
        }
    }
}


code:
/* 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 */


code:
/* 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);
    }
}