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 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 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();
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>(GnssModuleIfaceClass::AGPS_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 return HDF_FAILURE;
151 }
152 AddAgnssDeathRecipient(callbackObj);
153 g_agnssCallBackMap[remote.GetRefPtr()] = callbackObj;
154 return HDF_SUCCESS;
155 }
156
SetAgnssServer(const AGnssServerInfo & server)157 int32_t AGnssInterfaceImpl::SetAgnssServer(const AGnssServerInfo& server)
158 {
159 HDF_LOGI("%{public}s.", __func__);
160 int moduleType = static_cast<int>(GnssModuleIfaceClass::AGPS_INTERFACE);
161 LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
162 auto agnssInterface =
163 static_cast<const AGnssModuleInterface*>(interface->GetModuleInterface(moduleType));
164 if (agnssInterface == nullptr) {
165 HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
166 return HDF_ERR_INVALID_PARAM;
167 }
168 uint16_t type = static_cast<uint16_t>(server.type);
169 bool ret = agnssInterface->set_agnss_server(type, server.server.c_str(), server.server.length(), server.port);
170 if (!ret) {
171 HDF_LOGE("set_agnss_server failed.");
172 return HDF_FAILURE;
173 }
174 return HDF_SUCCESS;
175 }
176
SetAgnssRefInfo(const AGnssRefInfo & refInfo)177 int32_t AGnssInterfaceImpl::SetAgnssRefInfo(const AGnssRefInfo& refInfo)
178 {
179 int moduleType = static_cast<int>(GnssModuleIfaceClass::AGPS_INTERFACE);
180 LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
181 auto agnssInterface =
182 static_cast<const AGnssModuleInterface*>(interface->GetModuleInterface(moduleType));
183 if (agnssInterface == nullptr) {
184 HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
185 return HDF_ERR_INVALID_PARAM;
186 }
187 HDF_LOGI("%{public}s, g_refInfoType=%{public}d", __func__, refInfo.type);
188 AGnssRefLocInfo loc;
189 loc.type = g_refInfoType;
190 if (loc.type == static_cast<uint32_t>(AgnssRefLocClass::AGNSS_REF_LOC_CLASS_MAC)) {
191 for (size_t i = 0; i < MAC_LEN; i++) {
192 loc.u.mac.mac[i] = refInfo.mac.mac[i];
193 }
194 loc.u.mac.size = MAC_LEN;
195 } else if (loc.type == static_cast<uint32_t>(AgnssRefLocClass::AGNSS_REF_LOC_CLASS_CELLID)) {
196 switch (refInfo.cellId.type) {
197 case CELLID_TYPE_GSM:
198 loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::GSM_CELLID);
199 break;
200 case CELLID_TYPE_UMTS:
201 loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::UMTS_CELLID);
202 break;
203 case CELLID_TYPE_LTE:
204 loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::LTE_CELLID);
205 break;
206 case CELLID_TYPE_NR:
207 loc.u.cellId.type = static_cast<uint16_t>(CellIdClass::NR_CELLID);
208 break;
209 default:
210 HDF_LOGE("%{public}s wrong cellType.", __func__);
211 return HDF_ERR_INVALID_PARAM;
212 }
213 loc.u.cellId.mcc = refInfo.cellId.mcc;
214 loc.u.cellId.mnc = refInfo.cellId.mnc;
215 loc.u.cellId.lac = refInfo.cellId.lac;
216 loc.u.cellId.cid = refInfo.cellId.cid;
217 loc.u.cellId.tac = refInfo.cellId.tac;
218 loc.u.cellId.pcid = refInfo.cellId.pcid;
219 }
220 bool ret = agnssInterface->set_ref_location(&loc);
221 if (!ret) {
222 HDF_LOGE("set_ref_location 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>(GnssModuleIfaceClass::AGPS_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->set_setid(type, id.id.c_str(), id.id.length());
241 if (!ret) {
242 HDF_LOGE("set_setid 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
ResetAgnssDeathRecipient()281 void AGnssInterfaceImpl::ResetAgnssDeathRecipient()
282 {
283 std::unique_lock<std::mutex> lock(g_mutex);
284 for (const auto& iter : g_agnssCallBackMap) {
285 const auto& callback = iter.second;
286 if (callback != nullptr) {
287 RemoveAgnssDeathRecipient(callback);
288 }
289 }
290 }
291
ResetAgnss()292 void AGnssInterfaceImpl::ResetAgnss()
293 {
294 HDF_LOGI("%{public}s called.", __func__);
295 ResetAgnssDeathRecipient();
296 std::unique_lock<std::mutex> lock(g_mutex);
297 g_agnssCallBackMap.clear();
298 }
299 } // V1_0
300 } // Agnss
301 } // Location
302 } // HDI
303 } // OHOS
304