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