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_host.h"
16 #include <thread>
17 #include "loghelper.h"
18 #include "nfa_api.h"
19 #include "nfc_sdk_common.h"
20 #include "taginfo.h"
21 #include "tag_nci_adapter.h"
22
23 namespace OHOS {
24 namespace NFC {
25 namespace NCI {
26 static const int INVALID_VALUE = -1;
27 OHOS::NFC::SynchronizeEvent TagHost::fieldCheckWatchDog_;
TagHost(const std::vector<int> & tagTechList,const std::vector<int> & tagRfDiscIdList,const std::vector<int> & tagActivatedProtocols,const std::string & tagUid,const std::vector<std::string> & tagPollBytes,const std::vector<std::string> & tagActivatedBytes)28 TagHost::TagHost(const std::vector<int>& tagTechList,
29 const std::vector<int>& tagRfDiscIdList,
30 const std::vector<int>& tagActivatedProtocols,
31 const std::string& tagUid,
32 const std::vector<std::string>& tagPollBytes,
33 const std::vector<std::string>& tagActivatedBytes)
34 : tagTechList_(std::move(tagTechList)),
35 tagRfDiscIdList_(std::move(tagRfDiscIdList)),
36 tagActivatedProtocols_(std::move(tagActivatedProtocols)),
37 tagUid_(tagUid),
38 tagPollBytes_(std::move(tagPollBytes)),
39 tagActivatedBytes_(std::move(tagActivatedBytes)),
40 connectedTagDiscId_(INVALID_VALUE),
41 connectedTechIndex_(INVALID_VALUE),
42 isTagFieldOn_(true),
43 isFieldChecking_(false),
44 isPauseFieldChecking_(false),
45 addNdefTech_(false)
46 {
47 }
48
~TagHost()49 TagHost::~TagHost()
50 {
51 tagTechList_.clear();
52 technologyList_.clear();
53 tagRfDiscIdList_.clear();
54 tagActivatedProtocols_.clear();
55 tagPollBytes_.clear();
56 tagActivatedBytes_.clear();
57 }
58
Connect(int technology)59 bool TagHost::Connect(int technology)
60 {
61 DebugLog("TagHost::Connect");
62 PauseFieldChecking();
63 std::lock_guard<std::mutex> lock(mutex_);
64 bool result = false;
65 tNFA_STATUS status;
66 for (std::size_t i = 0; i < technologyList_.size(); i++) {
67 if (technology != technologyList_[i]) {
68 continue;
69 }
70 // try connect the tag
71 if (connectedTagDiscId_ != tagRfDiscIdList_[i]) {
72 if (connectedTagDiscId_ == INVALID_VALUE) {
73 // first connect
74 status = TagNciAdapter::GetInstance().Connect(tagRfDiscIdList_[i],
75 tagActivatedProtocols_[i], tagTechList_[i]);
76 } else {
77 bool reResult = TagNciAdapter::GetInstance().Reconnect(tagRfDiscIdList_[i],
78 tagActivatedProtocols_[i], tagTechList_[i], false);
79 status = reResult ? NFA_STATUS_OK : NFA_STATUS_FAILED;
80 }
81 } else {
82 if (technology == static_cast<int>(KITS::TagTechnology::NFC_NDEF_TECH)) {
83 // special for ndef
84 i = 0;
85 }
86 bool reResult = TagNciAdapter::GetInstance().Reconnect(tagRfDiscIdList_[i],
87 tagActivatedProtocols_[i], tagTechList_[i], false);
88 status = reResult ? NFA_STATUS_OK : NFA_STATUS_FAILED;
89 }
90 if (status == NFA_STATUS_OK) {
91 connectedTagDiscId_ = tagRfDiscIdList_[i];
92 connectedTechIndex_ = static_cast<int>(i);
93 isTagFieldOn_ = true;
94 result = true;
95 }
96 break;
97 }
98 ResumeFieldChecking();
99 DebugLog("TagHost::Connect exit, result = %{public}d", result);
100 return result;
101 }
102
Disconnect()103 bool TagHost::Disconnect()
104 {
105 DebugLog("TagHost::Disconnect");
106 std::lock_guard<std::mutex> lock(mutex_);
107 connectedTagDiscId_ = INVALID_VALUE;
108 connectedTechIndex_ = INVALID_VALUE;
109 isTagFieldOn_ = false;
110 bool result = TagNciAdapter::GetInstance().Disconnect();
111 {
112 NFC::SynchronizeGuard guard(fieldCheckWatchDog_);
113 fieldCheckWatchDog_.NotifyOne();
114 }
115 DebugLog("TagHost::Disconnect exit, result = %{public}d", result);
116 return result;
117 }
118
Reconnect()119 bool TagHost::Reconnect()
120 {
121 DebugLog("TagHost::Reconnect");
122 if (connectedTechIndex_ == INVALID_VALUE) {
123 return true;
124 }
125 PauseFieldChecking();
126 std::lock_guard<std::mutex> lock(mutex_);
127 bool result = TagNciAdapter::GetInstance().Reconnect(tagRfDiscIdList_[connectedTechIndex_],
128 tagActivatedProtocols_[connectedTechIndex_], tagTechList_[connectedTechIndex_], false);
129 ResumeFieldChecking();
130 DebugLog("TagHost::Reconnect exit, result = %{public}d", result);
131 return result;
132 }
133
Transceive(std::string & request,std::string & response)134 int TagHost::Transceive(std::string& request, std::string& response)
135 {
136 DebugLog("TagHost::Transceive");
137 PauseFieldChecking();
138 std::lock_guard<std::mutex> lock(mutex_);
139 int status = TagNciAdapter::GetInstance().Transceive(request, response);
140 ResumeFieldChecking();
141 DebugLog("TagHost::Transceive exit, result = %{public}d", status);
142 return status;
143 }
144
FieldOnCheckingThread()145 bool TagHost::FieldOnCheckingThread()
146 {
147 DebugLog("TagHost::FieldOnCheckingThread");
148 PauseFieldChecking();
149 std::lock_guard<std::mutex> lock(mutex_);
150 isTagFieldOn_ = TagNciAdapter::GetInstance().IsTagFieldOn();
151 ResumeFieldChecking();
152 return isTagFieldOn_;
153 }
154
IsTagFieldOn()155 bool TagHost::IsTagFieldOn()
156 {
157 DebugLog("TagHost::IsTagFieldOn, result = %{public}d", isTagFieldOn_);
158 return isTagFieldOn_;
159 }
160
PauseFieldChecking()161 void TagHost::PauseFieldChecking()
162 {
163 isPauseFieldChecking_ = true;
164 }
165
ResumeFieldChecking()166 void TagHost::ResumeFieldChecking()
167 {
168 isPauseFieldChecking_ = false;
169 }
170
FieldCheckingThread(TagHost::TagDisconnectedCallBack callback,int delayedMs)171 void TagHost::FieldCheckingThread(TagHost::TagDisconnectedCallBack callback, int delayedMs)
172 {
173 DebugLog("FieldCheckingThread::Start Field Checking");
174 while (isFieldChecking_) {
175 NFC::SynchronizeGuard guard(fieldCheckWatchDog_);
176 bool isNotify = fieldCheckWatchDog_.Wait(delayedMs);
177 if (isNotify || !isTagFieldOn_) {
178 break;
179 }
180 if (isPauseFieldChecking_) {
181 continue;
182 }
183 bool result = TagNciAdapter::GetInstance().IsTagFieldOn();
184 if (!result) {
185 DebugLog("FieldCheckingThread::Tag lost...");
186 break;
187 }
188 }
189 isTagFieldOn_ = false;
190 TagNciAdapter::GetInstance().ResetTag();
191 TagNciAdapter::GetInstance().Disconnect();
192 if (callback != nullptr && isFieldChecking_ && tagRfDiscIdList_.size() > 0) {
193 DebugLog("FieldCheckingThread::Disconnect callback %{public}d", tagRfDiscIdList_[0]);
194 callback(tagRfDiscIdList_[0]);
195 }
196 DebugLog("FieldCheckingThread::End Field Checking");
197 }
198
OnFieldChecking(TagDisconnectedCallBack callback,int delayedMs)199 void TagHost::OnFieldChecking(TagDisconnectedCallBack callback, int delayedMs)
200 {
201 DebugLog("TagHost::OnFieldChecking");
202 isTagFieldOn_ = true;
203 isFieldChecking_ = true;
204 if (delayedMs <= 0) {
205 delayedMs = DEFAULT_PRESENCE_CHECK_WATCH_DOG_TIMEOUT;
206 }
207 std::thread(&TagHost::FieldCheckingThread, this, callback, delayedMs).detach();
208 }
209
OffFieldChecking()210 void TagHost::OffFieldChecking()
211 {
212 DebugLog("TagHost::OffFieldChecking");
213 isFieldChecking_ = false;
214 }
215
GetTechList()216 std::vector<int> TagHost::GetTechList()
217 {
218 for (std::vector<int>::iterator it = tagTechList_.begin(); it != tagTechList_.end(); ++it) {
219 KITS::TagTechnology technology = KITS::TagTechnology::NFC_INVALID_TECH;
220 switch (*it) {
221 case TARGET_TYPE_ISO14443_3A:
222 technology = KITS::TagTechnology::NFC_A_TECH;
223 break;
224
225 case TARGET_TYPE_ISO14443_3B:
226 technology = KITS::TagTechnology::NFC_B_TECH;
227 break;
228
229 case TARGET_TYPE_ISO14443_4:
230 technology = KITS::TagTechnology::NFC_ISODEP_TECH;
231 break;
232
233 case TARGET_TYPE_FELICA:
234 technology = KITS::TagTechnology::NFC_F_TECH;
235 break;
236
237 case TARGET_TYPE_V:
238 technology = KITS::TagTechnology::NFC_V_TECH;
239 break;
240
241 case TARGET_TYPE_NDEF:
242 technology = KITS::TagTechnology::NFC_NDEF_TECH;
243 break;
244
245 case TARGET_TYPE_NDEF_FORMATABLE:
246 technology = KITS::TagTechnology::NFC_NDEF_FORMATABLE_TECH;
247 break;
248
249 case TARGET_TYPE_MIFARE_CLASSIC:
250 technology = KITS::TagTechnology::NFC_MIFARE_CLASSIC_TECH;
251 break;
252
253 case TARGET_TYPE_MIFARE_UL:
254 technology = KITS::TagTechnology::NFC_MIFARE_ULTRALIGHT_TECH;
255 break;
256
257 case TARGET_TYPE_UNKNOWN:
258 default:
259 technology = KITS::TagTechnology::NFC_INVALID_TECH;
260 break;
261 }
262 technologyList_.push_back(static_cast<int>(technology));
263 }
264 return technologyList_;
265 }
266
RemoveTech(int tech)267 void TagHost::RemoveTech(int tech)
268 {
269 DebugLog("TagHost::RemoveTech");
270 if (tech == INVALID_VALUE) {
271 DebugLog("Remove all");
272 }
273 }
274
GetTagUid()275 std::string TagHost::GetTagUid()
276 {
277 return tagUid_;
278 }
279
DoTargetTypeIso144433a(AppExecFwk::PacMap & pacMap,int index)280 void TagHost::DoTargetTypeIso144433a(AppExecFwk::PacMap &pacMap, int index)
281 {
282 std::string act = tagActivatedBytes_[index];
283 std::string poll = tagPollBytes_[index];
284 if (!(act.empty())) {
285 int sak = (KITS::NfcSdkCommon::GetByteFromHexStr(act, 0) & 0xff);
286 pacMap.PutIntValue(KITS::TagInfo::SAK, sak);
287 DebugLog("DoTargetTypeIso144433a SAK: 0x%{public}X", sak);
288 }
289 pacMap.PutStringValue(KITS::TagInfo::ATQA, poll);
290 DebugLog("DoTargetTypeIso144433a ATQA: %{public}s", poll.c_str());
291 }
292
DoTargetTypeIso144433b(AppExecFwk::PacMap & pacMap,int index)293 void TagHost::DoTargetTypeIso144433b(AppExecFwk::PacMap &pacMap, int index)
294 {
295 std::string poll = tagPollBytes_[index];
296 if (poll.empty()) {
297 DebugLog("DoTargetTypeIso144433b poll empty");
298 return;
299 }
300
301 if (KITS::NfcSdkCommon::GetHexStrBytesLen(poll) < NCI_APP_DATA_LENGTH + NCI_PROTOCOL_INFO_LENGTH) {
302 DebugLog("DoTargetTypeIso144433b poll.len: %{public}d", KITS::NfcSdkCommon::GetHexStrBytesLen(poll));
303 return;
304 }
305
306 std::string appData = poll.substr(0, NCI_APP_DATA_LENGTH);
307 pacMap.PutStringValue(KITS::TagInfo::APP_DATA, appData);
308 DebugLog("ParseTechExtras::TARGET_TYPE_ISO14443_3B APP_DATA: %{public}s", appData.c_str());
309
310 std::string protoInfo = poll.substr(NCI_APP_DATA_LENGTH, NCI_PROTOCOL_INFO_LENGTH);
311 pacMap.PutStringValue(KITS::TagInfo::PROTOCOL_INFO, protoInfo);
312 DebugLog("ParseTechExtras::TARGET_TYPE_ISO14443_3B PROTOCOL_INFO: %{public}s", protoInfo.c_str());
313 }
314
DoTargetTypeIso144434(AppExecFwk::PacMap & pacMap,int index)315 void TagHost::DoTargetTypeIso144434(AppExecFwk::PacMap &pacMap, int index)
316 {
317 bool hasNfcA = false;
318 std::string act = tagActivatedBytes_[index];
319 for (std::size_t i = 0; i < tagTechList_.size(); i++) {
320 if (tagTechList_[i] == TARGET_TYPE_ISO14443_3A) {
321 hasNfcA = true;
322 break;
323 }
324 }
325 if (hasNfcA) {
326 pacMap.PutStringValue(KITS::TagInfo::HISTORICAL_BYTES, act);
327 DebugLog("DoTargetTypeIso144434::HISTORICAL_BYTES: %{public}s", act.c_str());
328 } else {
329 pacMap.PutStringValue(KITS::TagInfo::HILAYER_RESPONSE, act);
330 DebugLog("DoTargetTypeIso144434::HILAYER_RESPONSE: %{public}s", act.c_str());
331 }
332 }
333
DoTargetTypeV(AppExecFwk::PacMap & pacMap,int index)334 void TagHost::DoTargetTypeV(AppExecFwk::PacMap &pacMap, int index)
335 {
336 std::string poll = tagPollBytes_[index];
337 if (poll.empty()) {
338 DebugLog("DoTargetTypeV poll empty");
339 return;
340 }
341
342 if (KITS::NfcSdkCommon::GetHexStrBytesLen(poll) < NCI_POLL_LENGTH_MIN) {
343 DebugLog("DoTargetTypeV poll.len: %{public}d", KITS::NfcSdkCommon::GetHexStrBytesLen(poll));
344 return;
345 }
346
347 // 1st byte is response flag, 2nd byte is dsf id.
348 pacMap.PutIntValue(KITS::TagInfo::RESPONSE_FLAGS, KITS::NfcSdkCommon::GetByteFromHexStr(poll, 0));
349 DebugLog("DoTargetTypeV::RESPONSE_FLAGS: %{public}d", KITS::NfcSdkCommon::GetByteFromHexStr(poll, 0));
350 pacMap.PutIntValue(KITS::TagInfo::DSF_ID, KITS::NfcSdkCommon::GetByteFromHexStr(poll, 1));
351 DebugLog("DoTargetTypeV::DSF_ID: %{public}d", KITS::NfcSdkCommon::GetByteFromHexStr(poll, 1));
352 }
353
DoTargetTypeF(AppExecFwk::PacMap & pacMap,int index)354 void TagHost::DoTargetTypeF(AppExecFwk::PacMap &pacMap, int index)
355 {
356 std::string poll = tagPollBytes_[index];
357 if (poll.empty()) {
358 DebugLog("DoTargetTypeF poll empty");
359 return;
360 }
361
362 if (KITS::NfcSdkCommon::GetHexStrBytesLen(poll) < SENSF_RES_LENGTH) {
363 DebugLog("DoTargetTypeF no ppm, poll.len: %{public}d", KITS::NfcSdkCommon::GetHexStrBytesLen(poll));
364 return;
365 }
366 pacMap.PutStringValue(KITS::TagInfo::NFCF_PMM, poll.substr(0, SENSF_RES_LENGTH)); // 8 bytes for ppm
367
368 if (KITS::NfcSdkCommon::GetHexStrBytesLen(poll) < F_POLL_LENGTH) {
369 DebugLog("DoTargetTypeF no sc, poll.len: %{public}d", KITS::NfcSdkCommon::GetHexStrBytesLen(poll));
370 return;
371 }
372 pacMap.PutStringValue(KITS::TagInfo::NFCF_SC, poll.substr(SENSF_RES_LENGTH, 2)); // 2 bytes for sc
373 }
374
DoTargetTypeNdef(AppExecFwk::PacMap & pacMap)375 void TagHost::DoTargetTypeNdef(AppExecFwk::PacMap &pacMap)
376 {
377 DebugLog("DoTargetTypeNdef");
378 pacMap = ndefExtras_;
379 ndefExtras_.Clear();
380 }
381
ParseTechExtras(int index)382 AppExecFwk::PacMap TagHost::ParseTechExtras(int index)
383 {
384 AppExecFwk::PacMap pacMap;
385 int targetType = tagTechList_[index];
386 DebugLog("ParseTechExtras::targetType: %{public}d", targetType);
387 switch (targetType) {
388 case TARGET_TYPE_MIFARE_CLASSIC:
389 break;
390
391 case TARGET_TYPE_ISO14443_3A: {
392 DoTargetTypeIso144433a(pacMap, index);
393 break;
394 }
395
396 case TARGET_TYPE_ISO14443_3B: {
397 DoTargetTypeIso144433b(pacMap, index);
398 break;
399 }
400
401 case TARGET_TYPE_ISO14443_4: {
402 DoTargetTypeIso144434(pacMap, index);
403 break;
404 }
405
406 case TARGET_TYPE_V: {
407 DoTargetTypeV(pacMap, index);
408 break;
409 }
410
411 case TARGET_TYPE_MIFARE_UL: {
412 bool isUlC = IsUltralightC();
413 pacMap.PutBooleanValue(KITS::TagInfo::MIFARE_ULTRALIGHT_C_TYPE, isUlC);
414 DebugLog("ParseTechExtras::TARGET_TYPE_MIFARE_UL MIFARE_ULTRALIGHT_C_TYPE: %{public}d", isUlC);
415 break;
416 }
417
418 case TARGET_TYPE_FELICA: {
419 DoTargetTypeF(pacMap, index);
420 break;
421 }
422
423 case TARGET_TYPE_NDEF: {
424 DoTargetTypeNdef(pacMap);
425 break;
426 }
427
428 case TARGET_TYPE_NDEF_FORMATABLE:
429 break;
430
431 case TARGET_TYPE_UNKNOWN:
432 break;
433
434 default:
435 DebugLog("ParseTechExtras::unhandle for : %{public}d", targetType);
436 break;
437 }
438 return pacMap;
439 }
440
GetTechExtrasData()441 std::vector<AppExecFwk::PacMap> TagHost::GetTechExtrasData()
442 {
443 DebugLog("TagHost::GetTechExtrasData, tech len.%{public}zu", tagTechList_.size());
444 techExtras_.clear();
445 for (std::size_t i = 0; i < tagTechList_.size(); i++) {
446 AppExecFwk::PacMap extra = ParseTechExtras(i);
447 techExtras_.push_back(extra);
448 }
449 return techExtras_;
450 }
451
GetTagRfDiscId()452 int TagHost::GetTagRfDiscId()
453 {
454 if (tagTechList_.size() > 0) {
455 return tagRfDiscIdList_[0];
456 }
457 return 0;
458 }
459
SetNdefReadOnly()460 bool TagHost::SetNdefReadOnly()
461 {
462 DebugLog("TagHost::SetNdefReadOnly");
463 PauseFieldChecking();
464 std::lock_guard<std::mutex> lock(mutex_);
465 bool result = TagNciAdapter::GetInstance().SetReadOnly();
466 ResumeFieldChecking();
467 return result;
468 }
469
ReadNdef()470 std::string TagHost::ReadNdef()
471 {
472 DebugLog("TagHost::ReadNdef");
473 PauseFieldChecking();
474 std::string response = "";
475 this->AddNdefTech();
476 std::lock_guard<std::mutex> lock(mutex_);
477 TagNciAdapter::GetInstance().ReadNdef(response);
478 ResumeFieldChecking();
479 return response;
480 }
481
AddNdefTech()482 void TagHost::AddNdefTech()
483 {
484 if (addNdefTech_) {
485 return;
486 }
487 addNdefTech_ = true;
488 DebugLog("TagHost::AddNdefTech");
489 std::lock_guard<std::mutex> lock(mutex_);
490 bool foundFormat = false;
491 int formatHandle = 0;
492 int formatLibNfcType = 0;
493 uint32_t index = tagTechList_.size();
494 for (uint32_t i = 0; i < index; i++) {
495 TagNciAdapter::GetInstance().Reconnect(tagRfDiscIdList_[i], tagActivatedProtocols_[i], tagTechList_[i], false);
496
497 if (!foundFormat) {
498 if (TagNciAdapter::GetInstance().IsNdefFormattable()) {
499 formatHandle = tagRfDiscIdList_[i];
500 formatLibNfcType = tagActivatedProtocols_[i];
501 foundFormat = true;
502 }
503 Reconnect();
504 }
505 std::vector<int> ndefInfo;
506 if (TagNciAdapter::GetInstance().IsNdefMsgContained(ndefInfo)) {
507 if (ndefInfo.size() < NDEF_INFO_SIZE) {
508 WarnLog("TagHost::AddNdefTech, invalid size = %{public}zu", ndefInfo.size());
509 return;
510 }
511 DebugLog("Add ndef tag info, index: %{public}d", index);
512 // parse extras data for ndef tech.
513 AppExecFwk::PacMap pacMap;
514 std::string ndefMsg = "";
515 TagNciAdapter::GetInstance().ReadNdef(ndefMsg);
516 pacMap.PutStringValue(KITS::TagInfo::NDEF_MSG, ndefMsg);
517 pacMap.PutIntValue(KITS::TagInfo::NDEF_FORUM_TYPE, GetNdefType(tagActivatedProtocols_[i]));
518 DebugLog("ParseTechExtras::TARGET_TYPE_NDEF NDEF_FORUM_TYPE: %{public}d",
519 GetNdefType(tagActivatedProtocols_[i]));
520 pacMap.PutIntValue(KITS::TagInfo::NDEF_TAG_LENGTH, ndefInfo[NDEF_SIZE_INDEX]);
521 pacMap.PutIntValue(KITS::TagInfo::NDEF_TAG_MODE, ndefInfo[NDEF_MODE_INDEX]);
522 DebugLog("ParseTechExtras::TARGET_TYPE_NDEF NDEF_TAG_MODE: %{public}d", ndefInfo[1]);
523
524 AddNdefTechToTagInfo(TARGET_TYPE_NDEF, tagRfDiscIdList_[i], tagActivatedProtocols_[i], pacMap);
525 foundFormat = false;
526 break;
527 }
528 }
529 if (foundFormat) {
530 DebugLog("Add ndef formatable tag info, index: %{public}d", index);
531 AppExecFwk::PacMap pacMap;
532 AddNdefTechToTagInfo(TARGET_TYPE_NDEF_FORMATABLE, formatHandle, formatLibNfcType, pacMap);
533 }
534 }
535
AddNdefTechToTagInfo(int tech,int discId,int actProto,AppExecFwk::PacMap pacMap)536 void TagHost::AddNdefTechToTagInfo(int tech, int discId, int actProto, AppExecFwk::PacMap pacMap)
537 {
538 InfoLog("AddNdefTechToTagInfo: tech = %{public}d", tech);
539 tagTechList_.push_back(tech);
540 tagRfDiscIdList_.push_back(discId);
541 tagActivatedProtocols_.push_back(actProto);
542 ndefExtras_ = pacMap; // techExtras_ will be handled in ParseTechExtras()
543 }
544
GetNdefType(int protocol) const545 int TagHost::GetNdefType(int protocol) const
546 {
547 int ndefType;
548 if (NFA_PROTOCOL_T1T == protocol) {
549 ndefType = NDEF_TYPE1_TAG;
550 } else if (NFA_PROTOCOL_T2T == protocol) {
551 ndefType = NDEF_TYPE2_TAG;
552 } else if (NFA_PROTOCOL_T3T == protocol) {
553 ndefType = NDEF_TYPE3_TAG;
554 } else if (NFA_PROTOCOL_ISO_DEP == protocol) {
555 ndefType = NDEF_TYPE4_TAG;
556 } else if (NFC_PROTOCOL_MIFARE == protocol) {
557 ndefType = NDEF_MIFARE_CLASSIC_TAG;
558 } else {
559 /* NFA_PROTOCOL_T5T, NFA_PROTOCOL_INVALID and others */
560 ndefType = NDEF_UNKNOWN_TYPE;
561 }
562 return ndefType;
563 }
564
WriteNdef(std::string & data)565 bool TagHost::WriteNdef(std::string& data)
566 {
567 DebugLog("TagHost::WriteNdef");
568 PauseFieldChecking();
569 std::lock_guard<std::mutex> lock(mutex_);
570 bool result = TagNciAdapter::GetInstance().WriteNdef(data);
571 ResumeFieldChecking();
572 DebugLog("TagHost::WriteNdef exit, result = %{public}d", result);
573 return result;
574 }
575
FormatNdef(const std::string & key)576 bool TagHost::FormatNdef(const std::string& key)
577 {
578 DebugLog("TagHost::FormatNdef");
579 if (key.empty()) {
580 DebugLog("key is null");
581 return false;
582 }
583 PauseFieldChecking();
584 std::lock_guard<std::mutex> lock(mutex_);
585 bool result = TagNciAdapter::GetInstance().FormatNdef();
586 ResumeFieldChecking();
587 DebugLog("TagHost::FormatNdef exit, result = %{public}d", result);
588 return result;
589 }
590
IsNdefFormatable()591 bool TagHost::IsNdefFormatable()
592 {
593 DebugLog("TagHost::IsNdefFormatable");
594 bool result = TagNciAdapter::GetInstance().IsNdefFormatable();
595 DebugLog("TagHost::IsNdefFormatable exit, result = %{public}d", result);
596 return result;
597 }
598
IsNdefMsgContained(std::vector<int> & ndefInfo)599 bool TagHost::IsNdefMsgContained(std::vector<int>& ndefInfo)
600 {
601 DebugLog("TagHost::IsNdefMsgContained");
602 PauseFieldChecking();
603 std::lock_guard<std::mutex> lock(mutex_);
604 bool result = TagNciAdapter::GetInstance().IsNdefMsgContained(ndefInfo);
605 ResumeFieldChecking();
606 if (result) {
607 DebugLog("NDEF supported by the tag");
608 } else {
609 DebugLog("NDEF unsupported by the tag");
610 }
611 return result;
612 }
613
GetConnectedTech()614 int TagHost::GetConnectedTech()
615 {
616 DebugLog("TagHost::GetConnectedTech");
617 if (connectedTechIndex_ != INVALID_VALUE) {
618 return tagTechList_[connectedTechIndex_];
619 }
620 return 0;
621 }
622
IsUltralightC()623 bool TagHost::IsUltralightC()
624 {
625 PauseFieldChecking();
626 std::lock_guard<std::mutex> lock(mutex_);
627 bool result = false;
628
629 // read the date content of speci addressed pages, see MIFARE Ultralight C
630 std::string command = "3002"; // 0x30 for mifare read, 0x02 for page address
631 std::string response;
632 TagNciAdapter::GetInstance().Transceive(command, response);
633 if (KITS::NfcSdkCommon::GetHexStrBytesLen(response) == NCI_MIFARE_ULTRALIGHT_C_RESPONSE_LENGTH) {
634 if (response[DATA_BYTE2] == NCI_MIFARE_ULTRALIGHT_C_BLANK_CARD &&
635 response[DATA_BYTE3] == NCI_MIFARE_ULTRALIGHT_C_BLANK_CARD &&
636 response[DATA_BYTE4] == NCI_MIFARE_ULTRALIGHT_C_BLANK_CARD &&
637 response[DATA_BYTE5] == NCI_MIFARE_ULTRALIGHT_C_BLANK_CARD &&
638 response[DATA_BYTE6] == NCI_MIFARE_ULTRALIGHT_C_BLANK_CARD &&
639 response[DATA_BYTE7] == NCI_MIFARE_ULTRALIGHT_C_BLANK_CARD &&
640 response[DATA_BYTE8] == NCI_MIFARE_ULTRALIGHT_C_VERSION_INFO_FIRST &&
641 response[DATA_BYTE9] == NCI_MIFARE_ULTRALIGHT_C_VERSION_INFO_SECOND) {
642 result = true;
643 } else if (response[DATA_BYTE4] == NCI_MIFARE_ULTRALIGHT_C_NDEF_CC &&
644 ((response[DATA_BYTE5] & 0xff) < NCI_MIFARE_ULTRALIGHT_C_NDEF_MAJOR_VERSION) &&
645 ((response[DATA_BYTE6] & 0xff) > NCI_MIFARE_ULTRALIGHT_C_NDEF_TAG_SIZE)) {
646 result = true;
647 }
648 }
649 ResumeFieldChecking();
650 return result;
651 }
652 } // namespace NCI
653 } // namespace NFC
654 } // namespace OHOS
655