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