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