• 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 "agnss_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 Agnss {
33 namespace V1_0 {
34 namespace {
35 using AgnssCallBackMap = std::unordered_map<IRemoteObject*, sptr<IAGnssCallback>>;
36 using AgnssDeathRecipientMap = std::unordered_map<IRemoteObject*, sptr<IRemoteObject::DeathRecipient>>;
37 using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
38 constexpr const char* AGNSS_SERVICE_NAME = "agnss_interface_service";
39 AgnssCallBackMap g_agnssCallBackMap;
40 AgnssDeathRecipientMap g_agnssCallBackDeathRecipientMap;
41 std::mutex g_mutex;
42 } // namespace
43 
AGnssInterfaceImplGetInstance(void)44 extern "C" IAGnssInterface* AGnssInterfaceImplGetInstance(void)
45 {
46     return new (std::nothrow) AGnssInterfaceImpl();
47 }
48 
OnStatusChangedCb(const AGnssStatusInfo * status)49 static void OnStatusChangedCb(const AGnssStatusInfo* status)
50 {
51     if (status == nullptr) {
52         HDF_LOGE("%{public}s:status is nullptr.", __func__);
53         return;
54     }
55     HDF_LOGI("%{public}s.", __func__);
56     AGnssDataLinkRequest agnssStatus;
57     agnssStatus.agnssType = static_cast<AGnssUserPlaneProtocol>(status->agnssType);
58     agnssStatus.setUpType = static_cast<DataLinkSetUpType>(status->connStatus);
59 
60     for (const auto& iter : g_agnssCallBackMap) {
61         auto& callback = iter.second;
62         if (callback != nullptr) {
63             callback->RequestSetUpAgnssDataLink(agnssStatus);
64         }
65     }
66 }
67 
GetSetidCb(uint16_t type)68 static void GetSetidCb(uint16_t type)
69 {
70     HDF_LOGI("%{public}s.", __func__);
71     for (const auto& iter : g_agnssCallBackMap) {
72         auto& callback = iter.second;
73         if (callback != nullptr) {
74             callback->RequestSubscriberSetId(static_cast<SubscriberSetIdType>(type));
75         }
76     }
77 }
GetRefLocationidCb(uint32_t type)78 static void GetRefLocationidCb(uint32_t type)
79 {
80     HDF_LOGI("%{public}s.", __func__);
81     for (const auto& iter : g_agnssCallBackMap) {
82         auto& callback = iter.second;
83         if (callback != nullptr) {
84             callback->RequestAgnssRefInfo();
85         }
86     }
87 }
88 
GetAGnssCallbackMethods(AGnssCallbackIfaces * device)89 static void GetAGnssCallbackMethods(AGnssCallbackIfaces* device)
90 {
91     if (device == nullptr) {
92         return;
93     }
94     device->size = sizeof(AGnssCallbackIfaces);
95     device->agnssStatusChange = OnStatusChangedCb;
96     device->getSetid = GetSetidCb;
97     device->getRefLoc = GetRefLocationidCb;
98 }
99 
AGnssInterfaceImpl()100 AGnssInterfaceImpl::AGnssInterfaceImpl()
101 {
102 }
103 
~AGnssInterfaceImpl()104 AGnssInterfaceImpl::~AGnssInterfaceImpl()
105 {
106     ResetAgnssDeathRecipient();
107     g_agnssCallBackMap.clear();
108 }
109 
SetAgnssCallback(const sptr<IAGnssCallback> & callbackObj)110 int32_t AGnssInterfaceImpl::SetAgnssCallback(const sptr<IAGnssCallback>& callbackObj)
111 {
112     HDF_LOGI("%{public}s.", __func__);
113     if (callbackObj == nullptr) {
114         HDF_LOGE("%{public}s:invalid callbackObj", __func__);
115         return HDF_ERR_INVALID_PARAM;
116     }
117     std::lock_guard<std::mutex> lock(g_mutex);
118     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
119     if (remote == nullptr) {
120         HDF_LOGE("%{public}s:invalid remote", __func__);
121         return HDF_ERR_INVALID_PARAM;
122     }
123     auto callBackIter = g_agnssCallBackMap.find(remote.GetRefPtr());
124     if (callBackIter != g_agnssCallBackMap.end()) {
125         const sptr<IRemoteObject>& lhs = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
126         const sptr<IRemoteObject>& rhs = OHOS::HDI::hdi_objcast<IAGnssCallback>(callBackIter->second);
127         return lhs == rhs ? HDF_SUCCESS : HDF_FAILURE;
128     }
129 
130     static AGnssCallbackIfaces agnsscallback;
131     GetAGnssCallbackMethods(&agnsscallback);
132 
133     int moduleType = static_cast<int>(GnssModuleIfaceClass::AGPS_INTERFACE);
134     LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
135     auto agnssInterface =
136         static_cast<const AGnssModuleInterface*>(interface->GetModuleInterface(moduleType));
137     if (agnssInterface == nullptr) {
138         HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
139         return HDF_ERR_INVALID_PARAM;
140     }
141     bool ret = agnssInterface->set_agnss_callback(&agnsscallback);
142     if (!ret) {
143         HDF_LOGE("set_agnss_callback failed.");
144         return HDF_FAILURE;
145     }
146     AddAgnssDeathRecipient(callbackObj);
147     g_agnssCallBackMap[remote.GetRefPtr()] = callbackObj;
148     return HDF_SUCCESS;
149 }
150 
SetAgnssServer(const AGnssServerInfo & server)151 int32_t AGnssInterfaceImpl::SetAgnssServer(const AGnssServerInfo& server)
152 {
153     HDF_LOGI("%{public}s.", __func__);
154     int moduleType = static_cast<int>(GnssModuleIfaceClass::AGPS_INTERFACE);
155     LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
156     auto agnssInterface =
157         static_cast<const AGnssModuleInterface*>(interface->GetModuleInterface(moduleType));
158     if (agnssInterface == nullptr) {
159         HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
160         return HDF_ERR_INVALID_PARAM;
161     }
162     uint16_t type = static_cast<uint16_t>(server.type);
163     bool ret = agnssInterface->set_agnss_server(type, server.server.c_str(), server.server.length(), server.port);
164     if (!ret) {
165         HDF_LOGE("set_agnss_server failed.");
166         return HDF_FAILURE;
167     }
168     return HDF_SUCCESS;
169 }
170 
SetAgnssRefInfo(const AGnssRefInfo & refInfo)171 int32_t AGnssInterfaceImpl::SetAgnssRefInfo(const AGnssRefInfo& refInfo)
172 {
173     int moduleType = static_cast<int>(GnssModuleIfaceClass::AGPS_INTERFACE);
174     LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
175     auto agnssInterface =
176         static_cast<const AGnssModuleInterface*>(interface->GetModuleInterface(moduleType));
177     if (agnssInterface == nullptr) {
178         HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
179         return HDF_ERR_INVALID_PARAM;
180     }
181     AGnssRefLocInfo loc;
182     loc.type = refInfo.type;
183     switch (refInfo.cellId.type) {
184         case CELLID_TYPE_GSM:
185             loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::GSM_CELLID);
186             break;
187         case CELLID_TYPE_UMTS:
188             loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::UMTS_CELLID);
189             break;
190         case CELLID_TYPE_LTE:
191             loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::LTE_CELLID);
192             break;
193         case CELLID_TYPE_NR:
194             loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::NR_CELLID);
195             break;
196         default:
197             HDF_LOGE("%{public}s wrong cellType.", __func__);
198             return HDF_ERR_INVALID_PARAM;
199     }
200     loc.u.cellId.mcc = refInfo.cellId.mcc;
201     loc.u.cellId.mnc = refInfo.cellId.mnc;
202     loc.u.cellId.lac = refInfo.cellId.lac;
203     loc.u.cellId.cid = refInfo.cellId.cid;
204     loc.u.cellId.tac = refInfo.cellId.tac;
205     loc.u.cellId.pcid = refInfo.cellId.pcid;
206     bool ret = agnssInterface->set_ref_location(&loc);
207     if (!ret) {
208         HDF_LOGE("set_ref_location failed.");
209         return HDF_FAILURE;
210     }
211     return HDF_SUCCESS;
212 }
213 
SetSubscriberSetId(const SubscriberSetId & id)214 int32_t AGnssInterfaceImpl::SetSubscriberSetId(const SubscriberSetId& id)
215 {
216     HDF_LOGI("%{public}s.", __func__);
217     int moduleType = static_cast<int>(GnssModuleIfaceClass::AGPS_INTERFACE);
218     LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
219     auto agnssInterface =
220         static_cast<const AGnssModuleInterface*>(interface->GetModuleInterface(moduleType));
221     if (agnssInterface == nullptr) {
222         HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
223         return HDF_ERR_INVALID_PARAM;
224     }
225     uint16_t type = static_cast<uint16_t>(id.type);
226     int ret = agnssInterface->set_setid(type, id.id.c_str(), id.id.length());
227     if (!ret) {
228         HDF_LOGE("set_setid failed.");
229         return HDF_FAILURE;
230     }
231     return HDF_SUCCESS;
232 }
233 
AddAgnssDeathRecipient(const sptr<IAGnssCallback> & callbackObj)234 int32_t AGnssInterfaceImpl::AddAgnssDeathRecipient(const sptr<IAGnssCallback>& callbackObj)
235 {
236     sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) AgnssCallBackDeathRecipient(this));
237     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
238     bool result = remote->AddDeathRecipient(death);
239     if (!result) {
240         HDF_LOGE("%{public}s: AGnssInterfaceImpl add deathRecipient fail", __func__);
241         return HDF_FAILURE;
242     }
243     g_agnssCallBackDeathRecipientMap[remote.GetRefPtr()] = death;
244     return HDF_SUCCESS;
245 }
246 
RemoveAgnssDeathRecipient(const sptr<IAGnssCallback> & callbackObj)247 int32_t AGnssInterfaceImpl::RemoveAgnssDeathRecipient(const sptr<IAGnssCallback>& callbackObj)
248 {
249     const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
250     auto iter = g_agnssCallBackDeathRecipientMap.find(remote.GetRefPtr());
251     if (iter == g_agnssCallBackDeathRecipientMap.end()) {
252         HDF_LOGE("%{public}s: AgnssInterfaceImpl can not find deathRecipient", __func__);
253         return HDF_FAILURE;
254     }
255     auto recipient = iter->second;
256     bool result = remote->RemoveDeathRecipient(recipient);
257     g_agnssCallBackDeathRecipientMap.erase(iter);
258     if (!result) {
259         HDF_LOGE("%{public}s: AgnssInterfaceImpl remove deathRecipient fail", __func__);
260         return HDF_FAILURE;
261     }
262     return HDF_SUCCESS;
263 }
264 
ResetAgnssDeathRecipient()265 void AGnssInterfaceImpl::ResetAgnssDeathRecipient()
266 {
267     std::lock_guard<std::mutex> lock(g_mutex);
268     for (const auto& iter : g_agnssCallBackMap) {
269         const auto& callback = iter.second;
270         if (callback != nullptr) {
271             RemoveAgnssDeathRecipient(callback);
272         }
273     }
274 }
275 
UnloadAgnssDevice()276 void AGnssInterfaceImpl::UnloadAgnssDevice()
277 {
278     auto devmgr = IDeviceManager::Get();
279     if (devmgr == nullptr) {
280         HDF_LOGE("fail to get devmgr.");
281         return;
282     }
283     if (devmgr->UnloadDevice(AGNSS_SERVICE_NAME) != 0) {
284         HDF_LOGE("unload agnss service failed!");
285     }
286     return;
287 }
288 
ResetAgnss()289 void AGnssInterfaceImpl::ResetAgnss()
290 {
291     HDF_LOGI("%{public}s called.", __func__);
292     ResetAgnssDeathRecipient();
293     g_agnssCallBackMap.clear();
294     UnloadAgnssDevice();
295 }
296 } // V1_0
297 } // Agnss
298 } // Location
299 } // HDI
300 } // OHOS
301