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
27 namespace OHOS {
28 namespace Location {
29 using namespace OHOS::HiviewDFX;
30 const int SVID_SHIFT_WIDTH = 8;
31 const int CONSTELLATION_TYPE_SHIFT_WIDTH = 4;
32 const int WEAK_GPS_SIGNAL_SCENARIO_COUNT = 3;
33 const int MAX_SV_COUNT = 64;
34 const int GPS_DUMMY_SV_COUNT = 5;
35 bool g_hasLocation = false;
36 bool g_svIncrease = false;
37 std::unique_ptr<SatelliteStatus> g_svInfo = nullptr;
38
ReportLocation(const LocationInfo & location)39 int32_t GnssEventCallback::ReportLocation(const LocationInfo& location)
40 {
41 auto gnssAbility = DelayedSingleton<GnssAbility>::GetInstance();
42 if (gnssAbility == nullptr) {
43 LBSLOGE(GNSS, "ReportLocation: gnss ability is nullptr.");
44 return ERR_OK;
45 }
46 std::string identity = IPCSkeleton::ResetCallingIdentity();
47 std::shared_ptr<Location> locationNew = std::make_shared<Location>();
48 locationNew->SetLatitude(location.latitude);
49 locationNew->SetLongitude(location.longitude);
50 locationNew->SetAltitude(location.altitude);
51 locationNew->SetAccuracy(location.accuracy);
52 locationNew->SetSpeed(location.speed);
53 locationNew->SetDirection(location.direction);
54 locationNew->SetTimeStamp(location.timeStamp);
55 locationNew->SetTimeSinceBoot(location.timeSinceBoot);
56 locationNew->SetIsFromMock(false);
57 if (gnssAbility->IsMockEnabled()) {
58 LBSLOGE(GNSS, "location mock is enabled, do not report gnss location!");
59 IPCSkeleton::SetCallingIdentity(identity);
60 return ERR_OK;
61 }
62 // add dummy sv if needed
63 SendDummySvInfo();
64 struct timeval now;
65 gettimeofday(&now, NULL);
66 auto receiveTimestamp = now.tv_sec * SEC_TO_MILLI_SEC + now.tv_usec / MICRO_PER_MILLI;
67 WriteLocationInnerEvent(RECEIVE_GNSS_LOCATION, {
68 "speed", std::to_string(location.speed),
69 "accuracy", std::to_string(location.accuracy),
70 "locationTimestamp", std::to_string(location.timeStamp),
71 "receiveTimestamp", std::to_string(receiveTimestamp),
72 "latitude", std::to_string(location.latitude),
73 "longitude", std::to_string(location.longitude)});
74 gnssAbility->ReportLocationInfo(GNSS_ABILITY, locationNew);
75 #ifdef FEATURE_PASSIVE_SUPPORT
76 gnssAbility->ReportLocationInfo(PASSIVE_ABILITY, locationNew);
77 #endif
78 IPCSkeleton::SetCallingIdentity(identity);
79 return ERR_OK;
80 }
81
ReportGnssWorkingStatus(GnssWorkingStatus status)82 int32_t GnssEventCallback::ReportGnssWorkingStatus(GnssWorkingStatus status)
83 {
84 auto gnssAbility = DelayedSingleton<GnssAbility>::GetInstance();
85 if (gnssAbility == nullptr) {
86 LBSLOGE(GNSS, "ReportGnssWorkingStatus: gnss ability is nullptr.");
87 return ERR_OK;
88 }
89 gnssAbility.get()->ReportGnssSessionStatus(static_cast<int>(status));
90 return ERR_OK;
91 }
92
ReportNmea(int64_t timestamp,const std::string & nmea,int32_t length)93 int32_t GnssEventCallback::ReportNmea(int64_t timestamp, const std::string& nmea, int32_t length)
94 {
95 auto gnssAbility = DelayedSingleton<GnssAbility>::GetInstance();
96 if (gnssAbility == nullptr) {
97 LBSLOGE(GNSS, "ReportNmea: gnss ability is nullptr.");
98 return ERR_OK;
99 }
100 std::string nmeaStr = nmea;
101 gnssAbility.get()->ReportNmea(timestamp, nmeaStr);
102 return ERR_OK;
103 }
104
ReportGnssCapabilities(GnssCapabilities capabilities)105 int32_t GnssEventCallback::ReportGnssCapabilities(GnssCapabilities capabilities)
106 {
107 return ERR_OK;
108 }
109
ReportSatelliteStatusInfo(const SatelliteStatusInfo & info)110 int32_t GnssEventCallback::ReportSatelliteStatusInfo(const SatelliteStatusInfo& info)
111 {
112 auto gnssAbility = DelayedSingleton<GnssAbility>::GetInstance();
113 if (gnssAbility == nullptr) {
114 LBSLOGE(GNSS, "ReportSatelliteStatusInfo: gnss ability is nullptr.");
115 return ERR_OK;
116 }
117 std::unique_ptr<SatelliteStatus> svStatus = std::make_unique<SatelliteStatus>();
118 if (info.satellitesNumber <= 0) {
119 LBSLOGD(GNSS, "SvStatusCallback, satellites_num <= 0!");
120 return ERR_INVALID_VALUE;
121 }
122 std::vector<std::string> names;
123 std::vector<std::string> satelliteStatusInfos;
124 names.push_back("SatelliteStatusInfo");
125 satelliteStatusInfos.push_back(std::to_string(info.satellitesNumber));
126
127 svStatus->SetSatellitesNumber(info.satellitesNumber);
128 for (unsigned int i = 0; i < info.satellitesNumber; i++) {
129 svStatus->SetAltitude(info.elevation[i]);
130 svStatus->SetAzimuth(info.azimuths[i]);
131 svStatus->SetCarrierFrequencie(info.carrierFrequencies[i]);
132 svStatus->SetCarrierToNoiseDensity(info.carrierToNoiseDensitys[i]);
133 svStatus->SetSatelliteId(info.satelliteIds[i]);
134 svStatus->SetConstellationType(info.constellation[i]);
135 std::string str_info = "satelliteId : " + std::to_string(info.satelliteIds[i]) +
136 ", carrierToNoiseDensity : " + std::to_string(info.carrierToNoiseDensitys[i]) +
137 ", elevation : " + std::to_string(info.elevation[i]) +
138 ", azimuth : " + std::to_string(info.azimuths[i]) +
139 ", carrierFrequencie : " + std::to_string(info.carrierFrequencies[i]);
140 names.push_back(std::to_string(i));
141 satelliteStatusInfos.push_back(str_info);
142 }
143 // save sv info
144 g_svInfo = nullptr;
145 g_svInfo = std::make_unique<SatelliteStatus>(*svStatus);
146 WriteLocationInnerEvent(RECEIVE_SATELLITESTATUSINFO, names, satelliteStatusInfos);
147 gnssAbility.get()->ReportSv(svStatus);
148 return ERR_OK;
149 }
150
SendDummySvInfo()151 void GnssEventCallback::SendDummySvInfo()
152 {
153 if (g_svInfo == nullptr) {
154 LBSLOGE(GNSS, "%{public}s: sv is nullptr.", __func__);
155 return;
156 }
157 // indicates location is coming
158 g_hasLocation = true;
159 int usedSvCount = 0;
160 int svListSize = g_svInfo->GetSatellitesNumber();
161 // calculate the num of used GPS satellites
162 for (int svSize = 0; svSize < svListSize; svSize++) {
163 if (IsSvTypeGps(g_svInfo, svSize) && IsSvUsed(g_svInfo, svSize)) {
164 usedSvCount++;
165 }
166 }
167 LBSLOGD(GNSS, "%{public}s: the USED GPS SV Count is %{public}d", __func__, usedSvCount);
168 // weak gps signal scenario
169 if (usedSvCount <= WEAK_GPS_SIGNAL_SCENARIO_COUNT) {
170 // indicates the need for dummy satellites
171 g_svIncrease = true;
172 LBSLOGD(GNSS, "%{public}s: start increase dummy sv", __func__);
173
174 if (MAX_SV_COUNT - svListSize >= GPS_DUMMY_SV_COUNT) {
175 AddDummySv(g_svInfo, 4, 6); // sv1: svid = 4, cN0Dbhz = 6
176 AddDummySv(g_svInfo, 7, 15); // sv2: svid = 7, cN0Dbhz = 15
177 AddDummySv(g_svInfo, 1, 2); // sv3: svid = 1, cN0Dbhz = 2
178 AddDummySv(g_svInfo, 11, 10); // sv4: svid = 11, cN0Dbhz = 10
179 AddDummySv(g_svInfo, 17, 5); // sv5: svid = 17, cN0Dbhz = 5
180 g_svInfo->
181 SetSatellitesNumber(g_svInfo->GetSatellitesNumber() + GPS_DUMMY_SV_COUNT);
182 ReportDummySv(g_svInfo);
183 } else {
184 LBSLOGD(GNSS, "%{public}s: sv number > 58, no need send dummy satellites", __func__);
185 }
186 LBSLOGD(GNSS, "%{public}s: increase sv finished", __func__);
187 } else {
188 // indicates no need for dummy satellites
189 g_svIncrease = false;
190 }
191 }
192
ReportDummySv(const std::unique_ptr<SatelliteStatus> & sv)193 void GnssEventCallback::ReportDummySv(const std::unique_ptr<SatelliteStatus> &sv)
194 {
195 auto gnssAbility = DelayedSingleton<GnssAbility>::GetInstance();
196 if (gnssAbility == nullptr || sv == nullptr) {
197 LBSLOGE(GNSS, "%{public}s gnss ability or sv is nullptr.", __func__);
198 return;
199 }
200 gnssAbility->ReportSv(sv);
201 }
202
IsNeedSvIncrease()203 bool GnssEventCallback::IsNeedSvIncrease()
204 {
205 if (g_hasLocation && g_svIncrease) {
206 return true;
207 }
208 return false;
209 }
210
IsSvTypeGps(const std::unique_ptr<SatelliteStatus> & sv,int index)211 bool GnssEventCallback::IsSvTypeGps(const std::unique_ptr<SatelliteStatus> &sv, int index)
212 {
213 if (sv == nullptr) {
214 return false;
215 }
216 return sv->GetConstellationTypes()[index] == GNSS_CONSTELLATION_GPS;
217 }
218
IsSvUsed(const std::unique_ptr<SatelliteStatus> & sv,int index)219 bool GnssEventCallback::IsSvUsed(const std::unique_ptr<SatelliteStatus> &sv, int index)
220 {
221 if (sv == nullptr) {
222 return false;
223 }
224 return (((static_cast<uint32_t>(sv->GetSatelliteIds()[index]) << SVID_SHIFT_WIDTH) |
225 (static_cast<uint32_t>(sv->GetConstellationTypes()[index]) << CONSTELLATION_TYPE_SHIFT_WIDTH)) &
226 (static_cast<uint8_t>(SATELLITES_STATUS_USED_IN_FIX))) != 0;
227 }
228
AddDummySv(std::unique_ptr<SatelliteStatus> & sv,int svid,int cN0Dbhz)229 void GnssEventCallback::AddDummySv(std::unique_ptr<SatelliteStatus> &sv, int svid, int cN0Dbhz)
230 {
231 if (sv == nullptr) {
232 return;
233 }
234 sv->SetSatelliteId(svid);
235 sv->SetConstellationType(GNSS_CONSTELLATION_GPS);
236 sv->SetCarrierToNoiseDensity(cN0Dbhz);
237 sv->SetAltitude(60); // elevationDegrees
238 sv->SetAzimuth(90); // azimuthDegrees
239 sv->SetCarrierFrequencie(0); // carrierFrequencyHz
240 }
241
RequestGnssReferenceInfo(GnssRefInfoType type)242 int32_t GnssEventCallback::RequestGnssReferenceInfo(GnssRefInfoType type)
243 {
244 return ERR_OK;
245 }
246
RequestPredictGnssData()247 int32_t GnssEventCallback::RequestPredictGnssData()
248 {
249 return ERR_OK;
250 }
251
ReportCachedLocation(const std::vector<LocationInfo> & gnssLocations)252 int32_t GnssEventCallback::ReportCachedLocation(const std::vector<LocationInfo>& gnssLocations)
253 {
254 return ERR_OK;
255 }
256 } // namespace Location
257 } // namespace OHOS
258 #endif
259