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
OnStatusChangedCb(const AGnssStatusInfo * status)51 static void OnStatusChangedCb(const AGnssStatusInfo* 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->agnssType);
60 agnssStatus.setUpType = static_cast<DataLinkSetUpType>(status->connStatus);
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->agnssStatusChange = OnStatusChangedCb;
102 device->getSetid = GetSetidCb;
103 device->getRefLoc = 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->set_agnss_callback(&agnsscallback);
148 if (!ret) {
149 HDF_LOGE("set_agnss_callback 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->set_agnss_server(type, server.server.c_str(), server.server.length(), server.port);
169 if (!ret) {
170 HDF_LOGE("set_agnss_server 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 AGnssRefLocInfo loc;
188 loc.type = g_refInfoType;
189 if (loc.type == static_cast<uint32_t>(AgnssRefLocClass::AGNSS_REF_LOC_CLASS_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.type == static_cast<uint32_t>(AgnssRefLocClass::AGNSS_REF_LOC_CLASS_CELLID)) {
195 switch (refInfo.cellId.type) {
196 case CELLID_TYPE_GSM:
197 loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::GSM_CELLID);
198 break;
199 case CELLID_TYPE_UMTS:
200 loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::UMTS_CELLID);
201 break;
202 case CELLID_TYPE_LTE:
203 loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::LTE_CELLID);
204 break;
205 case CELLID_TYPE_NR:
206 loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::NR_CELLID);
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 }
219 bool ret = agnssInterface->set_ref_location(&loc);
220 if (!ret) {
221 HDF_LOGE("set_ref_location failed.");
222 return HDF_FAILURE;
223 }
224 return HDF_SUCCESS;
225 }
226
SetSubscriberSetId(const SubscriberSetId & id)227 int32_t AGnssInterfaceImpl::SetSubscriberSetId(const SubscriberSetId& id)
228 {
229 HDF_LOGI("%{public}s.", __func__);
230 int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
231 LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
232 auto agnssInterface =
233 static_cast<const AGnssModuleInterface*>(interface->GetModuleInterface(moduleType));
234 if (agnssInterface == nullptr) {
235 HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
236 return HDF_ERR_INVALID_PARAM;
237 }
238 uint16_t type = static_cast<uint16_t>(id.type);
239 int ret = agnssInterface->set_setid(type, id.id.c_str(), id.id.length());
240 if (!ret) {
241 HDF_LOGE("set_setid failed.");
242 return HDF_FAILURE;
243 }
244 return HDF_SUCCESS;
245 }
246
AddAgnssDeathRecipient(const sptr<IAGnssCallback> & callbackObj)247 int32_t AGnssInterfaceImpl::AddAgnssDeathRecipient(const sptr<IAGnssCallback>& callbackObj)
248 {
249 sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) AgnssCallBackDeathRecipient(this));
250 const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
251 bool result = remote->AddDeathRecipient(death);
252 if (!result) {
253 HDF_LOGE("%{public}s: AGnssInterfaceImpl add deathRecipient fail", __func__);
254 return HDF_FAILURE;
255 }
256 std::unique_lock<std::mutex> lock(g_deathMutex);
257 g_agnssCallBackDeathRecipientMap[remote.GetRefPtr()] = death;
258 return HDF_SUCCESS;
259 }
260
RemoveAgnssDeathRecipient(const sptr<IAGnssCallback> & callbackObj)261 int32_t AGnssInterfaceImpl::RemoveAgnssDeathRecipient(const sptr<IAGnssCallback>& callbackObj)
262 {
263 std::unique_lock<std::mutex> lock(g_deathMutex);
264 const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
265 auto iter = g_agnssCallBackDeathRecipientMap.find(remote.GetRefPtr());
266 if (iter == g_agnssCallBackDeathRecipientMap.end()) {
267 HDF_LOGE("%{public}s: AgnssInterfaceImpl can not find deathRecipient", __func__);
268 return HDF_FAILURE;
269 }
270 auto recipient = iter->second;
271 bool result = remote->RemoveDeathRecipient(recipient);
272 g_agnssCallBackDeathRecipientMap.erase(iter);
273 if (!result) {
274 HDF_LOGE("%{public}s: AgnssInterfaceImpl remove deathRecipient fail", __func__);
275 return HDF_FAILURE;
276 }
277 return HDF_SUCCESS;
278 }
279
SendNetworkState(const NetworkState & state)280 int32_t AGnssInterfaceImpl::SendNetworkState(const NetworkState& state)
281 {
282 return HDF_SUCCESS;
283 }
284
ResetAgnssDeathRecipient()285 void AGnssInterfaceImpl::ResetAgnssDeathRecipient()
286 {
287 std::unique_lock<std::mutex> lock(g_mutex);
288 for (const auto& iter : g_agnssCallBackMap) {
289 const auto& callback = iter.second;
290 if (callback != nullptr) {
291 RemoveAgnssDeathRecipient(callback);
292 }
293 }
294 }
295
ResetAgnss()296 void AGnssInterfaceImpl::ResetAgnss()
297 {
298 HDF_LOGI("%{public}s called.", __func__);
299 ResetAgnssDeathRecipient();
300 std::unique_lock<std::mutex> lock(g_mutex);
301 g_agnssCallBackMap.clear();
302 }
303 } // V2_0
304 } // Agnss
305 } // Location
306 } // HDI
307 } // OHOS
308