• 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_session.h"
16 #include "loghelper.h"
17 #include "app_state_observer.h"
18 
19 namespace OHOS {
20 namespace NFC {
21 namespace TAG {
22 using OHOS::AppExecFwk::ElementName;
23 const std::string DUMP_LINE = "---------------------------";
24 const std::string DUMP_END = "\n";
25 
26 // NFC_A = 1 ~ NDEF_FORMATABLE = 10
27 const int MAX_TECH = 12;
28 int g_techTimeout[MAX_TECH] = {0};
29 int g_maxTransLength[MAX_TECH] = {0, 253, 253, 261, 255, 253, 0, 0, 253, 253, 0, 0};
30 std::shared_ptr<AppStateObserver> g_appStateObserver = nullptr;
31 
TagSession(std::shared_ptr<NfcService> service)32 TagSession::TagSession(std::shared_ptr<NfcService> service)
33     : nfcService_(service)
34 {
35     if (service) {
36         nciTagProxy_ = service->GetNciTagProxy();
37         nfcPollingManager_ = service->GetNfcPollingManager();
38     }
39     g_appStateObserver = std::make_shared<AppStateObserver>(this);
40 }
41 
~TagSession()42 TagSession::~TagSession()
43 {
44 }
45 
46 /**
47  * @brief To connect the tagRfDiscId by technology.
48  * @param tagRfDiscId the rf disc id of tag
49  * @param technology the tag technology
50  * @return the result to connect the tag
51  */
Connect(int tagRfDiscId,int technology)52 int TagSession::Connect(int tagRfDiscId, int technology)
53 {
54     if (technology < 0 || technology >= MAX_TECH) {
55         ErrorLog("Connect, invalid technology %{public}d", technology);
56         return NFC::KITS::ErrorCode::ERR_TAG_PARAMETERS;
57     }
58     if (nfcService_.expired() || nciTagProxy_.expired()) {
59         ErrorLog("Connect, expired");
60         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
61     }
62     if (!nfcService_.lock()->IsNfcEnabled()) {
63         ErrorLog("Connect, IsNfcEnabled error");
64         return NFC::KITS::ErrorCode::ERR_TAG_STATE_NFC_CLOSED;
65     }
66     if (!nciTagProxy_.lock()->IsTagFieldOn(tagRfDiscId)) {
67         ErrorLog("Connect, IsTagFieldOn error");
68         return NFC::KITS::ErrorCode::ERR_TAG_STATE_LOST;
69     }
70 
71     if (nciTagProxy_.lock()->Connect(tagRfDiscId, technology)) {
72         return NFC::KITS::ErrorCode::ERR_NONE;
73     } else {
74         ErrorLog("Connect, unallowd call error");
75         return NFC::KITS::ErrorCode::ERR_TAG_STATE_IO_FAILED;
76     }
77 }
78 /**
79  * @brief To reconnect the tagRfDiscId.
80  * @param tagRfDiscId the rf disc id of tag
81  * @return the result to reconnect the tag
82  */
Reconnect(int tagRfDiscId)83 int TagSession::Reconnect(int tagRfDiscId)
84 {
85     // Check if NFC is enabled
86     if (nfcService_.expired() || nciTagProxy_.expired()) {
87         ErrorLog("Reconnect, expired");
88         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
89     }
90     if (!nfcService_.lock()->IsNfcEnabled()) {
91         ErrorLog("Reconnect, IsNfcEnabled error");
92         return NFC::KITS::ErrorCode::ERR_TAG_STATE_NFC_CLOSED;
93     }
94 
95     if (nciTagProxy_.lock()->Reconnect(tagRfDiscId)) {
96         return NFC::KITS::ErrorCode::ERR_NONE;
97     } else {
98         ErrorLog("Reconnect, unallowd call error");
99         return NFC::KITS::ErrorCode::ERR_TAG_STATE_IO_FAILED;
100     }
101 }
102 /**
103  * @brief To disconnect the tagRfDiscId.
104  * @param tagRfDiscId the rf disc id of tag
105  */
Disconnect(int tagRfDiscId)106 void TagSession::Disconnect(int tagRfDiscId)
107 {
108     // Check if NFC is enabled
109     if (nfcService_.expired() || nciTagProxy_.expired() || !nfcService_.lock()->IsNfcEnabled()) {
110         ErrorLog("Disconnect, IsTagFieldOn error");
111         return;
112     }
113 
114     nciTagProxy_.lock()->Disconnect(tagRfDiscId);
115 }
116 
SetTimeout(int tagRfDiscId,int timeout,int technology)117 int TagSession::SetTimeout(int tagRfDiscId, int timeout, int technology)
118 {
119     if (technology < 0 || technology >= MAX_TECH) {
120         ErrorLog("SetTimeout, invalid technology %{public}d", technology);
121         return NFC::KITS::ErrorCode::ERR_TAG_PARAMETERS;
122     }
123     // Check if NFC is enabled
124     if (nfcService_.expired() || nciTagProxy_.expired()) {
125         ErrorLog("SetTimeout, expired");
126         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
127     }
128     if (!nfcService_.lock()->IsNfcEnabled()) {
129         ErrorLog("SetTimeout, IsNfcEnabled error");
130         return NFC::KITS::ErrorCode::ERR_TAG_STATE_NFC_CLOSED;
131     }
132 
133     nciTagProxy_.lock()->SetTimeout(tagRfDiscId, timeout, technology);
134     return NFC::KITS::ErrorCode::ERR_NONE;
135 }
136 
GetTimeout(int tagRfDiscId,int technology,int & timeout)137 int TagSession::GetTimeout(int tagRfDiscId, int technology, int &timeout)
138 {
139     if (technology < 0 || technology >= MAX_TECH) {
140         ErrorLog("GetTimeout, invalid technology %{public}d", technology);
141         return NFC::KITS::ErrorCode::ERR_TAG_PARAMETERS;
142     }
143     // Check if NFC is enabled
144     if (nfcService_.expired() || nciTagProxy_.expired()) {
145         ErrorLog("GetTimeout, expired");
146         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
147     }
148     if (!nfcService_.lock()->IsNfcEnabled()) {
149         ErrorLog("GetTimeout, IsNfcEnabled error");
150         return NFC::KITS::ErrorCode::ERR_TAG_STATE_NFC_CLOSED;
151     }
152 
153     uint32_t timeoutTemp = 0;
154     nciTagProxy_.lock()->GetTimeout(tagRfDiscId, timeoutTemp, technology);
155     timeout = timeoutTemp;
156     return NFC::KITS::ErrorCode::ERR_NONE;
157 }
158 
ResetTimeout(int tagRfDiscId)159 void TagSession::ResetTimeout(int tagRfDiscId)
160 {
161     nciTagProxy_.lock()->ResetTimeout(tagRfDiscId);
162     return;
163 }
164 
165 /**
166  * @brief Get the TechList of the tagRfDiscId.
167  * @param tagRfDiscId the rf disc id of tag
168  * @return TechList
169  */
GetTechList(int tagRfDiscId)170 std::vector<int> TagSession::GetTechList(int tagRfDiscId)
171 {
172     std::vector<int> techList;
173     // Check if NFC is enabled
174     if (nfcService_.expired() || nciTagProxy_.expired() || !nfcService_.lock()->IsNfcEnabled()) {
175         ErrorLog("GetTechList, IsTagFieldOn error");
176         return techList;
177     }
178 
179     return nciTagProxy_.lock()->GetTechList(tagRfDiscId);
180 }
181 /**
182  * @brief Checking the tagRfDiscId is present.
183  * @param tagRfDiscId the rf disc id of tag
184  * @return true - Presnet; the other - No Presnet
185  */
IsTagFieldOn(int tagRfDiscId)186 bool TagSession::IsTagFieldOn(int tagRfDiscId)
187 {
188     // Check if NFC is enabled
189     if (nfcService_.expired() || nciTagProxy_.expired() || !nfcService_.lock()->IsNfcEnabled()) {
190         ErrorLog("IsTagFieldOn, IsTagFieldOn error");
191         return false;
192     }
193 
194     return nciTagProxy_.lock()->IsTagFieldOn(tagRfDiscId);
195 }
196 /**
197  * @brief Checking the tagRfDiscId is a Ndef Tag.
198  * @param tagRfDiscId the rf disc id of tag
199  * @return true - Ndef Tag; the other - No Ndef Tag
200  */
IsNdef(int tagRfDiscId)201 bool TagSession::IsNdef(int tagRfDiscId)
202 {
203     // Check if NFC is enabled
204     if (nfcService_.expired() || nciTagProxy_.expired() || !nfcService_.lock()->IsNfcEnabled()) {
205         ErrorLog("IsNdef, IsTagFieldOn error");
206         return false;
207     }
208 
209     std::vector<int> ndefInfo;
210     return nciTagProxy_.lock()->DetectNdefInfo(tagRfDiscId, ndefInfo);
211 }
212 
SendRawFrame(int tagRfDiscId,std::string hexCmdData,bool raw,std::string & hexRespData)213 int TagSession::SendRawFrame(int tagRfDiscId, std::string hexCmdData, bool raw, std::string &hexRespData)
214 {
215     DebugLog("Send Raw(%{public}d) Frame", raw);
216     // Check if NFC is enabled
217     if (nfcService_.expired() || nciTagProxy_.expired()) {
218         ErrorLog("SendRawFrame, expired");
219         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
220     }
221     if (!nfcService_.lock()->IsNfcEnabled()) {
222         ErrorLog("SendRawFrame, IsNfcEnabled error");
223         return NFC::KITS::ErrorCode::ERR_TAG_STATE_NFC_CLOSED;
224     }
225 
226     // Check if length is within limits
227     int maxSize = 0;
228     GetMaxTransceiveLength(nciTagProxy_.lock()->GetConnectedTech(tagRfDiscId), maxSize);
229     if (KITS::NfcSdkCommon::GetHexStrBytesLen(hexCmdData) > static_cast<uint32_t>(maxSize)) {
230         return NFC::KITS::ErrorCode::ERR_TAG_PARAMETERS;
231     }
232 
233     int result = nciTagProxy_.lock()->Transceive(tagRfDiscId, hexCmdData, hexRespData);
234     DebugLog("TagSession::SendRawFrame, result = 0x%{public}X", result);
235     if ((result == 0) && (!hexRespData.empty())) {
236         return NFC::KITS::ErrorCode::ERR_NONE;
237     } else if (result == 1) {  // result == 1 means that Tag lost
238         ErrorLog("TagSession::SendRawFrame: tag lost.");
239         return NFC::KITS::ErrorCode::ERR_TAG_STATE_LOST;
240     }
241     ErrorLog("TagSession::SendRawFrame: result failed.");
242     return NFC::KITS::ErrorCode::ERR_TAG_STATE_IO_FAILED;
243 }
244 /**
245  * @brief Reading from the host tag
246  * @param tagRfDiscId the rf disc id of tag
247  * @return the read data
248  */
NdefRead(int tagRfDiscId)249 std::string TagSession::NdefRead(int tagRfDiscId)
250 {
251     // Check if NFC is enabled
252     if (nfcService_.expired() || nciTagProxy_.expired() || !nfcService_.lock()->IsNfcEnabled()) {
253         ErrorLog("NdefRead, IsTagFieldOn error");
254         return "";
255     }
256 
257     return nciTagProxy_.lock()->ReadNdef(tagRfDiscId);
258 }
259 /**
260  * @brief Writing the data into the host tag.
261  * @param tagRfDiscId the rf disc id of tag
262  * @param msg the wrote data
263  * @return the Writing Result
264  */
NdefWrite(int tagRfDiscId,std::string msg)265 int TagSession::NdefWrite(int tagRfDiscId, std::string msg)
266 {
267     // Check if NFC is enabled
268     if (nfcService_.expired() || nciTagProxy_.expired()) {
269         ErrorLog("NdefWrite, expired");
270         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
271     }
272     if (!nfcService_.lock()->IsNfcEnabled()) {
273         ErrorLog("NdefWrite, IsNfcEnabled error");
274         return NFC::KITS::ErrorCode::ERR_TAG_STATE_NFC_CLOSED;
275     }
276 
277     if (msg.empty()) {
278         ErrorLog("NdefWrite, msg.empty error");
279         return NFC::KITS::ErrorCode::ERR_TAG_PARAMETERS;
280     }
281 
282     if (nciTagProxy_.lock()->WriteNdef(tagRfDiscId, msg)) {
283         return NFC::KITS::ErrorCode::ERR_NONE;
284     }
285     return NFC::KITS::ErrorCode::ERR_TAG_STATE_IO_FAILED;
286 }
287 /**
288  * @brief Making the host tag to read only.
289  * @param tagRfDiscId the rf disc id of tag
290  * @return the making result
291  */
NdefMakeReadOnly(int tagRfDiscId)292 int TagSession::NdefMakeReadOnly(int tagRfDiscId)
293 {
294     // Check if NFC is enabled
295     if (nfcService_.expired() || nciTagProxy_.expired()) {
296         ErrorLog("NdefMakeReadOnly, expired");
297         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
298     }
299     if (!nfcService_.lock()->IsNfcEnabled()) {
300         ErrorLog("NdefMakeReadOnly, IsNfcEnabled error");
301         return NFC::KITS::ErrorCode::ERR_TAG_STATE_NFC_CLOSED;
302     }
303 
304     if (nciTagProxy_.lock()->SetNdefReadOnly(tagRfDiscId)) {
305         return NFC::KITS::ErrorCode::ERR_NONE;
306     }
307     return NFC::KITS::ErrorCode::ERR_TAG_STATE_IO_FAILED;
308 }
309 /**
310  * @brief format the tag by Ndef
311  * @param tagRfDiscId the rf disc id of tag
312  * @param key the format key
313  * @return the format result
314  */
FormatNdef(int tagRfDiscId,const std::string & key)315 int TagSession::FormatNdef(int tagRfDiscId, const std::string& key)
316 {
317     // Check if NFC is enabled
318     if (nfcService_.expired() || nciTagProxy_.expired()) {
319         ErrorLog("FormatNdef, expired");
320         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
321     }
322     if (!nfcService_.lock()->IsNfcEnabled()) {
323         ErrorLog("FormatNdef, IsNfcEnabled error");
324         return NFC::KITS::ErrorCode::ERR_TAG_STATE_NFC_CLOSED;
325     }
326 
327     if (nciTagProxy_.lock()->FormatNdef(tagRfDiscId, key)) {
328         return NFC::KITS::ErrorCode::ERR_NONE;
329     }
330     return NFC::KITS::ErrorCode::ERR_TAG_STATE_IO_FAILED;
331 }
332 
CanMakeReadOnly(int ndefType,bool & canSetReadOnly)333 int TagSession::CanMakeReadOnly(int ndefType, bool &canSetReadOnly)
334 {
335     if (nfcService_.expired() || nciTagProxy_.expired()) {
336         ErrorLog("CanMakeReadOnly, expired");
337         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
338     }
339     canSetReadOnly = nciTagProxy_.lock()->CanMakeReadOnly(ndefType);
340     return NFC::KITS::ErrorCode::ERR_NONE;
341 }
342 /**
343  * @brief Get Max Transceive Length
344  * @param technology the tag technology
345  * @return Max Transceive Length
346  */
GetMaxTransceiveLength(int technology,int & maxSize)347 int TagSession::GetMaxTransceiveLength(int technology, int &maxSize)
348 {
349     if (technology < 0 || technology >= MAX_TECH) {
350         ErrorLog("GetMaxTransceiveLength, technology not support");
351         return NFC::KITS::ErrorCode::ERR_TAG_PARAMETERS;
352     }
353     maxSize = g_maxTransLength[technology];
354     return NFC::KITS::ErrorCode::ERR_NONE;
355 }
356 
IsSupportedApdusExtended(bool & isSupported)357 int TagSession::IsSupportedApdusExtended(bool &isSupported)
358 {
359     if (nfcService_.expired() || nciTagProxy_.expired()) {
360         ErrorLog("IsSupportedApdusExtended, expired");
361         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
362     }
363     isSupported = nciTagProxy_.lock()->IsExtendedLengthApduSupported();
364     return NFC::KITS::ErrorCode::ERR_NONE;
365 }
366 
GetFgDataVecSize()367 uint16_t TagSession::GetFgDataVecSize()
368 {
369     std::shared_lock<std::shared_mutex> guard(fgMutex_);
370     return fgDataVec_.size();
371 }
372 
GetReaderDataVecSize()373 uint16_t TagSession::GetReaderDataVecSize()
374 {
375     std::shared_lock<std::shared_mutex> guard(fgMutex_);
376     return readerDataVec_.size();
377 }
378 
CheckFgAppStateChanged(const std::string & bundleName,const std::string & abilityName,int abilityState)379 void TagSession::CheckFgAppStateChanged(const std::string &bundleName, const std::string &abilityName,
380     int abilityState)
381 {
382     std::unique_lock<std::shared_mutex> guard(fgMutex_);
383     for (auto fgData = fgDataVec_.begin(); fgData != fgDataVec_.end(); fgData++) {
384         ElementName element = fgData->element_;
385         if (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName) {
386             // app changes to foreground, RegForegroundDispatch.
387             if (abilityState == static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_FOREGROUND) &&
388                 !fgData->isEnableForeground_) {
389                 InfoLog("app changes to foreground, RegForegroundDispatchInner");
390                 RegForegroundDispatchInner(element, fgData->techs_, fgData->cb_);
391                 return;
392             }
393             // app changes to background, UnregForegroundDispatchInner.
394             if (abilityState == static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_BACKGROUND) &&
395                 fgData->isEnableForeground_) {
396                 InfoLog("app changes to background, UnregForegroundDispatchInner");
397                 UnregForegroundDispatchInner(element, false);
398                 return;
399             }
400             // app death, UnregForegroundDispatchInner and erase from fgDtataVec_.
401             if (abilityState == static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED)) {
402                 InfoLog("app died, unregForegroundDispatchInner and erase fgData");
403                 UnregForegroundDispatchInner(element, false);
404                 fgDataVec_.erase(fgData);
405                 return;
406             }
407         }
408     }
409 }
410 
CheckReaderAppStateChanged(const std::string & bundleName,const std::string & abilityName,int abilityState)411 void TagSession::CheckReaderAppStateChanged(const std::string &bundleName, const std::string &abilityName,
412     int abilityState)
413 {
414     std::unique_lock<std::shared_mutex> guard(fgMutex_);
415     for (auto readerData = readerDataVec_.begin(); readerData != readerDataVec_.end(); readerData++) {
416         ElementName element = readerData->element_;
417         if (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName) {
418             // app changes to foreground, RegReaderModeInner.
419             if (abilityState == static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_FOREGROUND) &&
420                 !readerData->isEnabled_) {
421                 InfoLog("app changes to foreground, RegReaderModeInner");
422                 RegReaderModeInner(element, readerData->techs_, readerData->cb_);
423                 return;
424             }
425             // app changes to background, UnregReaderModeInner.
426             if (abilityState == static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_BACKGROUND) &&
427                 readerData->isEnabled_) {
428                 InfoLog("app changes to background, UnregReaderModeInner");
429                 UnregReaderModeInner(element, false);
430                 return;
431             }
432             // app death, UnregReaderModeInner and erase from readerDataVec_.
433             if (abilityState == static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED)) {
434                 InfoLog("app died, UnregReaderModeInner and erase readerData");
435                 UnregReaderModeInner(element, false);
436                 readerDataVec_.erase(readerData);
437                 return;
438             }
439         }
440     }
441 }
442 
HandleAppStateChanged(const std::string & bundleName,const std::string & abilityName,int abilityState)443 void TagSession::HandleAppStateChanged(const std::string &bundleName, const std::string &abilityName,
444     int abilityState)
445 {
446     InfoLog("HandleAppStateChanged: bundleName = %{public}s, abilityName = %{public}s, abilityState = %{public}d",
447         bundleName.c_str(), abilityName.c_str(), abilityState);
448     CheckFgAppStateChanged(bundleName, abilityName, abilityState);
449     CheckReaderAppStateChanged(bundleName, abilityName, abilityState);
450 }
451 
IsSameAppAbility(const ElementName & element,const ElementName & fgElement)452 bool TagSession::IsSameAppAbility(const ElementName &element, const ElementName &fgElement)
453 {
454     if (element.GetBundleName() == fgElement.GetBundleName() &&
455         element.GetAbilityName() == fgElement.GetAbilityName()) {
456         return true;
457     }
458     return false;
459 }
460 
RegForegroundDispatch(ElementName & element,std::vector<uint32_t> & discTech,const sptr<KITS::IForegroundCallback> & callback)461 KITS::ErrorCode TagSession::RegForegroundDispatch(ElementName &element, std::vector<uint32_t> &discTech,
462     const sptr<KITS::IForegroundCallback> &callback)
463 {
464     std::unique_lock<std::shared_mutex> guard(fgMutex_);
465     return RegForegroundDispatchInner(element, discTech, callback);
466 }
467 
RegForegroundDispatchInner(ElementName & element,const std::vector<uint32_t> & discTech,const sptr<KITS::IForegroundCallback> & callback)468 KITS::ErrorCode TagSession::RegForegroundDispatchInner(ElementName &element, const std::vector<uint32_t> &discTech,
469     const sptr<KITS::IForegroundCallback> &callback)
470 {
471     if (IsFgRegistered(element, discTech, callback)) {
472         WarnLog("%{public}s already RegForegroundDispatch", element.GetBundleName().c_str());
473         return KITS::ERR_NONE;
474     }
475     InfoLog("RegForegroundDispatch: bundleName = %{public}s, abilityName = %{public}s",
476         element.GetBundleName().c_str(), element.GetAbilityName().c_str());
477     if (nfcPollingManager_.expired()) {
478         ErrorLog("RegForegroundDispatch, expired");
479         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
480     }
481     if (nfcPollingManager_.lock()->EnableForegroundDispatch(element, discTech, callback)) {
482         return KITS::ERR_NONE;
483     }
484     return KITS::ERR_NFC_PARAMETERS;
485 }
486 
IsFgRegistered(const ElementName & element,const std::vector<uint32_t> & discTech,const sptr<KITS::IForegroundCallback> & callback)487 bool TagSession::IsFgRegistered(const ElementName &element, const std::vector<uint32_t> &discTech,
488     const sptr<KITS::IForegroundCallback> &callback)
489 {
490     for (FgData &fgData : fgDataVec_) {
491         ElementName fgElement = fgData.element_;
492         if (IsSameAppAbility(element, fgElement)) {
493             if (fgData.isEnableForeground_) {
494                 return true;
495             }
496             InfoLog("Enable FgData: bundleName = %{public}s, abilityName = %{public}s",
497                 fgElement.GetBundleName().c_str(), fgElement.GetAbilityName().c_str());
498             fgData.isEnableForeground_ = true;
499             return false;
500         }
501     }
502     FgData fgData(true, element, discTech, callback);
503     fgDataVec_.push_back(fgData);
504     InfoLog("Add new FgData to vector: %{public}s, %{public}s", element.GetBundleName().c_str(),
505         element.GetAbilityName().c_str());
506     return false;
507 }
508 
UnregForegroundDispatch(ElementName & element)509 KITS::ErrorCode TagSession::UnregForegroundDispatch(ElementName &element)
510 {
511     std::unique_lock<std::shared_mutex> guard(fgMutex_);
512     return UnregForegroundDispatchInner(element, true);
513 }
514 
UnregForegroundDispatchInner(const ElementName & element,bool isAppUnregister)515 KITS::ErrorCode TagSession::UnregForegroundDispatchInner(const ElementName &element, bool isAppUnregister)
516 {
517     if (IsFgUnregistered(element, isAppUnregister)) {
518         WarnLog("%{public}s already UnregForegroundDispatch", element.GetBundleName().c_str());
519         return KITS::ERR_NONE;
520     }
521     InfoLog("UnregForegroundDispatchInner: bundleName = %{public}s, abilityName = %{public}s",
522         element.GetBundleName().c_str(), element.GetAbilityName().c_str());
523     if (nfcPollingManager_.expired()) {
524         ErrorLog("UnregForegroundDispatch, expired");
525         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
526     }
527     if (nfcPollingManager_.lock()->DisableForegroundDispatch(element)) {
528         return KITS::ERR_NONE;
529     }
530     return KITS::ERR_NFC_PARAMETERS;
531 }
532 
IsFgUnregistered(const ElementName & element,bool isAppUnregister)533 bool TagSession::IsFgUnregistered(const ElementName &element, bool isAppUnregister)
534 {
535     if (fgDataVec_.size() == 0) {
536         return true;
537     }
538     bool isUnregistered = false;
539     for (auto fgData = fgDataVec_.begin(); fgData != fgDataVec_.end(); fgData++) {
540         if (IsSameAppAbility(element, fgData->element_)) {
541             // isEnableForeground_ is false => is already unregistered.
542             if (!fgData->isEnableForeground_) {
543                 isUnregistered = true;
544             }
545             fgData->isEnableForeground_ = false;
546             // app unregister, delete record
547             // background unregister, retain record, re-register when switching to foreground
548             if (isAppUnregister) {
549                 InfoLog("isAppUnregister: erase fgData");
550                 fgDataVec_.erase(fgData);
551             }
552             return isUnregistered;
553         }
554     }
555     // No record, indicating has not registered(or IsFgUnregistered).
556     return true;
557 }
558 
IsReaderRegistered(const ElementName & element,const std::vector<uint32_t> & discTech,const sptr<KITS::IReaderModeCallback> & callback)559 bool TagSession::IsReaderRegistered(const ElementName &element, const std::vector<uint32_t> &discTech,
560     const sptr<KITS::IReaderModeCallback> &callback)
561 {
562     for (ReaderData &readerData : readerDataVec_) {
563         ElementName readerElement = readerData.element_;
564         if (IsSameAppAbility(element, readerElement)) {
565             if (readerData.isEnabled_) {
566                 return true;
567             }
568             InfoLog("Enable ReaderData: bundleName = %{public}s, abilityName = %{public}s",
569                 readerElement.GetBundleName().c_str(), readerElement.GetAbilityName().c_str());
570             readerData.isEnabled_ = true;
571             return false;
572         }
573     }
574     ReaderData readerData(true, element, discTech, callback);
575     readerDataVec_.push_back(readerData);
576     InfoLog("Add new ReaderData to vector: %{public}s, %{public}s", element.GetBundleName().c_str(),
577         element.GetAbilityName().c_str());
578     return false;
579 }
580 
IsReaderUnregistered(const ElementName & element,bool isAppUnregistered)581 bool TagSession::IsReaderUnregistered(const ElementName &element, bool isAppUnregistered)
582 {
583     if (readerDataVec_.size() == 0) {
584         return true;
585     }
586     bool isUnregistered = false;
587     for (auto readerData = readerDataVec_.begin(); readerData != readerDataVec_.end(); readerData++) {
588         if (IsSameAppAbility(element, readerData->element_)) {
589             // isEnabled_ is false => is already unregistered.
590             if (!readerData->isEnabled_) {
591                 isUnregistered = true;
592             }
593             readerData->isEnabled_ = false;
594             // app unregister, delete record
595             // background unregister, retain record, re-register when switching to foreground
596             if (isAppUnregistered) {
597                 InfoLog("isAppUnregister: erase readerData");
598                 readerDataVec_.erase(readerData);
599             }
600             return isUnregistered;
601         }
602     }
603     // No record, indicating has not registered(or IsReaderUnregistered).
604     return true;
605 }
606 
RegReaderModeInner(ElementName & element,std::vector<uint32_t> & discTech,const sptr<KITS::IReaderModeCallback> & callback)607 KITS::ErrorCode TagSession::RegReaderModeInner(ElementName &element, std::vector<uint32_t> &discTech,
608     const sptr<KITS::IReaderModeCallback> &callback)
609 {
610     if (IsReaderRegistered(element, discTech, callback)) {
611         WarnLog("%{public}s already RegReaderMode", element.GetBundleName().c_str());
612         return KITS::ERR_NONE;
613     }
614     InfoLog("RegReaderModeInner: bundleName = %{public}s, abilityName = %{public}s",
615         element.GetBundleName().c_str(), element.GetAbilityName().c_str());
616     if (nfcPollingManager_.expired()) {
617         ErrorLog("RegReaderModeInner, expired");
618         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
619     }
620     if (nfcPollingManager_.lock()->EnableReaderMode(element, discTech, callback)) {
621         return KITS::ERR_NONE;
622     }
623     return KITS::ERR_NFC_PARAMETERS;
624 }
625 
UnregReaderModeInner(ElementName & element,bool isAppUnregister)626 KITS::ErrorCode TagSession::UnregReaderModeInner(ElementName &element, bool isAppUnregister)
627 {
628     if (IsReaderUnregistered(element, isAppUnregister)) {
629         WarnLog("%{public}s already UnregReaderMode", element.GetBundleName().c_str());
630         return KITS::ERR_NONE;
631     }
632     InfoLog("UnregReaderModeInner: bundleName = %{public}s, abilityName = %{public}s",
633         element.GetBundleName().c_str(), element.GetAbilityName().c_str());
634     if (nfcPollingManager_.expired()) {
635         ErrorLog("UnregReaderMode, expired");
636         return NFC::KITS::ErrorCode::ERR_NFC_STATE_UNBIND;
637     }
638     if (nfcPollingManager_.lock()->DisableReaderMode(element)) {
639         return KITS::ERR_NONE;
640     }
641     return KITS::ERR_NFC_PARAMETERS;
642 }
643 
RegReaderMode(ElementName & element,std::vector<uint32_t> & discTech,const sptr<KITS::IReaderModeCallback> & callback)644 KITS::ErrorCode TagSession::RegReaderMode(ElementName &element, std::vector<uint32_t> &discTech,
645     const sptr<KITS::IReaderModeCallback> &callback)
646 {
647     if (!g_appStateObserver->IsForegroundApp(element.GetBundleName())) {
648         return KITS::ERR_TAG_APP_NOT_FOREGROUND;
649     }
650     std::unique_lock<std::shared_mutex> guard(fgMutex_);
651     return RegReaderModeInner(element, discTech, callback);
652 }
653 
UnregReaderMode(ElementName & element)654 KITS::ErrorCode TagSession::UnregReaderMode(ElementName &element)
655 {
656     std::unique_lock<std::shared_mutex> guard(fgMutex_);
657     return UnregReaderModeInner(element, true);
658 }
659 
Dump(int32_t fd,const std::vector<std::u16string> & args)660 int32_t TagSession::Dump(int32_t fd, const std::vector<std::u16string>& args)
661 {
662     std::string info = GetDumpInfo();
663     int ret = dprintf(fd, "%s\n", info.c_str());
664     if (ret < 0) {
665         ErrorLog("TagSession Dump ret = %{public}d", ret);
666         return NFC::KITS::ErrorCode::ERR_TAG_PARAMETERS;
667     }
668     return NFC::KITS::ErrorCode::ERR_NONE;
669 }
670 
GetDumpInfo()671 std::string TagSession::GetDumpInfo()
672 {
673     std::string info;
674     if (nfcService_.expired()) {
675         return info;
676     }
677 
678     return info.append(DUMP_LINE)
679         .append(" TAG DUMP ")
680         .append(DUMP_LINE)
681         .append(DUMP_END)
682         .append("NFC_STATE          : ")
683         .append(std::to_string(nfcService_.lock()->GetNfcState()))
684         .append(DUMP_END)
685         .append("SCREEN_STATE       : ")
686         .append(std::to_string(nfcService_.lock()->GetScreenState()))
687         .append(DUMP_END)
688         .append("NCI_VERSION        : ")
689         .append(std::to_string(nfcService_.lock()->GetNciVersion()))
690         .append(DUMP_END);
691 }
692 }  // namespace TAG
693 }  // namespace NFC
694 }  // namespace OHOS
695