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