1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "agnss_interface_impl.h"
17094332d3Sopenharmony_ci
18094332d3Sopenharmony_ci#include <hdf_base.h>
19094332d3Sopenharmony_ci#include <hdf_log.h>
20094332d3Sopenharmony_ci#include <iproxy_broker.h>
21094332d3Sopenharmony_ci#include <mutex>
22094332d3Sopenharmony_ci#include <unordered_map>
23094332d3Sopenharmony_ci
24094332d3Sopenharmony_ci#include "idevmgr_hdi.h"
25094332d3Sopenharmony_ci#include "securec.h"
26094332d3Sopenharmony_ci#include "location_vendor_interface.h"
27094332d3Sopenharmony_ci#include "location_vendor_lib.h"
28094332d3Sopenharmony_ci
29094332d3Sopenharmony_cinamespace OHOS {
30094332d3Sopenharmony_cinamespace HDI {
31094332d3Sopenharmony_cinamespace Location {
32094332d3Sopenharmony_cinamespace Agnss {
33094332d3Sopenharmony_cinamespace V2_0 {
34094332d3Sopenharmony_cinamespace {
35094332d3Sopenharmony_ciusing AgnssCallBackMap = std::unordered_map<IRemoteObject*, sptr<IAGnssCallback>>;
36094332d3Sopenharmony_ciusing AgnssDeathRecipientMap = std::unordered_map<IRemoteObject*, sptr<IRemoteObject::DeathRecipient>>;
37094332d3Sopenharmony_ciusing OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
38094332d3Sopenharmony_ciAgnssCallBackMap g_agnssCallBackMap;
39094332d3Sopenharmony_ciAgnssDeathRecipientMap g_agnssCallBackDeathRecipientMap;
40094332d3Sopenharmony_cistd::mutex g_mutex;
41094332d3Sopenharmony_cistd::mutex g_deathMutex;
42094332d3Sopenharmony_ciuint32_t g_refInfoType; // reference loction info type
43094332d3Sopenharmony_ciconst int MAC_LEN = 6;
44094332d3Sopenharmony_ci} // namespace
45094332d3Sopenharmony_ci
46094332d3Sopenharmony_ciextern "C" IAGnssInterface* AGnssInterfaceImplGetInstance(void)
47094332d3Sopenharmony_ci{
48094332d3Sopenharmony_ci    return new (std::nothrow) AGnssInterfaceImpl();
49094332d3Sopenharmony_ci}
50094332d3Sopenharmony_ci
51094332d3Sopenharmony_cistatic void RequestSetupAgnssDataConnection(const AgnssDataConnectionRequest* status)
52094332d3Sopenharmony_ci{
53094332d3Sopenharmony_ci    if (status == nullptr) {
54094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:status is nullptr.", __func__);
55094332d3Sopenharmony_ci        return;
56094332d3Sopenharmony_ci    }
57094332d3Sopenharmony_ci    HDF_LOGI("%{public}s.", __func__);
58094332d3Sopenharmony_ci    AGnssDataLinkRequest agnssStatus;
59094332d3Sopenharmony_ci    agnssStatus.agnssType = static_cast<AGnssUserPlaneProtocol>(status->agnssCategory);
60094332d3Sopenharmony_ci    agnssStatus.setUpType = static_cast<DataLinkSetUpType>(status->requestCategory);
61094332d3Sopenharmony_ci    std::unique_lock<std::mutex> lock(g_mutex);
62094332d3Sopenharmony_ci    for (const auto& iter : g_agnssCallBackMap) {
63094332d3Sopenharmony_ci        auto& callback = iter.second;
64094332d3Sopenharmony_ci        if (callback != nullptr) {
65094332d3Sopenharmony_ci            callback->RequestSetUpAgnssDataLink(agnssStatus);
66094332d3Sopenharmony_ci        }
67094332d3Sopenharmony_ci    }
68094332d3Sopenharmony_ci}
69094332d3Sopenharmony_ci
70094332d3Sopenharmony_cistatic void GetSetidCb(uint16_t type)
71094332d3Sopenharmony_ci{
72094332d3Sopenharmony_ci    HDF_LOGI("%{public}s.", __func__);
73094332d3Sopenharmony_ci    std::unique_lock<std::mutex> lock(g_mutex);
74094332d3Sopenharmony_ci    for (const auto& iter : g_agnssCallBackMap) {
75094332d3Sopenharmony_ci        auto& callback = iter.second;
76094332d3Sopenharmony_ci        if (callback != nullptr) {
77094332d3Sopenharmony_ci            callback->RequestSubscriberSetId(static_cast<SubscriberSetIdType>(type));
78094332d3Sopenharmony_ci        }
79094332d3Sopenharmony_ci    }
80094332d3Sopenharmony_ci}
81094332d3Sopenharmony_ci
82094332d3Sopenharmony_cistatic void GetRefLocationidCb(uint32_t type)
83094332d3Sopenharmony_ci{
84094332d3Sopenharmony_ci    HDF_LOGI("%{public}s, type=%{public}d", __func__, type);
85094332d3Sopenharmony_ci    std::unique_lock<std::mutex> lock(g_mutex);
86094332d3Sopenharmony_ci    g_refInfoType = type;
87094332d3Sopenharmony_ci    for (const auto& iter : g_agnssCallBackMap) {
88094332d3Sopenharmony_ci        auto& callback = iter.second;
89094332d3Sopenharmony_ci        if (callback != nullptr) {
90094332d3Sopenharmony_ci            callback->RequestAgnssRefInfo(static_cast<AGnssRefInfoType>(type));
91094332d3Sopenharmony_ci        }
92094332d3Sopenharmony_ci    }
93094332d3Sopenharmony_ci}
94094332d3Sopenharmony_ci
95094332d3Sopenharmony_cistatic void GetAGnssCallbackMethods(AgnssCallbackIfaces* device)
96094332d3Sopenharmony_ci{
97094332d3Sopenharmony_ci    if (device == nullptr) {
98094332d3Sopenharmony_ci        return;
99094332d3Sopenharmony_ci    }
100094332d3Sopenharmony_ci    device->size = sizeof(AgnssCallbackIfaces);
101094332d3Sopenharmony_ci    device->requestSetupDataLink = RequestSetupAgnssDataConnection;
102094332d3Sopenharmony_ci    device->requestSetid = GetSetidCb;
103094332d3Sopenharmony_ci    device->requestRefInfo = GetRefLocationidCb;
104094332d3Sopenharmony_ci}
105094332d3Sopenharmony_ci
106094332d3Sopenharmony_ciAGnssInterfaceImpl::AGnssInterfaceImpl()
107094332d3Sopenharmony_ci{
108094332d3Sopenharmony_ci    g_refInfoType = 0;
109094332d3Sopenharmony_ci}
110094332d3Sopenharmony_ci
111094332d3Sopenharmony_ciAGnssInterfaceImpl::~AGnssInterfaceImpl()
112094332d3Sopenharmony_ci{
113094332d3Sopenharmony_ci    ResetAgnssDeathRecipient();
114094332d3Sopenharmony_ci}
115094332d3Sopenharmony_ci
116094332d3Sopenharmony_ciint32_t AGnssInterfaceImpl::SetAgnssCallback(const sptr<IAGnssCallback>& callbackObj)
117094332d3Sopenharmony_ci{
118094332d3Sopenharmony_ci    HDF_LOGI("%{public}s.", __func__);
119094332d3Sopenharmony_ci    if (callbackObj == nullptr) {
120094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:invalid callbackObj", __func__);
121094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
122094332d3Sopenharmony_ci    }
123094332d3Sopenharmony_ci    const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
124094332d3Sopenharmony_ci    if (remote == nullptr) {
125094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:invalid remote", __func__);
126094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
127094332d3Sopenharmony_ci    }
128094332d3Sopenharmony_ci    std::unique_lock<std::mutex> lock(g_mutex);
129094332d3Sopenharmony_ci    auto callBackIter = g_agnssCallBackMap.find(remote.GetRefPtr());
130094332d3Sopenharmony_ci    if (callBackIter != g_agnssCallBackMap.end()) {
131094332d3Sopenharmony_ci        const sptr<IRemoteObject>& lhs = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
132094332d3Sopenharmony_ci        const sptr<IRemoteObject>& rhs = OHOS::HDI::hdi_objcast<IAGnssCallback>(callBackIter->second);
133094332d3Sopenharmony_ci        return lhs == rhs ? HDF_SUCCESS : HDF_FAILURE;
134094332d3Sopenharmony_ci    }
135094332d3Sopenharmony_ci
136094332d3Sopenharmony_ci    static AgnssCallbackIfaces agnsscallback;
137094332d3Sopenharmony_ci    GetAGnssCallbackMethods(&agnsscallback);
138094332d3Sopenharmony_ci
139094332d3Sopenharmony_ci    int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
140094332d3Sopenharmony_ci    LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
141094332d3Sopenharmony_ci    auto agnssInterface =
142094332d3Sopenharmony_ci        static_cast<const AgnssModuleInterface*>(interface->GetModuleInterface(moduleType));
143094332d3Sopenharmony_ci    if (agnssInterface == nullptr) {
144094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
145094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
146094332d3Sopenharmony_ci    }
147094332d3Sopenharmony_ci    bool ret = agnssInterface->setAgnssCallback(&agnsscallback);
148094332d3Sopenharmony_ci    if (!ret) {
149094332d3Sopenharmony_ci        HDF_LOGE("setAgnssCallback failed.");
150094332d3Sopenharmony_ci    }
151094332d3Sopenharmony_ci    AddAgnssDeathRecipient(callbackObj);
152094332d3Sopenharmony_ci    g_agnssCallBackMap[remote.GetRefPtr()] = callbackObj;
153094332d3Sopenharmony_ci    return HDF_SUCCESS;
154094332d3Sopenharmony_ci}
155094332d3Sopenharmony_ci
156094332d3Sopenharmony_ciint32_t AGnssInterfaceImpl::SetAgnssServer(const AGnssServerInfo& server)
157094332d3Sopenharmony_ci{
158094332d3Sopenharmony_ci    HDF_LOGI("%{public}s.", __func__);
159094332d3Sopenharmony_ci    int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
160094332d3Sopenharmony_ci    LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
161094332d3Sopenharmony_ci    auto agnssInterface =
162094332d3Sopenharmony_ci        static_cast<const AgnssModuleInterface*>(interface->GetModuleInterface(moduleType));
163094332d3Sopenharmony_ci    if (agnssInterface == nullptr) {
164094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
165094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
166094332d3Sopenharmony_ci    }
167094332d3Sopenharmony_ci    uint16_t type = static_cast<uint16_t>(server.type);
168094332d3Sopenharmony_ci    bool ret = agnssInterface->setAgnssServer(type, server.server.c_str(), server.server.length(), server.port);
169094332d3Sopenharmony_ci    if (!ret) {
170094332d3Sopenharmony_ci        HDF_LOGE("setAgnssServer failed.");
171094332d3Sopenharmony_ci        return HDF_FAILURE;
172094332d3Sopenharmony_ci    }
173094332d3Sopenharmony_ci    return HDF_SUCCESS;
174094332d3Sopenharmony_ci}
175094332d3Sopenharmony_ci
176094332d3Sopenharmony_ciint32_t AGnssInterfaceImpl::SetAgnssRefInfo(const AGnssRefInfo& refInfo)
177094332d3Sopenharmony_ci{
178094332d3Sopenharmony_ci    int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
179094332d3Sopenharmony_ci    LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
180094332d3Sopenharmony_ci    auto agnssInterface =
181094332d3Sopenharmony_ci        static_cast<const AgnssModuleInterface*>(interface->GetModuleInterface(moduleType));
182094332d3Sopenharmony_ci    if (agnssInterface == nullptr) {
183094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
184094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
185094332d3Sopenharmony_ci    }
186094332d3Sopenharmony_ci    HDF_LOGI("%{public}s, g_refInfoType=%{public}d", __func__, refInfo.type);
187094332d3Sopenharmony_ci    AgnssReferenceInfo loc;
188094332d3Sopenharmony_ci    loc.category = g_refInfoType;
189094332d3Sopenharmony_ci    if (loc.category == static_cast<uint32_t>(AgnssRefInfoCategory::AGNSS_REF_INFO_CATEGORY_MAC)) {
190094332d3Sopenharmony_ci        for (size_t i = 0; i < MAC_LEN; i++) {
191094332d3Sopenharmony_ci            loc.u.mac.mac[i] = refInfo.mac.mac[i];
192094332d3Sopenharmony_ci        }
193094332d3Sopenharmony_ci        loc.u.mac.size = MAC_LEN;
194094332d3Sopenharmony_ci    } else if (loc.category == static_cast<uint32_t>(AgnssRefInfoCategory::AGNSS_REF_INFO_CATEGORY_CELLID)) {
195094332d3Sopenharmony_ci        switch (refInfo.cellId.type) {
196094332d3Sopenharmony_ci            case CELLID_TYPE_GSM:
197094332d3Sopenharmony_ci                loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_GSM);
198094332d3Sopenharmony_ci                break;
199094332d3Sopenharmony_ci            case CELLID_TYPE_UMTS:
200094332d3Sopenharmony_ci                loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_UMTS);
201094332d3Sopenharmony_ci                break;
202094332d3Sopenharmony_ci            case CELLID_TYPE_LTE:
203094332d3Sopenharmony_ci                loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_LTE);
204094332d3Sopenharmony_ci                break;
205094332d3Sopenharmony_ci            case CELLID_TYPE_NR:
206094332d3Sopenharmony_ci                loc.u.cellId.category = static_cast<uint16_t>(CellIdCategory::CELLID_CATEGORY_NR);
207094332d3Sopenharmony_ci                break;
208094332d3Sopenharmony_ci            default:
209094332d3Sopenharmony_ci                HDF_LOGE("%{public}s wrong cellType.", __func__);
210094332d3Sopenharmony_ci                return HDF_ERR_INVALID_PARAM;
211094332d3Sopenharmony_ci        }
212094332d3Sopenharmony_ci        loc.u.cellId.mcc = refInfo.cellId.mcc;
213094332d3Sopenharmony_ci        loc.u.cellId.mnc = refInfo.cellId.mnc;
214094332d3Sopenharmony_ci        loc.u.cellId.lac = refInfo.cellId.lac;
215094332d3Sopenharmony_ci        loc.u.cellId.cid = refInfo.cellId.cid;
216094332d3Sopenharmony_ci        loc.u.cellId.tac = refInfo.cellId.tac;
217094332d3Sopenharmony_ci        loc.u.cellId.pcid = refInfo.cellId.pcid;
218094332d3Sopenharmony_ci        loc.u.cellId.nci = refInfo.cellId.nci;
219094332d3Sopenharmony_ci    }
220094332d3Sopenharmony_ci    bool ret = agnssInterface->setAgnssReferenceInfo(&loc);
221094332d3Sopenharmony_ci    if (!ret) {
222094332d3Sopenharmony_ci        HDF_LOGE("setAgnssReferenceInfo failed.");
223094332d3Sopenharmony_ci        return HDF_FAILURE;
224094332d3Sopenharmony_ci    }
225094332d3Sopenharmony_ci    return HDF_SUCCESS;
226094332d3Sopenharmony_ci}
227094332d3Sopenharmony_ci
228094332d3Sopenharmony_ciint32_t AGnssInterfaceImpl::SetSubscriberSetId(const SubscriberSetId& id)
229094332d3Sopenharmony_ci{
230094332d3Sopenharmony_ci    HDF_LOGI("%{public}s.", __func__);
231094332d3Sopenharmony_ci    int moduleType = static_cast<int>(GnssModuleIfaceCategory::AGNSS_MODULE_INTERFACE);
232094332d3Sopenharmony_ci    LocationVendorInterface* interface = LocationVendorInterface::GetInstance();
233094332d3Sopenharmony_ci    auto agnssInterface =
234094332d3Sopenharmony_ci        static_cast<const AgnssModuleInterface*>(interface->GetModuleInterface(moduleType));
235094332d3Sopenharmony_ci    if (agnssInterface == nullptr) {
236094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:can not get agnssInterface.", __func__);
237094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
238094332d3Sopenharmony_ci    }
239094332d3Sopenharmony_ci    uint16_t type = static_cast<uint16_t>(id.type);
240094332d3Sopenharmony_ci    int ret = agnssInterface->setSetid(type, id.id.c_str(), id.id.length());
241094332d3Sopenharmony_ci    if (!ret) {
242094332d3Sopenharmony_ci        HDF_LOGE("setSetid failed.");
243094332d3Sopenharmony_ci        return HDF_FAILURE;
244094332d3Sopenharmony_ci    }
245094332d3Sopenharmony_ci    return HDF_SUCCESS;
246094332d3Sopenharmony_ci}
247094332d3Sopenharmony_ci
248094332d3Sopenharmony_ciint32_t AGnssInterfaceImpl::AddAgnssDeathRecipient(const sptr<IAGnssCallback>& callbackObj)
249094332d3Sopenharmony_ci{
250094332d3Sopenharmony_ci    sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) AgnssCallBackDeathRecipient(this));
251094332d3Sopenharmony_ci    const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
252094332d3Sopenharmony_ci    bool result = remote->AddDeathRecipient(death);
253094332d3Sopenharmony_ci    if (!result) {
254094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: AGnssInterfaceImpl add deathRecipient fail", __func__);
255094332d3Sopenharmony_ci        return HDF_FAILURE;
256094332d3Sopenharmony_ci    }
257094332d3Sopenharmony_ci    std::unique_lock<std::mutex> lock(g_deathMutex);
258094332d3Sopenharmony_ci    g_agnssCallBackDeathRecipientMap[remote.GetRefPtr()] = death;
259094332d3Sopenharmony_ci    return HDF_SUCCESS;
260094332d3Sopenharmony_ci}
261094332d3Sopenharmony_ci
262094332d3Sopenharmony_ciint32_t AGnssInterfaceImpl::RemoveAgnssDeathRecipient(const sptr<IAGnssCallback>& callbackObj)
263094332d3Sopenharmony_ci{
264094332d3Sopenharmony_ci    std::unique_lock<std::mutex> lock(g_deathMutex);
265094332d3Sopenharmony_ci    const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IAGnssCallback>(callbackObj);
266094332d3Sopenharmony_ci    auto iter = g_agnssCallBackDeathRecipientMap.find(remote.GetRefPtr());
267094332d3Sopenharmony_ci    if (iter == g_agnssCallBackDeathRecipientMap.end()) {
268094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: AgnssInterfaceImpl can not find deathRecipient", __func__);
269094332d3Sopenharmony_ci        return HDF_FAILURE;
270094332d3Sopenharmony_ci    }
271094332d3Sopenharmony_ci    auto recipient = iter->second;
272094332d3Sopenharmony_ci    bool result = remote->RemoveDeathRecipient(recipient);
273094332d3Sopenharmony_ci    g_agnssCallBackDeathRecipientMap.erase(iter);
274094332d3Sopenharmony_ci    if (!result) {
275094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: AgnssInterfaceImpl remove deathRecipient fail", __func__);
276094332d3Sopenharmony_ci        return HDF_FAILURE;
277094332d3Sopenharmony_ci    }
278094332d3Sopenharmony_ci    return HDF_SUCCESS;
279094332d3Sopenharmony_ci}
280094332d3Sopenharmony_ci
281094332d3Sopenharmony_ciint32_t AGnssInterfaceImpl::SendNetworkState(const NetworkState& state)
282094332d3Sopenharmony_ci{
283094332d3Sopenharmony_ci    return HDF_SUCCESS;
284094332d3Sopenharmony_ci}
285094332d3Sopenharmony_ci
286094332d3Sopenharmony_civoid AGnssInterfaceImpl::ResetAgnssDeathRecipient()
287094332d3Sopenharmony_ci{
288094332d3Sopenharmony_ci    std::unique_lock<std::mutex> lock(g_mutex);
289094332d3Sopenharmony_ci    for (const auto& iter : g_agnssCallBackMap) {
290094332d3Sopenharmony_ci        const auto& callback = iter.second;
291094332d3Sopenharmony_ci        if (callback != nullptr) {
292094332d3Sopenharmony_ci            RemoveAgnssDeathRecipient(callback);
293094332d3Sopenharmony_ci        }
294094332d3Sopenharmony_ci    }
295094332d3Sopenharmony_ci}
296094332d3Sopenharmony_ci
297094332d3Sopenharmony_civoid AGnssInterfaceImpl::ResetAgnss()
298094332d3Sopenharmony_ci{
299094332d3Sopenharmony_ci    HDF_LOGI("%{public}s called.", __func__);
300094332d3Sopenharmony_ci    ResetAgnssDeathRecipient();
301094332d3Sopenharmony_ci    std::unique_lock<std::mutex> lock(g_mutex);
302094332d3Sopenharmony_ci    g_agnssCallBackMap.clear();
303094332d3Sopenharmony_ci}
304094332d3Sopenharmony_ci} // V2_0
305094332d3Sopenharmony_ci} // Agnss
306094332d3Sopenharmony_ci} // Location
307094332d3Sopenharmony_ci} // HDI
308094332d3Sopenharmony_ci} // OHOS
309