1bc2ed2b3Sopenharmony_ci/*
2bc2ed2b3Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3bc2ed2b3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bc2ed2b3Sopenharmony_ci * you may not use this file except in compliance with the License.
5bc2ed2b3Sopenharmony_ci * You may obtain a copy of the License at
6bc2ed2b3Sopenharmony_ci *
7bc2ed2b3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8bc2ed2b3Sopenharmony_ci *
9bc2ed2b3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bc2ed2b3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bc2ed2b3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bc2ed2b3Sopenharmony_ci * See the License for the specific language governing permissions and
13bc2ed2b3Sopenharmony_ci * limitations under the License.
14bc2ed2b3Sopenharmony_ci */
15bc2ed2b3Sopenharmony_ci#ifndef NDEF_MESSAGE_H
16bc2ed2b3Sopenharmony_ci#define NDEF_MESSAGE_H
17bc2ed2b3Sopenharmony_ci
18bc2ed2b3Sopenharmony_ci#include <array>
19bc2ed2b3Sopenharmony_ci#include <string>
20bc2ed2b3Sopenharmony_ci#include <vector>
21bc2ed2b3Sopenharmony_ci
22bc2ed2b3Sopenharmony_cinamespace OHOS {
23bc2ed2b3Sopenharmony_cinamespace NFC {
24bc2ed2b3Sopenharmony_cinamespace KITS {
25bc2ed2b3Sopenharmony_ci// record data, see NFC Data Exchange Format (NDEF) Technical Specification.
26bc2ed2b3Sopenharmony_cistruct NdefRecord {
27bc2ed2b3Sopenharmony_ci    short tnf_;
28bc2ed2b3Sopenharmony_ci    std::string id_;            // hex string, 0x00~0xFF
29bc2ed2b3Sopenharmony_ci    std::string payload_;       // hex string, 0x00~0xFF
30bc2ed2b3Sopenharmony_ci    std::string tagRtdType_;    // hex string, 0x00~0xFF
31bc2ed2b3Sopenharmony_ci};
32bc2ed2b3Sopenharmony_ci
33bc2ed2b3Sopenharmony_ci// layout, see NFC Data Exchange Format (NDEF) Technical Specification.
34bc2ed2b3Sopenharmony_cistruct RecordLayout {
35bc2ed2b3Sopenharmony_ci    bool mb; // message begin
36bc2ed2b3Sopenharmony_ci    bool me; // message end
37bc2ed2b3Sopenharmony_ci    bool cf; // chunk flag
38bc2ed2b3Sopenharmony_ci    bool sr; // short record
39bc2ed2b3Sopenharmony_ci    bool il; // id length
40bc2ed2b3Sopenharmony_ci    short tnf; // type name format
41bc2ed2b3Sopenharmony_ci    uint16_t typeLength;
42bc2ed2b3Sopenharmony_ci    uint32_t payloadLength;
43bc2ed2b3Sopenharmony_ci    uint16_t idLength;
44bc2ed2b3Sopenharmony_ci};
45bc2ed2b3Sopenharmony_ci
46bc2ed2b3Sopenharmony_ci// URI charactor code defined by NFC Forum
47bc2ed2b3Sopenharmony_cistatic const size_t MAX_URI_CODE_NUM = 0x24;
48bc2ed2b3Sopenharmony_cistatic std::array<std::string, MAX_URI_CODE_NUM> g_uriPrefix = {
49bc2ed2b3Sopenharmony_ci    "",                            // NFC Forum define value: 0x00
50bc2ed2b3Sopenharmony_ci    "http://www.",                 // NFC Forum define value: 0x01
51bc2ed2b3Sopenharmony_ci    "https://www.",                // NFC Forum define value: 0x02
52bc2ed2b3Sopenharmony_ci    "http://",                     // NFC Forum define value: 0x03
53bc2ed2b3Sopenharmony_ci    "https://",                    // NFC Forum define value: 0x04
54bc2ed2b3Sopenharmony_ci    "tel:",                        // NFC Forum define value: 0x05
55bc2ed2b3Sopenharmony_ci    "mailto:",                     // NFC Forum define value: 0x06
56bc2ed2b3Sopenharmony_ci    "ftp://anonymous:anonymous@",  // NFC Forum define value: 0x07
57bc2ed2b3Sopenharmony_ci    "ftp://ftp.",                  // NFC Forum define value: 0x08
58bc2ed2b3Sopenharmony_ci    "ftps://",                     // NFC Forum define value: 0x09
59bc2ed2b3Sopenharmony_ci    "sftp://",                     // NFC Forum define value: 0x0A
60bc2ed2b3Sopenharmony_ci    "smb://",                      // NFC Forum define value: 0x0B
61bc2ed2b3Sopenharmony_ci    "nfs://",                      // NFC Forum define value: 0x0C
62bc2ed2b3Sopenharmony_ci    "ftp://",                      // NFC Forum define value: 0x0D
63bc2ed2b3Sopenharmony_ci    "dav://",                      // NFC Forum define value: 0x0E
64bc2ed2b3Sopenharmony_ci    "news:",                       // NFC Forum define value: 0x0F
65bc2ed2b3Sopenharmony_ci    "telnet://",                   // NFC Forum define value: 0x10
66bc2ed2b3Sopenharmony_ci    "imap:",                       // NFC Forum define value: 0x11
67bc2ed2b3Sopenharmony_ci    "rtsp://",                     // NFC Forum define value: 0x12
68bc2ed2b3Sopenharmony_ci    "urn:",                        // NFC Forum define value: 0x13
69bc2ed2b3Sopenharmony_ci    "pop:",                        // NFC Forum define value: 0x14
70bc2ed2b3Sopenharmony_ci    "sip:",                        // NFC Forum define value: 0x15
71bc2ed2b3Sopenharmony_ci    "sips:",                       // NFC Forum define value: 0x16
72bc2ed2b3Sopenharmony_ci    "tftp:",                       // NFC Forum define value: 0x17
73bc2ed2b3Sopenharmony_ci    "btspp://",                    // NFC Forum define value: 0x18
74bc2ed2b3Sopenharmony_ci    "btl2cap://",                  // NFC Forum define value: 0x19
75bc2ed2b3Sopenharmony_ci    "btgoep://",                   // NFC Forum define value: 0x1A
76bc2ed2b3Sopenharmony_ci    "tcpobex://",                  // NFC Forum define value: 0x1B
77bc2ed2b3Sopenharmony_ci    "irdaobex://",                 // NFC Forum define value: 0x1C
78bc2ed2b3Sopenharmony_ci    "file://",                     // NFC Forum define value: 0x1D
79bc2ed2b3Sopenharmony_ci    "urn:epc:id:",                 // NFC Forum define value: 0x1E
80bc2ed2b3Sopenharmony_ci    "urn:epc:tag:",                // NFC Forum define value: 0x1F
81bc2ed2b3Sopenharmony_ci    "urn:epc:pat:",                // NFC Forum define value: 0x20
82bc2ed2b3Sopenharmony_ci    "urn:epc:raw:",                // NFC Forum define value: 0x21
83bc2ed2b3Sopenharmony_ci    "urn:epc:",                    // NFC Forum define value: 0x22
84bc2ed2b3Sopenharmony_ci    "urn:nfc:",                    // NFC Forum define value: 0x23
85bc2ed2b3Sopenharmony_ci};
86bc2ed2b3Sopenharmony_ci
87bc2ed2b3Sopenharmony_ciclass NdefMessage final {
88bc2ed2b3Sopenharmony_cipublic:
89bc2ed2b3Sopenharmony_ci    const int MAX_RTD_TYPE_LEN = 2;
90bc2ed2b3Sopenharmony_ci    static const int MIN_RECORD_LEN = 3;
91bc2ed2b3Sopenharmony_ci    static const long int MAX_PAYLOAD_SIZE = 10 * (1 << 20);  // 10MB
92bc2ed2b3Sopenharmony_ci    static const int SHORT_RECORD_SIZE = 256;
93bc2ed2b3Sopenharmony_ci    static const unsigned int ONE_BYTE_SHIFT = 8;
94bc2ed2b3Sopenharmony_ci
95bc2ed2b3Sopenharmony_ci    // TNF Type define
96bc2ed2b3Sopenharmony_ci    enum EmTnfType {
97bc2ed2b3Sopenharmony_ci        TNF_EMPTY = 0x00,
98bc2ed2b3Sopenharmony_ci        TNF_WELL_KNOWN = 0x01,
99bc2ed2b3Sopenharmony_ci        TNF_MIME_MEDIA = 0x02,
100bc2ed2b3Sopenharmony_ci        TNF_ABSOLUTE_URI = 0x03,
101bc2ed2b3Sopenharmony_ci        TNF_EXTERNAL_TYPE = 0x04,
102bc2ed2b3Sopenharmony_ci        TNF_UNKNOWN = 0x05,
103bc2ed2b3Sopenharmony_ci        TNF_UNCHANGED = 0x06,
104bc2ed2b3Sopenharmony_ci        TNF_RESERVED = 0x07
105bc2ed2b3Sopenharmony_ci    };
106bc2ed2b3Sopenharmony_ci
107bc2ed2b3Sopenharmony_ci    // record Flag
108bc2ed2b3Sopenharmony_ci    enum EmRecordFlag {
109bc2ed2b3Sopenharmony_ci        FLAG_MB = 0x80,
110bc2ed2b3Sopenharmony_ci        FLAG_ME = 0x40,
111bc2ed2b3Sopenharmony_ci        FLAG_CF = 0x20,
112bc2ed2b3Sopenharmony_ci        FLAG_SR = 0x10,
113bc2ed2b3Sopenharmony_ci        FLAG_IL = 0x08,
114bc2ed2b3Sopenharmony_ci        FLAG_TNF = 0x07
115bc2ed2b3Sopenharmony_ci    };
116bc2ed2b3Sopenharmony_ci
117bc2ed2b3Sopenharmony_ci    enum EmRtdType {
118bc2ed2b3Sopenharmony_ci        RTD_UNKNOWN = 0,
119bc2ed2b3Sopenharmony_ci        RTD_TEXT,
120bc2ed2b3Sopenharmony_ci        RTD_URI,
121bc2ed2b3Sopenharmony_ci        RTD_SMART_POSTER,
122bc2ed2b3Sopenharmony_ci        RTD_ALTERNATIVE_CARRIER,
123bc2ed2b3Sopenharmony_ci        RTD_HANDOVER_CARRIER,
124bc2ed2b3Sopenharmony_ci        RTD_HANDOVER_REQUEST,
125bc2ed2b3Sopenharmony_ci        RTD_HANDOVER_SELECT,
126bc2ed2b3Sopenharmony_ci        RTD_OHOS_APP,
127bc2ed2b3Sopenharmony_ci        RTD_RESERVED,
128bc2ed2b3Sopenharmony_ci    };
129bc2ed2b3Sopenharmony_cipublic:
130bc2ed2b3Sopenharmony_ci    explicit NdefMessage(std::vector<std::shared_ptr<NdefRecord>> ndefRecords);
131bc2ed2b3Sopenharmony_ci    ~NdefMessage();
132bc2ed2b3Sopenharmony_ci
133bc2ed2b3Sopenharmony_ci    /**
134bc2ed2b3Sopenharmony_ci     * @Description constructe a ndef message with raw bytes.
135bc2ed2b3Sopenharmony_ci     * @param data raw bytes to parse ndef message
136bc2ed2b3Sopenharmony_ci     * @return std::shared_ptr<NdefMessage>
137bc2ed2b3Sopenharmony_ci     */
138bc2ed2b3Sopenharmony_ci    static std::shared_ptr<NdefMessage> GetNdefMessage(const std::string& data);
139bc2ed2b3Sopenharmony_ci    /**
140bc2ed2b3Sopenharmony_ci     * @Description constructe a ndef message with record list.
141bc2ed2b3Sopenharmony_ci     * @param ndefRecords record list to parse ndef message
142bc2ed2b3Sopenharmony_ci     * @return std::shared_ptr<NdefMessage>
143bc2ed2b3Sopenharmony_ci     */
144bc2ed2b3Sopenharmony_ci    static std::shared_ptr<NdefMessage> GetNdefMessage(std::vector<std::shared_ptr<NdefRecord>> ndefRecords);
145bc2ed2b3Sopenharmony_ci    /**
146bc2ed2b3Sopenharmony_ci     * @Description convert the rtd bytes into byte array defined in Nfc forum.
147bc2ed2b3Sopenharmony_ci     * @param rtdtype rtd type of a record
148bc2ed2b3Sopenharmony_ci     * @return rtd byte array
149bc2ed2b3Sopenharmony_ci     */
150bc2ed2b3Sopenharmony_ci    static std::string GetTagRtdType(EmRtdType rtdtype);
151bc2ed2b3Sopenharmony_ci    /**
152bc2ed2b3Sopenharmony_ci     * @Description Create a ndef record with uri data.
153bc2ed2b3Sopenharmony_ci     * @param uriString uri data for new a ndef record
154bc2ed2b3Sopenharmony_ci     * @return std::shared_ptr<NdefRecord>
155bc2ed2b3Sopenharmony_ci     */
156bc2ed2b3Sopenharmony_ci    static std::shared_ptr<NdefRecord> MakeUriRecord(const std::string& uriString);
157bc2ed2b3Sopenharmony_ci    /**
158bc2ed2b3Sopenharmony_ci     * @Description Create a ndef record with text data.
159bc2ed2b3Sopenharmony_ci     * @param text text data for new a ndef record
160bc2ed2b3Sopenharmony_ci     * @param locale language code for the ndef record . if locale is null, use default locale
161bc2ed2b3Sopenharmony_ci     * @return std::shared_ptr<NdefRecord>
162bc2ed2b3Sopenharmony_ci     */
163bc2ed2b3Sopenharmony_ci    static std::shared_ptr<NdefRecord> MakeTextRecord(const std::string& text, const std::string& locale);
164bc2ed2b3Sopenharmony_ci    /**
165bc2ed2b3Sopenharmony_ci     * @Description Create a ndef record with mime data.
166bc2ed2b3Sopenharmony_ci     * @param mimeType type of mime data for new a ndef record
167bc2ed2b3Sopenharmony_ci     * @param mimeData mime data for new a ndef record
168bc2ed2b3Sopenharmony_ci     * @return std::shared_ptr<NdefRecord>
169bc2ed2b3Sopenharmony_ci     */
170bc2ed2b3Sopenharmony_ci    static std::shared_ptr<NdefRecord> MakeMimeRecord(const std::string& mimeType, const std::string& mimeData);
171bc2ed2b3Sopenharmony_ci
172bc2ed2b3Sopenharmony_ci    /**
173bc2ed2b3Sopenharmony_ci     * @Description Create a ndef record with external data.
174bc2ed2b3Sopenharmony_ci     * @param domainName domain name of issuing organization for the external data
175bc2ed2b3Sopenharmony_ci     * @param serviceName domain specific type of data for the external data
176bc2ed2b3Sopenharmony_ci     * @param externalData data payload of a ndef record
177bc2ed2b3Sopenharmony_ci     * @return std::shared_ptr<NdefRecord>
178bc2ed2b3Sopenharmony_ci     */
179bc2ed2b3Sopenharmony_ci    static std::shared_ptr<NdefRecord> MakeExternalRecord(const std::string& domainName,
180bc2ed2b3Sopenharmony_ci                                                          const std::string& serviceName,
181bc2ed2b3Sopenharmony_ci                                                          const std::string& externalData);
182bc2ed2b3Sopenharmony_ci    /**
183bc2ed2b3Sopenharmony_ci     * @Description parse a ndef message into raw bytes.
184bc2ed2b3Sopenharmony_ci     * @param ndefMessage a ndef message to parse
185bc2ed2b3Sopenharmony_ci     * @return raw bytes of a ndef message
186bc2ed2b3Sopenharmony_ci     */
187bc2ed2b3Sopenharmony_ci    static std::string MessageToString(std::weak_ptr<NdefMessage> ndefMessage);
188bc2ed2b3Sopenharmony_ci    /**
189bc2ed2b3Sopenharmony_ci     * @Description parse a ndef record into raw bytes.
190bc2ed2b3Sopenharmony_ci     * @param record a ndef record to parse
191bc2ed2b3Sopenharmony_ci     * @param buffer raw bytes of a ndef record
192bc2ed2b3Sopenharmony_ci     * @param bIsMB the flag of begin record
193bc2ed2b3Sopenharmony_ci     * @param bIsME the flag of end record
194bc2ed2b3Sopenharmony_ci     * @return void
195bc2ed2b3Sopenharmony_ci     */
196bc2ed2b3Sopenharmony_ci    static void NdefRecordToString(std::weak_ptr<NdefRecord> record, std::string& buffer, bool bIsMB, bool bIsME);
197bc2ed2b3Sopenharmony_ci    /**
198bc2ed2b3Sopenharmony_ci     * @Description Get all records of a ndef message.
199bc2ed2b3Sopenharmony_ci     * @param void
200bc2ed2b3Sopenharmony_ci     * @return record list of a ndef message
201bc2ed2b3Sopenharmony_ci     */
202bc2ed2b3Sopenharmony_ci    std::vector<std::shared_ptr<NdefRecord>> GetNdefRecords() const;
203bc2ed2b3Sopenharmony_ci
204bc2ed2b3Sopenharmony_ciprivate:
205bc2ed2b3Sopenharmony_ci    static std::shared_ptr<NdefRecord> CreateNdefRecord(short tnf, const std::string& id,
206bc2ed2b3Sopenharmony_ci        const std::string& payload, const std::string& tagRtdType);
207bc2ed2b3Sopenharmony_ci    static bool CheckTnf(short tnf, const std::string& tagRtdType,
208bc2ed2b3Sopenharmony_ci        const std::string& id, const std::string& payload);
209bc2ed2b3Sopenharmony_ci    static std::vector<std::shared_ptr<NdefRecord>> ParseRecord(const std::string& data, bool isMbMeIgnored);
210bc2ed2b3Sopenharmony_ci    static void ParseRecordLayoutHead(RecordLayout& layout, unsigned char head);
211bc2ed2b3Sopenharmony_ci    static bool IsInvalidRecordLayoutHead(RecordLayout& layout, bool isChunkFound,
212bc2ed2b3Sopenharmony_ci        uint32_t parsedRecordSize, bool isMbMeIgnored);
213bc2ed2b3Sopenharmony_ci    static void ParseRecordLayoutLength(RecordLayout& layout, bool isChunkFound,
214bc2ed2b3Sopenharmony_ci        const std::string& data, uint32_t& parsedDataIndex);
215bc2ed2b3Sopenharmony_ci    static bool IsRecordLayoutLengthInvalid(RecordLayout& layout, bool isChunkFound);
216bc2ed2b3Sopenharmony_ci    static std::string ParseRecordType(RecordLayout& layout, const std::string& data, uint32_t& parsedDataIndex);
217bc2ed2b3Sopenharmony_ci    static std::string ParseRecordId(RecordLayout& layout, const std::string& data, uint32_t& parsedDataIndex);
218bc2ed2b3Sopenharmony_ci    static std::string ParseRecordPayload(RecordLayout& layout, const std::string& data, uint32_t& parsedDataIndex);
219bc2ed2b3Sopenharmony_ci
220bc2ed2b3Sopenharmony_ci    static void SaveRecordChunks(RecordLayout& layout, bool isChunkFound, std::vector<std::string>& chunks,
221bc2ed2b3Sopenharmony_ci        char& chunkTnf, const std::string& payload);
222bc2ed2b3Sopenharmony_ci    static std::string MergePayloadByChunks(RecordLayout& layout, bool isChunkFound, std::vector<std::string>& chunks,
223bc2ed2b3Sopenharmony_ci        char chunkTnf, const std::string& payload);
224bc2ed2b3Sopenharmony_ci
225bc2ed2b3Sopenharmony_ciprivate:
226bc2ed2b3Sopenharmony_ci    std::vector<std::shared_ptr<NdefRecord>> ndefRecordList_ {};
227bc2ed2b3Sopenharmony_ci};
228bc2ed2b3Sopenharmony_ci
229bc2ed2b3Sopenharmony_ci// RTD types definitions, see NFC Record Type Definition (RTD) Specification.
230bc2ed2b3Sopenharmony_ciconst static std::array<std::string, NdefMessage::EmRtdType::RTD_RESERVED> HEX_RTD_TYPE = {
231bc2ed2b3Sopenharmony_ci    "",                  // RTD_UNKNOWN
232bc2ed2b3Sopenharmony_ci    "54",                // 0x54, RTD_TEXT
233bc2ed2b3Sopenharmony_ci    "55",                // 0x55, RTD_URI
234bc2ed2b3Sopenharmony_ci};
235bc2ed2b3Sopenharmony_ci
236bc2ed2b3Sopenharmony_ci}  // namespace KITS
237bc2ed2b3Sopenharmony_ci}  // namespace NFC
238bc2ed2b3Sopenharmony_ci}  // namespace OHOS
239bc2ed2b3Sopenharmony_ci#endif  // NDEF_MESSAGE_H
240