• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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