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