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