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