1 /*
2  * Copyright (C) 2022-2023 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 #ifndef TAG_NCI_ADAPTER_H
16 #define TAG_NCI_ADAPTER_H
17 #include <mutex>
18 #include <vector>
19 #include "ndef_utils.h"
20 #include "nfa_api.h"
21 #include "nfa_rw_api.h"
22 #include "nfc_config.h"
23 #include "synchronize_event.h"
24 #include "tag_host.h"
25 
26 namespace OHOS {
27 namespace NFC {
28 namespace NCI {
29 class TagNciAdapter final {
30 public:
31     static TagNciAdapter& GetInstance();
32     TagNciAdapter();
33     ~TagNciAdapter();
34 
35 #if (NXP_EXTNS == TRUE)
36     enum TagState {
37         IDLE = 0,
38         SLEEP,
39         ACTIVE,
40         INACTIVE
41     };
42 #else
43     enum TagState { IDLE = 0, SLEEP, ACTIVE };
44 #endif
45 
46     typedef struct MultiTagParams {
47         tNFC_RESULT_DEVT discNtf;
48         tNFC_INTF_PARAMS intfParam;
49         bool isSkipIsoDepAct = false;
50     } MultiTagParams;
51 
52     void HandleSelectResult(uint8_t status);
53     void HandleTranceiveData(uint8_t status, uint8_t* data, uint32_t dataLen);
54     void HandleReadComplete(uint8_t status);
55     void HandleWriteComplete(uint8_t status);
56     void HandleFormatComplete(uint8_t status);
57     void HandleNdefCheckResult(uint8_t status, uint32_t currentSize, uint32_t flag, uint32_t maxSize);
58     void HandleActivatedResult(tNFA_CONN_EVT_DATA* data);
59     void HandleDeactivatedResult(tNFA_DEACTIVATE_TYPE deactType);
60     void HandleFieldCheckResult(uint8_t status);
61     void HandleSetReadOnlyResult(tNFA_STATUS status);
62     bool IsReconnecting();
63     void BuildTagInfo(tNFA_ACTIVATED activated);
64     void HandleDiscResult(tNFA_CONN_EVT_DATA* eventData);
65     void SetDeactivatedStatus();
66     void SetConnectStatus(bool isStatusOk);
67 
68     // tag connection and read or write.
69     // interfaces for nfc host
70     tNFA_STATUS Connect(uint32_t idx);
71     bool Disconnect();
72     bool Reconnect();
73     int Transceive(const std::string& request, std::string& response);
74     void SetTimeout(const uint32_t timeout, const uint32_t technology);
75     uint32_t GetTimeout(uint32_t technology) const;
76     void ResetTimeout();
77     void ResetTag();
78 
79     // functions for ndef tag only.
80     void RegisterNdefHandler();
81     void ReadNdef(std::string& response);
82     bool WriteNdef(std::string& ndefMessage);
83     bool IsNdefFormatable();
84     bool FormatNdef();
85     bool SetReadOnly() const;
86     bool DetectNdefInfo(std::vector<int>& ndefInfo);
87     bool IsNdefFormattable();
88 
89     // functions for checking the tag field on or not.
90     bool IsTagFieldOn();
91     void ResetTagFieldOnFlag();
92     void OnRfDiscLock();
93     void OffRfDiscLock();
94     bool IsTagDeactivating();
95 
96     void AbortWait();
97 
98     // functions for multiple protocol tag
99     void SetIsMultiTag(bool isMultiTag);
100     bool GetIsMultiTag() const;
101     void SetDiscRstEvtNum(uint32_t num);
102     uint32_t GetDiscRstEvtNum() const;
103     void GetMultiTagTechsFromData(const tNFA_DISC_RESULT& discoveryData);
104     void SelectTheFirstTag();
105     void SelectTheNextTag();
106 
107     // Sync tag connection status from NfccNciAdapter
108     void SetCurrRfInterface(uint32_t rfInterface);
109     void SetCurrRfProtocol(uint32_t protocol);
110 #if (NXP_EXTNS == TRUE)
111     void SetCurrRfMode(uint8_t type);
112     void SetNfcID0ForTypeB(uint8_t* nfcID0);
113     bool IsMultiMFCTag();
114     void ClearMultiMFCTagState();
115 #endif
116     void SetTagActivated();
117     void ResetTagState();
118     void SetTagDeactivated(bool isSleep);
119     TagState GetTagState();
120     bool IsSwitchingRfIface();
121     bool IsExpectedActRfProtocol(uint32_t protocol);
122 
123     /* method for SAK28 issue */
124     void SetSkipMifareInterface();
125 
126     // multiple protocol tag special status
127     bool isIsoDepDhReqFailed_ = false;
128 
129 private:
130     uint32_t GetT1tMaxMessageSize(tNFA_ACTIVATED activated) const;
131     std::string GetUidFromData(tNFA_ACTIVATED activated) const;
132     tNFA_INTF_TYPE GetRfInterface(uint32_t protocol) const;
133     bool IsTagActive() const;
134     bool IsDiscTypeA(uint8_t discType) const;
135     bool IsDiscTypeB(uint8_t discType) const;
136     bool IsDiscTypeF(uint8_t discType) const;
137     bool IsDiscTypeV(uint8_t discType) const;
138 
139     std::string GetTechPollForTypeB(tNFC_RF_TECH_PARAMS nfcRfTechParams, uint32_t tech);
140     std::string GetTechActForIsoDep(tNFA_ACTIVATED activated, tNFC_RF_TECH_PARAMS nfcRfTechParams, uint32_t tech) const;
141     void GetTechFromData(tNFA_ACTIVATED activated);
142     void GetTechPollFromData(tNFA_ACTIVATED activated);
143     void GetTechActFromData(tNFA_ACTIVATED activated);
144     void ParseSpecTagType(tNFA_ACTIVATED activated);
145     void SetMultiTagData(tNFC_RESULT_DEVT& discNtf);
146     // spacial card
147     bool IsT2TNackRsp(const uint8_t* response, uint32_t responseLen);
148 
149     // mifare
150     bool IsMifareConnected();
151     bool IsTagDetectedInTimeDiff(uint32_t timeDiff);
152     tNFA_STATUS HandleMfcTransceiveData(std::string& response);
153 
154     bool NfaDeactivateAndSelect(int discId, int protocol, tNFA_INTF_TYPE rfInterface);
155     bool Reselect(tNFA_INTF_TYPE rfInterface, bool isSwitchingIface);
156     bool SendReselectReqIfNeed(int protocol, int tech);
157     tNFA_STATUS DoSelectForMultiTag(uint32_t currIdx);
158     tNFA_STATUS SendRawFrameForHaltPICC();
159 
160     // methods for SAK28 issue
161     void ClearNonStdTagData();
162     bool SkipProtoActivateIfNeed(tNFC_PROTOCOL protocol);
163     void SetNonStdTagData();
164 
165     void DoNfaNdefRegisterEvt(tNFA_NDEF_EVT_DATA* eventData);
166     void DoNfaNdefDataEvt(tNFA_NDEF_EVT_DATA* eventData);
167 
168     // static callback functions regiter to nci stack.
169     static void NdefCallback(uint8_t event, tNFA_NDEF_EVT_DATA* eventData);
170 
171 private:
172     // synchronized lock
173     std::mutex rfDiscoveryMutex_;
174     OHOS::NFC::SynchronizeEvent transceiveEvent_;
175     OHOS::NFC::SynchronizeEvent fieldCheckEvent_;
176     OHOS::NFC::SynchronizeEvent readNdefEvent_;
177     OHOS::NFC::SynchronizeEvent writeNdefEvent_;
178     OHOS::NFC::SynchronizeEvent formatNdefEvent_;
179     OHOS::NFC::SynchronizeEvent checkNdefEvent_;
180     OHOS::NFC::SynchronizeEvent selectEvent_;
181     OHOS::NFC::SynchronizeEvent activatedEvent_;
182     OHOS::NFC::SynchronizeEvent deactivatedEvent_;
183     OHOS::NFC::SynchronizeEvent setReadOnlyEvent_;
184     OHOS::NFC::SynchronizeEvent reconnectEvent_;
185 
186     bool isTagFieldOn_ = false;
187     bool isReconnecting_ = false;
188     bool isReconnected_ = false;
189     bool isInTransceive_ = false;
190     bool isTransceiveTimeout_ = false;
191     uint32_t t1tMaxMessageSize_ = 0;
192     bool isWaitingDeactRst_ = false; // deactive wrating state in reselect command can be modeified only in reselect
193 
194     // const values for Mifare Ultralight
195     static const uint32_t MANUFACTURER_ID_NXP = 0x04;
196     static const uint32_t SAK_MIFARE_UL_1 = 0x00;
197     static const uint32_t SAK_MIFARE_UL_2 = 0x04;
198     static const uint32_t ATQA_MIFARE_UL_0 = 0x44;
199     static const uint32_t ATQA_MIFARE_UL_1 = 0x00;
200 
201     // const values for Mifare DESFire
202     static const uint32_t SAK_MIFARE_DESFIRE = 0x20;
203     static const uint32_t ATQA_MIFARE_DESFIRE_0 = 0x44;
204     static const uint32_t ATQA_MIFARE_DESFIRE_1 = 0x03;
205 
206     static const uint32_t MAX_NUM_TECHNOLOGY = 12;
207 
208     // tag technology data for tag host and nfcservice.
209     std::vector<int> tagTechList_ {};
210     std::vector<uint32_t> tagRfDiscIdList_ {};          // disc id
211     std::vector<uint32_t> tagRfProtocols_ {};           // protocol
212     std::vector<std::string> tagPollBytes_ {};
213     std::vector<std::string> tagActivatedBytes_ {};     // current tech list index
214 
215     // tag connection status data
216     uint32_t connectedProtocol_ = 0;
217     uint32_t connectedType_ = TagHost::TARGET_TYPE_UNKNOWN;
218     uint32_t connectedTechIdx_ = 0;
219     uint32_t connectedRfIface_ = NFA_INTERFACE_ISO_DEP;
220     TagState tagState_ = IDLE;
221 
222     // data for updating connection status
223     int targetType_ = 0;
224     bool isSwitchingRfIface_ = false;
225 
226     // spec tag type
227     bool isFelicaLite_ = false;
228     bool isMifareUltralight_ = false;
229     bool isMifareDESFire_ = false;
230     bool isCashbee_ = false;
231     tNFA_RW_PRES_CHK_OPTION presChkOption_;
232 
233     // ndef checked status.
234     uint32_t lastNdefCheckedStatus_ = NFA_STATUS_FAILED;
235     bool isNdefCapable_ = false;
236     uint32_t lastCheckedNdefSize_ = 0;
237     uint32_t lastCheckedNdefMaxSize_ = 0;
238     uint32_t lastCheckedNdefMode_ = 0;
239     bool isNdefWriteSuccess_ = false;
240     bool isNdefFormatSuccess_ = false;
241     uint16_t ndefTypeHandle_ = NFA_HANDLE_INVALID;
242     std::string readNdefData_ = {};
243     bool isNdefReadTimeOut_ = false;
244     bool isNdefReading_ = false;
245     bool isNdefChecking_ = false;
246 
247     // multiple protocol tag values
248     bool isMultiTag_ = false;
249     uint32_t discRstEvtNum_ = 0; // number of tag, increased with the times of NFA_DISC_RESULT_EVT
250                                     // and decreased while selecting next tag
251     uint32_t discNtfIndex_ = 0;
252     uint32_t multiTagTmpTechIdx_ = 0; // to store the last techlist index for the last tag
253     uint32_t selectedTagIdx_ = 0;          // to store the last selected tag index
254     std::vector<int> multiTagDiscId_ {};
255     std::vector<int> multiTagDiscProtocol_ {};
256     uint32_t techListIndex_ = 0;             // current tech list index
257 
258     // special vals for special tags
259     uint8_t nfcID0_[4] {}; // Type B
260     uint8_t nfcID1_[10] {};
261     bool isSkipNdefRead_ = false;
262     bool isMultiProtoMFC_ = false;
263     bool isLegacyMifareReader_ = false;
264     bool isMfcTransRspErr_ = false;
265     long lastTagFoundTime_ = 0;
266     bool isMultiTagSupported_ = false;
267 
268     // timeout and time diffs
269     int technologyTimeoutsTable_[MAX_NUM_TECHNOLOGY] = {0}; // index equals to the technology value
270     std::vector<uint32_t> multiTagTimeDiff_ {};
271     bool isSkipMifareActive_ = false;
272     std::basic_string<uint8_t> receivedData_ {};
273     // values for SAK28 issue
274     int g_selectedIdx = 0;
275 #if (NXP_EXTNS == TRUE)
276     MultiTagParams g_multiTagParams;
277 #endif
278     uint8_t firstUid[NCI_NFCID1_MAX_LEN] = {0};
279 };
280 }  // namespace NCI
281 }  // namespace NFC
282 }  // namespace OHOS
283 #endif  // TAG_NCI_ADAPTER_H
284