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