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