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