1 /*
2 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
3 * Not a Contribution
4 */
5 /*
6 * Copyright (C) 2016 The Android Open Source Project
7 *
8 * Licensed under the Apache License, Version 2_0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2_0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 #define LOG_TAG "LocSvc_GnssConfigurationInterface"
22
23 #include <log_util.h>
24 #include "Gnss.h"
25 #include "GnssConfiguration.h"
26 #include "ContextBase.h"
27 #include <android/hardware/gnss/1.0/types.h>
28
29 namespace android {
30 namespace hardware {
31 namespace gnss {
32 namespace V2_1 {
33 namespace implementation {
34
35 using ::android::hardware::gnss::V2_0::GnssConstellationType;
36 using namespace loc_core;
37
GnssConfiguration(Gnss * gnss)38 GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
39 }
40
41 // Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
setSuplEs(bool enabled)42 Return<bool> GnssConfiguration::setSuplEs(bool enabled) {
43 // deprecated function. Must return false to pass VTS
44 return false;
45 }
46
setSuplVersion(uint32_t version)47 Return<bool> GnssConfiguration::setSuplVersion(uint32_t version) {
48 if (mGnss == nullptr) {
49 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
50 return false;
51 }
52
53 GnssConfig config;
54 memset(&config, 0, sizeof(GnssConfig));
55 config.size = sizeof(GnssConfig);
56 config.flags = GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
57 switch (version) {
58 case 0x00020004:
59 config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_4;
60 break;
61 case 0x00020002:
62 config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_2;
63 break;
64 case 0x00020000:
65 config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_0;
66 break;
67 case 0x00010000:
68 config.suplVersion = GNSS_CONFIG_SUPL_VERSION_1_0_0;
69 break;
70 default:
71 LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
72 return false;
73 }
74
75 return mGnss->updateConfiguration(config);
76 }
77
setSuplMode(uint8_t mode)78 Return<bool> GnssConfiguration::setSuplMode(uint8_t mode) {
79 if (mGnss == nullptr) {
80 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
81 return false;
82 }
83
84 GnssConfig config;
85 memset(&config, 0, sizeof(GnssConfig));
86 config.size = sizeof(GnssConfig);
87 config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
88 switch (mode) {
89 case 0:
90 config.suplModeMask = 0; // STANDALONE ONLY
91 break;
92 case 1:
93 config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT;
94 break;
95 case 2:
96 config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT;
97 break;
98 case 3:
99 config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT;
100 break;
101 default:
102 LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
103 return false;
104 }
105
106 return mGnss->updateConfiguration(config);
107 }
108
setLppProfile(uint8_t lppProfileMask)109 Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfileMask) {
110 if (mGnss == nullptr) {
111 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
112 return false;
113 }
114
115 GnssConfig config = {};
116 config.size = sizeof(GnssConfig);
117 config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
118 config.lppProfileMask = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE; //default
119
120 if (lppProfileMask & (1<<0)) {
121 config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_BIT;
122 }
123 if (lppProfileMask & (1<<1)) {
124 config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_BIT;
125 }
126 if (lppProfileMask & (1<<2)) {
127 config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_OVER_NR5G_SA_BIT;
128 }
129 if (lppProfileMask & (1<<3)) {
130 config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_OVER_NR5G_SA_BIT;
131 }
132
133 return mGnss->updateConfiguration(config);
134 }
135
setGlonassPositioningProtocol(uint8_t protocol)136 Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
137 if (mGnss == nullptr) {
138 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
139 return false;
140 }
141
142 GnssConfig config;
143 memset(&config, 0, sizeof(GnssConfig));
144 config.size = sizeof(GnssConfig);
145
146 config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
147 if (protocol & (1<<0)) {
148 config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT;
149 }
150 if (protocol & (1<<1)) {
151 config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT;
152 }
153 if (protocol & (1<<2)) {
154 config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT;
155 }
156 if (protocol & (1<<3)) {
157 config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT;
158 }
159
160 return mGnss->updateConfiguration(config);
161 }
162
setGpsLock(uint8_t lock)163 Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
164
165 if (mGnss == nullptr) {
166 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
167 return false;
168 }
169
170 GnssConfig config = {};
171 config.size = sizeof(GnssConfig);
172 config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
173 switch (lock) {
174 case 0:
175 config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
176 break;
177 case 1:
178 config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO;
179 break;
180 case 2:
181 config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI;
182 break;
183 case 3:
184 config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
185 break;
186 default:
187 LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
188 return false;
189 }
190
191 mGnss->updateConfiguration(config);
192 // Must return false to pass VTS
193 return false;
194 }
195
setEmergencySuplPdn(bool enabled)196 Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
197 if (mGnss == nullptr) {
198 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
199 return false;
200 }
201
202 GnssConfig config;
203 memset(&config, 0, sizeof(GnssConfig));
204 config.size = sizeof(GnssConfig);
205 config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
206 config.emergencyPdnForEmergencySupl = (enabled ?
207 GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES :
208 GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO);
209
210 return mGnss->updateConfiguration(config);
211 }
212
213 // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
setBlacklist(const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource> & blacklist)214 Return<bool> GnssConfiguration::setBlacklist(
215 const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>& blacklist) {
216
217 ENTRY_LOG_CALLFLOW();
218 if (nullptr == mGnss) {
219 LOC_LOGe("mGnss is null");
220 return false;
221 }
222
223 // blValid is true if blacklist is empty, i.e. clearing the BL;
224 // if blacklist is not empty, blValid is initialied to false, and later
225 // updated in the for loop to become true only if there is at least
226 // one {constellation, svid} in the list that is valid.
227 bool blValid = (0 == blacklist.size());
228 GnssConfig config;
229 memset(&config, 0, sizeof(GnssConfig));
230 config.size = sizeof(GnssConfig);
231 config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
232 config.blacklistedSvIds.clear();
233
234 GnssSvIdSource source = {};
235 for (int idx = 0; idx < (int)blacklist.size(); idx++) {
236 // Set blValid true if any one source is valid
237 blValid = setBlacklistedSource(source, (GnssConstellationType)blacklist[idx].constellation,
238 blacklist[idx].svid) || blValid;
239 config.blacklistedSvIds.push_back(source);
240 }
241
242 // Update configuration only if blValid is true
243 // i.e. only if atleast one source is valid for blacklisting
244 return (blValid && mGnss->updateConfiguration(config));
245 }
246
setBlacklistedSource(GnssSvIdSource & copyToSource,const GnssConstellationType & constellation,const int16_t svid)247 bool GnssConfiguration::setBlacklistedSource(
248 GnssSvIdSource& copyToSource, const GnssConstellationType& constellation,
249 const int16_t svid) {
250
251 bool retVal = true;
252 uint16_t svIdOffset = 0;
253 copyToSource.size = sizeof(GnssSvIdSource);
254 copyToSource.svId = svid;
255
256 switch(constellation) {
257 case GnssConstellationType::GPS:
258 copyToSource.constellation = GNSS_SV_TYPE_GPS;
259 LOC_LOGe("GPS SVs can't be blacklisted.");
260 retVal = false;
261 break;
262 case GnssConstellationType::SBAS:
263 copyToSource.constellation = GNSS_SV_TYPE_SBAS;
264 LOC_LOGe("SBAS SVs can't be blacklisted.");
265 retVal = false;
266 break;
267 case GnssConstellationType::GLONASS:
268 copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
269 svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
270 break;
271 case GnssConstellationType::QZSS:
272 copyToSource.constellation = GNSS_SV_TYPE_QZSS;
273 svIdOffset = 0;
274 break;
275 case GnssConstellationType::BEIDOU:
276 copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
277 svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
278 break;
279 case GnssConstellationType::GALILEO:
280 copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
281 svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
282 break;
283 case GnssConstellationType::IRNSS:
284 copyToSource.constellation = GNSS_SV_TYPE_NAVIC;
285 svIdOffset = 0;
286 break;
287 default:
288 copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
289 LOC_LOGe("Invalid constellation %hhu", constellation);
290 retVal = false;
291 break;
292 }
293
294 if (copyToSource.svId > 0 && svIdOffset > 0) {
295 copyToSource.svId += svIdOffset;
296 }
297
298 return retVal;
299 }
300
setBlacklistedSource(GnssSvIdSource & copyToSource,const GnssConfiguration::BlacklistedSource & copyFromSource)301 bool GnssConfiguration::setBlacklistedSource(
302 GnssSvIdSource& copyToSource,
303 const GnssConfiguration::BlacklistedSource& copyFromSource) {
304
305 bool retVal = true;
306 uint16_t svIdOffset = 0;
307 copyToSource.size = sizeof(GnssSvIdSource);
308 copyToSource.svId = copyFromSource.svid;
309
310 switch(copyFromSource.constellation) {
311 case GnssConstellationType::GPS:
312 copyToSource.constellation = GNSS_SV_TYPE_GPS;
313 LOC_LOGe("GPS SVs can't be blacklisted.");
314 retVal = false;
315 break;
316 case GnssConstellationType::SBAS:
317 copyToSource.constellation = GNSS_SV_TYPE_SBAS;
318 LOC_LOGe("SBAS SVs can't be blacklisted.");
319 retVal = false;
320 break;
321 case GnssConstellationType::GLONASS:
322 copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
323 svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
324 break;
325 case GnssConstellationType::QZSS:
326 copyToSource.constellation = GNSS_SV_TYPE_QZSS;
327 svIdOffset = GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID - 1;
328 break;
329 case GnssConstellationType::BEIDOU:
330 copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
331 svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
332 break;
333 case GnssConstellationType::GALILEO:
334 copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
335 svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
336 break;
337 case GnssConstellationType::IRNSS:
338 copyToSource.constellation = GNSS_SV_TYPE_NAVIC;
339 svIdOffset = GNSS_SV_CONFIG_NAVIC_INITIAL_SV_ID - 1;
340 break;
341 default:
342 copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
343 LOC_LOGe("Invalid constellation %hhu", copyFromSource.constellation);
344 retVal = false;
345 break;
346 }
347
348 if (copyToSource.svId > 0 && svIdOffset > 0) {
349 copyToSource.svId += svIdOffset;
350 }
351
352 return retVal;
353 }
354
355 // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
setEsExtensionSec(uint32_t emergencyExtensionSeconds)356 Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
357 ENTRY_LOG_CALLFLOW();
358 if (mGnss == nullptr) {
359 LOC_LOGe("mGnss is nullptr");
360 return false;
361 }
362
363 GnssConfig config;
364 memset(&config, 0, sizeof(GnssConfig));
365 config.size = sizeof(GnssConfig);
366 config.flags = GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT;
367 config.emergencyExtensionSeconds = emergencyExtensionSeconds;
368
369 return mGnss->updateConfiguration(config);
370 }
371
372 // Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
setBlacklist_2_1(const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource> & blacklist)373 Return<bool> GnssConfiguration::setBlacklist_2_1(
374 const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& blacklist) {
375 ENTRY_LOG_CALLFLOW();
376 if (nullptr == mGnss) {
377 LOC_LOGe("mGnss is null");
378 return false;
379 }
380
381 // blValid is true if blacklist is empty, i.e. clearing the BL;
382 // if blacklist is not empty, blValid is initialied to false, and later
383 // updated in the for loop to become true only if there is at least
384 // one {constellation, svid} in the list that is valid.
385 bool blValid = (0 == blacklist.size());
386 GnssConfig config;
387 memset(&config, 0, sizeof(GnssConfig));
388 config.size = sizeof(GnssConfig);
389 config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
390 config.blacklistedSvIds.clear();
391
392 GnssSvIdSource source = {};
393 for (int idx = 0; idx < (int)blacklist.size(); idx++) {
394 // Set blValid true if any one source is valid
395 blValid = setBlacklistedSource(source, blacklist[idx]) || blValid;
396 config.blacklistedSvIds.push_back(source);
397 }
398
399 // Update configuration only if blValid is true
400 // i.e. only if atleast one source is valid for blacklisting
401 return (blValid && mGnss->updateConfiguration(config));
402 }
403
404 } // namespace implementation
405 } // namespace V2_1
406 } // namespace gnss
407 } // namespace hardware
408 } // namespace android
409