• 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 
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