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