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(¶ms);
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(¶ms);
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