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