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