1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifdef FEATURE_GNSS_SUPPORT
17 #include "gnss_event_callback.h"
18 #include <singleton.h>
19 #include <sys/time.h>
20 #include "ipc_skeleton.h"
21 #include "common_utils.h"
22 #include "gnss_ability.h"
23 #include "location_log.h"
24 #include "location_log_event_ids.h"
25 #include "common_hisysevent.h"
26 #include "agnss_ni_manager.h"
27
28 #ifdef TIME_SERVICE_ENABLE
29 #include "ntp_time_check.h"
30 #include "time_service_client.h"
31 #endif
32 namespace OHOS {
33 namespace Location {
34 using namespace OHOS::HiviewDFX;
35 const int WEAK_GPS_SIGNAL_SCENARIO_COUNT = 3;
36 const int MAX_SV_COUNT = 64;
37 const int GPS_DUMMY_SV_COUNT = 5;
38 const int AZIMUTH_DEGREES = 60;
39 const int ELEVATION_DEGREES = 90;
40 const int SATELLITES_ADDITIONAL = 4;
41 bool g_hasLocation = false;
42 bool g_svIncrease = false;
43 std::unique_ptr<SatelliteStatus> g_svInfo = nullptr;
44
SetGpsTime(int64_t gpsTime)45 static void SetGpsTime(int64_t gpsTime)
46 {
47 #ifdef TIME_SERVICE_ENABLE
48 auto ntpTimeCheck = NtpTimeCheck::GetInstance();
49 if (ntpTimeCheck != nullptr) {
50 auto elapsedRealTime = MiscServices::TimeServiceClient::GetInstance()->GetBootTimeMs();
51 ntpTimeCheck->SetGpsTime(gpsTime, elapsedRealTime);
52 }
53 #endif
54 }
55
ReportLocation(const LocationInfo & location)56 int32_t GnssEventCallback::ReportLocation(const LocationInfo& location)
57 {
58 auto gnssAbility = GnssAbility::GetInstance();
59 if (gnssAbility == nullptr) {
60 LBSLOGE(GNSS, "ReportLocation: gnss ability is nullptr.");
61 return ERR_OK;
62 }
63 std::string identity = IPCSkeleton::ResetCallingIdentity();
64 std::shared_ptr<Location> locationNew = std::make_shared<Location>();
65 locationNew->SetLatitude(location.latitude);
66 locationNew->SetLongitude(location.longitude);
67 locationNew->SetAltitude(location.altitude);
68 locationNew->SetAccuracy(location.horizontalAccuracy);
69 locationNew->SetSpeed(location.speed);
70 locationNew->SetDirection(location.bearing);
71 locationNew->SetAltitudeAccuracy(location.verticalAccuracy);
72 locationNew->SetSpeedAccuracy(location.speedAccuracy);
73 locationNew->SetDirectionAccuracy(location.bearingAccuracy);
74 locationNew->SetTimeStamp(location.timeForFix);
75 locationNew->SetTimeSinceBoot(location.timeSinceBoot);
76 locationNew->SetUncertaintyOfTimeSinceBoot(location.timeUncertainty);
77 locationNew->SetIsFromMock(false);
78 locationNew->SetLocationSourceType(LocationSourceType::GNSS_TYPE);
79 locationNew->SetFieldValidity(location.fieldValidity);
80 if (gnssAbility->IsMockEnabled()) {
81 LBSLOGE(GNSS, "location mock is enabled, do not report gnss location!");
82 IPCSkeleton::SetCallingIdentity(identity);
83 return ERR_OK;
84 }
85 // add dummy sv if needed
86 SendDummySvInfo();
87 struct timeval now;
88 gettimeofday(&now, NULL);
89 WriteLocationInnerEvent(RECEIVE_GNSS_LOCATION, {
90 "speed", std::to_string(location.speed),
91 "accuracy", std::to_string(location.horizontalAccuracy),
92 "locationTimestamp", std::to_string(location.timeForFix / MILLI_PER_SEC),
93 "receiveTimestamp", std::to_string(CommonUtils::GetCurrentTimeStamp()),
94 "latitude", std::to_string(location.latitude),
95 "longitude", std::to_string(location.longitude)});
96 gnssAbility->ReportLocationInfo(GNSS_ABILITY, locationNew);
97 #ifdef FEATURE_PASSIVE_SUPPORT
98 gnssAbility->ReportLocationInfo(PASSIVE_ABILITY, locationNew);
99 #endif
100 SetGpsTime(locationNew->GetTimeStamp());
101 IPCSkeleton::SetCallingIdentity(identity);
102 return ERR_OK;
103 }
104
ReportGnssWorkingStatus(GnssWorkingStatus status)105 int32_t GnssEventCallback::ReportGnssWorkingStatus(GnssWorkingStatus status)
106 {
107 auto gnssAbility = GnssAbility::GetInstance();
108 if (gnssAbility == nullptr) {
109 LBSLOGE(GNSS, "ReportGnssWorkingStatus: gnss ability is nullptr.");
110 return ERR_OK;
111 }
112 gnssAbility->ReportGnssSessionStatus(static_cast<int>(status));
113 return ERR_OK;
114 }
115
ReportNmea(int64_t timestamp,const std::string & nmea,int32_t length)116 int32_t GnssEventCallback::ReportNmea(int64_t timestamp, const std::string& nmea, int32_t length)
117 {
118 auto gnssAbility = GnssAbility::GetInstance();
119 if (gnssAbility == nullptr) {
120 LBSLOGE(GNSS, "ReportNmea: gnss ability is nullptr.");
121 return ERR_OK;
122 }
123 std::string nmeaStr = nmea;
124 gnssAbility->ReportNmea(timestamp, nmeaStr);
125 return ERR_OK;
126 }
127
ReportGnssCapabilities(unsigned int capabilities)128 int32_t GnssEventCallback::ReportGnssCapabilities(unsigned int capabilities)
129 {
130 return ERR_OK;
131 }
132
ReportSatelliteStatusInfo(const SatelliteStatusInfo & info)133 int32_t GnssEventCallback::ReportSatelliteStatusInfo(const SatelliteStatusInfo& info)
134 {
135 auto gnssAbility = GnssAbility::GetInstance();
136 if (gnssAbility == nullptr) {
137 LBSLOGE(GNSS, "ReportSatelliteStatusInfo: gnss ability is nullptr.");
138 return ERR_OK;
139 }
140 std::unique_ptr<SatelliteStatus> svStatus = std::make_unique<SatelliteStatus>();
141 if (info.satellitesNumber < 0) {
142 LBSLOGD(GNSS, "SvStatusCallback, satellites_num < 0!");
143 return ERR_INVALID_VALUE;
144 }
145 std::vector<std::string> names;
146 std::vector<std::string> satelliteStatusInfos;
147 names.push_back("SatelliteStatusInfo");
148 satelliteStatusInfos.push_back(std::to_string(info.satellitesNumber));
149
150 svStatus->SetSatellitesNumber(info.satellitesNumber);
151 for (unsigned int i = 0; i < info.satellitesNumber; i++) {
152 svStatus->SetAltitude(info.elevation[i]);
153 svStatus->SetAzimuth(info.azimuths[i]);
154 svStatus->SetCarrierFrequencie(info.carrierFrequencies[i]);
155 svStatus->SetCarrierToNoiseDensity(info.carrierToNoiseDensitys[i]);
156 svStatus->SetSatelliteId(info.satelliteIds[i]);
157 svStatus->SetConstellationType(info.constellation[i]);
158 svStatus->SetSatelliteAdditionalInfo(info.additionalInfo[i]);
159 std::string str_info = "satelliteId : " + std::to_string(info.satelliteIds[i]) +
160 ", carrierToNoiseDensity : " + std::to_string(info.carrierToNoiseDensitys[i]) +
161 ", elevation : " + std::to_string(info.elevation[i]) +
162 ", azimuth : " + std::to_string(info.azimuths[i]) +
163 ", carrierFrequencie : " + std::to_string(info.carrierFrequencies[i]);
164 names.push_back(std::to_string(i));
165 satelliteStatusInfos.push_back(str_info);
166 }
167 // save sv info
168 std::unique_lock<std::mutex> lock(svInfoMutex_, std::defer_lock);
169 lock.lock();
170 g_svInfo = nullptr;
171 g_svInfo = std::make_unique<SatelliteStatus>(*svStatus);
172 lock.unlock();
173 WriteLocationInnerEvent(RECEIVE_SATELLITESTATUSINFO, names, satelliteStatusInfos);
174 gnssAbility->ReportSv(svStatus);
175 return ERR_OK;
176 }
177
SendDummySvInfo()178 void GnssEventCallback::SendDummySvInfo()
179 {
180 std::unique_lock<std::mutex> lock(svInfoMutex_);
181 if (g_svInfo == nullptr) {
182 LBSLOGE(GNSS, "%{public}s: sv is nullptr.", __func__);
183 return;
184 }
185 // indicates location is coming
186 g_hasLocation = true;
187 int usedSvCount = 0;
188 int svListSize = g_svInfo->GetSatellitesNumber();
189 // calculate the num of used GPS satellites
190 for (int svSize = 0; svSize < svListSize; svSize++) {
191 if (IsSvTypeGps(g_svInfo, svSize) && IsSvUsed(g_svInfo, svSize)) {
192 usedSvCount++;
193 }
194 }
195 LBSLOGD(GNSS, "%{public}s: the USED GPS SV Count is %{public}d", __func__, usedSvCount);
196 // weak gps signal scenario
197 if (usedSvCount <= WEAK_GPS_SIGNAL_SCENARIO_COUNT) {
198 // indicates the need for dummy satellites
199 g_svIncrease = true;
200 LBSLOGD(GNSS, "%{public}s: start increase dummy sv", __func__);
201
202 if (MAX_SV_COUNT - svListSize >= GPS_DUMMY_SV_COUNT) {
203 AddDummySv(g_svInfo, 4, 6); // sv1: svid = 4, cN0Dbhz = 6
204 AddDummySv(g_svInfo, 7, 15); // sv2: svid = 7, cN0Dbhz = 15
205 AddDummySv(g_svInfo, 1, 2); // sv3: svid = 1, cN0Dbhz = 2
206 AddDummySv(g_svInfo, 11, 10); // sv4: svid = 11, cN0Dbhz = 10
207 AddDummySv(g_svInfo, 17, 5); // sv5: svid = 17, cN0Dbhz = 5
208 g_svInfo->
209 SetSatellitesNumber(g_svInfo->GetSatellitesNumber() + GPS_DUMMY_SV_COUNT);
210 ReportDummySv(g_svInfo);
211 } else {
212 LBSLOGD(GNSS, "%{public}s: sv number > 58, no need send dummy satellites", __func__);
213 }
214 LBSLOGD(GNSS, "%{public}s: increase sv finished", __func__);
215 } else {
216 // indicates no need for dummy satellites
217 g_svIncrease = false;
218 }
219 }
220
ReportDummySv(const std::unique_ptr<SatelliteStatus> & sv)221 void GnssEventCallback::ReportDummySv(const std::unique_ptr<SatelliteStatus> &sv)
222 {
223 auto gnssAbility = GnssAbility::GetInstance();
224 if (gnssAbility == nullptr || sv == nullptr) {
225 LBSLOGE(GNSS, "%{public}s gnss ability or sv is nullptr.", __func__);
226 return;
227 }
228 gnssAbility->ReportSv(sv);
229 }
230
IsNeedSvIncrease()231 bool GnssEventCallback::IsNeedSvIncrease()
232 {
233 if (g_hasLocation && g_svIncrease) {
234 return true;
235 }
236 return false;
237 }
238
IsSvTypeGps(const std::unique_ptr<SatelliteStatus> & sv,int index)239 bool GnssEventCallback::IsSvTypeGps(const std::unique_ptr<SatelliteStatus> &sv, int index)
240 {
241 if (sv == nullptr) {
242 return false;
243 }
244 return sv->GetConstellationTypes()[index] == HDI::Location::Gnss::V2_0::CONSTELLATION_CATEGORY_GPS;
245 }
246
IsSvUsed(const std::unique_ptr<SatelliteStatus> & sv,int index)247 bool GnssEventCallback::IsSvUsed(const std::unique_ptr<SatelliteStatus> &sv, int index)
248 {
249 if (sv == nullptr) {
250 return false;
251 }
252 return static_cast<uint32_t>(sv->GetSatelliteAdditionalInfoList()[index]) &
253 static_cast<uint8_t>(HDI::Location::Gnss::V2_0::SATELLITES_ADDITIONAL_INFO_USED_IN_FIX);
254 }
255
AddDummySv(std::unique_ptr<SatelliteStatus> & sv,int svid,int cN0Dbhz)256 void GnssEventCallback::AddDummySv(std::unique_ptr<SatelliteStatus> &sv, int svid, int cN0Dbhz)
257 {
258 if (sv == nullptr) {
259 return;
260 }
261 sv->SetSatelliteId(svid);
262 sv->SetConstellationType(HDI::Location::Gnss::V2_0::CONSTELLATION_CATEGORY_GPS);
263 sv->SetCarrierToNoiseDensity(cN0Dbhz);
264 sv->SetAltitude(ELEVATION_DEGREES); // elevationDegrees
265 sv->SetAzimuth(AZIMUTH_DEGREES); // azimuthDegrees
266 sv->SetCarrierFrequencie(0); // carrierFrequencyHz
267 sv->SetSatelliteAdditionalInfo(SATELLITES_ADDITIONAL); // satellites_additional
268 }
269
RequestGnssReferenceInfo(GnssRefInfoType type)270 int32_t GnssEventCallback::RequestGnssReferenceInfo(GnssRefInfoType type)
271 {
272 LBSLOGI(GNSS, "RequestGnssReferenceInfo: request type %{public}d", static_cast<int>(type));
273 auto gnssAbility = GnssAbility::GetInstance();
274 if (gnssAbility == nullptr) {
275 LBSLOGE(GNSS, "%{public}s gnss ability is nullptr.", __func__);
276 return ERR_OK;
277 }
278 switch (type) {
279 case GnssRefInfoType::GNSS_REF_INFO_TIME:
280 gnssAbility->InjectTime();
281 break;
282 case GnssRefInfoType::GNSS_REF_INFO_LOCATION:
283 gnssAbility->InjectLocation();
284 break;
285 default:
286 LBSLOGI(GNSS, "RequestGnssReferenceInfo: request type not support now");
287 break;
288 }
289 return ERR_OK;
290 }
291
RequestPredictGnssData()292 int32_t GnssEventCallback::RequestPredictGnssData()
293 {
294 return ERR_OK;
295 }
296
ReportCachedLocation(const std::vector<LocationInfo> & gnssLocations)297 int32_t GnssEventCallback::ReportCachedLocation(const std::vector<LocationInfo>& gnssLocations)
298 {
299 return ERR_OK;
300 }
301
ReportGnssNiNotification(const GnssNiNotificationRequest & notification)302 int32_t GnssEventCallback::ReportGnssNiNotification(const GnssNiNotificationRequest& notification)
303 {
304 auto agnssNiManager = AGnssNiManager::GetInstance();
305 if (agnssNiManager == nullptr) {
306 LBSLOGE(GNSS, "ReportGnssNiNotification: agnssNiManager is nullptr.");
307 return ERR_OK;
308 }
309 agnssNiManager->HandleNiNotification(notification);
310 return ERR_OK;
311 }
312 } // namespace Location
313 } // namespace OHOS
314 #endif
315