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