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