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