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