• 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 #include "gnss_interface_impl.h"
17 
18 #include <hdf_base.h>
19 #include <hdf_log.h>
20 #include <iproxy_broker.h>
21 #include <mutex>
22 #include <unordered_map>
23 
24 #include "idevmgr_hdi.h"
25 
26 #include "location_vendor_interface.h"
27 #include "location_vendor_lib.h"
28 
29 namespace OHOS {
30 namespace HDI {
31 namespace Location {
32 namespace Gnss {
33 namespace V1_0 {
34 namespace {
35 using LocationCallBackMap = std::unordered_map<IRemoteObject*, sptr<IGnssCallback>>;
36 using GnssDeathRecipientMap = std::unordered_map<IRemoteObject*, sptr<IRemoteObject::DeathRecipient>>;
37 using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
38 constexpr const char* GNSS_SERVICE_NAME = "gnss_interface_service";
39 LocationCallBackMap g_locationCallBackMap;
40 GnssDeathRecipientMap g_gnssCallBackDeathRecipientMap;
41 std::mutex g_mutex;
42 } // namespace
43 
GnssInterfaceImplGetInstance(void)44 extern "C" IGnssInterface* GnssInterfaceImplGetInstance(void)
45 {
46     return new (std::nothrow) GnssInterfaceImpl();
47 }
48 
LocationUpdate(GnssLocation * location)49 static void LocationUpdate(GnssLocation* location)
50 {
51     if (location == nullptr) {
52         HDF_LOGE("%{public}s:location is nullptr.", __func__);
53         return;
54     }
55     HDF_LOGI("%{public}s:LocationUpdate.", __func__);
56     LocationInfo locationNew;
57     locationNew.latitude = location->latitude;
58     locationNew.longitude = location->longitude;
59     locationNew.altitude = location->altitude;
60     locationNew.accuracy = location->horizontalAccuracy;
61     locationNew.speed = location->speed;
62     locationNew.direction = location->bearing;
63     locationNew.timeStamp = location->timestamp;
64     locationNew.timeSinceBoot = location->timestampSinceBoot;
65     for (const auto& iter : g_locationCallBackMap) {
66         auto& callback = iter.second;
67         if (callback != nullptr) {
68             callback->ReportLocation(locationNew);
69         }
70     }
71 }
72 
StatusCallback(uint16_t * status)73 static void StatusCallback(uint16_t* status)
74 {
75     if (status == nullptr) {
76         HDF_LOGE("%{public}s:param is nullptr.", __func__);
77         return;
78     }
79     GnssWorkingStatus gnssStatus = static_cast<GnssWorkingStatus>(*status);
80     for (const auto& iter : g_locationCallBackMap) {
81         auto& callback = iter.second;
82         if (callback != nullptr) {
83             callback->ReportGnssWorkingStatus(gnssStatus);
84         }
85     }
86 }
87 
SvStatusCallback(GnssSatelliteStatus * svInfo)88 static void SvStatusCallback(GnssSatelliteStatus* svInfo)
89 {
90     if (svInfo == nullptr) {
91         HDF_LOGE("%{public}s:sv_info is null.", __func__);
92         return;
93     }
94     if (svInfo->satellitesNum == 0) {
95         HDF_LOGE("%{public}s:satellites_num == 0.", __func__);
96         return;
97     }
98     SatelliteStatusInfo svStatus;
99     svStatus.satellitesNumber = svInfo->satellitesNum;
100     for (unsigned int i = 0; i < svInfo->satellitesNum; i++) {
101         svStatus.satelliteIds.push_back(svInfo->satellitesList[i].satelliteId);
102         svStatus.constellation.push_back(
103             static_cast<GnssConstellationType>(svInfo->satellitesList[i].constellationType));
104         svStatus.elevation.push_back(svInfo->satellitesList[i].elevation);
105         svStatus.azimuths.push_back(svInfo->satellitesList[i].azimuth);
106         svStatus.carrierFrequencies.push_back(svInfo->satellitesList[i].carrierFrequencie);
107         svStatus.carrierToNoiseDensitys.push_back(svInfo->satellitesList[i].cn0);
108     }
109     for (const auto& iter : g_locationCallBackMap) {
110         auto& callback = iter.second;
111         if (callback != nullptr) {
112             callback->ReportSatelliteStatusInfo(svStatus);
113         }
114     }
115 }
116 
NmeaCallback(int64_t timestamp,const char * nmea,int length)117 static void NmeaCallback(int64_t timestamp, const char* nmea, int length)
118 {
119     if (nmea == nullptr) {
120         HDF_LOGE("%{public}s:nmea is nullptr.", __func__);
121         return;
122     }
123     for (const auto& iter : g_locationCallBackMap) {
124         auto& callback = iter.second;
125         if (callback != nullptr) {
126             callback->ReportNmea(timestamp, nmea, length);
127         }
128     }
129 }
130 
GetGnssBasicCallbackMethods(GnssBasicCallbackIfaces * device)131 static void GetGnssBasicCallbackMethods(GnssBasicCallbackIfaces* device)
132 {
133     if (device == nullptr) {
134         return;
135     }
136     device->size = sizeof(GnssCallbackStruct);
137     device->locationUpdate = LocationUpdate;
138     device->statusUpdate = StatusCallback;
139     device->svStatusUpdate = SvStatusCallback;
140     device->nmeaUpdate = NmeaCallback;
141     device->capabilitiesUpdate = nullptr;
142     device->refInfoRequest = nullptr;
143     device->downloadRequestCb = nullptr;
144 }
145 
GetGnssCacheCallbackMethods(GnssCacheCallbackIfaces * device)146 static void GetGnssCacheCallbackMethods(GnssCacheCallbackIfaces* device)
147 {
148     if (device == nullptr) {
149         return;
150     }
151     device->size = 0;
152     device->cachedLocationCb = nullptr;
153 }
154 
GetGnssCallbackMethods(GnssCallbackStruct * device)155 static void GetGnssCallbackMethods(GnssCallbackStruct* device)
156 {
157     if (device == nullptr) {
158         return;
159     }
160     device->size = sizeof(GnssCallbackStruct);
161     static GnssBasicCallbackIfaces basicCallback;
162     GetGnssBasicCallbackMethods(&basicCallback);
163     device->gnssCb = basicCallback;
164     static GnssCacheCallbackIfaces cacheCallback;
165     GetGnssCacheCallbackMethods(&cacheCallback);
166     device->gnssCacheCb = cacheCallback;
167 }
168 
GnssInterfaceImpl()169 GnssInterfaceImpl::GnssInterfaceImpl()
170 {
171 }
172 
~GnssInterfaceImpl()173 GnssInterfaceImpl::~GnssInterfaceImpl()
174 {
175     ResetGnssDeathRecipient();
176 }
177 
SetGnssConfigPara(const GnssConfigPara & para)178 int32_t GnssInterfaceImpl::SetGnssConfigPara(const GnssConfigPara& para)
179 {
180     HDF_LOGI("%{public}s.", __func__);
181     return HDF_SUCCESS;
182 }
183 
EnableGnss(const sptr<IGnssCallback> & callbackObj)184 int32_t GnssInterfaceImpl::EnableGnss(const sptr<IGnssCallback>& callbackObj)
185 {
186     HDF_LOGI("%{public}s.", __func__);
187     if (callbackObj == nullptr) {
188         HDF_LOGE("%{public}s:invalid callbackObj", __func__);
189         return HDF_ERR_INVALID_PARAM;
190     }
191     std::lock_guard<std::mutex> lock(g_mutex);
192     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IGnssCallback>(callbackObj);
193     if (remote == nullptr) {
194         HDF_LOGE("%{public}s:invalid remote", __func__);
195         return HDF_ERR_INVALID_PARAM;
196     }
197     auto callBackIter = g_locationCallBackMap.find(remote.GetRefPtr());
198     if (callBackIter != g_locationCallBackMap.end()) {
199         const sptr<IRemoteObject>& lhs = OHOS::HDI::hdi_objcast<IGnssCallback>(callbackObj);
200         const sptr<IRemoteObject>& rhs = OHOS::HDI::hdi_objcast<IGnssCallback>(callBackIter->second);
201         return lhs == rhs ? HDF_SUCCESS : HDF_FAILURE;
202     }
203     static GnssCallbackStruct gnssCallback;
204     GetGnssCallbackMethods(&gnssCallback);
205     auto gnssInterface = LocationVendorInterface::GetInstance()->GetGnssVendorInterface();
206     if (gnssInterface == nullptr) {
207         HDF_LOGE("%{public}s:GetGnssVendorInterface return nullptr.", __func__);
208         return HDF_ERR_INVALID_PARAM;
209     }
210     AddGnssDeathRecipient(callbackObj);
211     int ret = gnssInterface->enable_gnss(&gnssCallback);
212     g_locationCallBackMap[remote.GetRefPtr()] = callbackObj;
213     return ret;
214 }
215 
DisableGnss()216 int32_t GnssInterfaceImpl::DisableGnss()
217 {
218     HDF_LOGI("%{public}s.", __func__);
219     std::lock_guard<std::mutex> lock(g_mutex);
220     auto gnssInterface = LocationVendorInterface::GetInstance()->GetGnssVendorInterface();
221     if (gnssInterface == nullptr) {
222         HDF_LOGE("%{public}s:GetGnssVendorInterface return nullptr.", __func__);
223         return HDF_ERR_INVALID_PARAM;
224     }
225     int ret = gnssInterface->disable_gnss();
226     g_locationCallBackMap.clear();
227     return ret;
228 }
229 
StartGnss(GnssStartType type)230 int32_t GnssInterfaceImpl::StartGnss(GnssStartType type)
231 {
232     HDF_LOGI("%{public}s.", __func__);
233     int startType = int(type);
234     auto gnssInterface = LocationVendorInterface::GetInstance()->GetGnssVendorInterface();
235     if (gnssInterface == nullptr) {
236         HDF_LOGE("%{public}s:GetGnssVendorInterface return nullptr.", __func__);
237         return HDF_ERR_INVALID_PARAM;
238     }
239     int ret = gnssInterface->start_gnss(startType);
240     return ret;
241 }
242 
StopGnss(GnssStartType type)243 int32_t GnssInterfaceImpl::StopGnss(GnssStartType type)
244 {
245     HDF_LOGI("%{public}s.", __func__);
246     int startType = static_cast<int>(type);
247     auto gnssInterface = LocationVendorInterface::GetInstance()->GetGnssVendorInterface();
248     if (gnssInterface == nullptr) {
249         HDF_LOGE("%{public}s:GetGnssVendorInterface return nullptr.", __func__);
250         return HDF_ERR_INVALID_PARAM;
251     }
252     int ret = gnssInterface->stop_gnss(startType);
253     return ret;
254 }
255 
SetGnssReferenceInfo(const GnssRefInfo & refInfo)256 int32_t GnssInterfaceImpl::SetGnssReferenceInfo(const GnssRefInfo& refInfo)
257 {
258     HDF_LOGI("%{public}s.", __func__);
259     return HDF_SUCCESS;
260 }
261 
DeleteAuxiliaryData(GnssAuxiliaryData data)262 int32_t GnssInterfaceImpl::DeleteAuxiliaryData(GnssAuxiliaryData data)
263 {
264     HDF_LOGI("%{public}s.", __func__);
265     return HDF_SUCCESS;
266 }
267 
SetPredictGnssData(const std::string & data)268 int32_t GnssInterfaceImpl::SetPredictGnssData(const std::string& data)
269 {
270     HDF_LOGI("%{public}s.", __func__);
271     return HDF_SUCCESS;
272 }
273 
GetCachedGnssLocationsSize(int32_t & size)274 int32_t GnssInterfaceImpl::GetCachedGnssLocationsSize(int32_t& size)
275 {
276     HDF_LOGI("%{public}s.", __func__);
277     return HDF_SUCCESS;
278 }
279 
GetCachedGnssLocations()280 int32_t GnssInterfaceImpl::GetCachedGnssLocations()
281 {
282     HDF_LOGI("%{public}s.", __func__);
283     return HDF_SUCCESS;
284 }
285 
AddGnssDeathRecipient(const sptr<IGnssCallback> & callbackObj)286 int32_t GnssInterfaceImpl::AddGnssDeathRecipient(const sptr<IGnssCallback>& callbackObj)
287 {
288     sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) GnssCallBackDeathRecipient(this));
289     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IGnssCallback>(callbackObj);
290     bool result = remote->AddDeathRecipient(death);
291     if (!result) {
292         HDF_LOGE("%{public}s: GnssInterfaceImpl add deathRecipient fail", __func__);
293         return HDF_FAILURE;
294     }
295     g_gnssCallBackDeathRecipientMap[remote.GetRefPtr()] = death;
296     return HDF_SUCCESS;
297 }
298 
RemoveGnssDeathRecipient(const sptr<IGnssCallback> & callbackObj)299 int32_t GnssInterfaceImpl::RemoveGnssDeathRecipient(const sptr<IGnssCallback>& callbackObj)
300 {
301     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IGnssCallback>(callbackObj);
302     auto iter = g_gnssCallBackDeathRecipientMap.find(remote.GetRefPtr());
303     if (iter == g_gnssCallBackDeathRecipientMap.end()) {
304         HDF_LOGE("%{public}s: GnssInterfaceImpl can not find deathRecipient", __func__);
305         return HDF_FAILURE;
306     }
307     auto recipient = iter->second;
308     bool result = remote->RemoveDeathRecipient(recipient);
309     g_gnssCallBackDeathRecipientMap.erase(iter);
310     if (!result) {
311         HDF_LOGE("%{public}s: GnssInterfaceImpl remove deathRecipient fail", __func__);
312         return HDF_FAILURE;
313     }
314     return HDF_SUCCESS;
315 }
316 
ResetGnssDeathRecipient()317 void GnssInterfaceImpl::ResetGnssDeathRecipient()
318 {
319     std::lock_guard<std::mutex> lock(g_mutex);
320     for (const auto& iter : g_locationCallBackMap) {
321         const auto& callback = iter.second;
322         if (callback != nullptr) {
323             RemoveGnssDeathRecipient(callback);
324         }
325     }
326 }
327 
UnloadGnssDevice()328 void GnssInterfaceImpl::UnloadGnssDevice()
329 {
330     auto devmgr = IDeviceManager::Get();
331     if (devmgr == nullptr) {
332         HDF_LOGE("fail to get devmgr.");
333         return;
334     }
335     if (devmgr->UnloadDevice(GNSS_SERVICE_NAME) != 0) {
336         HDF_LOGE("unload gnss service failed!");
337     }
338     return;
339 }
340 
ResetGnss()341 void GnssInterfaceImpl::ResetGnss()
342 {
343     HDF_LOGI("%{public}s called.", __func__);
344     ResetGnssDeathRecipient();
345     DisableGnss();
346     UnloadGnssDevice();
347 }
348 } // V1_0
349 } // Gnss
350 } // Location
351 } // HDI
352 } // OHOS
353