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