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