• 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         WarnLog("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     if (eventData == nullptr) {
1061         WarnLog("HandleDiscResult invalid eventData.");
1062         return;
1063     }
1064     tNFC_RESULT_DEVT& discoveryNtf = eventData->disc_result.discovery_ntf;
1065     DebugLog("TagNciAdapter::HandleDiscResult, discId: %{public}d, protocol: %{public}d",
1066         discoveryNtf.rf_disc_id, discoveryNtf.protocol);
1067 
1068     tagDiscIdListOfDiscResult_.push_back(discoveryNtf.rf_disc_id);
1069     tagProtocolsOfDiscResult_.push_back(discoveryNtf.protocol);
1070     if (discoveryNtf.more == NCI_DISCOVER_NTF_MORE) {
1071         return;
1072     }
1073 
1074     uint32_t index = MAX_NUM_TECHNOLOGY;
1075     for (std::size_t i = 0; i < tagProtocolsOfDiscResult_.size(); i++) {
1076         if (tagProtocolsOfDiscResult_[i] != NFA_PROTOCOL_NFC_DEP) {
1077             index = i;
1078             break;
1079         }
1080     }
1081 
1082     if (index >= MAX_NUM_TECHNOLOGY) {
1083         DebugLog("Has technology NFA_PROTOCOL_NFC_DEP only, don't handle it.");
1084         return;
1085     }
1086 
1087     // get the rf interface based on the found technology.
1088     tNFA_INTF_TYPE rfInterface = NFA_INTERFACE_FRAME;
1089     int foundTech = tagProtocolsOfDiscResult_[index];
1090     if (foundTech == NFA_PROTOCOL_ISO_DEP) {
1091         rfInterface = NFA_INTERFACE_ISO_DEP;
1092     } else if (foundTech == NFC_PROTOCOL_MIFARE) {
1093         rfInterface = NFA_INTERFACE_MIFARE;
1094     }
1095 
1096     // select the rf interface.
1097     rfDiscoveryMutex_.lock();
1098     tNFA_STATUS status = nciAdaptations_->NfaSelect(
1099         (uint8_t)tagDiscIdListOfDiscResult_[index], (tNFA_NFC_PROTOCOL)foundTech, rfInterface);
1100     if (status != NFA_STATUS_OK) {
1101         ErrorLog("TagNciAdapter::HandleDiscResult: NfaSelect error = 0x%{public}X", status);
1102     }
1103     connectedProtocol_ = foundTech;
1104     connectedTagDiscId_ = tagDiscIdListOfDiscResult_[index];
1105     rfDiscoveryMutex_.unlock();
1106 }
1107 
OnRfDiscLock()1108 void TagNciAdapter::OnRfDiscLock()
1109 {
1110     rfDiscoveryMutex_.lock();
1111 }
1112 
OffRfDiscLock()1113 void TagNciAdapter::OffRfDiscLock()
1114 {
1115     rfDiscoveryMutex_.unlock();
1116 }
1117 
SetNciAdaptations(std::shared_ptr<INfcNci> nciAdaptations)1118 void TagNciAdapter::SetNciAdaptations(std::shared_ptr<INfcNci> nciAdaptations)
1119 {
1120     nciAdaptations_ = nciAdaptations;
1121 }
1122 
IsNdefFormattable()1123 bool TagNciAdapter::IsNdefFormattable()
1124 {
1125     DebugLog("check IsNdefFormattable");
1126     const int IDX_NDEF_FORMAT_1ST = 7;
1127     const int IDX_NDEF_FORMAT_2ND = 8;
1128     if (tagActivatedProtocol_ == NFA_PROTOCOL_T1T || tagActivatedProtocol_ == NFA_PROTOCOL_T5T ||
1129         tagActivatedProtocol_ == NFC_PROTOCOL_MIFARE) {
1130         return true;
1131     } else if (tagActivatedProtocol_ == NFA_PROTOCOL_T2T) {
1132         return isMifareUltralight_;
1133     } else if (tagActivatedProtocol_ == NFA_PROTOCOL_T3T) {
1134         return isFelicaLite_;
1135     } else if (tagActivatedProtocol_ == NFA_PROTOCOL_ISO_DEP && isMifareDESFire_) {
1136         std::string hexRequest = "9060000000";
1137         std::string response;
1138         Transceive(hexRequest, response);
1139         if (KITS::NfcSdkCommon::GetHexStrBytesLen(response) == MIFACE_DES_FIRE_RESPONSE_LENGTH &&
1140             KITS::NfcSdkCommon::GetByteFromHexStr(response, IDX_NDEF_FORMAT_1ST) == NDEF_FORMATTABLE_1ST &&
1141             KITS::NfcSdkCommon::GetByteFromHexStr(response, IDX_NDEF_FORMAT_2ND) == NDEF_FORMATTABLE_2ND) {
1142             return true;
1143         }
1144     }
1145     return false;
1146 }
1147 
AbortWait()1148 void TagNciAdapter::AbortWait()
1149 {
1150     DebugLog("TagNciAdapter::AbortWait");
1151     {
1152         NFC::SynchronizeGuard guard(transceiveEvent_);
1153         transceiveEvent_.NotifyOne();
1154     }
1155     {
1156         NFC::SynchronizeGuard guard(filedCheckEvent_);
1157         filedCheckEvent_.NotifyOne();
1158     }
1159     {
1160         NFC::SynchronizeGuard guard(readNdefEvent_);
1161         readNdefEvent_.NotifyOne();
1162     }
1163     {
1164         NFC::SynchronizeGuard guard(writeNdefEvent_);
1165         writeNdefEvent_.NotifyOne();
1166     }
1167     {
1168         NFC::SynchronizeGuard guard(formatNdefEvent_);
1169         formatNdefEvent_.NotifyOne();
1170     }
1171     {
1172         NFC::SynchronizeGuard guard(checkNdefEvent_);
1173         checkNdefEvent_.NotifyOne();
1174     }
1175     {
1176         NFC::SynchronizeGuard guard(selectEvent_);
1177         selectEvent_.NotifyOne();
1178     }
1179     {
1180         NFC::SynchronizeGuard guard(activatedEvent_);
1181         activatedEvent_.NotifyOne();
1182     }
1183     {
1184         NFC::SynchronizeGuard guard(deactivatedEvent_);
1185         deactivatedEvent_.NotifyOne();
1186     }
1187 }
1188 
GetT1tMaxMessageSize(tNFA_ACTIVATED activated) const1189 int TagNciAdapter::GetT1tMaxMessageSize(tNFA_ACTIVATED activated) const
1190 {
1191     int t1tMaxMessageSize;
1192     DebugLog("GetT1tMaxMessageSize");
1193     if (activated.activate_ntf.protocol != NFC_PROTOCOL_T1T) {
1194         t1tMaxMessageSize = 0;
1195         return t1tMaxMessageSize;
1196     }
1197     // examine the first byte of header ROM bytes
1198     switch (activated.params.t1t.hr[0]) {
1199         case RW_T1T_IS_TOPAZ96:
1200             t1tMaxMessageSize = TOPAZ96_MAX_MESSAGE_SIZE;
1201             break;
1202         case RW_T1T_IS_TOPAZ512:
1203             t1tMaxMessageSize = TOPAZ512_MAX_MESSAGE_SIZE;
1204             break;
1205         default:
1206             ErrorLog("GetT1tMaxMessageSize: unknown T1T HR0=%u", activated.params.t1t.hr[0]);
1207             t1tMaxMessageSize = 0;
1208             break;
1209     }
1210     return t1tMaxMessageSize;
1211 }
1212 
GetRfInterface(int protocol) const1213 tNFA_INTF_TYPE TagNciAdapter::GetRfInterface(int protocol) const
1214 {
1215     tNFA_INTF_TYPE rfInterface;
1216     if (protocol == NFA_PROTOCOL_ISO_DEP) {
1217         rfInterface = NFA_INTERFACE_ISO_DEP;
1218     } else if (protocol == NFA_PROTOCOL_MIFARE) {
1219         rfInterface = NFA_INTERFACE_MIFARE;
1220     } else {
1221         rfInterface = NFA_INTERFACE_FRAME;
1222     }
1223     return rfInterface;
1224 }
1225 
IsTagActive() const1226 bool TagNciAdapter::IsTagActive() const
1227 {
1228     if (!NfccNciAdapter::GetInstance().IsNfcActive()) {
1229         DebugLog("Nfc is not active");
1230         return false;
1231     }
1232     if (!NfccNciAdapter::GetInstance().IsTagActive()) {
1233         DebugLog("Tag already deactive");
1234         return false;
1235     }
1236     return true;
1237 }
1238 
SetIsMultiTag(bool isMultiTag)1239 void TagNciAdapter::SetIsMultiTag(bool isMultiTag)
1240 {
1241     isMultiTag_ = isMultiTag;
1242 }
1243 
GetIsMultiTag() const1244 bool TagNciAdapter::GetIsMultiTag() const
1245 {
1246     return isMultiTag_;
1247 }
1248 
SetDiscRstEvtNum(uint32_t num)1249 void TagNciAdapter::SetDiscRstEvtNum(uint32_t num)
1250 {
1251     if (num < MAX_NUM_TECHNOLOGY) {
1252         discRstEvtNum_ = num;
1253     }
1254 }
1255 
GetDiscRstEvtNum() const1256 uint32_t TagNciAdapter::GetDiscRstEvtNum() const
1257 {
1258     return discRstEvtNum_;
1259 }
1260 
GetMultiTagTechsFromData(const tNFA_DISC_RESULT & discoveryData)1261 void TagNciAdapter::GetMultiTagTechsFromData(const tNFA_DISC_RESULT& discoveryData)
1262 {
1263     uint32_t idx = discRstEvtNum_;
1264     if (idx >= MAX_NUM_TECHNOLOGY) {
1265         ErrorLog("TagNciAdapter::GetMultiTagTechsFromData: index error, index = %{public}d", idx);
1266         return;
1267     }
1268     multiTagDiscId_[idx] = discoveryData.discovery_ntf.rf_disc_id;
1269     multiTagDiscProtocol_[idx] = discoveryData.discovery_ntf.protocol;
1270     if (discNtfIndex_ < MAX_NUM_TECHNOLOGY) {
1271         discNtfIndex_++;
1272     }
1273     DebugLog("TagNciAdapter::GetMultiTagTechsFromData: discRstEvtNum_ = %{public}d, discNtfIndex_ = %{public}d"
1274         "discId = 0x%{public}X, protocol = 0x%{public}X",
1275         discRstEvtNum_, discNtfIndex_, multiTagDiscId_[idx], multiTagDiscProtocol_[idx]);
1276 }
1277 
DoSelectForMultiTag(int currIdx)1278 tNFA_STATUS TagNciAdapter::DoSelectForMultiTag(int currIdx)
1279 {
1280     tNFA_STATUS result = NFA_STATUS_FAILED;
1281     if (currIdx == INVALID_TAG_INDEX) {
1282         ErrorLog("TagNciAdapter::DoSelectForMultiTag: is NFC_DEP");
1283         return result;
1284     }
1285     InfoLog("TagNciAdapter::DoSelectForMultiTag: protocol = 0x%{public}X", multiTagDiscProtocol_[currIdx]);
1286 
1287     if (multiTagDiscProtocol_[currIdx] == NFA_PROTOCOL_ISO_DEP) {
1288         result = NFA_Select(multiTagDiscId_[currIdx], multiTagDiscProtocol_[currIdx], NFA_INTERFACE_ISO_DEP);
1289     } else if (multiTagDiscProtocol_[currIdx] == NFA_PROTOCOL_MIFARE) {
1290         result = NFA_Select(multiTagDiscId_[currIdx], multiTagDiscProtocol_[currIdx], NFA_INTERFACE_MIFARE);
1291     } else {
1292         result = NFA_Select(multiTagDiscId_[currIdx], multiTagDiscProtocol_[currIdx], NFA_INTERFACE_FRAME);
1293     }
1294     return result;
1295 }
1296 
SelectTheFirstTag()1297 void TagNciAdapter::SelectTheFirstTag()
1298 {
1299     unsigned int currIdx = INVALID_TAG_INDEX;
1300     for (unsigned int i = 0; i < discNtfIndex_; i++) {
1301         InfoLog("TagNciAdapter::SelectTheFirstTag index = %{public}d discId = 0x%{public}X protocol = 0x%{public}X",
1302             i, multiTagDiscId_[i], multiTagDiscProtocol_[i]);
1303         if (multiTagDiscProtocol_[i] != NFA_PROTOCOL_NFC_DEP) {
1304             selectedTagIdx_ = i;
1305             currIdx = i;
1306             break;
1307         }
1308     }
1309     tNFA_STATUS result = DoSelectForMultiTag(currIdx);
1310     InfoLog("TagNciAdapter::SelectTheFirstTag result = %{public}d", result);
1311 }
1312 
SelectTheNextTag()1313 void TagNciAdapter::SelectTheNextTag()
1314 {
1315     if (discRstEvtNum_ == 0) {
1316         ErrorLog("TagNciAdapter::SelectTheNextTag: next tag does not exist");
1317         return;
1318     }
1319     unsigned int currIdx = INVALID_TAG_INDEX;
1320     discRstEvtNum_--;
1321     for (unsigned int i = 0; i < discNtfIndex_; i++) {
1322         InfoLog("TagNciAdapter::SelectTheNextTag index = %{public}d discId = 0x%{public}X protocol = 0x%{public}X",
1323             i, multiTagDiscId_[i], multiTagDiscProtocol_[i]);
1324         if (multiTagDiscId_[i] != multiTagDiscId_[selectedTagIdx_] ||
1325             (multiTagDiscProtocol_[i] != multiTagDiscProtocol_[selectedTagIdx_] &&
1326             (multiTagDiscProtocol_[i] != NFA_PROTOCOL_NFC_DEP))) {
1327             selectedTagIdx_ = i;
1328             currIdx = i;
1329             break;
1330         }
1331     }
1332     tNFA_STATUS result = DoSelectForMultiTag(currIdx);
1333     InfoLog("TagNciAdapter::DoSelectForMultiTag result = %{public}d", result);
1334 }
1335 }  // namespace NCI
1336 }  // namespace NFC
1337 }  // namespace OHOS
1338