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 #ifndef MIFARE_CLASSIC_TAG_H
16 #define MIFARE_CLASSIC_TAG_H
17 
18 #include "basic_tag_session.h"
19 
20 namespace OHOS {
21 namespace NFC {
22 namespace KITS {
23 class MifareClassicTag final : public BasicTagSession {
24 public:
25     enum EmType { TYPE_UNKNOWN = 0, TYPE_CLASSIC = 1, TYPE_PLUS = 2, TYPE_PRO = 3 };
26 
27     static const int SAK01 = 0x01;
28     static const int SAK08 = 0x08;
29     static const int SAK09 = 0x09;
30     static const int SAK10 = 0x10;
31     static const int SAK11 = 0x11;
32     static const int SAK18 = 0x18;
33     static const int SAK19 = 0x19;
34     static const int SAK28 = 0x28;
35     static const int SAK38 = 0x38;
36     static const int SAK88 = 0x88;
37     static const int SAK98 = 0x98;
38     static const int SAKB8 = 0xB8;
39 
40     static const int MC_BLOCK_SIZE = 16;
41     static const int MC_MAX_BLOCK_INDEX = 256;
42     static const int MC_KEY_LEN = 6;
43     static const int MC_ERROR_VALUE = -1;
44 
45     static const char MC_KEY_DEFAULT[MC_KEY_LEN];                       // 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
46     static const char MC_KEY_MAD[MC_KEY_LEN];  // 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5
47     static const char MC_KEY_NFC_FORUM[MC_KEY_LEN];                     // 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7
48 
49     // sector 0-32,4 blocks per sector, sector 33-40, 16 blocks per sector
50     static const int MC_BLOCK_COUNT = 4;
51     static const int MC_BLOCK_COUNT_OF_4K = 16;
52 
53     // 5 sectors per tag, 4 blocks per sector
54     static const int MC_SIZE_MINI = 320;
55     static const int MC_SECTOR_COUNT_OF_SIZE_MINI = 5;
56     // 16 sectors per tag, 4 blocks per sector
57     static const int MC_SIZE_1K = 1024;
58     static const int MC_SECTOR_COUNT_OF_SIZE_1K = 16;
59     // 32 sectors per tag, 4 blocks per sector
60     static const int MC_SIZE_2K = 2048;
61     static const int MC_SECTOR_COUNT_OF_SIZE_2K = 32;
62     // 40 sectors per tag, 4 blocks per sector
63     static const int MC_SIZE_4K = 4096;
64     static const int MC_MAX_SECTOR_COUNT = 40;
65 
66     static const unsigned char AUTHENTICATION_WITH_KEY_A = 0x60;
67     static const unsigned char AUTHENTICATION_WITH_KEY_B = 0x61;
68     static const unsigned char MIFARE_READ = 0x30;
69     static const unsigned char MIFARE_WRITE = 0xA0;
70     static const unsigned char MIFARE_TRANSFER = 0xB0;
71     static const unsigned char MIFARE_DECREMENT = 0xC0;
72     static const unsigned char MIFARE_INCREMENT = 0xC1;
73     static const unsigned char MIFARE_RESTORE = 0xC2;
74 
75 public:
76     explicit MifareClassicTag(std::weak_ptr<TagInfo> tag);
~MifareClassicTag()77     ~MifareClassicTag() override {}
78 
79     /**
80      * @Description Get an object of MifareClassicTag for the given tag.
81      * @param tag compatible with all types of tag
82      * @return std::shared_ptr<MifareClassicTag>
83      */
84     static std::shared_ptr<MifareClassicTag> GetTag(std::weak_ptr<TagInfo> tag);
85     /**
86      * @Description Authenticate a sector with the key.Only successful authentication sector can be operated.
87      * @param sectorIndex Index of sector to authenticate
88      * @param key key(6-byte) to authenticate
89      * @param bIsKeyA KeyA flag. true means KeyA, otherwise KeyB
90      * @return the error code of calling function.
91      */
92     int AuthenticateSector(int sectorIndex, const std::string& key, bool bIsKeyA);
93     /**
94      * @Description Read a block
95      * @param blockIndex index of block to read
96      * @param hexRespData the hex response data for reading.
97      * @return the error code of calling function.
98      */
99     int ReadSingleBlock(uint32_t blockIndex, std::string &hexRespData);
100     /**
101      * @Description Write a block
102      * @param blockIndex index of block to write
103      * @param hexData block data to write
104      * @return Errorcode of write. if return 0, means successful.
105      */
106     int WriteSingleBlock(uint32_t blockIndex, const std::string& hexData);
107     /**
108      * @Description Increment a value block
109      * @param blockIndex index of block to increment
110      * @param value value to increment, none-negative
111      * @return Errorcode of increment. if return 0, means successful.
112      */
113     int IncrementBlock(uint32_t blockIndex, int value);
114     /**
115      * @Description Decrement a value block
116      * @param blockIndex index of block to decrement
117      * @param value value to increment, none-negative
118      * @return Errorcode of decrement. if return 0, means successful.
119      */
120     int DecrementBlock(uint32_t blockIndex, int value);
121     /**
122      * @Description Copy from the value of register to the value block
123      * @param blockIndex index of value block to copy to
124      * @return Errorcode of operation. if return 0, means successful.
125      */
126     int TransferToBlock(uint32_t blockIndex);
127     /**
128      * @Description Copy from the value block to the register
129      * @param blockIndex index of value block to copy from
130      * @return Errorcode of operation. if return 0, means successful.
131      */
132     int RestoreFromBlock(uint32_t blockIndex);
133     /**
134      * @Description Get the number of sectors in mifareclassic tag
135      * @param void
136      * @return the number of sectors.
137      */
138     int GetSectorCount() const;
139     /**
140      * @Description Get the number of blocks in the sector.
141      * @param sectorIndex index of sector
142      * @return the number of blocks.
143      */
144     int GetBlockCountInSector(int sectorIndex) const;
145     /**
146      * @Description Get the type of the MifareClassic tag in bytes.
147      * @param void
148      * @return type of MifareClassic tag.
149      */
150     MifareClassicTag::EmType GetMifareTagType() const;
151     /**
152      * @Description Get size of the tag in bytes.
153      * @param void
154      * @return size of the tag
155      */
156     int GetSize() const;
157     /**
158      * @Description check if if tag is emulated
159      * @param void
160      * @return return true if tag is emulated, otherwise return false.
161      */
162     bool IsEmulated() const;
163     /**
164      * @Description Get the first block of the sector.
165      * @param sectorIndex index of sector
166      * @return index of first block in the sector
167      */
168     int GetBlockIndexFromSector(int sectorIndex) const;
169     /**
170      * @Description Get the sector index that contains the specific block.
171      * @param blockIndex index of block
172      * @return the sector index that contains the block.
173      */
174     int GetSectorIndexFromBlock(int blockIndex) const;
175 private:
176     void SetSizeBySak(int sak);
177 
178     MifareClassicTag::EmType mifareTagType_ {MifareClassicTag::EmType::TYPE_UNKNOWN};
179     int size_ {};
180     bool isEmulated_ {};
181 };
182 }  // namespace KITS
183 }  // namespace NFC
184 }  // namespace OHOS
185 #endif  // MIFARE_CLASSIC_TAG_H
186