• 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 int MIN_RECORD_LEN = 3;
91     static const long int MAX_PAYLOAD_SIZE = 10 * (1 << 20);  // 10MB
92     static const int SHORT_RECORD_SIZE = 256;
93     static const uint8_t TYPE_LONG_PAYLOAD_LEN_SIZE = 8;
94     static const unsigned int ONE_BYTE_SHIFT = 8;
95     static const int MAX_NDEF_MESSAGE_LEN = 0xFFFF;
96 
97     // TNF Type define
98     enum EmTnfType {
99         TNF_EMPTY = 0x00,
100         TNF_WELL_KNOWN = 0x01,
101         TNF_MIME_MEDIA = 0x02,
102         TNF_ABSOLUTE_URI = 0x03,
103         TNF_EXTERNAL_TYPE = 0x04,
104         TNF_UNKNOWN = 0x05,
105         TNF_UNCHANGED = 0x06,
106         TNF_RESERVED = 0x07
107     };
108 
109     // record Flag
110     enum EmRecordFlag {
111         FLAG_MB = 0x80,
112         FLAG_ME = 0x40,
113         FLAG_CF = 0x20,
114         FLAG_SR = 0x10,
115         FLAG_IL = 0x08,
116         FLAG_TNF = 0x07
117     };
118 
119     enum EmRtdType {
120         RTD_UNKNOWN = 0,
121         RTD_TEXT,
122         RTD_URI,
123         RTD_SMART_POSTER,
124         RTD_ALTERNATIVE_CARRIER,
125         RTD_HANDOVER_CARRIER,
126         RTD_HANDOVER_REQUEST,
127         RTD_HANDOVER_SELECT,
128         RTD_OHOS_APP,
129         RTD_RESERVED,
130     };
131 public:
132     explicit NdefMessage(std::vector<std::shared_ptr<NdefRecord>> ndefRecords);
133     ~NdefMessage();
134 
135     /**
136      * @Description constructe a ndef message with raw bytes.
137      * @param data raw bytes to parse ndef message
138      * @return std::shared_ptr<NdefMessage>
139      */
140     static std::shared_ptr<NdefMessage> GetNdefMessage(const std::string& data);
141     /**
142      * @Description constructe a ndef message with record list.
143      * @param ndefRecords record list to parse ndef message
144      * @return std::shared_ptr<NdefMessage>
145      */
146     static std::shared_ptr<NdefMessage> GetNdefMessage(std::vector<std::shared_ptr<NdefRecord>> ndefRecords);
147     /**
148      * @Description convert the rtd bytes into byte array defined in Nfc forum.
149      * @param rtdtype rtd type of a record
150      * @return rtd byte array
151      */
152     static std::string GetTagRtdType(EmRtdType rtdtype);
153     /**
154      * @Description Create a ndef record with uri data.
155      * @param uriString uri data for new a ndef record
156      * @return std::shared_ptr<NdefRecord>
157      */
158     static std::shared_ptr<NdefRecord> MakeUriRecord(const std::string& uriString);
159     /**
160      * @Description Create a ndef record with text data.
161      * @param text text data for new a ndef record
162      * @param locale language code for the ndef record . if locale is null, use default locale
163      * @return std::shared_ptr<NdefRecord>
164      */
165     static std::shared_ptr<NdefRecord> MakeTextRecord(const std::string& text, const std::string& locale);
166     /**
167      * @Description Create a ndef record with mime data.
168      * @param mimeType type of mime data for new a ndef record
169      * @param mimeData mime data for new a ndef record
170      * @return std::shared_ptr<NdefRecord>
171      */
172     static std::shared_ptr<NdefRecord> MakeMimeRecord(const std::string& mimeType, const std::string& mimeData);
173 
174     /**
175      * @Description Create a ndef record with external data.
176      * @param domainName domain name of issuing organization for the external data
177      * @param serviceName domain specific type of data for the external data
178      * @param externalData data payload of a ndef record
179      * @return std::shared_ptr<NdefRecord>
180      */
181     static std::shared_ptr<NdefRecord> MakeExternalRecord(const std::string& domainName,
182                                                           const std::string& serviceName,
183                                                           const std::string& externalData);
184 
185     /**
186      * @Description Create a ndef record with package name.
187      * @param packageName package Name of the application
188      * @return std::shared_ptr<NdefRecord>
189      */
190     static std::shared_ptr<NdefRecord> MakeApplicationRecord(const std::string& packageName);
191 
192     /**
193      * @Description parse a ndef message into raw bytes.
194      * @param ndefMessage a ndef message to parse
195      * @return raw bytes of a ndef message
196      */
197     static std::string MessageToString(std::weak_ptr<NdefMessage> ndefMessage);
198     /**
199      * @Description parse a ndef record into raw bytes.
200      * @param record a ndef record to parse
201      * @param buffer raw bytes of a ndef record
202      * @param bIsMB the flag of begin record
203      * @param bIsME the flag of end record
204      * @return void
205      */
206     static void NdefRecordToString(std::weak_ptr<NdefRecord> record, std::string& buffer, bool bIsMB, bool bIsME);
207     /**
208      * @Description Get all records of a ndef message.
209      * @param void
210      * @return record list of a ndef message
211      */
212     std::vector<std::shared_ptr<NdefRecord>> GetNdefRecords() const;
213 
214 private:
215     static std::shared_ptr<NdefRecord> CreateNdefRecord(short tnf, const std::string& id,
216         const std::string& payload, const std::string& tagRtdType);
217     static bool CheckTnf(short tnf, const std::string& tagRtdType,
218         const std::string& id, const std::string& payload);
219     static std::vector<std::shared_ptr<NdefRecord>> ParseRecord(const std::string& data, bool isMbMeIgnored);
220     static void ParseRecordLayoutHead(RecordLayout& layout, unsigned char head);
221     static bool IsInvalidRecordLayoutHead(RecordLayout& layout, bool isChunkFound,
222         uint32_t parsedRecordSize, bool isMbMeIgnored);
223     static void ParseRecordLayoutLength(RecordLayout& layout, bool isChunkFound,
224         const std::string& data, uint32_t& parsedDataIndex);
225     static bool IsRecordLayoutLengthInvalid(RecordLayout& layout, bool isChunkFound);
226     static std::string ParseRecordType(RecordLayout& layout, const std::string& data, uint32_t& parsedDataIndex);
227     static std::string ParseRecordId(RecordLayout& layout, const std::string& data, uint32_t& parsedDataIndex);
228     static std::string ParseRecordPayload(RecordLayout& layout, const std::string& data, uint32_t& parsedDataIndex);
229 
230     static void SaveRecordChunks(RecordLayout& layout, bool isChunkFound, std::vector<std::string>& chunks,
231         char& chunkTnf, const std::string& payload);
232     static std::string MergePayloadByChunks(RecordLayout& layout, bool isChunkFound, std::vector<std::string>& chunks,
233         char chunkTnf, const std::string& payload);
234 
235 private:
236     std::vector<std::shared_ptr<NdefRecord>> ndefRecordList_ {};
237 };
238 
239 // RTD types definitions, see NFC Record Type Definition (RTD) Specification.
240 const static std::array<std::string, NdefMessage::EmRtdType::RTD_RESERVED> HEX_RTD_TYPE = {
241     "",                  // RTD_UNKNOWN
242     "54",                // 0x54, RTD_TEXT
243     "55",                // 0x55, RTD_URI
244 };
245 
246 }  // namespace KITS
247 }  // namespace NFC
248 }  // namespace OHOS
249 #endif  // NDEF_MESSAGE_H
250