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