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 break;
74 }
75
76 return mGnss->updateConfiguration(config);
77 }
78
setSuplMode(uint8_t mode)79 Return<bool> GnssConfiguration::setSuplMode(uint8_t mode) {
80 if (mGnss == nullptr) {
81 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
82 return false;
83 }
84
85 GnssConfig config;
86 memset(&config, 0, sizeof(GnssConfig));
87 config.size = sizeof(GnssConfig);
88 config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
89 switch (mode) {
90 case 0:
91 config.suplModeMask = 0; // STANDALONE ONLY
92 break;
93 case 1:
94 config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT;
95 break;
96 case 2:
97 config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT;
98 break;
99 case 3:
100 config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT;
101 break;
102 default:
103 LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
104 return false;
105 break;
106 }
107
108 return mGnss->updateConfiguration(config);
109 }
110
setLppProfile(uint8_t lppProfile)111 Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
112 if (mGnss == nullptr) {
113 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
114 return false;
115 }
116
117 GnssConfig config = {};
118 config.size = sizeof(GnssConfig);
119 config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
120 switch (lppProfile) {
121 case 0:
122 config.lppProfile = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE;
123 break;
124 case 1:
125 config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE;
126 break;
127 case 2:
128 config.lppProfile = GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE;
129 break;
130 case 3:
131 config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE;
132 break;
133 default:
134 LOC_LOGE("%s]: invalid lppProfile: %d.", __FUNCTION__, lppProfile);
135 return false;
136 break;
137 }
138
139 return mGnss->updateConfiguration(config);
140 }
141
setGlonassPositioningProtocol(uint8_t protocol)142 Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
143 if (mGnss == nullptr) {
144 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
145 return false;
146 }
147
148 GnssConfig config;
149 memset(&config, 0, sizeof(GnssConfig));
150 config.size = sizeof(GnssConfig);
151
152 config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
153 if (protocol & (1<<0)) {
154 config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT;
155 }
156 if (protocol & (1<<1)) {
157 config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT;
158 }
159 if (protocol & (1<<2)) {
160 config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT;
161 }
162 if (protocol & (1<<3)) {
163 config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT;
164 }
165
166 return mGnss->updateConfiguration(config);
167 }
168
setGpsLock(uint8_t lock)169 Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
170
171 if (mGnss == nullptr) {
172 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
173 return false;
174 }
175
176 GnssConfig config = {};
177 config.size = sizeof(GnssConfig);
178 config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
179 switch (lock) {
180 case 0:
181 config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
182 break;
183 case 1:
184 config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO;
185 break;
186 case 2:
187 config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI;
188 break;
189 case 3:
190 config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
191 break;
192 default:
193 LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
194 return false;
195 break;
196 }
197
198 mGnss->updateConfiguration(config);
199 // Must return false to pass VTS
200 return false;
201 }
202
setEmergencySuplPdn(bool enabled)203 Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
204 if (mGnss == nullptr) {
205 LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
206 return false;
207 }
208
209 GnssConfig config;
210 memset(&config, 0, sizeof(GnssConfig));
211 config.size = sizeof(GnssConfig);
212 config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
213 config.emergencyPdnForEmergencySupl = (enabled ?
214 GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES :
215 GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO);
216
217 return mGnss->updateConfiguration(config);
218 }
219
220 // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
setBlacklist(const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource> & blacklist)221 Return<bool> GnssConfiguration::setBlacklist(
222 const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>& blacklist) {
223
224 ENTRY_LOG_CALLFLOW();
225 if (nullptr == mGnss) {
226 LOC_LOGe("mGnss is null");
227 return false;
228 }
229
230 // blValid is true if blacklist is empty, i.e. clearing the BL;
231 // if blacklist is not empty, blValid is initialied to false, and later
232 // updated in the for loop to become true only if there is at least
233 // one {constellation, svid} in the list that is valid.
234 bool blValid = (0 == blacklist.size());
235 GnssConfig config;
236 memset(&config, 0, sizeof(GnssConfig));
237 config.size = sizeof(GnssConfig);
238 config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
239 config.blacklistedSvIds.clear();
240
241 GnssSvIdSource source = {};
242 for (int idx = 0; idx < (int)blacklist.size(); idx++) {
243 // Set blValid true if any one source is valid
244 blValid = setBlacklistedSource(source, (GnssConstellationType)blacklist[idx].constellation,
245 blacklist[idx].svid) || blValid;
246 config.blacklistedSvIds.push_back(source);
247 }
248
249 // Update configuration only if blValid is true
250 // i.e. only if atleast one source is valid for blacklisting
251 return (blValid && mGnss->updateConfiguration(config));
252 }
253
setBlacklistedSource(GnssSvIdSource & copyToSource,const GnssConstellationType & constellation,const int16_t svid)254 bool GnssConfiguration::setBlacklistedSource(
255 GnssSvIdSource& copyToSource, const GnssConstellationType& constellation,
256 const int16_t svid) {
257
258 bool retVal = true;
259 uint16_t svIdOffset = 0;
260 copyToSource.size = sizeof(GnssSvIdSource);
261 copyToSource.svId = svid;
262
263 switch(constellation) {
264 case GnssConstellationType::GPS:
265 copyToSource.constellation = GNSS_SV_TYPE_GPS;
266 LOC_LOGe("GPS SVs can't be blacklisted.");
267 retVal = false;
268 break;
269 case GnssConstellationType::SBAS:
270 copyToSource.constellation = GNSS_SV_TYPE_SBAS;
271 LOC_LOGe("SBAS SVs can't be blacklisted.");
272 retVal = false;
273 break;
274 case GnssConstellationType::GLONASS:
275 copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
276 svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
277 break;
278 case GnssConstellationType::QZSS:
279 copyToSource.constellation = GNSS_SV_TYPE_QZSS;
280 svIdOffset = 0;
281 break;
282 case GnssConstellationType::BEIDOU:
283 copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
284 svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
285 break;
286 case GnssConstellationType::GALILEO:
287 copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
288 svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
289 break;
290 case GnssConstellationType::IRNSS:
291 copyToSource.constellation = GNSS_SV_TYPE_NAVIC;
292 svIdOffset = 0;
293 break;
294 default:
295 copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
296 LOC_LOGe("Invalid constellation %hhu", constellation);
297 retVal = false;
298 break;
299 }
300
301 if (copyToSource.svId > 0 && svIdOffset > 0) {
302 copyToSource.svId += svIdOffset;
303 }
304
305 return retVal;
306 }
307
setBlacklistedSource(GnssSvIdSource & copyToSource,const GnssConfiguration::BlacklistedSource & copyFromSource)308 bool GnssConfiguration::setBlacklistedSource(
309 GnssSvIdSource& copyToSource,
310 const GnssConfiguration::BlacklistedSource& copyFromSource) {
311
312 bool retVal = true;
313 uint16_t svIdOffset = 0;
314 copyToSource.size = sizeof(GnssSvIdSource);
315 copyToSource.svId = copyFromSource.svid;
316
317 switch(copyFromSource.constellation) {
318 case GnssConstellationType::GPS:
319 copyToSource.constellation = GNSS_SV_TYPE_GPS;
320 LOC_LOGe("GPS SVs can't be blacklisted.");
321 retVal = false;
322 break;
323 case GnssConstellationType::SBAS:
324 copyToSource.constellation = GNSS_SV_TYPE_SBAS;
325 LOC_LOGe("SBAS SVs can't be blacklisted.");
326 retVal = false;
327 break;
328 case GnssConstellationType::GLONASS:
329 copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
330 svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
331 break;
332 case GnssConstellationType::QZSS:
333 copyToSource.constellation = GNSS_SV_TYPE_QZSS;
334 svIdOffset = GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID - 1;
335 break;
336 case GnssConstellationType::BEIDOU:
337 copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
338 svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
339 break;
340 case GnssConstellationType::GALILEO:
341 copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
342 svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
343 break;
344 case GnssConstellationType::IRNSS:
345 copyToSource.constellation = GNSS_SV_TYPE_NAVIC;
346 svIdOffset = 0;
347 break;
348 default:
349 copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
350 LOC_LOGe("Invalid constellation %hhu", copyFromSource.constellation);
351 retVal = false;
352 break;
353 }
354
355 if (copyToSource.svId > 0 && svIdOffset > 0) {
356 copyToSource.svId += svIdOffset;
357 }
358
359 return retVal;
360 }
361
362 // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
setEsExtensionSec(uint32_t emergencyExtensionSeconds)363 Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
364 ENTRY_LOG_CALLFLOW();
365 if (mGnss == nullptr) {
366 LOC_LOGe("mGnss is nullptr");
367 return false;
368 }
369
370 GnssConfig config;
371 memset(&config, 0, sizeof(GnssConfig));
372 config.size = sizeof(GnssConfig);
373 config.flags = GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT;
374 config.emergencyExtensionSeconds = emergencyExtensionSeconds;
375
376 return mGnss->updateConfiguration(config);
377 }
378
379 // Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
setBlacklist_2_1(const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource> & blacklist)380 Return<bool> GnssConfiguration::setBlacklist_2_1(
381 const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& blacklist) {
382 ENTRY_LOG_CALLFLOW();
383 if (nullptr == mGnss) {
384 LOC_LOGe("mGnss is null");
385 return false;
386 }
387
388 // blValid is true if blacklist is empty, i.e. clearing the BL;
389 // if blacklist is not empty, blValid is initialied to false, and later
390 // updated in the for loop to become true only if there is at least
391 // one {constellation, svid} in the list that is valid.
392 bool blValid = (0 == blacklist.size());
393 GnssConfig config;
394 memset(&config, 0, sizeof(GnssConfig));
395 config.size = sizeof(GnssConfig);
396 config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
397 config.blacklistedSvIds.clear();
398
399 GnssSvIdSource source = {};
400 for (int idx = 0; idx < (int)blacklist.size(); idx++) {
401 // Set blValid true if any one source is valid
402 blValid = setBlacklistedSource(source, blacklist[idx]) || blValid;
403 config.blacklistedSvIds.push_back(source);
404 }
405
406 // Update configuration only if blValid is true
407 // i.e. only if atleast one source is valid for blacklisting
408 return (blValid && mGnss->updateConfiguration(config));
409 }
410
411 } // namespace implementation
412 } // namespace V2_1
413 } // namespace gnss
414 } // namespace hardware
415 } // namespace android
416