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