• 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_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