1 /*
2  * Copyright (c) 2017-2019, 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_0 {
33 namespace implementation {
34 
35 using ::android::hardware::gnss::V1_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 0x00020002:
59             config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_2;
60             break;
61         case 0x00020000:
62             config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_0;
63             break;
64         case 0x00010000:
65             config.suplVersion = GNSS_CONFIG_SUPL_VERSION_1_0_0;
66             break;
67         default:
68             LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
69             return false;
70             break;
71     }
72 
73     return mGnss->updateConfiguration(config);
74 }
75 
setSuplMode(uint8_t mode)76 Return<bool> GnssConfiguration::setSuplMode(uint8_t mode)  {
77     if (mGnss == nullptr) {
78         LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
79         return false;
80     }
81 
82     GnssConfig config;
83     memset(&config, 0, sizeof(GnssConfig));
84     config.size = sizeof(GnssConfig);
85     config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
86     switch (mode) {
87         case 0:
88             config.suplModeMask = 0; // STANDALONE ONLY
89             break;
90         case 1:
91             config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT;
92             break;
93         case 2:
94             config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT;
95             break;
96         case 3:
97             config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT;
98             break;
99         default:
100             LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
101             return false;
102             break;
103     }
104 
105     return mGnss->updateConfiguration(config);
106 }
107 
setLppProfile(uint8_t lppProfile)108 Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
109     if (mGnss == nullptr) {
110         LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
111         return false;
112     }
113 
114     GnssConfig config = {};
115     config.size = sizeof(GnssConfig);
116     config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
117     switch (lppProfile) {
118         case 0:
119             config.lppProfile = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE;
120             break;
121         case 1:
122             config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE;
123             break;
124         case 2:
125             config.lppProfile = GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE;
126             break;
127         case 3:
128             config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE;
129             break;
130         default:
131             LOC_LOGE("%s]: invalid lppProfile: %d.", __FUNCTION__, lppProfile);
132             return false;
133             break;
134     }
135 
136     return mGnss->updateConfiguration(config);
137 }
138 
setGlonassPositioningProtocol(uint8_t protocol)139 Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
140     if (mGnss == nullptr) {
141         LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
142         return false;
143     }
144 
145     GnssConfig config;
146     memset(&config, 0, sizeof(GnssConfig));
147     config.size = sizeof(GnssConfig);
148 
149     config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
150     if (protocol & (1<<0)) {
151         config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT;
152     }
153     if (protocol & (1<<1)) {
154         config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT;
155     }
156     if (protocol & (1<<2)) {
157         config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT;
158     }
159     if (protocol & (1<<3)) {
160         config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT;
161     }
162 
163     return mGnss->updateConfiguration(config);
164 }
165 
setGpsLock(uint8_t lock)166 Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
167 
168     if (mGnss == nullptr) {
169         LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
170         return false;
171     }
172 
173     GnssConfig config = {};
174     config.size = sizeof(GnssConfig);
175     config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
176     switch (lock) {
177     case 0:
178         config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
179         break;
180     case 1:
181         config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO;
182         break;
183     case 2:
184         config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI;
185         break;
186     case 3:
187         config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
188         break;
189     default:
190         LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
191         return false;
192         break;
193     }
194 
195     mGnss->updateConfiguration(config);
196     // Must return false to pass VTS
197     return false;
198 }
199 
setEmergencySuplPdn(bool enabled)200 Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
201     if (mGnss == nullptr) {
202         LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
203         return false;
204     }
205 
206     GnssConfig config;
207     memset(&config, 0, sizeof(GnssConfig));
208     config.size = sizeof(GnssConfig);
209     config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
210     config.emergencyPdnForEmergencySupl = (enabled ?
211             GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES :
212             GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO);
213 
214     return mGnss->updateConfiguration(config);
215 }
216 
217 // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
setBlacklist(const hidl_vec<GnssConfiguration::BlacklistedSource> & blacklist)218 Return<bool> GnssConfiguration::setBlacklist(
219             const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) {
220 
221     ENTRY_LOG_CALLFLOW();
222     if (nullptr == mGnss) {
223         LOC_LOGe("mGnss is null");
224         return false;
225     }
226 
227     // blValid is true if blacklist is empty, i.e. clearing the BL;
228     // if blacklist is not empty, blValid is initialied to false, and later
229     // updated in the for loop to become true only if there is at least
230     // one {constellation, svid} in the list that is valid.
231     bool blValid = (0 == blacklist.size());
232     GnssConfig config;
233     memset(&config, 0, sizeof(GnssConfig));
234     config.size = sizeof(GnssConfig);
235     config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
236     config.blacklistedSvIds.clear();
237 
238     GnssSvIdSource source = {};
239     for (int idx = 0; idx < (int)blacklist.size(); idx++) {
240         // Set blValid true if any one source is valid
241         blValid = setBlacklistedSource(source, blacklist[idx]) || blValid;
242         config.blacklistedSvIds.push_back(source);
243     }
244 
245     // Update configuration only if blValid is true
246     // i.e. only if atleast one source is valid for blacklisting
247     return (blValid && mGnss->updateConfiguration(config));
248 }
249 
setBlacklistedSource(GnssSvIdSource & copyToSource,const GnssConfiguration::BlacklistedSource & copyFromSource)250 bool GnssConfiguration::setBlacklistedSource(
251         GnssSvIdSource& copyToSource,
252         const GnssConfiguration::BlacklistedSource& copyFromSource) {
253 
254     bool retVal = true;
255     uint16_t svIdOffset = 0;
256     copyToSource.size = sizeof(GnssSvIdSource);
257     copyToSource.svId = copyFromSource.svid;
258 
259     switch(copyFromSource.constellation) {
260     case GnssConstellationType::GPS:
261         copyToSource.constellation = GNSS_SV_TYPE_GPS;
262         LOC_LOGe("GPS SVs can't be blacklisted.");
263         retVal = false;
264         break;
265     case GnssConstellationType::SBAS:
266         copyToSource.constellation = GNSS_SV_TYPE_SBAS;
267         LOC_LOGe("SBAS SVs can't be blacklisted.");
268         retVal = false;
269         break;
270     case GnssConstellationType::GLONASS:
271         copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
272         svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
273         break;
274     case GnssConstellationType::QZSS:
275         copyToSource.constellation = GNSS_SV_TYPE_QZSS;
276         svIdOffset = 0;
277         break;
278     case GnssConstellationType::BEIDOU:
279         copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
280         svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
281         break;
282     case GnssConstellationType::GALILEO:
283         copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
284         svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
285         break;
286     default:
287         copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
288         LOC_LOGe("Invalid constellation %hhu", copyFromSource.constellation);
289         retVal = false;
290         break;
291     }
292 
293     if (copyToSource.svId > 0 && svIdOffset > 0) {
294         copyToSource.svId += svIdOffset;
295     }
296 
297     return retVal;
298 }
299 
300 // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
setEsExtensionSec(uint32_t emergencyExtensionSeconds)301 Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
302     ENTRY_LOG_CALLFLOW();
303     if (mGnss == nullptr) {
304         LOC_LOGe("mGnss is nullptr");
305         return false;
306     }
307 
308     GnssConfig config;
309     memset(&config, 0, sizeof(GnssConfig));
310     config.size = sizeof(GnssConfig);
311     config.flags = GNSS_CONFIG_FLAGS_EMERGENCY_EXTENSION_SECONDS_BIT;
312     config.emergencyExtensionSeconds = emergencyExtensionSeconds;
313 
314     return mGnss->updateConfiguration(config);
315 }
316 
317 }  // namespace implementation
318 }  // namespace V2_0
319 }  // namespace gnss
320 }  // namespace hardware
321 }  // namespace android
322