• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "tag_nci_adapter.h"
16 
17 #include "loghelper.h"
18 #include "nci_adaptations.h"
19 #include "nfc_brcm_defs.h"
20 #include "nfc_config.h"
21 #include "nfc_sdk_common.h"
22 #include "nfcc_host.h"
23 #include "nfcc_nci_adapter.h"
24 #include "rw_int.h"
25 
26 namespace OHOS {
27 namespace NFC {
28 namespace NCI {
29 static const int DEFAULT_TIMEOUT = 1000;
30 static const int ISO14443_3A_DEFAULT_TIMEOUT = 618;   // NfcA
31 static const int ISO14443_3B_DEFAULT_TIMEOUT = 1000;  // NfcB
32 static const int ISO14443_4_DEFAULT_TIMEOUT = 618;    // ISO-DEP
33 static const int FELICA_DEFAULT_TIMEOUT = 255;        // Felica
34 static const int ISO15693_DEFAULT_TIMEOUT = 1000;     // NfcV
35 static const int NDEF_DEFAULT_TIMEOUT = 1000;
36 static const int NDEF_FORMATABLE_DEFAULT_TIMEOUT = 1000;
37 static const int MIFARE_CLASSIC_DEFAULT_TIMEOUT = 618;  // MifareClassic
38 static const int MIFARE_UL_DEFAULT_TIMEOUT = 618;       // MifareUltralight
39 static const int POS_NFCF_STSTEM_CODE_HIGH = 8;
40 static const int POS_NFCF_STSTEM_CODE_LOW = 9;
41 static const int TOPAZ512_MAX_MESSAGE_SIZE = 462;
42 static const int TOPAZ96_MAX_MESSAGE_SIZE = 90;
43 static const int SENSF_RES_LENGTH = 8;
44 static const int SENS_RES_LENGTH = 2;
45 static const int SENSB_RES_POLL_POS = 4;
46 static const int SYSTEM_CODE_SHIFT = 8;
47 static const int F_POLL_LENGTH = 10;
48 static const int I93_POLL_LENGTH = 2;
49 static const int I93_ACT_LENGTH = 2;
50 static const int MIFACE_DES_FIRE_RESPONSE_LENGTH = 9;
51 static const int NDEF_FORMATTABLE_1ST = 0x91;
52 static const int NDEF_FORMATTABLE_2ND = 0xAF;
53 static const int NDEF_MODE_READ_ONLY = 1;
54 static const int NDEF_MODE_READ_WRITE = 2;
55 static const int NDEF_MODE_UNKNOWN = 3;
56 static uint8_t RW_TAG_SLP_REQ[] = {0x50, 0x00};
57 static uint8_t RW_DESELECT_REQ[] = {0xC2};
58 static const unsigned int INVALID_TAG_INDEX = 0xFF;
59 
60 std::mutex TagNciAdapter::rfDiscoveryMutex_;
61 OHOS::NFC::SynchronizeEvent TagNciAdapter::transceiveEvent_;
62 OHOS::NFC::SynchronizeEvent TagNciAdapter::filedCheckEvent_;
63 OHOS::NFC::SynchronizeEvent TagNciAdapter::readNdefEvent_;
64 OHOS::NFC::SynchronizeEvent TagNciAdapter::writeNdefEvent_;
65 OHOS::NFC::SynchronizeEvent TagNciAdapter::formatNdefEvent_;
66 OHOS::NFC::SynchronizeEvent TagNciAdapter::checkNdefEvent_;
67 OHOS::NFC::SynchronizeEvent TagNciAdapter::selectEvent_;
68 OHOS::NFC::SynchronizeEvent TagNciAdapter::activatedEvent_;
69 OHOS::NFC::SynchronizeEvent TagNciAdapter::deactivatedEvent_;
70 
71 bool TagNciAdapter::isTagFieldOn_ = true;
72 int TagNciAdapter::connectedProtocol_ = NCI_PROTOCOL_UNKNOWN;
73 int TagNciAdapter::connectedTargetType_ = TagHost::TARGET_TYPE_UNKNOWN;
74 int TagNciAdapter::connectedTagDiscId_ = -1;
75 bool TagNciAdapter::isReconnecting_ = false;
76 bool TagNciAdapter::isInTransceive_ = false;
77 int TagNciAdapter::t1tMaxMessageSize_ = 0;
78 std::string TagNciAdapter::receivedData_ = "";
79 int TagNciAdapter::lastNdefCheckedStatus_ = NFA_STATUS_FAILED;
80 bool TagNciAdapter::isNdefCapable_ = false;
81 int TagNciAdapter::lastCheckedNdefSize_ = 0;
82 int TagNciAdapter::lastCheckedNdefMaxSize_ = 0;
83 int TagNciAdapter::lastCheckedNdefMode_ = NDEF_MODE_UNKNOWN;
84 bool TagNciAdapter::isNdefWriteSuccess_ = false;
85 bool TagNciAdapter::isNdefFormatSuccess_ = false;
86 unsigned short int TagNciAdapter::ndefTypeHandle_ = NFA_HANDLE_INVALID;
87 std::string TagNciAdapter::readNdefData = "";
88 std::shared_ptr<INfcNci> TagNciAdapter::nciAdaptations_ = std::make_shared<NciAdaptations>();
89 
TagNciAdapter()90 TagNciAdapter::TagNciAdapter()
91     : techListIndex_(0),
92       tagActivatedProtocol_(NCI_PROTOCOL_UNKNOWN),
93       isFelicaLite_(false),
94       isMifareUltralight_(false),
95       isMifareDESFire_(false),
96       presChkOption_(NFA_RW_PRES_CHK_DEFAULT),
97       isMultiTag_(false),
98       discRstEvtNum_(0),
99       discNtfIndex_(0),
100       multiTagTmpTechIdx_(0),
101       selectedTagIdx_(0)
102 {
103     ResetTimeout();
104     if (NfcConfig::hasKey(NAME_PRESENCE_CHECK_ALGORITHM)) {
105         presChkOption_ = NfcConfig::getUnsigned(NAME_PRESENCE_CHECK_ALGORITHM);
106     } else {
107         presChkOption_ = NFA_RW_PRES_CHK_ISO_DEP_NAK; // to be removed when read config from hdiimpl enabled
108     }
109 }
110 
~TagNciAdapter()111 TagNciAdapter::~TagNciAdapter()
112 {
113     tagTechList_.clear();
114     tagRfDiscIdList_.clear();
115     tagActivatedProtocols_.clear();
116     tagPollBytes_.clear();
117     tagActivatedBytes_.clear();
118     tagDiscIdListOfDiscResult_.clear();
119     tagProtocolsOfDiscResult_.clear();
120     techListIndex_ = 0;
121     tagActivatedProtocol_ = NCI_PROTOCOL_UNKNOWN;
122     isFelicaLite_ = false;
123     isMifareUltralight_ = false;
124     isMifareDESFire_ = false;
125     isMultiTag_ = false;
126     discRstEvtNum_ = 0;
127     discNtfIndex_ = 0;
128     multiTagTmpTechIdx_ = 0;
129     selectedTagIdx_ = 0;
130 };
131 
GetInstance()132 TagNciAdapter& TagNciAdapter::GetInstance()
133 {
134     static TagNciAdapter tagNciAdapter;
135     return tagNciAdapter;
136 }
137 
NdefCallback(unsigned char event,tNFA_NDEF_EVT_DATA * eventData)138 void TagNciAdapter::NdefCallback(unsigned char event, tNFA_NDEF_EVT_DATA* eventData)
139 {
140     DebugLog("TagNciAdapter::NdefCallback");
141     switch (event) {
142         case NFA_NDEF_REGISTER_EVT: {
143             DebugLog("NdefCallback: NFA_NDEF_REGISTER_EVT; status=0x%{public}X; handle=0x%{public}X",
144                      eventData->ndef_reg.status,
145                      eventData->ndef_reg.ndef_type_handle);
146             ndefTypeHandle_ = eventData->ndef_reg.ndef_type_handle;
147             break;
148         }
149         case NFA_NDEF_DATA_EVT: {
150             DebugLog("NdefCallback: NFA_NDEF_DATA_EVT; data_len = %u", eventData->ndef_data.len);
151             uint32_t ndefDataLen = eventData->ndef_data.len;
152             readNdefData = KITS::NfcSdkCommon::BytesVecToHexString(
153                 eventData->ndef_data.p_data, ndefDataLen);
154             break;
155         }
156         default: {
157             DebugLog("%{public}s: Unknown event %{public}u", "NdefCallback", event);
158             break;
159         }
160     }
161 }
162 
RegisterNdefHandler()163 void TagNciAdapter::RegisterNdefHandler()
164 {
165     DebugLog("TagNciAdapter::RegisterNdefHandler");
166     ndefTypeHandle_ = NFA_HANDLE_INVALID;
167     nciAdaptations_->NfaRegisterNDefTypeHandler(true, NFA_TNF_DEFAULT, (unsigned char*)"", 0, NdefCallback);
168 }
169 
Connect(int discId,int protocol,int tech)170 tNFA_STATUS TagNciAdapter::Connect(int discId, int protocol, int tech)
171 {
172     DebugLog("TagNciAdapter::Connect: discId: %{public}d, protocol: %{public}d, tech: %{public}d",
173         discId, protocol, tech);
174     if (!IsTagActive()) {
175         return NFA_STATUS_BUSY;
176     }
177     NFC::SynchronizeGuard guard(selectEvent_);
178     tNFA_INTF_TYPE rfInterface = GetRfInterface(protocol);
179     rfDiscoveryMutex_.lock();
180     tNFA_STATUS status = nciAdaptations_->NfaSelect((uint8_t)discId, (tNFA_NFC_PROTOCOL)protocol, rfInterface);
181     if (status != NFA_STATUS_OK) {
182         ErrorLog("TagNciAdapter::Connect: select fail; error = 0x%{public}X", status);
183         rfDiscoveryMutex_.unlock();
184         return status;
185     }
186     if (selectEvent_.Wait(DEFAULT_TIMEOUT) == false) {
187         ErrorLog("TagNciAdapter::Connect: Time out when select");
188         status = nciAdaptations_->NfaDeactivate(false);
189         if (status != NFA_STATUS_OK) {
190             ErrorLog("TagNciAdapter::Connect: deactivate failed, error = 0x%{public}X", status);
191         }
192         rfDiscoveryMutex_.unlock();
193         return NFA_STATUS_TIMEOUT;  // time out
194     }
195     connectedProtocol_ = protocol;
196     connectedTagDiscId_ = discId;
197     connectedTargetType_ = tech;
198     rfDiscoveryMutex_.unlock();
199     return NFA_STATUS_OK;
200 }
201 
Disconnect()202 bool TagNciAdapter::Disconnect()
203 {
204     DebugLog("TagNciAdapter::Disconnect");
205     rfDiscoveryMutex_.lock();
206     tNFA_STATUS status = nciAdaptations_->NfaDeactivate(false);
207     if (status != NFA_STATUS_OK) {
208         ErrorLog("TagNciAdapter::Disconnect: deactivate failed; error = 0x%{public}X", status);
209     }
210     connectedProtocol_ = NCI_PROTOCOL_UNKNOWN;
211     connectedTagDiscId_ = -1;
212     connectedTargetType_ = TagHost::TARGET_TYPE_UNKNOWN;
213     isReconnecting_ = false;
214     ResetTag();
215     rfDiscoveryMutex_.unlock();
216     return (status == NFA_STATUS_OK);
217 }
218 
Reselect(tNFA_INTF_TYPE rfInterface)219 bool TagNciAdapter::Reselect(tNFA_INTF_TYPE rfInterface) // should set rfDiscoveryMutex_ outer when called
220 {
221     tNFA_INTF_TYPE currInterface = GetRfInterface(connectedProtocol_);
222     DebugLog("TagNciAdapter::Reselect: target interface: %{public}d, currInterface = %{public}d"
223         "connectedProtocol_ = %{public}d", rfInterface, currInterface, connectedProtocol_);
224     tNFA_STATUS status = NFA_STATUS_FAILED;
225     if ((currInterface == NFA_INTERFACE_FRAME) &&
226         (NfccNciAdapter::GetInstance().GetNciVersion() >= NCI_VERSION_2_0)) {
227         NFC::SynchronizeGuard guard(activatedEvent_);
228         if (connectedProtocol_ == NFA_PROTOCOL_T2T) {
229             status = nciAdaptations_->NfaSendRawFrame(RW_TAG_SLP_REQ, sizeof(RW_TAG_SLP_REQ), 0);
230         } else if (connectedProtocol_ == NFA_PROTOCOL_ISO_DEP) {
231             status = nciAdaptations_->NfaSendRawFrame(RW_DESELECT_REQ, sizeof(RW_DESELECT_REQ), 0);
232         } else {
233             DebugLog("TagNciAdapter::Reselect: do nothing");
234             return false;
235         }
236         DebugLog("TagNciAdapter::Reselect: SendRawFrame seccess, status = 0x%{public}X", status);
237         activatedEvent_.Wait(4); // this request do not have response, so no need to wait for callback
238         isReconnecting_ = true;
239         status = nciAdaptations_->NfaDeactivate(true);
240         if (status != NFA_STATUS_OK) {
241             ErrorLog("TagNciAdapter::Reselect: deactivate failed, err = 0x%{public}X", status);
242         }
243         isReconnecting_ = false;
244     }
245     return (status == NFA_STATUS_OK);
246 }
247 
SendReselectReqIfNeed(int protocol,int tech)248 bool TagNciAdapter::SendReselectReqIfNeed(int protocol, int tech)
249 {
250     DebugLog("TagNciAdapter::SendReselectReqIfNeed: protocol = %{public}d, tech = %{public}d",
251         protocol, tech);
252     if (protocol != NCI_PROTOCOL_ISO_DEP && protocol != NCI_PROTOCOL_MIFARE) {
253         DebugLog("TagNciAdapter::SendReselectReqIfNeed: do nothing for non isodep protocol");
254         return false;
255     }
256 
257     if (tech == TagHost::TARGET_TYPE_ISO14443_3A || tech == TagHost::TARGET_TYPE_ISO14443_3B) {
258         return Reselect(NFA_INTERFACE_FRAME);
259     } else if (tech == TagHost::TARGET_TYPE_MIFARE_CLASSIC) {
260         return Reselect(NFA_INTERFACE_MIFARE);
261     } else {
262         return Reselect(NFA_INTERFACE_ISO_DEP);
263     }
264     return true;
265 }
266 
IsReconnecting()267 bool TagNciAdapter::IsReconnecting()
268 {
269     return isReconnecting_;
270 }
271 
NfaDeactivateAndSelect(int discId,int protocol)272 bool TagNciAdapter::NfaDeactivateAndSelect(int discId, int protocol)
273 {
274     {
275         NFC::SynchronizeGuard guard(deactivatedEvent_);
276         tNFA_STATUS status = nciAdaptations_->NfaDeactivate(true);
277         if (status != NFA_STATUS_OK) {
278             ErrorLog("NfaDeactivateAndSelect, NfaDeactivate1 failed, status=0x%{public}X", status);
279             return false;
280         }
281         deactivatedEvent_.Wait(DEFAULT_TIMEOUT);
282     }
283     {
284         NFC::SynchronizeGuard guard(activatedEvent_);
285         tNFA_STATUS status = nciAdaptations_->NfaSelect((uint8_t)discId, (tNFA_NFC_PROTOCOL)protocol,
286             GetRfInterface(protocol));
287         if (status != NFA_STATUS_OK) {
288             ErrorLog("NfaDeactivateAndSelect NfaSelect failed, status=0x%{public}X", status);
289             return false;
290         }
291         if (activatedEvent_.Wait(DEFAULT_TIMEOUT) == false) {
292             ErrorLog("NfaDeactivateAndSelect, Timeout when NfaSelect.");
293             status = nciAdaptations_->NfaDeactivate(false);
294             if (status != NFA_STATUS_OK) {
295                 ErrorLog("NfaDeactivateAndSelect, NfaDeactivate2 failed, status=0x%{public}X", status);
296             }
297             return false;
298         }
299     }
300     return true;
301 }
302 
Reconnect(int discId,int protocol,int tech,bool restart)303 bool TagNciAdapter::Reconnect(int discId, int protocol, int tech, bool restart)
304 {
305     if (!IsTagActive()) {
306         return false;
307     }
308     rfDiscoveryMutex_.lock();
309     if (connectedProtocol_ == protocol && !restart) {
310         rfDiscoveryMutex_.unlock();
311         return true;
312     }
313     if (!SendReselectReqIfNeed(protocol, tech)) {
314         rfDiscoveryMutex_.unlock();
315         return false;
316     }
317     isReconnecting_ = true;
318     if (!NfaDeactivateAndSelect(discId, protocol)) {
319         isReconnecting_ = false;
320         rfDiscoveryMutex_.unlock();
321         return false;
322     }
323     isReconnecting_ = false;
324     {
325         NFC::SynchronizeGuard guard(activatedEvent_);
326         activatedEvent_.Wait(DEFAULT_TIMEOUT);
327     }
328     connectedProtocol_ = protocol;
329     connectedTagDiscId_ = discId;
330     connectedTargetType_ = tech;
331     rfDiscoveryMutex_.unlock();
332     return true;
333 }
334 
Transceive(std::string & request,std::string & response)335 int TagNciAdapter::Transceive(std::string& request, std::string& response)
336 {
337     if (!IsTagActive()) {
338         return NFA_STATUS_BUSY;
339     }
340     tNFA_STATUS status = NFA_STATUS_FAILED;
341     isInTransceive_ = true;
342     bool retry = false;
343     do {
344         NFC::SynchronizeGuard guard(transceiveEvent_);
345         uint16_t length = KITS::NfcSdkCommon::GetHexStrBytesLen(request);
346         std::vector<unsigned char> requestInCharVec;
347         KITS::NfcSdkCommon::HexStringToBytes(request, requestInCharVec);
348         InfoLog("TagNciAdapter::Transceive: requestLen = %{public}d", length);
349         receivedData_ = "";
350         status = nciAdaptations_->NfaSendRawFrame(static_cast<uint8_t *>(requestInCharVec.data()),
351             length, NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY);
352         if (status != NFA_STATUS_OK) {
353             ErrorLog("TagNciAdapter::Transceive: fail send; error=%{public}d", status);
354             break;
355         }
356         int transceiveTimeout = GetTimeout(connectedTargetType_);
357         bool wait = transceiveEvent_.Wait(transceiveTimeout);
358         if (!wait) {
359             ErrorLog("TagNciAdapter::Transceive: wait response timeout");
360             status = NFA_STATUS_TIMEOUT;
361             break;
362         }
363         response = receivedData_;
364         InfoLog("TagNciAdapter::Transceive: rsp len = %{public}d", KITS::NfcSdkCommon::GetHexStrBytesLen(response));
365 
366         // not auth
367         if (retry) {
368             retry = false;
369         } else if (connectedProtocol_ == NFA_PROTOCOL_MIFARE &&
370             KITS::NfcSdkCommon::GetByteFromHexStr(request, 0) != 0x60 &&
371             KITS::NfcSdkCommon::GetByteFromHexStr(request, 0) != 0x61 &&
372             KITS::NfcSdkCommon::GetHexStrBytesLen(response) == 1 &&
373             KITS::NfcSdkCommon::GetByteFromHexStr(response, 0) != 0x00) {
374             DebugLog("NFA_PROTOCOL_MIFARE retry");
375             retry = true;
376         }
377 
378         if (!retry) {
379             if (connectedProtocol_ == NFA_PROTOCOL_MIFARE &&
380                 KITS::NfcSdkCommon::GetHexStrBytesLen(response) == 1 &&
381                 KITS::NfcSdkCommon::GetByteFromHexStr(response, 0) != 0x00) {
382                 DebugLog("Ready to reconnect");
383                 Reconnect(connectedTagDiscId_, NFA_PROTOCOL_MIFARE, TagHost::TARGET_TYPE_MIFARE_CLASSIC, true);
384             }
385         }
386     } while (retry);
387     isInTransceive_ = false;
388     return status;
389 }
390 
HandleTranceiveData(unsigned char status,unsigned char * data,int dataLen)391 void TagNciAdapter::HandleTranceiveData(unsigned char status, unsigned char* data, int dataLen)
392 {
393     DebugLog("TagNciAdapter::HandleTranceiveData");
394     NFC::SynchronizeGuard guard(transceiveEvent_);
395     if (status == NFA_STATUS_OK || status == NFA_STATUS_CONTINUE) {
396         receivedData_ = KITS::NfcSdkCommon::BytesVecToHexString(data, dataLen);
397     }
398     if (status == NFA_STATUS_OK) {
399         transceiveEvent_.NotifyOne();
400     }
401 }
402 
IsTagFieldOn()403 bool TagNciAdapter::IsTagFieldOn()
404 {
405     if (!IsTagActive()) {
406         return false;
407     }
408     if (isInTransceive_) {
409         return true;
410     }
411     if (!rfDiscoveryMutex_.try_lock()) {
412         return true;
413     }
414 
415     {
416         NFC::SynchronizeGuard guard(filedCheckEvent_);
417         tNFA_STATUS status = nciAdaptations_->NfaRwPresenceCheck(presChkOption_);
418         if (status == NFA_STATUS_OK) {
419             if (filedCheckEvent_.Wait(DEFAULT_TIMEOUT) == false) {
420                 DebugLog("filed on check timeout...");
421                 isTagFieldOn_ = false;
422             }
423         }
424     }
425     rfDiscoveryMutex_.unlock();
426     return isTagFieldOn_;
427 }
428 
HandleFieldCheckResult(unsigned char status)429 void TagNciAdapter::HandleFieldCheckResult(unsigned char status)
430 {
431     NFC::SynchronizeGuard guard(filedCheckEvent_);
432     isTagFieldOn_ = (status == NFA_STATUS_OK);
433     filedCheckEvent_.NotifyOne();
434 }
435 
HandleSelectResult()436 void TagNciAdapter::HandleSelectResult()
437 {
438     DebugLog("TagNciAdapter::HandleSelectResult");
439     {
440         NFC::SynchronizeGuard guard(selectEvent_);
441         selectEvent_.NotifyOne();
442     }
443 }
444 
HandleActivatedResult()445 void TagNciAdapter::HandleActivatedResult()
446 {
447     DebugLog("TagNciAdapter::HandleActivatedResult");
448     {
449         NFC::SynchronizeGuard guard(activatedEvent_);
450         activatedEvent_.NotifyOne();
451     }
452 }
453 
HandleDeactivatedResult()454 void TagNciAdapter::HandleDeactivatedResult()
455 {
456     DebugLog("TagNciAdapter::HandleDeactivatedResult");
457     {
458         NFC::SynchronizeGuard guard(deactivatedEvent_);
459         deactivatedEvent_.NotifyOne();
460     }
461 }
462 
ResetTagFieldOnFlag()463 void TagNciAdapter::ResetTagFieldOnFlag()
464 {
465     DebugLog("TagNciAdapter::ResetTagFieldOnFlag");
466     isTagFieldOn_ = true;
467 }
468 
GetTimeout(int technology) const469 int TagNciAdapter::GetTimeout(int technology) const
470 {
471     int timeout = DEFAULT_TIMEOUT;
472     if (technology > 0 && technology <= MAX_NUM_TECHNOLOGY) {
473         timeout = technologyTimeoutsTable_[technology];
474     } else {
475         WarnLog("TagNciAdapter::GetTimeout, Unknown technology");
476     }
477     return timeout;
478 }
479 
ResetTimeout()480 void TagNciAdapter::ResetTimeout()
481 {
482     technologyTimeoutsTable_[TagHost::TARGET_TYPE_ISO14443_3A] = ISO14443_3A_DEFAULT_TIMEOUT;
483     technologyTimeoutsTable_[TagHost::TARGET_TYPE_ISO14443_3B] = ISO14443_3B_DEFAULT_TIMEOUT;
484     technologyTimeoutsTable_[TagHost::TARGET_TYPE_ISO14443_4] = ISO14443_4_DEFAULT_TIMEOUT;
485     technologyTimeoutsTable_[TagHost::TARGET_TYPE_FELICA] = FELICA_DEFAULT_TIMEOUT;
486     technologyTimeoutsTable_[TagHost::TARGET_TYPE_V] = ISO15693_DEFAULT_TIMEOUT;
487     technologyTimeoutsTable_[TagHost::TARGET_TYPE_NDEF] = NDEF_DEFAULT_TIMEOUT;
488     technologyTimeoutsTable_[TagHost::TARGET_TYPE_NDEF_FORMATABLE] = NDEF_FORMATABLE_DEFAULT_TIMEOUT;
489     technologyTimeoutsTable_[TagHost::TARGET_TYPE_MIFARE_CLASSIC] = MIFARE_CLASSIC_DEFAULT_TIMEOUT;
490     technologyTimeoutsTable_[TagHost::TARGET_TYPE_MIFARE_UL] = MIFARE_UL_DEFAULT_TIMEOUT;
491 }
492 
SetReadOnly() const493 bool TagNciAdapter::SetReadOnly() const
494 {
495     DebugLog("TagNciAdapter::SetReadOnly");
496     unsigned char status = nciAdaptations_->NfaRwSetTagReadOnly(true);
497     if (status == NCI_STATUS_REJECTED) {
498         status = nciAdaptations_->NfaRwSetTagReadOnly(false);
499         if (status != NCI_STATUS_OK) {
500             return false;
501         }
502     } else if (status != NCI_STATUS_OK) {
503         return false;
504     }
505     return true;
506 }
507 
ReadNdef(std::string & response)508 void TagNciAdapter::ReadNdef(std::string& response)
509 {
510     DebugLog("TagNciAdapter::ReadNdef");
511     if (!IsTagActive()) {
512         ErrorLog("ReadNdef, IsTagActive failed");
513         return;
514     }
515     rfDiscoveryMutex_.lock();
516     readNdefData = "";
517     NFC::SynchronizeGuard guard(readNdefEvent_);
518     if (lastCheckedNdefSize_ > 0) {
519         tNFA_STATUS status = nciAdaptations_->NfaRwReadNdef();
520         if (status != NFA_STATUS_OK) {
521             ErrorLog("ReadNdef, Read ndef fail");
522             return;
523         }
524         readNdefEvent_.Wait();
525 
526         if (KITS::NfcSdkCommon::GetHexStrBytesLen(readNdefData) > 0) {
527             response = readNdefData;
528         }
529     }
530     rfDiscoveryMutex_.unlock();
531     return;
532 }
533 
HandleReadComplete(unsigned char status)534 void TagNciAdapter::HandleReadComplete(unsigned char status)
535 {
536     DebugLog("TagNciAdapter::HandleReadComplete");
537     NFC::SynchronizeGuard guard(readNdefEvent_);
538     if (status != NFA_STATUS_OK) {
539         ErrorLog("Read ndef fail");
540         readNdefData = "";
541     }
542     readNdefEvent_.NotifyOne();
543 }
544 
WriteNdef(std::string & ndefMessage)545 bool TagNciAdapter::WriteNdef(std::string& ndefMessage)
546 {
547     DebugLog("TagNciAdapter::WriteNdef");
548     if (!IsTagActive()) {
549         ErrorLog("WriteNdef, IsTagActive failed");
550         return false;
551     }
552     rfDiscoveryMutex_.lock();
553     isNdefWriteSuccess_ = false;
554     tNFA_STATUS status = NFA_STATUS_FAILED;
555     const uint32_t maxBufferSize = 1024;
556     uint8_t buffer[maxBufferSize] = {0};
557     uint32_t curDataSize = 0;
558     NFC::SynchronizeGuard guard(writeNdefEvent_);
559     uint32_t length = KITS::NfcSdkCommon::GetHexStrBytesLen(ndefMessage);
560     unsigned char data[length];
561     for (uint32_t i = 0; i < length; i++) {
562         data[i] = KITS::NfcSdkCommon::GetByteFromHexStr(ndefMessage, i);
563     }
564     if (lastNdefCheckedStatus_ == NFA_STATUS_FAILED) {
565         if (isNdefCapable_) {
566             DebugLog("Format ndef first");
567             this->FormatNdef();
568         }
569         status = nciAdaptations_->NfaRwWriteNdef(data, length);
570     } else if (length == 0) {
571         DebugLog("Create and write an empty ndef message");
572         nciAdaptations_->NdefMsgInit(buffer, maxBufferSize, &curDataSize);
573         nciAdaptations_->NdefMsgAddRec(buffer, maxBufferSize, &curDataSize, NDEF_TNF_EMPTY, NULL, 0, NULL, 0, NULL, 0);
574         status = nciAdaptations_->NfaRwWriteNdef(buffer, curDataSize);
575     } else {
576         status = nciAdaptations_->NfaRwWriteNdef(data, length);
577     }
578 
579     if (status == NCI_STATUS_OK) {
580         writeNdefEvent_.Wait();
581     } else {
582         ErrorLog("WriteNdef, Write ndef fail");
583     }
584     rfDiscoveryMutex_.unlock();
585     return isNdefWriteSuccess_;
586 }
587 
HandleWriteComplete(unsigned char status)588 void TagNciAdapter::HandleWriteComplete(unsigned char status)
589 {
590     DebugLog("TagNciAdapter::HandleWriteComplete");
591     NFC::SynchronizeGuard guard(writeNdefEvent_);
592     isNdefWriteSuccess_ = (status == NFA_STATUS_OK);
593     writeNdefEvent_.NotifyOne();
594 }
595 
FormatNdef()596 bool TagNciAdapter::FormatNdef()
597 {
598     DebugLog("TagNciAdapter::FormatNdef");
599     if (!IsTagActive()) {
600         return false;
601     }
602     NFC::SynchronizeGuard guard(formatNdefEvent_);
603     isNdefFormatSuccess_ = false;
604     tNFA_STATUS status = nciAdaptations_->NfaRwFormatTag();
605     if (status == NFA_STATUS_OK) {
606         formatNdefEvent_.Wait();
607         if (!isNdefFormatSuccess_) {
608             status = NFA_STATUS_FAILED;
609         }
610     } else {
611         ErrorLog("Format Ndef error, status= %{public}d", status);
612     }
613     return (status == NFA_STATUS_OK);
614 }
615 
HandleFormatComplete(unsigned char status)616 void TagNciAdapter::HandleFormatComplete(unsigned char status)
617 {
618     DebugLog("TagNciAdapter::HandleFormatComplete");
619     NFC::SynchronizeGuard guard(formatNdefEvent_);
620     isNdefFormatSuccess_ = (status == NFA_STATUS_OK);
621     formatNdefEvent_.NotifyOne();
622 }
623 
IsNdefFormatable()624 bool TagNciAdapter::IsNdefFormatable()
625 {
626     DebugLog("TagNciAdapter::IsNdefFormatable");
627     return isNdefFormatSuccess_;
628 }
629 
IsNdefMsgContained(std::vector<int> & ndefInfo)630 bool TagNciAdapter::IsNdefMsgContained(std::vector<int>& ndefInfo)
631 {
632     DebugLog("TagNciAdapter::IsNdefMsgContained");
633     if (!IsTagActive()) {
634         return false;
635     }
636     rfDiscoveryMutex_.lock();
637     NFC::SynchronizeGuard guard(checkNdefEvent_);
638     tNFA_STATUS status = NFA_STATUS_FAILED;
639     isReconnecting_ = false;
640 
641     status = nciAdaptations_->NfaRwDetectNdef();
642     if (status != NFA_STATUS_OK) {
643         ErrorLog("NFA_RwDetectNDef failed, status: %{public}d", status);
644         rfDiscoveryMutex_.unlock();
645         return false;
646     }
647     if (checkNdefEvent_.Wait(DEFAULT_TIMEOUT) == false) {
648         ErrorLog("TagNciAdapter::IsNdefMsgContained time out");
649         rfDiscoveryMutex_.unlock();
650         return false;
651     }
652 
653     if (isNdefCapable_) {
654         if (connectedProtocol_ == NFA_PROTOCOL_T1T) {
655             ndefInfo.push_back(t1tMaxMessageSize_);
656         } else {
657             ndefInfo.push_back(lastCheckedNdefMaxSize_);
658         }
659         ndefInfo.push_back(lastCheckedNdefMode_);
660     }
661     rfDiscoveryMutex_.unlock();
662     return isNdefCapable_;
663 }
664 
HandleNdefCheckResult(unsigned char status,int currentSize,uint32_t flag,int maxSize)665 void TagNciAdapter::HandleNdefCheckResult(unsigned char status, int currentSize, uint32_t flag, int maxSize)
666 {
667     DebugLog("TagNciAdapter::HandleNdefCheckResult");
668     auto uFlag = static_cast<unsigned char>(flag & 0xFF);
669     if (uFlag & RW_NDEF_FL_FORMATED) {
670         DebugLog("Ndef check: Tag formated for NDEF");
671     }
672     if (uFlag & RW_NDEF_FL_SUPPORTED) {
673         DebugLog("Ndef check: NDEF supported by the tag");
674     }
675     if (uFlag & RW_NDEF_FL_UNKNOWN) {
676         DebugLog("Ndef check: Unable to find if tag is ndef capable/formated/read only");
677     }
678     if (uFlag & RW_NDEF_FL_FORMATABLE) {
679         DebugLog("Ndef check: Tag supports format operation");
680     }
681     NFC::SynchronizeGuard guard(checkNdefEvent_);
682     if (uFlag & RW_NDEF_FL_READ_ONLY) {
683         DebugLog("Ndef check: Tag is read only");
684         lastCheckedNdefMode_ = NDEF_MODE_READ_ONLY;
685     } else {
686         lastCheckedNdefMode_ = NDEF_MODE_READ_WRITE;
687     }
688 
689     lastNdefCheckedStatus_ = status;
690     if (lastNdefCheckedStatus_ != NFA_STATUS_OK && lastNdefCheckedStatus_ != NFA_STATUS_TIMEOUT) {
691         lastNdefCheckedStatus_ = NFA_STATUS_FAILED;
692         isNdefCapable_ = false;
693     }
694 
695     isNdefCapable_ = false;
696     if (lastNdefCheckedStatus_ == NFA_STATUS_OK) {
697         lastCheckedNdefSize_ = currentSize;
698         lastCheckedNdefMaxSize_ = maxSize;
699         isNdefCapable_ = true;
700     } else if (lastNdefCheckedStatus_ == NFA_STATUS_FAILED) {
701         lastCheckedNdefSize_ = 0;
702         lastCheckedNdefMaxSize_ = 0;
703         if ((uFlag & RW_NDEF_FL_SUPPORTED) && ((uFlag & RW_NDEF_FL_UNKNOWN) == 0)) {
704             DebugLog("Tag is ndef capable");
705             isNdefCapable_ = true;
706         }
707     } else {
708         lastCheckedNdefSize_ = 0;
709         lastCheckedNdefMaxSize_ = 0;
710     }
711     checkNdefEvent_.NotifyOne();
712 }
713 
IsDiscTypeA(char discType) const714 bool TagNciAdapter::IsDiscTypeA(char discType) const
715 {
716     if (discType == NCI_DISCOVERY_TYPE_POLL_A) {
717         return true;
718     }
719     if (discType == NCI_DISCOVERY_TYPE_POLL_A_ACTIVE) {
720         return true;
721     }
722     if (discType == NCI_DISCOVERY_TYPE_LISTEN_A) {
723         return true;
724     }
725     if (discType == NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE) {
726         return true;
727     }
728     return false;
729 }
730 
IsDiscTypeB(char discType) const731 bool TagNciAdapter::IsDiscTypeB(char discType) const
732 {
733     if (discType == NCI_DISCOVERY_TYPE_POLL_B) {
734         return true;
735     }
736     if (discType == NFC_DISCOVERY_TYPE_POLL_B_PRIME) {
737         return true;
738     }
739     if (discType == NCI_DISCOVERY_TYPE_LISTEN_B) {
740         return true;
741     }
742     if (discType == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
743         return true;
744     }
745     return false;
746 }
747 
IsDiscTypeF(char discType) const748 bool TagNciAdapter::IsDiscTypeF(char discType) const
749 {
750     if (discType == NCI_DISCOVERY_TYPE_POLL_F) {
751         return true;
752     }
753     if (discType == NCI_DISCOVERY_TYPE_POLL_F_ACTIVE) {
754         return true;
755     }
756     if (discType == NCI_DISCOVERY_TYPE_LISTEN_F) {
757         return true;
758     }
759     if (discType == NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE) {
760         return true;
761     }
762     return false;
763 }
764 
IsDiscTypeV(char discType) const765 bool TagNciAdapter::IsDiscTypeV(char discType) const
766 {
767     if (discType == NCI_DISCOVERY_TYPE_POLL_V) {
768         return true;
769     }
770     if (discType == NCI_DISCOVERY_TYPE_LISTEN_ISO15693) {
771         return true;
772     }
773     return false;
774 }
775 
GetTechFromData(tNFA_ACTIVATED activated)776 void TagNciAdapter::GetTechFromData(tNFA_ACTIVATED activated)
777 {
778     int tech[MAX_NUM_TECHNOLOGY];
779     if (activated.activate_ntf.protocol == NCI_PROTOCOL_T1T) {
780         tech[techListIndex_] = TagHost::TARGET_TYPE_ISO14443_3A;
781     } else if (activated.activate_ntf.protocol == NCI_PROTOCOL_T2T) {
782         tech[techListIndex_] = TagHost::TARGET_TYPE_ISO14443_3A;
783         // can also be mifare
784         if (activated.activate_ntf.rf_tech_param.param.pa.nfcid1[0] == MANUFACTURER_ID_NXP &&
785             (activated.activate_ntf.rf_tech_param.param.pa.sel_rsp == SAK_MIFARE_UL_1 ||
786             activated.activate_ntf.rf_tech_param.param.pa.sel_rsp == SAK_MIFARE_UL_2)) {
787             InfoLog("TagNciAdapter::GetTechFromData: MifareUltralight");
788             techListIndex_++;
789             tech[techListIndex_] = TagHost::TARGET_TYPE_MIFARE_UL;
790         }
791     } else if (activated.activate_ntf.protocol == NCI_PROTOCOL_T3BT) {
792         tech[techListIndex_] = TagHost::TARGET_TYPE_ISO14443_3B;
793     } else if (activated.activate_ntf.protocol == NCI_PROTOCOL_T3T) {
794         tech[techListIndex_] = TagHost::TARGET_TYPE_FELICA;
795     } else if (activated.activate_ntf.protocol == NCI_PROTOCOL_ISO_DEP) {
796         tech[techListIndex_] = TagHost::TARGET_TYPE_ISO14443_4;
797         // A OR B
798         char discType = activated.activate_ntf.rf_tech_param.mode;
799         if (IsDiscTypeA(discType)) {
800             techListIndex_++;
801             tech[techListIndex_] = TagHost::TARGET_TYPE_ISO14443_3A;
802         } else if (IsDiscTypeB(discType)) {
803             techListIndex_++;
804             tech[techListIndex_] = TagHost::TARGET_TYPE_ISO14443_3B;
805         }
806     } else if (activated.activate_ntf.protocol == NCI_PROTOCOL_15693) {
807         tech[techListIndex_] = TagHost::TARGET_TYPE_V;
808     } else if (activated.activate_ntf.protocol == NFC_PROTOCOL_MIFARE) {
809         InfoLog("TagNciAdapter::GetTechFromData: MifareClassic");
810         tech[techListIndex_] = TagHost::TARGET_TYPE_ISO14443_3A;
811 
812         techListIndex_++;
813         tech[techListIndex_] = TagHost::TARGET_TYPE_MIFARE_CLASSIC;
814     } else {
815         tech[techListIndex_] = TagHost::TARGET_TYPE_UNKNOWN;
816     }
817     techListIndex_++;
818 
819     int tagRfDiscId = activated.activate_ntf.rf_disc_id;
820     int tagNtfProtocol = activated.activate_ntf.protocol;
821     for (uint32_t i = multiTagTmpTechIdx_; i < techListIndex_; i++) {
822         tagTechList_.push_back(tech[i]);
823         tagRfDiscIdList_.push_back(tagRfDiscId);
824         tagActivatedProtocols_.push_back(tagNtfProtocol);
825         InfoLog("GetTechFromData: index = %{public}d, tech = %{public}d, RfDiscId = %{public}d, protocol = %{public}d",
826                 i, tech[i], tagRfDiscId, tagNtfProtocol);
827     }
828 }
829 
GetUidFromData(tNFA_ACTIVATED activated) const830 std::string TagNciAdapter::GetUidFromData(tNFA_ACTIVATED activated) const
831 {
832     std::string uid;
833     tNFC_RF_TECH_PARAMS nfcRfTechParams = activated.activate_ntf.rf_tech_param;
834     char discType = nfcRfTechParams.mode;
835     if (IsDiscTypeA(discType)) {
836         int nfcid1Len = nfcRfTechParams.param.pa.nfcid1_len;
837         uid = KITS::NfcSdkCommon::BytesVecToHexString(nfcRfTechParams.param.pa.nfcid1, nfcid1Len);
838     } else if (IsDiscTypeB(discType)) {
839         uid = KITS::NfcSdkCommon::BytesVecToHexString(nfcRfTechParams.param.pb.nfcid0, NFC_NFCID0_MAX_LEN);
840     } else if (IsDiscTypeF(discType)) {
841         uid = KITS::NfcSdkCommon::BytesVecToHexString(nfcRfTechParams.param.pf.nfcid2, NFC_NFCID2_LEN);
842     } else if (IsDiscTypeV(discType)) {
843         unsigned char* i93Uid = activated.params.i93.uid;
844         unsigned char i93UidReverse[I93_UID_BYTE_LEN];
845         for (int i = 0; i < I93_UID_BYTE_LEN; i++) {
846             i93UidReverse[i] = i93Uid[I93_UID_BYTE_LEN - i - 1];
847         }
848         uid = KITS::NfcSdkCommon::BytesVecToHexString(i93UidReverse, I93_UID_BYTE_LEN);
849     } else {
850         uid = "";
851     }
852     return uid;
853 }
854 
GetTechPollForTypeB(tNFC_RF_TECH_PARAMS nfcRfTechParams,int tech)855 std::string TagNciAdapter::GetTechPollForTypeB(tNFC_RF_TECH_PARAMS nfcRfTechParams, int tech)
856 {
857     std::string techPoll = "";
858     if (tech == TagHost::TARGET_TYPE_ISO14443_3B) {
859         int length = nfcRfTechParams.param.pb.sensb_res_len;
860         if (length > NFC_NFCID0_MAX_LEN) {
861             length = length - NFC_NFCID0_MAX_LEN;
862         } else {
863             WarnLog("sensb_res_len %{public}d error", length);
864             length = 0;
865         }
866         techPoll = KITS::NfcSdkCommon::BytesVecToHexString(
867             nfcRfTechParams.param.pb.sensb_res + SENSB_RES_POLL_POS, length);
868     }
869     return techPoll;
870 }
871 
GetTechPollFromData(tNFA_ACTIVATED activated)872 void TagNciAdapter::GetTechPollFromData(tNFA_ACTIVATED activated)
873 {
874     std::string techPoll = "";
875     tNFC_RF_TECH_PARAMS nfcRfTechParams = activated.activate_ntf.rf_tech_param;
876     char discType = nfcRfTechParams.mode;
877     for (uint32_t i = multiTagTmpTechIdx_; i < techListIndex_; i++) {
878         if (IsDiscTypeA(discType)) {
879             techPoll = KITS::NfcSdkCommon::BytesVecToHexString(
880                 nfcRfTechParams.param.pa.sens_res, SENS_RES_LENGTH);
881         } else if (IsDiscTypeB(discType)) {
882             techPoll = GetTechPollForTypeB(nfcRfTechParams, tagTechList_[i]);
883         } else if (IsDiscTypeF(discType)) {
884             unsigned char cTechPoll[F_POLL_LENGTH];
885             unsigned char *sensfRes = nfcRfTechParams.param.pf.sensf_res;
886 
887             // save the pmm value.
888             for (int j = 0; j < SENSF_RES_LENGTH; j++) {
889                 cTechPoll[j] = static_cast<unsigned char>(sensfRes[j + SENSF_RES_LENGTH]);
890             }
891 
892             // save the system code.
893             if (activated.params.t3t.num_system_codes > 0) {
894                 unsigned short *pSystemCodes = activated.params.t3t.p_system_codes;
895                 cTechPoll[POS_NFCF_STSTEM_CODE_HIGH] =
896                     static_cast<unsigned char>(*pSystemCodes >> SYSTEM_CODE_SHIFT);
897                 cTechPoll[POS_NFCF_STSTEM_CODE_LOW] = static_cast<unsigned char>(*pSystemCodes);
898             }
899             techPoll = KITS::NfcSdkCommon::BytesVecToHexString(cTechPoll, F_POLL_LENGTH);
900         } else if (IsDiscTypeV(discType)) {
901             unsigned char cTechPoll[2] = {activated.params.i93.afi, activated.params.i93.dsfid};
902             techPoll = KITS::NfcSdkCommon::BytesVecToHexString(cTechPoll, I93_POLL_LENGTH);
903         } else {
904             techPoll = "";
905         }
906         tagPollBytes_.push_back(techPoll);
907     }
908 }
909 
GetTechActForIsoDep(tNFA_ACTIVATED activated,tNFC_RF_TECH_PARAMS nfcRfTechParams,int tech) const910 std::string TagNciAdapter::GetTechActForIsoDep(tNFA_ACTIVATED activated,
911                                                tNFC_RF_TECH_PARAMS nfcRfTechParams,
912                                                int tech) const
913 {
914     std::string techAct = "";
915     if (tech == TagHost::TARGET_TYPE_ISO14443_4) {
916         char discType = nfcRfTechParams.mode;
917         if (IsDiscTypeA(discType)) {
918             if (activated.activate_ntf.intf_param.type == NFC_INTERFACE_ISO_DEP) {
919                 tNFC_INTF_PA_ISO_DEP paIso = activated.activate_ntf.intf_param.intf_param.pa_iso;
920                 techAct = (paIso.his_byte_len > 0) ? KITS::NfcSdkCommon::BytesVecToHexString(
921                     paIso.his_byte, paIso.his_byte_len) : "";
922             }
923         } else if (IsDiscTypeB(discType)) {
924             if (activated.activate_ntf.intf_param.type == NFC_INTERFACE_ISO_DEP) {
925                 tNFC_INTF_PB_ISO_DEP pbIso = activated.activate_ntf.intf_param.intf_param.pb_iso;
926                 techAct = (pbIso.hi_info_len > 0) ? KITS::NfcSdkCommon::BytesVecToHexString(
927                     pbIso.hi_info, pbIso.hi_info_len) : "";
928             }
929         }
930     } else if (tech == TagHost::TARGET_TYPE_ISO14443_3A) {
931         techAct = KITS::NfcSdkCommon::UnsignedCharToHexString(nfcRfTechParams.param.pa.sel_rsp);
932     } else {
933         // do nothing
934     }
935     return techAct;
936 }
937 
GetTechActFromData(tNFA_ACTIVATED activated)938 void TagNciAdapter::GetTechActFromData(tNFA_ACTIVATED activated)
939 {
940     unsigned char protocol = activated.activate_ntf.protocol;
941     tNFC_RF_TECH_PARAMS nfcRfTechParams = activated.activate_ntf.rf_tech_param;
942     for (uint32_t i = multiTagTmpTechIdx_; i < techListIndex_; i++) {
943         std::string techAct = "";
944         if (protocol == NCI_PROTOCOL_T1T) {
945             techAct = KITS::NfcSdkCommon::UnsignedCharToHexString(nfcRfTechParams.param.pa.sel_rsp);
946         } else if (protocol == NCI_PROTOCOL_T2T) {
947             techAct = KITS::NfcSdkCommon::UnsignedCharToHexString(nfcRfTechParams.param.pa.sel_rsp);
948         } else if (protocol == NCI_PROTOCOL_T3T) {
949             techAct = "";
950         } else if (protocol == NCI_PROTOCOL_ISO_DEP) {
951             techAct = GetTechActForIsoDep(activated, nfcRfTechParams, tagTechList_[i]);
952         } else if (protocol == NCI_PROTOCOL_15693) {
953             unsigned char techActivated[2] = {activated.params.i93.afi, activated.params.i93.dsfid};
954             techAct = KITS::NfcSdkCommon::BytesVecToHexString(techActivated, I93_ACT_LENGTH);
955         } else if (protocol == NFC_PROTOCOL_MIFARE) {
956             techAct = KITS::NfcSdkCommon::UnsignedCharToHexString(nfcRfTechParams.param.pa.sel_rsp);
957         } else {
958             // do nothing
959         }
960         tagActivatedBytes_.push_back(techAct);
961     }
962 }
963 
ParseSpecTagType(tNFA_ACTIVATED activated)964 void TagNciAdapter::ParseSpecTagType(tNFA_ACTIVATED activated)
965 {
966     // parse for FelicaLite
967     if (activated.activate_ntf.protocol == NFC_PROTOCOL_T3T) {
968         int i = 0;
969         while (i < activated.params.t3t.num_system_codes) {
970             if (activated.params.t3t.p_system_codes[i++] == T3T_SYSTEM_CODE_FELICA_LITE) {
971                 isFelicaLite_ = true;
972                 break;
973             }
974         }
975     }
976     // parse for MifareUltralight, NFC Digital Protocol, see SENS_RES and SEL_RES
977     if (activated.activate_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
978         if ((activated.activate_ntf.rf_tech_param.param.pa.sens_res[0] == ATQA_MIFARE_UL_0) &&
979             (activated.activate_ntf.rf_tech_param.param.pa.sens_res[1] == ATQA_MIFARE_UL_1) &&
980             ((activated.activate_ntf.rf_tech_param.param.pa.sel_rsp == SAK_MIFARE_UL_1) ||
981             (activated.activate_ntf.rf_tech_param.param.pa.sel_rsp == SAK_MIFARE_UL_2)) &&
982             (activated.activate_ntf.rf_tech_param.param.pa.nfcid1[0] == MANUFACTURER_ID_NXP)) {
983             isMifareUltralight_ = true;
984         }
985     }
986 
987     // parse for MifareDESFire, one sak byte and 2 ATQA bytes
988     if ((activated.activate_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
989         (activated.activate_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
990         (activated.activate_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE)) {
991         if ((activated.activate_ntf.rf_tech_param.param.pa.sens_res[0] == ATQA_MIFARE_DESFIRE_0) &&
992             (activated.activate_ntf.rf_tech_param.param.pa.sens_res[1] == ATQA_MIFARE_DESFIRE_1) &&
993             (activated.activate_ntf.rf_tech_param.param.pa.sel_rsp == SAK_MIFARE_DESFIRE)) {
994             isMifareDESFire_ = true;
995         }
996     }
997     InfoLog("isFelicaLite_ = %{public}d, isMifareUltralight_ = %{public}d, isMifareDESFire_ = %{public}d",
998         isFelicaLite_, isMifareUltralight_, isMifareDESFire_);
999 }
1000 
BuildTagInfo(const tNFA_CONN_EVT_DATA * eventData)1001 void TagNciAdapter::BuildTagInfo(const tNFA_CONN_EVT_DATA* eventData)
1002 {
1003     DebugLog("TagNciAdapter::BuildTagInfo, discRstEvtNum_ = %{public}d", discRstEvtNum_);
1004     if (techListIndex_ >= MAX_NUM_TECHNOLOGY) {
1005         return;
1006     }
1007     if (multiTagTmpTechIdx_ < (MAX_NUM_TECHNOLOGY - 1)) {
1008         techListIndex_ = multiTagTmpTechIdx_;
1009     }
1010 
1011     tNFA_ACTIVATED activated = eventData->activated;
1012     GetTechFromData(activated); // techListIndex_ is increased in this func
1013     std::string tagUid = GetUidFromData(activated);
1014     GetTechPollFromData(activated);
1015     GetTechActFromData(activated);
1016 
1017     tagActivatedProtocol_ = activated.activate_ntf.protocol;
1018     t1tMaxMessageSize_ = GetT1tMaxMessageSize(activated);
1019     ParseSpecTagType(activated);
1020 
1021     if (discRstEvtNum_ == 0) {
1022         multiTagTmpTechIdx_ = 0;
1023         std::unique_ptr<NCI::ITagHost> tagHost = std::make_unique<NCI::TagHost>(tagTechList_,
1024             tagRfDiscIdList_, tagActivatedProtocols_, tagUid, tagPollBytes_, tagActivatedBytes_);
1025         NfccHost::TagDiscovered(std::move(tagHost));
1026     } else {
1027         multiTagTmpTechIdx_ = techListIndex_;
1028         InfoLog("TagNciAdapter::BuildTagInfo, select next tag if exists");
1029     }
1030     InfoLog("TagNciAdapter::BuildTagInfo, multiTagTmpTechIdx_ = %{public}d, techListIndex_ = %{public}d",
1031         multiTagTmpTechIdx_, techListIndex_);
1032 }
1033 
ResetTag()1034 void TagNciAdapter::ResetTag()
1035 {
1036     DebugLog("TagNciAdapter::ResetTag");
1037     tagTechList_.clear();
1038     tagRfDiscIdList_.clear();
1039     tagActivatedProtocols_.clear();
1040     tagPollBytes_.clear();
1041     tagActivatedBytes_.clear();
1042     tagDiscIdListOfDiscResult_.clear();
1043     tagProtocolsOfDiscResult_.clear();
1044     techListIndex_ = 0;
1045     multiTagTmpTechIdx_ = 0;
1046     tagActivatedProtocol_ = NCI_PROTOCOL_UNKNOWN;
1047     isFelicaLite_ = false;
1048     isMifareUltralight_ = false;
1049     isMifareDESFire_ = false;
1050     isMultiTag_ = false;
1051     discRstEvtNum_ = 0;
1052     discNtfIndex_ = 0;
1053     multiTagTmpTechIdx_ = 0;
1054     selectedTagIdx_ = 0;
1055     ResetTimeout();
1056 }
1057 
HandleDiscResult(tNFA_CONN_EVT_DATA * eventData)1058 void TagNciAdapter::HandleDiscResult(tNFA_CONN_EVT_DATA* eventData)
1059 {
1060     tNFC_RESULT_DEVT& discoveryNtf = eventData->disc_result.discovery_ntf;
1061     DebugLog("TagNciAdapter::HandleDiscResult, discId: %{public}d, protocol: %{public}d",
1062         discoveryNtf.rf_disc_id, discoveryNtf.protocol);
1063 
1064     tagDiscIdListOfDiscResult_.push_back(discoveryNtf.rf_disc_id);
1065     tagProtocolsOfDiscResult_.push_back(discoveryNtf.protocol);
1066     if (discoveryNtf.more == NCI_DISCOVER_NTF_MORE) {
1067         return;
1068     }
1069 
1070     uint32_t index = MAX_NUM_TECHNOLOGY;
1071     for (std::size_t i = 0; i < tagProtocolsOfDiscResult_.size(); i++) {
1072         if (tagProtocolsOfDiscResult_[i] != NFA_PROTOCOL_NFC_DEP) {
1073             index = i;
1074             break;
1075         }
1076     }
1077 
1078     if (index >= MAX_NUM_TECHNOLOGY) {
1079         DebugLog("Has technology NFA_PROTOCOL_NFC_DEP only, don't handle it.");
1080         return;
1081     }
1082 
1083     // get the rf interface based on the found technology.
1084     tNFA_INTF_TYPE rfInterface = NFA_INTERFACE_FRAME;
1085     int foundTech = tagProtocolsOfDiscResult_[index];
1086     if (foundTech == NFA_PROTOCOL_ISO_DEP) {
1087         rfInterface = NFA_INTERFACE_ISO_DEP;
1088     } else if (foundTech == NFC_PROTOCOL_MIFARE) {
1089         rfInterface = NFA_INTERFACE_MIFARE;
1090     }
1091 
1092     // select the rf interface.
1093     rfDiscoveryMutex_.lock();
1094     tNFA_STATUS status = nciAdaptations_->NfaSelect(
1095         (uint8_t)tagDiscIdListOfDiscResult_[index], (tNFA_NFC_PROTOCOL)foundTech, rfInterface);
1096     if (status != NFA_STATUS_OK) {
1097         ErrorLog("TagNciAdapter::HandleDiscResult: NfaSelect error = 0x%{public}X", status);
1098     }
1099     connectedProtocol_ = foundTech;
1100     connectedTagDiscId_ = tagDiscIdListOfDiscResult_[index];
1101     rfDiscoveryMutex_.unlock();
1102 }
1103 
OnRfDiscLock()1104 void TagNciAdapter::OnRfDiscLock()
1105 {
1106     rfDiscoveryMutex_.lock();
1107 }
1108 
OffRfDiscLock()1109 void TagNciAdapter::OffRfDiscLock()
1110 {
1111     rfDiscoveryMutex_.unlock();
1112 }
1113 
SetNciAdaptations(std::shared_ptr<INfcNci> nciAdaptations)1114 void TagNciAdapter::SetNciAdaptations(std::shared_ptr<INfcNci> nciAdaptations)
1115 {
1116     nciAdaptations_ = nciAdaptations;
1117 }
1118 
IsNdefFormattable()1119 bool TagNciAdapter::IsNdefFormattable()
1120 {
1121     DebugLog("check IsNdefFormattable");
1122     const int IDX_NDEF_FORMAT_1ST = 7;
1123     const int IDX_NDEF_FORMAT_2ND = 8;
1124     if (tagActivatedProtocol_ == NFA_PROTOCOL_T1T || tagActivatedProtocol_ == NFA_PROTOCOL_T5T ||
1125         tagActivatedProtocol_ == NFC_PROTOCOL_MIFARE) {
1126         return true;
1127     } else if (tagActivatedProtocol_ == NFA_PROTOCOL_T2T) {
1128         return isMifareUltralight_;
1129     } else if (tagActivatedProtocol_ == NFA_PROTOCOL_T3T) {
1130         return isFelicaLite_;
1131     } else if (tagActivatedProtocol_ == NFA_PROTOCOL_ISO_DEP && isMifareDESFire_) {
1132         std::string hexRequest = "9060000000";
1133         std::string response;
1134         Transceive(hexRequest, response);
1135         if (KITS::NfcSdkCommon::GetHexStrBytesLen(response) == MIFACE_DES_FIRE_RESPONSE_LENGTH &&
1136             KITS::NfcSdkCommon::GetByteFromHexStr(response, IDX_NDEF_FORMAT_1ST) == NDEF_FORMATTABLE_1ST &&
1137             KITS::NfcSdkCommon::GetByteFromHexStr(response, IDX_NDEF_FORMAT_2ND) == NDEF_FORMATTABLE_2ND) {
1138             return true;
1139         }
1140     }
1141     return false;
1142 }
1143 
AbortWait()1144 void TagNciAdapter::AbortWait()
1145 {
1146     DebugLog("TagNciAdapter::AbortWait");
1147     {
1148         NFC::SynchronizeGuard guard(transceiveEvent_);
1149         transceiveEvent_.NotifyOne();
1150     }
1151     {
1152         NFC::SynchronizeGuard guard(filedCheckEvent_);
1153         filedCheckEvent_.NotifyOne();
1154     }
1155     {
1156         NFC::SynchronizeGuard guard(readNdefEvent_);
1157         readNdefEvent_.NotifyOne();
1158     }
1159     {
1160         NFC::SynchronizeGuard guard(writeNdefEvent_);
1161         writeNdefEvent_.NotifyOne();
1162     }
1163     {
1164         NFC::SynchronizeGuard guard(formatNdefEvent_);
1165         formatNdefEvent_.NotifyOne();
1166     }
1167     {
1168         NFC::SynchronizeGuard guard(checkNdefEvent_);
1169         checkNdefEvent_.NotifyOne();
1170     }
1171     {
1172         NFC::SynchronizeGuard guard(selectEvent_);
1173         selectEvent_.NotifyOne();
1174     }
1175     {
1176         NFC::SynchronizeGuard guard(activatedEvent_);
1177         activatedEvent_.NotifyOne();
1178     }
1179     {
1180         NFC::SynchronizeGuard guard(deactivatedEvent_);
1181         deactivatedEvent_.NotifyOne();
1182     }
1183 }
1184 
GetT1tMaxMessageSize(tNFA_ACTIVATED activated) const1185 int TagNciAdapter::GetT1tMaxMessageSize(tNFA_ACTIVATED activated) const
1186 {
1187     int t1tMaxMessageSize;
1188     DebugLog("GetT1tMaxMessageSize");
1189     if (activated.activate_ntf.protocol != NFC_PROTOCOL_T1T) {
1190         t1tMaxMessageSize = 0;
1191         return t1tMaxMessageSize;
1192     }
1193     // examine the first byte of header ROM bytes
1194     switch (activated.params.t1t.hr[0]) {
1195         case RW_T1T_IS_TOPAZ96:
1196             t1tMaxMessageSize = TOPAZ96_MAX_MESSAGE_SIZE;
1197             break;
1198         case RW_T1T_IS_TOPAZ512:
1199             t1tMaxMessageSize = TOPAZ512_MAX_MESSAGE_SIZE;
1200             break;
1201         default:
1202             ErrorLog("GetT1tMaxMessageSize: unknown T1T HR0=%u", activated.params.t1t.hr[0]);
1203             t1tMaxMessageSize = 0;
1204             break;
1205     }
1206     return t1tMaxMessageSize;
1207 }
1208 
GetRfInterface(int protocol) const1209 tNFA_INTF_TYPE TagNciAdapter::GetRfInterface(int protocol) const
1210 {
1211     tNFA_INTF_TYPE rfInterface;
1212     if (protocol == NFA_PROTOCOL_ISO_DEP) {
1213         rfInterface = NFA_INTERFACE_ISO_DEP;
1214     } else if (protocol == NFA_PROTOCOL_MIFARE) {
1215         rfInterface = NFA_INTERFACE_MIFARE;
1216     } else {
1217         rfInterface = NFA_INTERFACE_FRAME;
1218     }
1219     return rfInterface;
1220 }
1221 
IsTagActive() const1222 bool TagNciAdapter::IsTagActive() const
1223 {
1224     if (!NfccNciAdapter::GetInstance().IsNfcActive()) {
1225         DebugLog("Nfc is not active");
1226         return false;
1227     }
1228     if (!NfccNciAdapter::GetInstance().IsTagActive()) {
1229         DebugLog("Tag already deactive");
1230         return false;
1231     }
1232     return true;
1233 }
1234 
SetIsMultiTag(bool isMultiTag)1235 void TagNciAdapter::SetIsMultiTag(bool isMultiTag)
1236 {
1237     isMultiTag_ = isMultiTag;
1238 }
1239 
GetIsMultiTag() const1240 bool TagNciAdapter::GetIsMultiTag() const
1241 {
1242     return isMultiTag_;
1243 }
1244 
SetDiscRstEvtNum(uint32_t num)1245 void TagNciAdapter::SetDiscRstEvtNum(uint32_t num)
1246 {
1247     if (num < MAX_NUM_TECHNOLOGY) {
1248         discRstEvtNum_ = num;
1249     }
1250 }
1251 
GetDiscRstEvtNum() const1252 uint32_t TagNciAdapter::GetDiscRstEvtNum() const
1253 {
1254     return discRstEvtNum_;
1255 }
1256 
GetMultiTagTechsFromData(const tNFA_DISC_RESULT & discoveryData)1257 void TagNciAdapter::GetMultiTagTechsFromData(const tNFA_DISC_RESULT& discoveryData)
1258 {
1259     uint32_t idx = discRstEvtNum_;
1260     if (idx >= MAX_NUM_TECHNOLOGY) {
1261         ErrorLog("TagNciAdapter::GetMultiTagTechsFromData: index error, index = %{public}d", idx);
1262         return;
1263     }
1264     multiTagDiscId_[idx] = discoveryData.discovery_ntf.rf_disc_id;
1265     multiTagDiscProtocol_[idx] = discoveryData.discovery_ntf.protocol;
1266     if (discNtfIndex_ < MAX_NUM_TECHNOLOGY) {
1267         discNtfIndex_++;
1268     }
1269     DebugLog("TagNciAdapter::GetMultiTagTechsFromData: discRstEvtNum_ = %{public}d, discNtfIndex_ = %{public}d"
1270         "discId = 0x%{public}X, protocol = 0x%{public}X",
1271         discRstEvtNum_, discNtfIndex_, multiTagDiscId_[idx], multiTagDiscProtocol_[idx]);
1272 }
1273 
DoSelectForMultiTag(int currIdx)1274 tNFA_STATUS TagNciAdapter::DoSelectForMultiTag(int currIdx)
1275 {
1276     tNFA_STATUS result = NFA_STATUS_FAILED;
1277     if (currIdx == INVALID_TAG_INDEX) {
1278         ErrorLog("TagNciAdapter::DoSelectForMultiTag: is NFC_DEP");
1279         return result;
1280     }
1281     InfoLog("TagNciAdapter::DoSelectForMultiTag: protocol = 0x%{public}X", multiTagDiscProtocol_[currIdx]);
1282 
1283     if (multiTagDiscProtocol_[currIdx] == NFA_PROTOCOL_ISO_DEP) {
1284         result = NFA_Select(multiTagDiscId_[currIdx], multiTagDiscProtocol_[currIdx], NFA_INTERFACE_ISO_DEP);
1285     } else if (multiTagDiscProtocol_[currIdx] == NFA_PROTOCOL_MIFARE) {
1286         result = NFA_Select(multiTagDiscId_[currIdx], multiTagDiscProtocol_[currIdx], NFA_INTERFACE_MIFARE);
1287     } else {
1288         result = NFA_Select(multiTagDiscId_[currIdx], multiTagDiscProtocol_[currIdx], NFA_INTERFACE_FRAME);
1289     }
1290     return result;
1291 }
1292 
SelectTheFirstTag()1293 void TagNciAdapter::SelectTheFirstTag()
1294 {
1295     unsigned int currIdx = INVALID_TAG_INDEX;
1296     for (unsigned int i = 0; i < discNtfIndex_; i++) {
1297         InfoLog("TagNciAdapter::SelectTheFirstTag index = %{public}d discId = 0x%{public}X protocol = 0x%{public}X",
1298             i, multiTagDiscId_[i], multiTagDiscProtocol_[i]);
1299         if (multiTagDiscProtocol_[i] != NFA_PROTOCOL_NFC_DEP) {
1300             selectedTagIdx_ = i;
1301             currIdx = i;
1302             break;
1303         }
1304     }
1305     tNFA_STATUS result = DoSelectForMultiTag(currIdx);
1306     InfoLog("TagNciAdapter::SelectTheFirstTag result = %{public}d", result);
1307 }
1308 
SelectTheNextTag()1309 void TagNciAdapter::SelectTheNextTag()
1310 {
1311     if (discRstEvtNum_ == 0) {
1312         ErrorLog("TagNciAdapter::SelectTheNextTag: next tag does not exist");
1313         return;
1314     }
1315     unsigned int currIdx = INVALID_TAG_INDEX;
1316     discRstEvtNum_--;
1317     for (unsigned int i = 0; i < discNtfIndex_; i++) {
1318         InfoLog("TagNciAdapter::SelectTheNextTag index = %{public}d discId = 0x%{public}X protocol = 0x%{public}X",
1319             i, multiTagDiscId_[i], multiTagDiscProtocol_[i]);
1320         if (multiTagDiscId_[i] != multiTagDiscId_[selectedTagIdx_] ||
1321             (multiTagDiscProtocol_[i] != multiTagDiscProtocol_[selectedTagIdx_] &&
1322             (multiTagDiscProtocol_[i] != NFA_PROTOCOL_NFC_DEP))) {
1323             selectedTagIdx_ = i;
1324             currIdx = i;
1325             break;
1326         }
1327     }
1328     tNFA_STATUS result = DoSelectForMultiTag(currIdx);
1329     InfoLog("TagNciAdapter::DoSelectForMultiTag result = %{public}d", result);
1330 }
1331 }  // namespace NCI
1332 }  // namespace NFC
1333 }  // namespace OHOS
1334