1bc2ed2b3Sopenharmony_ci/*
2bc2ed2b3Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3bc2ed2b3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bc2ed2b3Sopenharmony_ci * you may not use this file except in compliance with the License.
5bc2ed2b3Sopenharmony_ci * You may obtain a copy of the License at
6bc2ed2b3Sopenharmony_ci *
7bc2ed2b3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8bc2ed2b3Sopenharmony_ci *
9bc2ed2b3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bc2ed2b3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bc2ed2b3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bc2ed2b3Sopenharmony_ci * See the License for the specific language governing permissions and
13bc2ed2b3Sopenharmony_ci * limitations under the License.
14bc2ed2b3Sopenharmony_ci */
15bc2ed2b3Sopenharmony_ci#include "nfc_service.h"
16bc2ed2b3Sopenharmony_ci#include <unistd.h>
17bc2ed2b3Sopenharmony_ci#include "app_data_parser.h"
18bc2ed2b3Sopenharmony_ci#include "infc_controller_callback.h"
19bc2ed2b3Sopenharmony_ci#include "iservice_registry.h"
20bc2ed2b3Sopenharmony_ci#include "loghelper.h"
21bc2ed2b3Sopenharmony_ci#include "nfc_preferences.h"
22bc2ed2b3Sopenharmony_ci#include "nfc_event_handler.h"
23bc2ed2b3Sopenharmony_ci#include "nfc_event_publisher.h"
24bc2ed2b3Sopenharmony_ci#include "nfc_hisysevent.h"
25bc2ed2b3Sopenharmony_ci#include "nfc_polling_params.h"
26bc2ed2b3Sopenharmony_ci#include "nfc_sdk_common.h"
27bc2ed2b3Sopenharmony_ci#include "nfc_timer.h"
28bc2ed2b3Sopenharmony_ci#include "nfc_watch_dog.h"
29bc2ed2b3Sopenharmony_ci#include "tag_session.h"
30bc2ed2b3Sopenharmony_ci#include "external_deps_proxy.h"
31bc2ed2b3Sopenharmony_ci#include "want.h"
32bc2ed2b3Sopenharmony_ci#include "nci_nfcc_proxy.h"
33bc2ed2b3Sopenharmony_ci#include "nci_tag_proxy.h"
34bc2ed2b3Sopenharmony_ci#include "nci_ce_proxy.h"
35bc2ed2b3Sopenharmony_ci#include "hce_session.h"
36bc2ed2b3Sopenharmony_ci
37bc2ed2b3Sopenharmony_cinamespace OHOS {
38bc2ed2b3Sopenharmony_cinamespace NFC {
39bc2ed2b3Sopenharmony_ciconst std::u16string NFC_SERVICE_NAME = OHOS::to_utf16("ohos.nfc.service");
40bc2ed2b3Sopenharmony_ciuint32_t NfcService::unloadStaSaTimerId{0};
41bc2ed2b3Sopenharmony_ci
42bc2ed2b3Sopenharmony_ciNfcService::NfcService()
43bc2ed2b3Sopenharmony_ci    : eventHandler_(nullptr),
44bc2ed2b3Sopenharmony_ci    tagDispatcher_(nullptr),
45bc2ed2b3Sopenharmony_ci    nfcControllerImpl_(nullptr),
46bc2ed2b3Sopenharmony_ci    nfcState_(KITS::STATE_OFF)
47bc2ed2b3Sopenharmony_ci{
48bc2ed2b3Sopenharmony_ci}
49bc2ed2b3Sopenharmony_ci
50bc2ed2b3Sopenharmony_ciNfcService::~NfcService()
51bc2ed2b3Sopenharmony_ci{
52bc2ed2b3Sopenharmony_ci    nfcControllerImpl_ = nullptr;
53bc2ed2b3Sopenharmony_ci    nfcPollingManager_ = nullptr;
54bc2ed2b3Sopenharmony_ci    nfcRoutingManager_ = nullptr;
55bc2ed2b3Sopenharmony_ci    if (task_ && task_->joinable()) {
56bc2ed2b3Sopenharmony_ci        task_->join();
57bc2ed2b3Sopenharmony_ci    }
58bc2ed2b3Sopenharmony_ci    if (rootTask_ && rootTask_->joinable()) {
59bc2ed2b3Sopenharmony_ci        rootTask_->join();
60bc2ed2b3Sopenharmony_ci    }
61bc2ed2b3Sopenharmony_ci}
62bc2ed2b3Sopenharmony_ci
63bc2ed2b3Sopenharmony_cistd::weak_ptr<NfcService> NfcService::GetInstance() const
64bc2ed2b3Sopenharmony_ci{
65bc2ed2b3Sopenharmony_ci    return nfcService_;
66bc2ed2b3Sopenharmony_ci}
67bc2ed2b3Sopenharmony_ci
68bc2ed2b3Sopenharmony_cistd::weak_ptr<NCI::INciTagInterface> NfcService::GetNciTagProxy(void)
69bc2ed2b3Sopenharmony_ci{
70bc2ed2b3Sopenharmony_ci    return nciTagProxy_;
71bc2ed2b3Sopenharmony_ci}
72bc2ed2b3Sopenharmony_ci
73bc2ed2b3Sopenharmony_cistd::weak_ptr<NfcPollingManager> NfcService::GetNfcPollingManager()
74bc2ed2b3Sopenharmony_ci{
75bc2ed2b3Sopenharmony_ci    return nfcPollingManager_;
76bc2ed2b3Sopenharmony_ci}
77bc2ed2b3Sopenharmony_ci
78bc2ed2b3Sopenharmony_cistd::weak_ptr<NfcRoutingManager> NfcService::GetNfcRoutingManager()
79bc2ed2b3Sopenharmony_ci{
80bc2ed2b3Sopenharmony_ci    return nfcRoutingManager_;
81bc2ed2b3Sopenharmony_ci}
82bc2ed2b3Sopenharmony_ci
83bc2ed2b3Sopenharmony_cistd::weak_ptr<CeService> NfcService::GetCeService()
84bc2ed2b3Sopenharmony_ci{
85bc2ed2b3Sopenharmony_ci    return ceService_;
86bc2ed2b3Sopenharmony_ci}
87bc2ed2b3Sopenharmony_ci
88bc2ed2b3Sopenharmony_cistd::string NfcService::GetSimVendorBundleName()
89bc2ed2b3Sopenharmony_ci{
90bc2ed2b3Sopenharmony_ci    return nciCeProxy_->GetSimVendorBundleName();
91bc2ed2b3Sopenharmony_ci}
92bc2ed2b3Sopenharmony_ci
93bc2ed2b3Sopenharmony_cibool NfcService::Initialize()
94bc2ed2b3Sopenharmony_ci{
95bc2ed2b3Sopenharmony_ci    nfcService_ = shared_from_this();
96bc2ed2b3Sopenharmony_ci    InfoLog("Nfc service initialize.");
97bc2ed2b3Sopenharmony_ci    nciNfccProxy_ = std::make_shared<NFC::NCI::NciNfccProxy>();
98bc2ed2b3Sopenharmony_ci    nciTagProxy_ = std::make_shared<NFC::NCI::NciTagProxy>();
99bc2ed2b3Sopenharmony_ci    nciCeProxy_ = std::make_shared<NFC::NCI::NciCeProxy>();
100bc2ed2b3Sopenharmony_ci    nciTagProxy_->SetTagListener(nfcService_);
101bc2ed2b3Sopenharmony_ci    nciCeProxy_->SetCeHostListener(nfcService_);
102bc2ed2b3Sopenharmony_ci
103bc2ed2b3Sopenharmony_ci    // inner message handler, used by other modules as initialization parameters
104bc2ed2b3Sopenharmony_ci    std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("nfcservice::EventRunner");
105bc2ed2b3Sopenharmony_ci    eventHandler_ = std::make_shared<NfcEventHandler>(runner, shared_from_this());
106bc2ed2b3Sopenharmony_ci    tagDispatcher_ = std::make_shared<TAG::TagDispatcher>(shared_from_this());
107bc2ed2b3Sopenharmony_ci    ceService_ = std::make_shared<CeService>(shared_from_this(), nciCeProxy_);
108bc2ed2b3Sopenharmony_ci
109bc2ed2b3Sopenharmony_ci    nfcPollingManager_ = std::make_shared<NfcPollingManager>(shared_from_this(), nciNfccProxy_, nciTagProxy_);
110bc2ed2b3Sopenharmony_ci    nfcRoutingManager_ = std::make_shared<NfcRoutingManager>(eventHandler_, nciNfccProxy_,
111bc2ed2b3Sopenharmony_ci    nciCeProxy_, shared_from_this());
112bc2ed2b3Sopenharmony_ci    tagSessionIface_ = new TAG::TagSession(shared_from_this());
113bc2ed2b3Sopenharmony_ci    hceSessionIface_ = new HCE::HceSession(shared_from_this());
114bc2ed2b3Sopenharmony_ci
115bc2ed2b3Sopenharmony_ci    // used by NfcSaManager::Init(), to public for the proxy.
116bc2ed2b3Sopenharmony_ci    nfcControllerImpl_ = new NfcControllerImpl(shared_from_this());
117bc2ed2b3Sopenharmony_ci    nfcPollingManager_->ResetCurrPollingParams();
118bc2ed2b3Sopenharmony_ci
119bc2ed2b3Sopenharmony_ci    runner->Run();
120bc2ed2b3Sopenharmony_ci    // NFC ROOT
121bc2ed2b3Sopenharmony_ci    ExecuteTask(KITS::TASK_INITIALIZE);
122bc2ed2b3Sopenharmony_ci    return true;
123bc2ed2b3Sopenharmony_ci}
124bc2ed2b3Sopenharmony_ci
125bc2ed2b3Sopenharmony_civoid NfcService::UnloadNfcSa()
126bc2ed2b3Sopenharmony_ci{
127bc2ed2b3Sopenharmony_ci    InfoLog("%{public}s enter, systemAbilityId = [%{public}d] unloading", __func__, KITS::NFC_MANAGER_SYS_ABILITY_ID);
128bc2ed2b3Sopenharmony_ci    sptr<ISystemAbilityManager> samgr =
129bc2ed2b3Sopenharmony_ci        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
130bc2ed2b3Sopenharmony_ci    if (samgr == nullptr) {
131bc2ed2b3Sopenharmony_ci        ErrorLog("%{public}s: get system ability manager failed!", __func__);
132bc2ed2b3Sopenharmony_ci        return;
133bc2ed2b3Sopenharmony_ci    }
134bc2ed2b3Sopenharmony_ci    int32_t ret = samgr->UnloadSystemAbility(KITS::NFC_MANAGER_SYS_ABILITY_ID);
135bc2ed2b3Sopenharmony_ci    if (ret != ERR_NONE) {
136bc2ed2b3Sopenharmony_ci        ErrorLog("%{public}s: Failed to unload system ability, SA Id = [%{public}d], ret = [%{public}d].",
137bc2ed2b3Sopenharmony_ci            __func__, KITS::NFC_MANAGER_SYS_ABILITY_ID, ret);
138bc2ed2b3Sopenharmony_ci    }
139bc2ed2b3Sopenharmony_ci}
140bc2ed2b3Sopenharmony_ci
141bc2ed2b3Sopenharmony_cistd::weak_ptr<TAG::TagDispatcher> NfcService::GetTagDispatcher()
142bc2ed2b3Sopenharmony_ci{
143bc2ed2b3Sopenharmony_ci    return tagDispatcher_;
144bc2ed2b3Sopenharmony_ci}
145bc2ed2b3Sopenharmony_ci
146bc2ed2b3Sopenharmony_ciOHOS::sptr<IRemoteObject> NfcService::GetTagServiceIface()
147bc2ed2b3Sopenharmony_ci{
148bc2ed2b3Sopenharmony_ci    return tagSessionIface_;
149bc2ed2b3Sopenharmony_ci}
150bc2ed2b3Sopenharmony_ci
151bc2ed2b3Sopenharmony_civoid NfcService::OnTagDiscovered(uint32_t tagDiscId)
152bc2ed2b3Sopenharmony_ci{
153bc2ed2b3Sopenharmony_ci    InfoLog("NfcService::OnTagDiscovered tagDiscId %{public}d", tagDiscId);
154bc2ed2b3Sopenharmony_ci    eventHandler_->SendEvent(static_cast<uint32_t>(NfcCommonEvent::MSG_TAG_FOUND), tagDiscId, 0);
155bc2ed2b3Sopenharmony_ci    InfoLog("NfcService::OnTagDiscovered end");
156bc2ed2b3Sopenharmony_ci}
157bc2ed2b3Sopenharmony_ci
158bc2ed2b3Sopenharmony_civoid NfcService::OnTagLost(uint32_t tagDiscId)
159bc2ed2b3Sopenharmony_ci{
160bc2ed2b3Sopenharmony_ci    InfoLog("NfcService::OnTagLost tagDiscId %{public}d", tagDiscId);
161bc2ed2b3Sopenharmony_ci    eventHandler_->SendEvent(static_cast<uint32_t>(NfcCommonEvent::MSG_TAG_LOST), tagDiscId, 0);
162bc2ed2b3Sopenharmony_ci}
163bc2ed2b3Sopenharmony_ci
164bc2ed2b3Sopenharmony_civoid NfcService::FieldActivated()
165bc2ed2b3Sopenharmony_ci{
166bc2ed2b3Sopenharmony_ci    InfoLog("NfcService::FieldActivated");
167bc2ed2b3Sopenharmony_ci    eventHandler_->SendEvent(static_cast<uint32_t>(NfcCommonEvent::MSG_FIELD_ACTIVATED));
168bc2ed2b3Sopenharmony_ci}
169bc2ed2b3Sopenharmony_ci
170bc2ed2b3Sopenharmony_civoid NfcService::FieldDeactivated()
171bc2ed2b3Sopenharmony_ci{
172bc2ed2b3Sopenharmony_ci    InfoLog("NfcService::FieldDeactivated");
173bc2ed2b3Sopenharmony_ci    eventHandler_->SendEvent(static_cast<uint32_t>(NfcCommonEvent::MSG_FIELD_DEACTIVATED));
174bc2ed2b3Sopenharmony_ci}
175bc2ed2b3Sopenharmony_ci
176bc2ed2b3Sopenharmony_ci#ifdef VENDOR_APPLICATIONS_ENABLED
177bc2ed2b3Sopenharmony_civoid NfcService::OnVendorEvent(int eventType, int arg1, std::string arg2)
178bc2ed2b3Sopenharmony_ci{
179bc2ed2b3Sopenharmony_ci    InfoLog("NfcService::OnVendorEvent");
180bc2ed2b3Sopenharmony_ci    eventHandler_->SendEvent(static_cast<uint32_t>(NfcCommonEvent::MSG_VENDOR_EVENT), eventType, 0);
181bc2ed2b3Sopenharmony_ci}
182bc2ed2b3Sopenharmony_ci#endif
183bc2ed2b3Sopenharmony_ci
184bc2ed2b3Sopenharmony_civoid NfcService::OnCardEmulationData(const std::vector<uint8_t> &data)
185bc2ed2b3Sopenharmony_ci{
186bc2ed2b3Sopenharmony_ci    InfoLog("NfcService::OnCardEmulationData");
187bc2ed2b3Sopenharmony_ci    ceService_->OnCardEmulationData(data);
188bc2ed2b3Sopenharmony_ci}
189bc2ed2b3Sopenharmony_ci
190bc2ed2b3Sopenharmony_civoid NfcService::OnCardEmulationActivated()
191bc2ed2b3Sopenharmony_ci{
192bc2ed2b3Sopenharmony_ci    InfoLog("NfcService::OnCardEmulationActivated");
193bc2ed2b3Sopenharmony_ci    ceService_->OnCardEmulationActivated();
194bc2ed2b3Sopenharmony_ci}
195bc2ed2b3Sopenharmony_ci
196bc2ed2b3Sopenharmony_ciOHOS::sptr<IRemoteObject> NfcService::GetHceServiceIface()
197bc2ed2b3Sopenharmony_ci{
198bc2ed2b3Sopenharmony_ci    return hceSessionIface_;
199bc2ed2b3Sopenharmony_ci}
200bc2ed2b3Sopenharmony_ci
201bc2ed2b3Sopenharmony_civoid NfcService::OnCardEmulationDeactivated()
202bc2ed2b3Sopenharmony_ci{
203bc2ed2b3Sopenharmony_ci    InfoLog("NfcService::OnCardEmulationDeactivated");
204bc2ed2b3Sopenharmony_ci    ceService_->OnCardEmulationDeactivated();
205bc2ed2b3Sopenharmony_ci}
206bc2ed2b3Sopenharmony_ci
207bc2ed2b3Sopenharmony_cibool NfcService::IsNfcTaskReady(std::future<int>& future) const
208bc2ed2b3Sopenharmony_ci{
209bc2ed2b3Sopenharmony_ci    for (uint8_t count = 0; count < MAX_RETRY_TIME; count++) {
210bc2ed2b3Sopenharmony_ci        if (future.valid()) {
211bc2ed2b3Sopenharmony_ci            std::future_status result = future.wait_for(std::chrono::milliseconds(TASK_THREAD_WAIT_MS));
212bc2ed2b3Sopenharmony_ci            if (result != std::future_status::ready) {
213bc2ed2b3Sopenharmony_ci                InfoLog("result = %{public}d, not ready", result);
214bc2ed2b3Sopenharmony_ci                usleep(TASK_THREAD_WAIT_US);
215bc2ed2b3Sopenharmony_ci                continue;
216bc2ed2b3Sopenharmony_ci            } else {
217bc2ed2b3Sopenharmony_ci                InfoLog("result = %{public}d, ready", result);
218bc2ed2b3Sopenharmony_ci                return true;
219bc2ed2b3Sopenharmony_ci            }
220bc2ed2b3Sopenharmony_ci        } else {
221bc2ed2b3Sopenharmony_ci            return true;
222bc2ed2b3Sopenharmony_ci        }
223bc2ed2b3Sopenharmony_ci    }
224bc2ed2b3Sopenharmony_ci    return false;
225bc2ed2b3Sopenharmony_ci}
226bc2ed2b3Sopenharmony_ci
227bc2ed2b3Sopenharmony_ciint NfcService::ExecuteTask(KITS::NfcTask param)
228bc2ed2b3Sopenharmony_ci{
229bc2ed2b3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
230bc2ed2b3Sopenharmony_ci    if (nfcState_ == KITS::STATE_TURNING_OFF || nfcState_ == KITS::STATE_TURNING_ON) {
231bc2ed2b3Sopenharmony_ci        WarnLog("Execute task %{public}d from bad state %{public}d", param, nfcState_);
232bc2ed2b3Sopenharmony_ci        return ERR_NONE;
233bc2ed2b3Sopenharmony_ci    }
234bc2ed2b3Sopenharmony_ci
235bc2ed2b3Sopenharmony_ci    // Check the current state
236bc2ed2b3Sopenharmony_ci    if (param == KITS::TASK_TURN_ON && nfcState_ == KITS::STATE_ON) {
237bc2ed2b3Sopenharmony_ci        WarnLog("NFC Turn On, already On");
238bc2ed2b3Sopenharmony_ci        ExternalDepsProxy::GetInstance().UpdateNfcState(KITS::STATE_ON);
239bc2ed2b3Sopenharmony_ci        return ERR_NONE;
240bc2ed2b3Sopenharmony_ci    }
241bc2ed2b3Sopenharmony_ci    if (param == KITS::TASK_TURN_OFF && nfcState_ == KITS::STATE_OFF) {
242bc2ed2b3Sopenharmony_ci        WarnLog("NFC Turn Off, already Off");
243bc2ed2b3Sopenharmony_ci        ExternalDepsProxy::GetInstance().UpdateNfcState(KITS::STATE_OFF);
244bc2ed2b3Sopenharmony_ci        UnloadNfcSa();
245bc2ed2b3Sopenharmony_ci        return ERR_NONE;
246bc2ed2b3Sopenharmony_ci    }
247bc2ed2b3Sopenharmony_ci
248bc2ed2b3Sopenharmony_ci    std::promise<int> promise;
249bc2ed2b3Sopenharmony_ci    if (rootTask_) {
250bc2ed2b3Sopenharmony_ci        if (!IsNfcTaskReady(future_)) {
251bc2ed2b3Sopenharmony_ci            WarnLog("ExecuteTask, IsNfcTaskReady is false.");
252bc2ed2b3Sopenharmony_ci            return KITS::ERR_NFC_STATE_INVALID;
253bc2ed2b3Sopenharmony_ci        }
254bc2ed2b3Sopenharmony_ci        if (task_ && task_->joinable()) {
255bc2ed2b3Sopenharmony_ci            task_->join();
256bc2ed2b3Sopenharmony_ci        }
257bc2ed2b3Sopenharmony_ci        future_ = promise.get_future();
258bc2ed2b3Sopenharmony_ci        task_ = std::make_unique<std::thread>([this, param, promise = std::move(promise)]() mutable {
259bc2ed2b3Sopenharmony_ci            this->NfcTaskThread(param, std::move(promise));
260bc2ed2b3Sopenharmony_ci        });
261bc2ed2b3Sopenharmony_ci    } else {
262bc2ed2b3Sopenharmony_ci        rootTask_ = std::make_unique<std::thread>([this, param, promise = std::move(promise)]() mutable {
263bc2ed2b3Sopenharmony_ci            this->NfcTaskThread(param, std::move(promise));
264bc2ed2b3Sopenharmony_ci        });
265bc2ed2b3Sopenharmony_ci    }
266bc2ed2b3Sopenharmony_ci    return ERR_NONE;
267bc2ed2b3Sopenharmony_ci}
268bc2ed2b3Sopenharmony_ci
269bc2ed2b3Sopenharmony_civoid NfcService::NfcTaskThread(KITS::NfcTask params, std::promise<int> promise)
270bc2ed2b3Sopenharmony_ci{
271bc2ed2b3Sopenharmony_ci    InfoLog("Nfc task thread params %{public}d", params);
272bc2ed2b3Sopenharmony_ci    switch (params) {
273bc2ed2b3Sopenharmony_ci        case KITS::TASK_TURN_ON:
274bc2ed2b3Sopenharmony_ci            DoTurnOn();
275bc2ed2b3Sopenharmony_ci            break;
276bc2ed2b3Sopenharmony_ci        case KITS::TASK_TURN_OFF:
277bc2ed2b3Sopenharmony_ci            DoTurnOff();
278bc2ed2b3Sopenharmony_ci            break;
279bc2ed2b3Sopenharmony_ci        case KITS::TASK_INITIALIZE:
280bc2ed2b3Sopenharmony_ci            DoInitialize();
281bc2ed2b3Sopenharmony_ci            break;
282bc2ed2b3Sopenharmony_ci        default:
283bc2ed2b3Sopenharmony_ci            break;
284bc2ed2b3Sopenharmony_ci    }
285bc2ed2b3Sopenharmony_ci    promise.set_value_at_thread_exit(0);
286bc2ed2b3Sopenharmony_ci    return;
287bc2ed2b3Sopenharmony_ci}
288bc2ed2b3Sopenharmony_ci
289bc2ed2b3Sopenharmony_cibool NfcService::DoTurnOn()
290bc2ed2b3Sopenharmony_ci{
291bc2ed2b3Sopenharmony_ci    InfoLog("Nfc do turn on: current state %{public}d", nfcState_);
292bc2ed2b3Sopenharmony_ci
293bc2ed2b3Sopenharmony_ci    CancelUnloadNfcSaTimer();
294bc2ed2b3Sopenharmony_ci    UpdateNfcState(KITS::STATE_TURNING_ON);
295bc2ed2b3Sopenharmony_ci    NfcWatchDog nfcWatchDog("DoTurnOn", WAIT_MS_INIT, nciNfccProxy_);
296bc2ed2b3Sopenharmony_ci    nfcWatchDog.Run();
297bc2ed2b3Sopenharmony_ci    // Routing WakeLock acquire
298bc2ed2b3Sopenharmony_ci    if (!nciNfccProxy_->Initialize()) {
299bc2ed2b3Sopenharmony_ci        ErrorLog("Nfc do turn on err");
300bc2ed2b3Sopenharmony_ci        UpdateNfcState(KITS::STATE_OFF);
301bc2ed2b3Sopenharmony_ci        // Routing Wake Lock release
302bc2ed2b3Sopenharmony_ci        nfcWatchDog.Cancel();
303bc2ed2b3Sopenharmony_ci        // Do turn on failed, openRequestCnt and openFailedCnt = 1, others = 0
304bc2ed2b3Sopenharmony_ci        ExternalDepsProxy::GetInstance().WriteOpenAndCloseHiSysEvent(DEFAULT_COUNT, DEFAULT_COUNT,
305bc2ed2b3Sopenharmony_ci            NOT_COUNT, NOT_COUNT);
306bc2ed2b3Sopenharmony_ci        // Record failed event
307bc2ed2b3Sopenharmony_ci        ExternalDepsProxy::GetInstance().WriteNfcFailedHiSysEvent(MainErrorCode::NFC_OPEN_FAILED,
308bc2ed2b3Sopenharmony_ci            SubErrorCode::NCI_RESP_ERROR);
309bc2ed2b3Sopenharmony_ci        return false;
310bc2ed2b3Sopenharmony_ci    }
311bc2ed2b3Sopenharmony_ci    // Routing Wake Lock release
312bc2ed2b3Sopenharmony_ci    nfcWatchDog.Cancel();
313bc2ed2b3Sopenharmony_ci
314bc2ed2b3Sopenharmony_ci    nciVersion_ = nciNfccProxy_->GetNciVersion();
315bc2ed2b3Sopenharmony_ci    InfoLog("Get nci version: ver %{public}d", nciVersion_);
316bc2ed2b3Sopenharmony_ci
317bc2ed2b3Sopenharmony_ci    UpdateNfcState(KITS::STATE_ON);
318bc2ed2b3Sopenharmony_ci
319bc2ed2b3Sopenharmony_ci    NfcWatchDog nfcRoutingManagerDog("RoutingManager", WAIT_ROUTING_INIT, nciNfccProxy_);
320bc2ed2b3Sopenharmony_ci    nfcRoutingManagerDog.Run();
321bc2ed2b3Sopenharmony_ci    screenState_ = (int)eventHandler_->CheckScreenState();
322bc2ed2b3Sopenharmony_ci    nciNfccProxy_->SetScreenStatus(screenState_);
323bc2ed2b3Sopenharmony_ci
324bc2ed2b3Sopenharmony_ci    /* Start polling loop */
325bc2ed2b3Sopenharmony_ci    nfcPollingManager_->StartPollingLoop(true);
326bc2ed2b3Sopenharmony_ci    ceService_->Initialize();
327bc2ed2b3Sopenharmony_ci    ceService_->InitConfigAidRouting(true);
328bc2ed2b3Sopenharmony_ci
329bc2ed2b3Sopenharmony_ci    nfcRoutingManager_->ComputeRoutingParams(ceService_->GetDefaultPaymentType());
330bc2ed2b3Sopenharmony_ci    nfcRoutingManager_->CommitRouting();
331bc2ed2b3Sopenharmony_ci    nfcRoutingManagerDog.Cancel();
332bc2ed2b3Sopenharmony_ci    // Do turn on success, openRequestCnt = 1, others = 0
333bc2ed2b3Sopenharmony_ci    ExternalDepsProxy::GetInstance().WriteOpenAndCloseHiSysEvent(DEFAULT_COUNT, NOT_COUNT, NOT_COUNT, NOT_COUNT);
334bc2ed2b3Sopenharmony_ci    // Record success event
335bc2ed2b3Sopenharmony_ci    ExternalDepsProxy::GetInstance().WriteNfcFailedHiSysEvent(
336bc2ed2b3Sopenharmony_ci        MainErrorCode::NFC_OPEN_SUCCEED, SubErrorCode::DEFAULT_ERR_DEF);
337bc2ed2b3Sopenharmony_ci    return true;
338bc2ed2b3Sopenharmony_ci}
339bc2ed2b3Sopenharmony_ci
340bc2ed2b3Sopenharmony_cibool NfcService::DoTurnOff()
341bc2ed2b3Sopenharmony_ci{
342bc2ed2b3Sopenharmony_ci    InfoLog("Nfc do turn off: current state %{public}d", nfcState_);
343bc2ed2b3Sopenharmony_ci    UpdateNfcState(KITS::STATE_TURNING_OFF);
344bc2ed2b3Sopenharmony_ci
345bc2ed2b3Sopenharmony_ci    /* WatchDog to monitor for Deinitialize failed */
346bc2ed2b3Sopenharmony_ci    NfcWatchDog nfcWatchDog("DoTurnOff", WAIT_MS_SET_ROUTE, nciNfccProxy_);
347bc2ed2b3Sopenharmony_ci    nfcWatchDog.Run();
348bc2ed2b3Sopenharmony_ci
349bc2ed2b3Sopenharmony_ci    bool result = nciNfccProxy_->Deinitialize();
350bc2ed2b3Sopenharmony_ci    InfoLog("Nfcc deinitialize result %{public}d", result);
351bc2ed2b3Sopenharmony_ci
352bc2ed2b3Sopenharmony_ci    nfcWatchDog.Cancel();
353bc2ed2b3Sopenharmony_ci
354bc2ed2b3Sopenharmony_ci    nfcPollingManager_->ResetCurrPollingParams();
355bc2ed2b3Sopenharmony_ci    ceService_->Deinitialize();
356bc2ed2b3Sopenharmony_ci    UpdateNfcState(KITS::STATE_OFF);
357bc2ed2b3Sopenharmony_ci
358bc2ed2b3Sopenharmony_ci    // Do turn off success, closeRequestCnt = 1, others = 0
359bc2ed2b3Sopenharmony_ci    ExternalDepsProxy::GetInstance().WriteOpenAndCloseHiSysEvent(NOT_COUNT, NOT_COUNT, DEFAULT_COUNT, NOT_COUNT);
360bc2ed2b3Sopenharmony_ci    // Record success event
361bc2ed2b3Sopenharmony_ci    ExternalDepsProxy::GetInstance().WriteNfcFailedHiSysEvent(
362bc2ed2b3Sopenharmony_ci        MainErrorCode::NFC_CLOSE_SUCCEED, SubErrorCode::DEFAULT_ERR_DEF);
363bc2ed2b3Sopenharmony_ci    return result;
364bc2ed2b3Sopenharmony_ci}
365bc2ed2b3Sopenharmony_ci
366bc2ed2b3Sopenharmony_civoid NfcService::DoInitialize()
367bc2ed2b3Sopenharmony_ci{
368bc2ed2b3Sopenharmony_ci    eventHandler_->Intialize(tagDispatcher_, ceService_, nfcPollingManager_, nfcRoutingManager_, nciNfccProxy_);
369bc2ed2b3Sopenharmony_ci    ExternalDepsProxy::GetInstance().InitAppList();
370bc2ed2b3Sopenharmony_ci
371bc2ed2b3Sopenharmony_ci    if (ExternalDepsProxy::GetInstance().GetNfcStateFromParam() == KITS::STATE_ON) {
372bc2ed2b3Sopenharmony_ci        InfoLog("should turn nfc on.");
373bc2ed2b3Sopenharmony_ci        ExecuteTask(KITS::TASK_TURN_ON);
374bc2ed2b3Sopenharmony_ci    } else {
375bc2ed2b3Sopenharmony_ci        // 5min later unload nfc_service, if nfc state is off
376bc2ed2b3Sopenharmony_ci        SetupUnloadNfcSaTimer(true);
377bc2ed2b3Sopenharmony_ci    }
378bc2ed2b3Sopenharmony_ci}
379bc2ed2b3Sopenharmony_ci
380bc2ed2b3Sopenharmony_ciint NfcService::SetRegisterCallBack(const sptr<INfcControllerCallback> &callback,
381bc2ed2b3Sopenharmony_ci    const std::string& type, Security::AccessToken::AccessTokenID callerToken)
382bc2ed2b3Sopenharmony_ci{
383bc2ed2b3Sopenharmony_ci    InfoLog("NfcService SetRegisterCallBack");
384bc2ed2b3Sopenharmony_ci    if (callback == nullptr) {
385bc2ed2b3Sopenharmony_ci        ErrorLog("register callback is nullptr");
386bc2ed2b3Sopenharmony_ci        return KITS::ERR_NFC_PARAMETERS;
387bc2ed2b3Sopenharmony_ci    }
388bc2ed2b3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
389bc2ed2b3Sopenharmony_ci    bool isExist = false;
390bc2ed2b3Sopenharmony_ci    NfcStateRegistryRecord record;
391bc2ed2b3Sopenharmony_ci    InfoLog("RecordsSize=%{public}zu,isExist=%{public}d,type=%{public}s",
392bc2ed2b3Sopenharmony_ci        stateRecords_.size(), isExist, type.c_str());
393bc2ed2b3Sopenharmony_ci    for (size_t i = 0; i < stateRecords_.size(); i++) {
394bc2ed2b3Sopenharmony_ci        record = stateRecords_[i];
395bc2ed2b3Sopenharmony_ci        InfoLog("record.type_=%{public}s", record.type_.c_str());
396bc2ed2b3Sopenharmony_ci        if (record.type_.compare(type) == 0 && record.callerToken_ == callerToken) {
397bc2ed2b3Sopenharmony_ci            isExist = true;
398bc2ed2b3Sopenharmony_ci            break;
399bc2ed2b3Sopenharmony_ci        }
400bc2ed2b3Sopenharmony_ci    }
401bc2ed2b3Sopenharmony_ci    InfoLog("isExist=%{public}d", isExist);
402bc2ed2b3Sopenharmony_ci    if (!isExist) {
403bc2ed2b3Sopenharmony_ci        record.type_ = type;
404bc2ed2b3Sopenharmony_ci        record.callerToken_ = callerToken;
405bc2ed2b3Sopenharmony_ci        record.nfcStateChangeCallback_ = callback;
406bc2ed2b3Sopenharmony_ci        stateRecords_.push_back(record);
407bc2ed2b3Sopenharmony_ci        callback->OnNfcStateChanged(nfcState_);
408bc2ed2b3Sopenharmony_ci    }
409bc2ed2b3Sopenharmony_ci    return KITS::ERR_NONE;
410bc2ed2b3Sopenharmony_ci}
411bc2ed2b3Sopenharmony_ci
412bc2ed2b3Sopenharmony_ciint NfcService::RemoveRegisterCallBack(const std::string& type,
413bc2ed2b3Sopenharmony_ci    Security::AccessToken::AccessTokenID callerToken)
414bc2ed2b3Sopenharmony_ci{
415bc2ed2b3Sopenharmony_ci    InfoLog("NfcService RemoveRegisterCallBack");
416bc2ed2b3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
417bc2ed2b3Sopenharmony_ci    int32_t result = KITS::ERR_NFC_PARAMETERS;
418bc2ed2b3Sopenharmony_ci    std::vector<NfcStateRegistryRecord>::iterator it;
419bc2ed2b3Sopenharmony_ci    for (it = stateRecords_.begin(); it != stateRecords_.end(); ++it) {
420bc2ed2b3Sopenharmony_ci        if (it->type_.compare(type) == 0 && it->callerToken_ == callerToken) {
421bc2ed2b3Sopenharmony_ci            InfoLog("NfcService RemoveRegisterCallBack success.");
422bc2ed2b3Sopenharmony_ci            stateRecords_.erase(it);
423bc2ed2b3Sopenharmony_ci            result = KITS::ERR_NONE;
424bc2ed2b3Sopenharmony_ci            break;
425bc2ed2b3Sopenharmony_ci        }
426bc2ed2b3Sopenharmony_ci    }
427bc2ed2b3Sopenharmony_ci    return result;
428bc2ed2b3Sopenharmony_ci}
429bc2ed2b3Sopenharmony_ci
430bc2ed2b3Sopenharmony_ciint NfcService::RemoveAllRegisterCallBack(Security::AccessToken::AccessTokenID callerToken)
431bc2ed2b3Sopenharmony_ci{
432bc2ed2b3Sopenharmony_ci    InfoLog("NfcService RemoveAllRegisterCallBack");
433bc2ed2b3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
434bc2ed2b3Sopenharmony_ci    int32_t result = KITS::ERR_NFC_PARAMETERS;
435bc2ed2b3Sopenharmony_ci    std::vector<NfcStateRegistryRecord>::iterator it;
436bc2ed2b3Sopenharmony_ci    for (it = stateRecords_.begin(); it != stateRecords_.end(); ++it) {
437bc2ed2b3Sopenharmony_ci        if (it->callerToken_ == callerToken) {
438bc2ed2b3Sopenharmony_ci            InfoLog("NfcService RemoveAllRegisterCallBack success.");
439bc2ed2b3Sopenharmony_ci            stateRecords_.erase(it);
440bc2ed2b3Sopenharmony_ci            result = KITS::ERR_NONE;
441bc2ed2b3Sopenharmony_ci            break;
442bc2ed2b3Sopenharmony_ci        }
443bc2ed2b3Sopenharmony_ci    }
444bc2ed2b3Sopenharmony_ci    return result;
445bc2ed2b3Sopenharmony_ci}
446bc2ed2b3Sopenharmony_ci
447bc2ed2b3Sopenharmony_civoid NfcService::UpdateNfcState(int newState)
448bc2ed2b3Sopenharmony_ci{
449bc2ed2b3Sopenharmony_ci    InfoLog("Update nfc state: oldState %{public}d, newState %{public}d", nfcState_, newState);
450bc2ed2b3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
451bc2ed2b3Sopenharmony_ci    if (newState == nfcState_) {
452bc2ed2b3Sopenharmony_ci        return;
453bc2ed2b3Sopenharmony_ci    }
454bc2ed2b3Sopenharmony_ci    nfcState_ = newState;
455bc2ed2b3Sopenharmony_ci
456bc2ed2b3Sopenharmony_ci    ExternalDepsProxy::GetInstance().UpdateNfcState(newState);
457bc2ed2b3Sopenharmony_ci    ExternalDepsProxy::GetInstance().PublishNfcStateChanged(newState);
458bc2ed2b3Sopenharmony_ci    InfoLog("Update nfc state: nfcState_ %{public}d, newState %{public}d succ", nfcState_, newState);
459bc2ed2b3Sopenharmony_ci
460bc2ed2b3Sopenharmony_ci    // notify the nfc state changed by callback to JS APP
461bc2ed2b3Sopenharmony_ci    InfoLog("stateRecords_.size[%{public}zu]", stateRecords_.size());
462bc2ed2b3Sopenharmony_ci    for (size_t i = 0; i < stateRecords_.size(); i++) {
463bc2ed2b3Sopenharmony_ci        NfcStateRegistryRecord record = stateRecords_[i];
464bc2ed2b3Sopenharmony_ci        DebugLog("stateRecords_[%{public}d]:type_=%{public}s ",
465bc2ed2b3Sopenharmony_ci            (int)i, record.type_.c_str());
466bc2ed2b3Sopenharmony_ci        if (record.nfcStateChangeCallback_ != nullptr) {
467bc2ed2b3Sopenharmony_ci            record.nfcStateChangeCallback_->OnNfcStateChanged(newState);
468bc2ed2b3Sopenharmony_ci        }
469bc2ed2b3Sopenharmony_ci    }
470bc2ed2b3Sopenharmony_ci    if (nfcState_ == KITS::STATE_OFF) {
471bc2ed2b3Sopenharmony_ci        // 5min later unload nfc_service, if nfc state is off
472bc2ed2b3Sopenharmony_ci        SetupUnloadNfcSaTimer(true);
473bc2ed2b3Sopenharmony_ci    } else {
474bc2ed2b3Sopenharmony_ci        CancelUnloadNfcSaTimer();
475bc2ed2b3Sopenharmony_ci    }
476bc2ed2b3Sopenharmony_ci}
477bc2ed2b3Sopenharmony_ci
478bc2ed2b3Sopenharmony_ciint NfcService::GetNfcState()
479bc2ed2b3Sopenharmony_ci{
480bc2ed2b3Sopenharmony_ci    InfoLog("start to get nfc state.");
481bc2ed2b3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
482bc2ed2b3Sopenharmony_ci    // 5min later unload nfc_service, if nfc state is off
483bc2ed2b3Sopenharmony_ci    if (nfcState_ == KITS::STATE_OFF) {
484bc2ed2b3Sopenharmony_ci        SetupUnloadNfcSaTimer(false);
485bc2ed2b3Sopenharmony_ci    }
486bc2ed2b3Sopenharmony_ci    InfoLog("get nfc state[%{public}d]", nfcState_);
487bc2ed2b3Sopenharmony_ci    return nfcState_;
488bc2ed2b3Sopenharmony_ci}
489bc2ed2b3Sopenharmony_ci
490bc2ed2b3Sopenharmony_ciint NfcService::GetScreenState()
491bc2ed2b3Sopenharmony_ci{
492bc2ed2b3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
493bc2ed2b3Sopenharmony_ci    return screenState_;
494bc2ed2b3Sopenharmony_ci}
495bc2ed2b3Sopenharmony_ci
496bc2ed2b3Sopenharmony_ciint NfcService::GetNciVersion()
497bc2ed2b3Sopenharmony_ci{
498bc2ed2b3Sopenharmony_ci    return nciVersion_;
499bc2ed2b3Sopenharmony_ci}
500bc2ed2b3Sopenharmony_ci
501bc2ed2b3Sopenharmony_cibool NfcService::IsNfcEnabled()
502bc2ed2b3Sopenharmony_ci{
503bc2ed2b3Sopenharmony_ci    InfoLog("IsNfcEnabled, nfcState_=%{public}d", nfcState_);
504bc2ed2b3Sopenharmony_ci    return (nfcState_ == KITS::STATE_ON);
505bc2ed2b3Sopenharmony_ci}
506bc2ed2b3Sopenharmony_ci
507bc2ed2b3Sopenharmony_civoid NfcService::HandleShutdown()
508bc2ed2b3Sopenharmony_ci{
509bc2ed2b3Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
510bc2ed2b3Sopenharmony_ci    ExternalDepsProxy::GetInstance().UpdateNfcState(nfcState_);
511bc2ed2b3Sopenharmony_ci    InfoLog("device is shutting down, nfcState_ = %{public}d", nfcState_);
512bc2ed2b3Sopenharmony_ci    nciNfccProxy_->Shutdown();
513bc2ed2b3Sopenharmony_ci}
514bc2ed2b3Sopenharmony_ci
515bc2ed2b3Sopenharmony_cibool NfcService::RegNdefMsgCb(const sptr<INdefMsgCallback> &callback)
516bc2ed2b3Sopenharmony_ci{
517bc2ed2b3Sopenharmony_ci    DebugLog("NfcService::RegNdefMsgCb");
518bc2ed2b3Sopenharmony_ci    tagDispatcher_->RegNdefMsgCb(callback);
519bc2ed2b3Sopenharmony_ci    return true;
520bc2ed2b3Sopenharmony_ci}
521bc2ed2b3Sopenharmony_ci
522bc2ed2b3Sopenharmony_civoid NfcService::SetupUnloadNfcSaTimer(bool shouldRestartTimer)
523bc2ed2b3Sopenharmony_ci{
524bc2ed2b3Sopenharmony_ci    TimeOutCallback timeoutCallback = []() { NfcService::UnloadNfcSa(); };
525bc2ed2b3Sopenharmony_ci    if (unloadStaSaTimerId != 0) {
526bc2ed2b3Sopenharmony_ci        if (!shouldRestartTimer) {
527bc2ed2b3Sopenharmony_ci            InfoLog("timer already started.");
528bc2ed2b3Sopenharmony_ci            return;
529bc2ed2b3Sopenharmony_ci        }
530bc2ed2b3Sopenharmony_ci        NfcTimer::GetInstance()->UnRegister(unloadStaSaTimerId);
531bc2ed2b3Sopenharmony_ci        unloadStaSaTimerId = 0;
532bc2ed2b3Sopenharmony_ci    }
533bc2ed2b3Sopenharmony_ci    NfcTimer::GetInstance()->Register(timeoutCallback, unloadStaSaTimerId, TIMEOUT_UNLOAD_NFC_SA);
534bc2ed2b3Sopenharmony_ci}
535bc2ed2b3Sopenharmony_ci
536bc2ed2b3Sopenharmony_civoid NfcService::CancelUnloadNfcSaTimer()
537bc2ed2b3Sopenharmony_ci{
538bc2ed2b3Sopenharmony_ci    if (unloadStaSaTimerId != 0) {
539bc2ed2b3Sopenharmony_ci        NfcTimer::GetInstance()->UnRegister(unloadStaSaTimerId);
540bc2ed2b3Sopenharmony_ci        unloadStaSaTimerId = 0;
541bc2ed2b3Sopenharmony_ci    }
542bc2ed2b3Sopenharmony_ci}
543bc2ed2b3Sopenharmony_ci
544bc2ed2b3Sopenharmony_ci}  // namespace NFC
545bc2ed2b3Sopenharmony_ci}  // namespace OHOS
546