• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "loghelper.h"
17 #include "app_data_parser.h"
18 #include "external_deps_proxy.h"
19 #include "host_card_emulation_manager.h"
20 #include "ability_manager_client.h"
21 #include "nfc_sdk_common.h"
22 #include "accesstoken_kit.h"
23 #include "hap_token_info.h"
24 #include "ability_manager_service.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27 #include "nfc_ability_connection_callback.h"
28 #include "ability_info.h"
29 
30 namespace OHOS {
31 namespace NFC {
32 #ifdef VENDOR_APPLICATIONS_ENABLED
33 static const int CODE_SEND_FIELD_DEACTIVATE = 0;
34 static const int CODE_SEND_FIELD_ACTIVATE = 1;
35 static const int CODE_SEND_APDU_DATA = 2;
36 #endif
37 const uint32_t SELECT_APDU_HDR_LENGTH = 5;
38 const uint8_t INSTR_SELECT = 0xA4;
39 const uint32_t MINIMUM_AID_LENGTH = 5;
40 const uint8_t SELECT_00 = 0x00;
41 const uint8_t SELECT_P1 = 0x04;
42 const uint32_t INDEX_CLASS_BYTE = 0;
43 const uint32_t INDEX_CHAIN_INSTRUCTION = 1;
44 const uint32_t INDEX_P1 = 2;
45 const uint32_t INDEX_3 = 3;
46 const uint32_t INDEX_AID_LEN = 4;
47 const int32_t USERID = 100;
48 using OHOS::AppExecFwk::ElementName;
HostCardEmulationManager(std::weak_ptr<NfcService> nfcService,std::weak_ptr<NCI::INciCeInterface> nciCeProxy,std::weak_ptr<CeService> ceService)49 HostCardEmulationManager::HostCardEmulationManager(std::weak_ptr<NfcService> nfcService,
50                                                    std::weak_ptr<NCI::INciCeInterface> nciCeProxy,
51                                                    std::weak_ptr<CeService> ceService)
52     : nfcService_(nfcService), nciCeProxy_(nciCeProxy), ceService_(ceService)
53 {
54     hceState_ = HostCardEmulationManager::INITIAL_STATE;
55     queueHceData_.clear();
56     abilityConnection_ = new (std::nothrow) NfcAbilityConnectionCallback();
57 }
~HostCardEmulationManager()58 HostCardEmulationManager::~HostCardEmulationManager()
59 {
60     WarnLog("~HostCardEmulationManager");
61     // both hceState_ and bundleNameToHceCmdRegData_ must be protected in destructing
62     std::lock_guard<std::mutex> lock(hceStateMutex_);
63     std::lock_guard<std::mutex> lockRegInfo(regInfoMutex_);
64     hceState_ = HostCardEmulationManager::INITIAL_STATE;
65     queueHceData_.clear();
66     abilityConnection_ = nullptr;
67     bundleNameToHceCmdRegData_.clear();
68 }
69 
NfcGetBundleMgrProxy()70 sptr<AppExecFwk::IBundleMgr> HostCardEmulationManager::NfcGetBundleMgrProxy()
71 {
72     sptr<ISystemAbilityManager> systemAbilityManager =
73         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
74     if (!systemAbilityManager) {
75         ErrorLog("NfcGetBundleMgrProxy, systemAbilityManager is null");
76         return nullptr;
77     }
78     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
79     if (!remoteObject) {
80         ErrorLog("NfcGetBundleMgrProxy, remoteObject is null");
81         return nullptr;
82     }
83     return iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
84 }
85 
IsFaModeApplication(ElementName & elementName)86 bool HostCardEmulationManager::IsFaModeApplication(ElementName& elementName)
87 {
88     sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = NfcGetBundleMgrProxy();
89     if (bundleMgrProxy == nullptr) {
90         ErrorLog("IsFaModeApplication, bundleMgrProxy is nullptr.");
91         return false;
92     }
93 
94     constexpr auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT;
95     AppExecFwk::AbilityInfo hceAbilityInfo;
96     AAFwk::Want want;
97     want.SetElement(elementName);
98 
99     if (!bundleMgrProxy->QueryAbilityInfo(want, flag, USERID, hceAbilityInfo)) {
100         ErrorLog("IsFaModeApplication QueryAbilityInfo fail!");
101         return false;
102     }
103     InfoLog("IsFaModeApplication QueryAbilityInfo bundleName=[%{public}s], isStageBasedModel=[%{public}d]",
104         hceAbilityInfo.bundleName.c_str(), hceAbilityInfo.isStageBasedModel);
105     if (hceAbilityInfo.isStageBasedModel) {
106         return false;
107     }
108     return true;
109 }
110 
111 /* Handle received APDU data for FA Model Application */
HandleDataForFaApplication(const std::string & aid,ElementName & aidElement,const std::vector<uint8_t> & data)112 void HostCardEmulationManager::HandleDataForFaApplication(const std::string& aid,
113     ElementName& aidElement, const std::vector<uint8_t>& data)
114 {
115     InfoLog("HandleDataForFaApplication hce state is %{public}d.", hceState_);
116     switch (hceState_) {
117         case HostCardEmulationManager::INITIAL_STATE: {
118             InfoLog("got data on state fa INITIAL_STATE");
119             return;
120         }
121         case HostCardEmulationManager::WAIT_FOR_SELECT: {
122             InfoLog("got data on state fa WAIT_FOR_SELECT");
123             HandleDataOnW4SelectForFa(aid, aidElement, data);
124             break;
125         }
126         case HostCardEmulationManager::WAIT_FOR_SERVICE: {
127             InfoLog("got data on state fa w4 service");
128             return;
129         }
130         case HostCardEmulationManager::DATA_TRANSFER: {
131             InfoLog("got data on state fa DATA_TRANSFER");
132             HandleDataOnDataTransferForFa(aid, aidElement, data);
133             break;
134         }
135         case HostCardEmulationManager::WAIT_FOR_DEACTIVATE: {
136             InfoLog("got data on state fa w4 deactivate");
137             return;
138         }
139         default: break;
140     }
141 }
142 /* Handle received APDU data for Stage Model Application */
HandleDataForStageApplication(const std::string & aid,ElementName & aidElement,const std::vector<uint8_t> & data)143 void HostCardEmulationManager::HandleDataForStageApplication(const std::string& aid,
144     ElementName& aidElement, const std::vector<uint8_t>& data)
145 {
146     InfoLog("HandleDataForStageApplication hce state is %{public}d.", hceState_);
147     switch (hceState_) {
148         case HostCardEmulationManager::INITIAL_STATE: {
149             InfoLog("got data on state stage INITIAL_STATE");
150             return;
151         }
152         case HostCardEmulationManager::WAIT_FOR_SELECT: {
153             InfoLog("got data on state stage WAIT_FOR_SELECT");
154             HandleDataOnW4Select(aid, aidElement, data);
155             break;
156         }
157         case HostCardEmulationManager::WAIT_FOR_SERVICE: {
158             InfoLog("got data on state stage w4 service");
159             return;
160         }
161         case HostCardEmulationManager::DATA_TRANSFER: {
162             InfoLog("got data on state stage DATA_TRANSFER");
163             HandleDataOnDataTransfer(aid, aidElement, data);
164             break;
165         }
166         case HostCardEmulationManager::WAIT_FOR_DEACTIVATE: {
167             InfoLog("got data on state stage w4 deactivate");
168             return;
169         }
170         default: break;
171     }
172 }
173 
OnHostCardEmulationDataNfcA(const std::vector<uint8_t> & data)174 void HostCardEmulationManager::OnHostCardEmulationDataNfcA(const std::vector<uint8_t>& data)
175 {
176     if (data.empty()) {
177         InfoLog("onHostCardEmulationDataNfcA: no data");
178         return;
179     }
180     std::string dataStr = KITS::NfcSdkCommon::BytesVecToHexString(&data[0], data.size());
181     InfoLog("onHostCardEmulationDataNfcA: Data Length = %{public}zu; Data as "
182             "String = %{public}s",
183             data.size(), dataStr.c_str());
184 
185 #ifdef VENDOR_APPLICATIONS_ENABLED
186     // send data to vendor
187     sptr<IOnCardEmulationNotifyCb> notifyApduDataCallback =
188         ExternalDepsProxy::GetInstance().GetNotifyCardEmulationCallback();
189     if (notifyApduDataCallback && notifyApduDataCallback->OnCardEmulationNotify(CODE_SEND_APDU_DATA, dataStr)) {
190         InfoLog("onHostCardEmulationDataNfcA: data to vendor");
191         return;
192     }
193 #endif
194 
195     std::string aid = ParseSelectAid(data);
196     InfoLog("onHostCardEmulationDataNfcA: selectAid = %{public}s, state %{public}d", aid.c_str(), hceState_);
197     ElementName aidElement;
198     if (ceService_.expired()) {
199         ErrorLog("ce service expired.");
200         return;
201     }
202     ceService_.lock()->SearchElementByAid(aid, aidElement);
203     /* check aid */
204     if (!aid.empty() && !aidElement.GetBundleName().empty()) {
205         aidElement_ = aidElement;
206     }
207     std::lock_guard<std::mutex> lock(hceStateMutex_);
208 
209     if (IsFaModeApplication(aidElement_)) {
210         HandleDataForFaApplication(aid, aidElement_, data);
211     } else {
212         HandleDataForStageApplication(aid, aidElement_, data);
213     }
214 }
215 
OnCardEmulationActivated()216 void HostCardEmulationManager::OnCardEmulationActivated()
217 {
218     InfoLog("OnCardEmulationActivated: state %{public}d", hceState_);
219     std::lock_guard<std::mutex> lock(hceStateMutex_);
220     hceState_ = HostCardEmulationManager::WAIT_FOR_SELECT;
221     InfoLog("hce state is %{public}d.", hceState_);
222 
223 #ifdef VENDOR_APPLICATIONS_ENABLED
224     // send data to vendor
225     sptr<IOnCardEmulationNotifyCb> notifyApduDataCallback =
226         ExternalDepsProxy::GetInstance().GetNotifyCardEmulationCallback();
227     if (notifyApduDataCallback != nullptr) {
228         std::string data{};
229         notifyApduDataCallback->OnCardEmulationNotify(CODE_SEND_FIELD_ACTIVATE, data);
230     }
231 #endif
232 
233     queueHceData_.clear();
234 }
235 
OnCardEmulationDeactivated()236 void HostCardEmulationManager::OnCardEmulationDeactivated()
237 {
238     InfoLog("OnCardEmulationDeactivated: state %{public}d", hceState_);
239     std::lock_guard<std::mutex> lock(hceStateMutex_);
240     hceState_ = HostCardEmulationManager::INITIAL_STATE;
241     InfoLog("hce state is %{public}d.", hceState_);
242 
243 #ifdef VENDOR_APPLICATIONS_ENABLED
244     // send data to vendor
245     sptr<IOnCardEmulationNotifyCb> notifyApduDataCallback =
246         ExternalDepsProxy::GetInstance().GetNotifyCardEmulationCallback();
247     if (notifyApduDataCallback != nullptr) {
248         std::string data{};
249         notifyApduDataCallback->OnCardEmulationNotify(CODE_SEND_FIELD_DEACTIVATE, data);
250     }
251 #endif
252 
253     queueHceData_.clear();
254     /* clear aidElement_ status */
255     aidElement_.SetBundleName("");
256     if (abilityConnection_ == nullptr) {
257         ErrorLog("OnCardEmulationDeactivated abilityConnection_ nullptr.");
258         return;
259     }
260     ErrCode releaseCallRet = AAFwk::AbilityManagerClient::GetInstance()->ReleaseCall(
261         abilityConnection_, abilityConnection_->GetConnectedElement());
262     InfoLog("Release call end. ret = %{public}d", releaseCallRet);
263 }
264 
HandleDataOnW4Select(const std::string & aid,ElementName & aidElement,const std::vector<uint8_t> & data)265 void HostCardEmulationManager::HandleDataOnW4Select(const std::string& aid, ElementName& aidElement,
266                                                     const std::vector<uint8_t>& data)
267 {
268     bool existService = ExistService(aidElement);
269     if (!aid.empty()) {
270         if (existService) {
271             InfoLog("HandleDataOnW4Select: existing service, try to send data "
272                     "directly.");
273             hceState_ = HostCardEmulationManager::DATA_TRANSFER;
274             InfoLog("hce state is %{public}d.", hceState_);
275             SendDataToService(data);
276             return;
277         } else {
278             InfoLog("HandleDataOnW4Select: try to connect service.");
279             queueHceData_ = std::move(data);
280             DispatchAbilitySingleApp(aidElement);
281             return;
282         }
283     } else if (existService) {
284         InfoLog("HandleDataOnW4Select: existing service, try to send data "
285                 "directly.");
286         hceState_ = HostCardEmulationManager::DATA_TRANSFER;
287         SendDataToService(data);
288         return;
289     } else {
290         InfoLog("no aid got");
291         std::string unknowError = "6F00";
292         if (nciCeProxy_.expired()) {
293             ErrorLog("HandleDataOnW4Select: nciCeProxy_ is nullptr.");
294             return;
295         }
296         nciCeProxy_.lock()->SendRawFrame(unknowError);
297     }
298 }
299 
HandleDataOnW4SelectForFa(const std::string & aid,ElementName & aidElement,const std::vector<uint8_t> & data)300 void HostCardEmulationManager::HandleDataOnW4SelectForFa(const std::string& aid, ElementName& aidElement,
301     const std::vector<uint8_t>& data)
302 {
303     /* check aidElement.BundleName */
304     bool existService = IsFaServiceConnected(aidElement);
305     if (!aid.empty()) {
306         if (existService) {
307             InfoLog("HandleDataOnW4SelectForFa: existing service, try to send data "
308                     "directly.");
309             hceState_ = HostCardEmulationManager::DATA_TRANSFER;
310             InfoLog("hce state is %{public}d.", hceState_);
311             SendDataToFaService(data, aidElement.GetBundleName());
312             return;
313         } else {
314             InfoLog("HandleDataOnW4SelectForFa: try to connect service.");
315             queueHceData_ = std::move(data);
316             DispatchAbilitySingleAppForFaModel(aidElement);
317             return;
318         }
319     } else if (existService) {
320         InfoLog("HandleDataOnW4SelectForFa: existing service, try to send data "
321                 "directly.");
322         hceState_ = HostCardEmulationManager::DATA_TRANSFER;
323         SendDataToFaService(data, aidElement.GetBundleName());
324         return;
325     } else {
326         InfoLog("no aid got");
327         std::string unknowError = "6F00";
328         if (nciCeProxy_.expired()) {
329             ErrorLog("HandleDataOnW4SelectForFa: nciCeProxy_ is nullptr.");
330             return;
331         }
332         nciCeProxy_.lock()->SendRawFrame(unknowError);
333     }
334 }
335 
HandleDataOnDataTransfer(const std::string & aid,ElementName & aidElement,const std::vector<uint8_t> & data)336 void HostCardEmulationManager::HandleDataOnDataTransfer(const std::string& aid, ElementName& aidElement,
337                                                         const std::vector<uint8_t>& data)
338 {
339     bool existService = ExistService(aidElement);
340     if (!aid.empty()) {
341         if (existService) {
342             InfoLog("HandleDataOnDataTransfer: existing service, try to send "
343                     "data directly.");
344             hceState_ = HostCardEmulationManager::DATA_TRANSFER;
345             InfoLog("hce state is %{public}d.", hceState_);
346             SendDataToService(data);
347             return;
348         } else {
349             InfoLog("HandleDataOnDataTransfer: existing service, try to "
350                     "connect service.");
351             queueHceData_ = std::move(data);
352             DispatchAbilitySingleApp(aidElement);
353             return;
354         }
355     } else if (existService) {
356         InfoLog("HandleDataOnDataTransfer: existing service, try to send data "
357                 "directly.");
358         hceState_ = HostCardEmulationManager::DATA_TRANSFER;
359         InfoLog("hce state is %{public}d.", hceState_);
360         SendDataToService(data);
361         return;
362     } else {
363         InfoLog("no service, drop apdu data.");
364     }
365 }
366 
HandleDataOnDataTransferForFa(const std::string & aid,ElementName & aidElement,const std::vector<uint8_t> & data)367 void HostCardEmulationManager::HandleDataOnDataTransferForFa(const std::string& aid, ElementName& aidElement,
368     const std::vector<uint8_t>& data)
369 {
370     /* check aidElement.BundleName */
371     bool existService = IsFaServiceConnected(aidElement);
372     if (!aid.empty()) {
373         if (existService) {
374             InfoLog("HandleDataOnDataTransferforFa: existing service, try to send "
375                     "data directly.");
376             hceState_ = HostCardEmulationManager::DATA_TRANSFER;
377             InfoLog("hce state is %{public}d.", hceState_);
378             SendDataToFaService(data, aidElement.GetBundleName());
379             return;
380         } else {
381             InfoLog("HandleDataOnDataTransferforFa: existing service, try to "
382                     "connect service.");
383             queueHceData_ = std::move(data);
384             DispatchAbilitySingleAppForFaModel(aidElement);
385             return;
386         }
387     } else if (existService) {
388         InfoLog("HandleDataOnDataTransferforFa: existing service, try to send data "
389                 "directly.");
390         hceState_ = HostCardEmulationManager::DATA_TRANSFER;
391         InfoLog("hce state is %{public}d.", hceState_);
392         SendDataToFaService(data, aidElement.GetBundleName());
393         return;
394     } else {
395         InfoLog("no service, drop apdu data.");
396     }
397 }
398 
IsFaServiceConnected(ElementName & aidElement)399 bool HostCardEmulationManager::IsFaServiceConnected(ElementName& aidElement)
400 {
401     std::string bundleName = aidElement.GetBundleName();
402     std::lock_guard<std::mutex> lock(regInfoMutex_);
403     auto it = bundleNameToHceCmdRegData_.find(bundleName);
404     if (it == bundleNameToHceCmdRegData_.end()) {
405         InfoLog("IsFaServiceConnected not register data for %{public}s", bundleName.c_str());
406         return false;
407     }
408     InfoLog("IsFaServiceConnected is Connected:%{public}s", bundleName.c_str());
409     return true;
410 }
411 
ExistService(ElementName & aidElement)412 bool HostCardEmulationManager::ExistService(ElementName& aidElement)
413 {
414     if (abilityConnection_ == nullptr || (!abilityConnection_->ServiceConnected())) {
415         InfoLog("no service connected.");
416         return false;
417     }
418     std::string bundleName = abilityConnection_->GetConnectedElement().GetBundleName();
419     std::lock_guard<std::mutex> lock(regInfoMutex_);
420     auto it = bundleNameToHceCmdRegData_.find(bundleName);
421     if (it == bundleNameToHceCmdRegData_.end()) {
422         ErrorLog("no register data for %{public}s", abilityConnection_->GetConnectedElement().GetURI().c_str());
423         return false;
424     }
425     if (it->second.callback_ == nullptr) {
426         ErrorLog("callback is null");
427         return false;
428     }
429 
430     if (aidElement.GetBundleName().empty()) {
431         InfoLog("aid is empty.");
432         // normal data not select data
433         return true;
434     }
435     // only verify the element name for select data
436     if (aidElement.GetBundleName() == abilityConnection_->GetConnectedElement().GetBundleName() &&
437         aidElement.GetAbilityName() == abilityConnection_->GetConnectedElement().GetAbilityName()) {
438         InfoLog("ability is already connected.");
439         return true;
440     } else {
441         WarnLog("not the same element");
442         return false;
443     }
444 }
445 
ParseSelectAid(const std::vector<uint8_t> & data)446 std::string HostCardEmulationManager::ParseSelectAid(const std::vector<uint8_t>& data)
447 {
448     if (data.empty() || data.size() < SELECT_APDU_HDR_LENGTH + MINIMUM_AID_LENGTH) {
449         InfoLog("invalid data. Data size less than hdr length plus minumum length.");
450         return "";
451     }
452 
453     if (data[INDEX_CLASS_BYTE] == SELECT_00 && data[INDEX_CHAIN_INSTRUCTION] == INSTR_SELECT &&
454         data[INDEX_P1] == SELECT_P1) {
455         if (data[INDEX_3] != SELECT_00) {
456             InfoLog("not supported aid");
457             return "";
458         }
459 
460         uint8_t aidLength = data[INDEX_AID_LEN];
461         if (data.size() < SELECT_APDU_HDR_LENGTH + aidLength) {
462             InfoLog("invalid data. Data size less than hdr length plus aid declared length.");
463             return "";
464         }
465 
466         std::vector<uint8_t> aidVec(data.begin() + SELECT_APDU_HDR_LENGTH,
467                                     data.begin() + SELECT_APDU_HDR_LENGTH + aidLength);
468         return KITS::NfcSdkCommon::BytesVecToHexString(&aidVec[0], aidVec.size());
469     }
470 
471     return "";
472 }
473 
RegHceCmdCallback(const sptr<KITS::IHceCmdCallback> & callback,const std::string & type,Security::AccessToken::AccessTokenID callerToken)474 bool HostCardEmulationManager::RegHceCmdCallback(const sptr<KITS::IHceCmdCallback>& callback,
475                                                  const std::string& type,
476                                                  Security::AccessToken::AccessTokenID callerToken)
477 {
478     if (nfcService_.expired()) {
479         ErrorLog("RegHceCmdCallback: nfcService_ is nullptr.");
480         return false;
481     }
482     if (!nfcService_.lock()->IsNfcEnabled()) {
483         ErrorLog("RegHceCmdCallback: NFC not enabled, do not set");
484         return false;
485     }
486     Security::AccessToken::HapTokenInfo hapTokenInfo;
487     int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callerToken, hapTokenInfo);
488 
489     InfoLog("get hap token info, result = %{public}d", result);
490     if (result) {
491         return false;
492     }
493     if (hapTokenInfo.bundleName.empty()) {
494         ErrorLog("RegHceCmdCallback: not got bundle name");
495         return false;
496     }
497     HostCardEmulationManager::HceCmdRegistryData regData;
498 
499     regData.callback_ = callback;
500     regData.callerToken_ = callerToken;
501     {
502         std::lock_guard<std::mutex> lock(regInfoMutex_);
503         InfoLog("RegHceCmdCallback start, register size =%{public}zu.", bundleNameToHceCmdRegData_.size());
504         if (bundleNameToHceCmdRegData_.find(hapTokenInfo.bundleName) != bundleNameToHceCmdRegData_.end()) {
505             InfoLog("override the register data for %{public}s", hapTokenInfo.bundleName.c_str());
506         }
507         bundleNameToHceCmdRegData_[hapTokenInfo.bundleName] = regData;
508         InfoLog("RegHceCmdCallback end, register size =%{public}zu.", bundleNameToHceCmdRegData_.size());
509     }
510     /* If there is APDU data and the application is the fa model, the data will be sent to the application */
511     ElementName aidElement;
512     std::string abilityName = "";
513     std::vector<AppDataParser::HceAppAidInfo> hceApps;
514     ExternalDepsProxy::GetInstance().GetHceApps(hceApps);
515     for (const AppDataParser::HceAppAidInfo &appAidInfo : hceApps) {
516         if (appAidInfo.element.GetBundleName() == hapTokenInfo.bundleName) {
517             abilityName = appAidInfo.element.GetAbilityName();
518             InfoLog("RegHceCmdCallback: abilityName = [%{public}s]", abilityName.c_str());
519             break;
520         }
521     }
522 
523     if (abilityName.empty()) {
524         ErrorLog("RegHceCmdCallback: abilityName is not find");
525         return false;
526     }
527     aidElement.SetBundleName(hapTokenInfo.bundleName);
528     aidElement.SetAbilityName(abilityName);
529     if (IsFaModeApplication(aidElement)) {
530         HandleQueueDataForFa(aidElement.GetBundleName());
531     }
532     return true;
533 }
534 
SendHostApduData(std::string hexCmdData,bool raw,std::string & hexRespData,Security::AccessToken::AccessTokenID callerToken)535 bool HostCardEmulationManager::SendHostApduData(std::string hexCmdData, bool raw, std::string& hexRespData,
536                                                 Security::AccessToken::AccessTokenID callerToken)
537 {
538     if (nfcService_.expired()) {
539         ErrorLog("SendHostApduData: nfcService_ is nullptr.");
540         return false;
541     }
542     if (!nfcService_.lock()->IsNfcEnabled()) {
543         ErrorLog("SendHostApduData: NFC not enabled, do not send.");
544         return false;
545     }
546     if (IsFaModeApplication(aidElement_)) {
547         if (!IsFaServiceConnected(aidElement_)) {
548             ErrorLog("SendHostApduData fa: not the connected app, do not send.");
549             return false;
550         }
551     } else {
552         if (!IsCorrespondentService(callerToken)) {
553             ErrorLog("SendHostApduData stage: not the connected app, do not send.");
554             return false;
555         }
556     }
557 
558     return nciCeProxy_.lock()->SendRawFrame(hexCmdData);
559 }
IsCorrespondentService(Security::AccessToken::AccessTokenID callerToken)560 bool HostCardEmulationManager::IsCorrespondentService(Security::AccessToken::AccessTokenID callerToken)
561 {
562     Security::AccessToken::HapTokenInfo hapTokenInfo;
563     int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callerToken, hapTokenInfo);
564 
565     InfoLog("get hap token info, result = %{public}d", result);
566 #ifdef VENDOR_APPLICATIONS_ENABLED
567     if (result) {
568         WarnLog("vendor application, allow to send raw frame.");
569         return true;
570     }
571 #endif
572     if (abilityConnection_ == nullptr) {
573         ErrorLog("IsCorrespondentService abilityConnection_ is null");
574         return false;
575     }
576     if (!hapTokenInfo.bundleName.empty() &&
577         hapTokenInfo.bundleName == abilityConnection_->GetConnectedElement().GetBundleName()) {
578         return true;
579     }
580     ErrorLog("SendHostApduData: diff app, the call app %{public}s , the connected app %{public}s",
581              hapTokenInfo.bundleName.c_str(), abilityConnection_->GetConnectedElement().GetBundleName().c_str());
582     return false;
583 }
584 
HandleQueueData()585 void HostCardEmulationManager::HandleQueueData()
586 {
587     std::lock_guard<std::mutex> lock(hceStateMutex_);
588     bool shouldSendQueueData = hceState_ == HostCardEmulationManager::WAIT_FOR_SERVICE && !queueHceData_.empty();
589 
590     std::string queueData = KITS::NfcSdkCommon::BytesVecToHexString(&queueHceData_[0], queueHceData_.size());
591     if (abilityConnection_ == nullptr) {
592         ErrorLog("HandleQueueData abilityConnection_ is null");
593         return;
594     }
595     InfoLog("RegHceCmdCallback queue data %{public}s, hceState= %{public}d, "
596             "service connected= %{public}d",
597             queueData.c_str(), hceState_, abilityConnection_->ServiceConnected());
598     if (shouldSendQueueData) {
599         InfoLog("RegHceCmdCallback should send queue data");
600         hceState_ = HostCardEmulationManager::DATA_TRANSFER;
601         InfoLog("hce state is %{public}d.", hceState_);
602         SendDataToService(queueHceData_);
603         queueHceData_.clear();
604         return;
605     }
606     WarnLog("HandleQueueData can not send the data.");
607 }
608 
HandleQueueDataForFa(const std::string & bundleName)609 void HostCardEmulationManager::HandleQueueDataForFa(const std::string &bundleName)
610 {
611     std::lock_guard<std::mutex> lock(hceStateMutex_);
612     if (queueHceData_.size() == 0) {
613         WarnLog("HandleQueueDataForFa queueHceData is null");
614         return;
615     }
616     std::string queueData = KITS::NfcSdkCommon::BytesVecToHexString(&queueHceData_[0], queueHceData_.size());
617     InfoLog("RegHceCmdCallback queue data for fa %{public}s, hceState= %{public}d, "
618             "service connected= %{public}d",
619             queueData.c_str(), hceState_, abilityConnection_->ServiceConnected());
620     hceState_ = HostCardEmulationManager::WAIT_FOR_SERVICE;
621     bool shouldSendQueueData = hceState_ == HostCardEmulationManager::WAIT_FOR_SERVICE && !queueHceData_.empty();
622     if (shouldSendQueueData) {
623         InfoLog("RegHceCmdCallback should send queue data");
624         hceState_ = HostCardEmulationManager::DATA_TRANSFER;
625         InfoLog("hce state is %{public}d.", hceState_);
626         SendDataToFaService(queueHceData_, bundleName);
627         queueHceData_.clear();
628         return;
629     }
630     WarnLog("HandleQueueDataForFa can not send the data.");
631 }
632 
SendDataToService(const std::vector<uint8_t> & data)633 void HostCardEmulationManager::SendDataToService(const std::vector<uint8_t>& data)
634 {
635     if (abilityConnection_ == nullptr) {
636         ErrorLog("SendDataToService abilityConnection_ is null");
637         return;
638     }
639     std::string bundleName = abilityConnection_->GetConnectedElement().GetBundleName();
640 
641     std::lock_guard<std::mutex> lock(regInfoMutex_);
642     InfoLog("SendDataToService register size = %{public}zu.", bundleNameToHceCmdRegData_.size());
643     auto it = bundleNameToHceCmdRegData_.find(bundleName);
644     if (it == bundleNameToHceCmdRegData_.end()) {
645         ErrorLog("no register data for %{public}s", abilityConnection_->GetConnectedElement().GetURI().c_str());
646         ExternalDepsProxy::GetInstance().WriteNfcHceCmdCbHiSysEvent(bundleName, SubErrorCode::HCE_CMD_CB_NOT_EXIST);
647         return;
648     }
649     if (it->second.callback_ == nullptr) {
650         ErrorLog("callback is null");
651         ExternalDepsProxy::GetInstance().WriteNfcHceCmdCbHiSysEvent(bundleName, SubErrorCode::HCE_CMD_CB_NULL);
652         return;
653     }
654     it->second.callback_->OnCeApduData(data);
655     ExternalDepsProxy::GetInstance().WriteNfcHceCmdCbHiSysEvent(bundleName, SubErrorCode::HCE_CMD_CB_EXIST);
656 }
657 
SendDataToFaService(const std::vector<uint8_t> & data,const std::string & bundleName)658 void HostCardEmulationManager::SendDataToFaService(const std::vector<uint8_t>& data, const std::string &bundleName)
659 {
660     std::lock_guard<std::mutex> lock(regInfoMutex_);
661     InfoLog("SendDataToFaService register size = %{public}zu.", bundleNameToHceCmdRegData_.size());
662     auto it = bundleNameToHceCmdRegData_.find(bundleName);
663     if (it == bundleNameToHceCmdRegData_.end()) {
664         ErrorLog("no register data for %{public}s", abilityConnection_->GetConnectedElement().GetURI().c_str());
665         return;
666     }
667     if (it->second.callback_ == nullptr) {
668         ErrorLog("callback is null");
669         return;
670     }
671     it->second.callback_->OnCeApduData(data);
672 }
673 
DispatchAbilitySingleApp(ElementName & element)674 bool HostCardEmulationManager::DispatchAbilitySingleApp(ElementName& element)
675 {
676     if (abilityConnection_ == nullptr) {
677         ErrorLog("DispatchAbilitySingleApp abilityConnection_ is null");
678         return false;
679     }
680     abilityConnection_->SetHceManager(shared_from_this());
681     if (element.GetBundleName().empty() && !nciCeProxy_.expired()) {
682         ErrorLog("DispatchAbilitySingleApp element empty");
683         std::string aidNotFound = "6A82";
684         nciCeProxy_.lock()->SendRawFrame(aidNotFound);
685         return false;
686     }
687 
688     InfoLog("DispatchAbilitySingleApp for element %{public}s", element.GetURI().c_str());
689     AAFwk::Want want;
690     want.SetElement(element);
691 
692     if (AAFwk::AbilityManagerClient::GetInstance() == nullptr) {
693         ErrorLog("DispatchAbilitySingleApp AbilityManagerClient is null");
694         return false;
695     }
696     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbilityByCall(want, abilityConnection_);
697     InfoLog("DispatchAbilitySingleApp call StartAbility end. ret = %{public}d", err);
698     if (err == ERR_NONE) {
699         hceState_ = HostCardEmulationManager::WAIT_FOR_SERVICE;
700         InfoLog("hce state is %{public}d.", hceState_);
701         ExternalDepsProxy::GetInstance().WriteHceSwipeResultHiSysEvent(element.GetBundleName(), DEFAULT_COUNT);
702 
703         NfcFailedParams params;
704         ExternalDepsProxy::GetInstance().BuildFailedParams(params, MainErrorCode::HCE_SWIPE_CARD,
705                                                            SubErrorCode::DEFAULT_ERR_DEF);
706         params.appPackageName = element.GetBundleName();
707         ExternalDepsProxy::GetInstance().WriteNfcFailedHiSysEvent(&params);
708         return true;
709     }
710     return false;
711 }
712 
DispatchAbilitySingleAppForFaModel(ElementName & element)713 bool HostCardEmulationManager::DispatchAbilitySingleAppForFaModel(ElementName& element)
714 {
715     if (element.GetBundleName().empty() && !nciCeProxy_.expired()) {
716         ErrorLog("DispatchAbilitySingleAppForFaModel element empty");
717         std::string aidNotFound = "6A82";
718         nciCeProxy_.lock()->SendRawFrame(aidNotFound);
719         return false;
720     }
721 
722     InfoLog("DispatchAbilitySingleAppForFaModel for element %{public}s", element.GetURI().c_str());
723     AAFwk::Want want;
724     want.SetElement(element);
725 
726     if (AAFwk::AbilityManagerClient::GetInstance() == nullptr) {
727         ErrorLog("DispatchAbilitySingleAppForFaModel AbilityManagerClient is null");
728         return false;
729     }
730     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
731     InfoLog("DispatchAbilitySingleAppForFaModel call StartAbility end. ret = %{public}d", err);
732     if (err == ERR_NONE) {
733         hceState_ = HostCardEmulationManager::WAIT_FOR_SERVICE;
734         InfoLog("hce state is %{public}d.", hceState_);
735         ExternalDepsProxy::GetInstance().WriteHceSwipeResultHiSysEvent(element.GetBundleName(), DEFAULT_COUNT);
736 
737         NfcFailedParams params;
738         ExternalDepsProxy::GetInstance().BuildFailedParams(params, MainErrorCode::HCE_SWIPE_CARD,
739                                                            SubErrorCode::DEFAULT_ERR_DEF);
740         params.appPackageName = element.GetBundleName();
741         ExternalDepsProxy::GetInstance().WriteNfcFailedHiSysEvent(&params);
742         return true;
743     }
744     return false;
745 }
746 
UnRegHceCmdCallback(const std::string & type,Security::AccessToken::AccessTokenID callerToken)747 bool HostCardEmulationManager::UnRegHceCmdCallback(const std::string& type,
748                                                    Security::AccessToken::AccessTokenID callerToken)
749 {
750     return EraseHceCmdCallback(callerToken);
751 }
EraseHceCmdCallback(Security::AccessToken::AccessTokenID callerToken)752 bool HostCardEmulationManager::EraseHceCmdCallback(Security::AccessToken::AccessTokenID callerToken)
753 {
754     Security::AccessToken::HapTokenInfo hapTokenInfo;
755     int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callerToken, hapTokenInfo);
756 
757     InfoLog("get hap token info, result = %{public}d", result);
758     if (result) {
759         return false;
760     }
761     if (hapTokenInfo.bundleName.empty()) {
762         ErrorLog("EraseHceCmdCallback: not got bundle name");
763         return false;
764     }
765     std::lock_guard<std::mutex> lock(regInfoMutex_);
766     InfoLog("EraseHceCmdCallback start, register size =%{public}zu.", bundleNameToHceCmdRegData_.size());
767     if (bundleNameToHceCmdRegData_.find(hapTokenInfo.bundleName) != bundleNameToHceCmdRegData_.end()) {
768         InfoLog("unregister data for  %{public}s", hapTokenInfo.bundleName.c_str());
769     }
770     bundleNameToHceCmdRegData_.erase(hapTokenInfo.bundleName);
771     InfoLog("EraseHceCmdCallback end, register size =%{public}zu.", bundleNameToHceCmdRegData_.size());
772     return true;
773 }
774 
UnRegAllCallback(Security::AccessToken::AccessTokenID callerToken)775 bool HostCardEmulationManager::UnRegAllCallback(Security::AccessToken::AccessTokenID callerToken)
776 {
777     return EraseHceCmdCallback(callerToken);
778 }
779 } // namespace NFC
780 } // namespace OHOS