1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains definitions for some utility functions to help parse
22  *  and build NFC Data Exchange Format (NDEF) messages
23  *
24  ******************************************************************************/
25 
26 #ifndef NDEF_UTILS_H
27 #define NDEF_UTILS_H
28 
29 #include "bt_types.h"
30 
31 #define NDEF_MB_MASK 0x80  /* Message Begin */
32 #define NDEF_ME_MASK 0x40  /* Message End */
33 #define NDEF_CF_MASK 0x20  /* Chunk Flag */
34 #define NDEF_SR_MASK 0x10  /* Short Record */
35 #define NDEF_IL_MASK 0x08  /* ID Length */
36 #define NDEF_TNF_MASK 0x07 /* Type Name Format */
37 /* First valid ASCII as per RTD specification */
38 #define NDEF_RTD_VALID_START 0x20
39 /* Last valid ASCII as per RTD specification */
40 #define NDEF_RTD_VALID_END 0x7E
41 
42 /* NDEF Type Name Format */
43 #define NDEF_TNF_EMPTY 0     /* Empty (type/id/payload len =0) */
44 #define NDEF_TNF_WKT 1       /* NFC Forum well-known type/RTD */
45 #define NDEF_TNF_MEDIA 2     /* Media-type as defined in RFC 2046 */
46 #define NDEF_TNF_URI 3       /* Absolute URI as defined in RFC 3986 */
47 #define NDEF_TNF_EXT 4       /* NFC Forum external type/RTD */
48 #define NDEF_TNF_UNKNOWN 5   /* Unknown (type len =0) */
49 #define NDEF_TNF_UNCHANGED 6 /* Unchanged (type len =0) */
50 #define NDEF_TNF_RESERVED 7  /* Reserved */
51 
52 /* Define the status code returned from the Validate, Parse or Build functions
53 */
54 enum {
55   NDEF_OK, /* 0 - OK                                   */
56 
57   NDEF_REC_NOT_FOUND,         /* 1 - No record matching the find criteria */
58   NDEF_MSG_TOO_SHORT,         /* 2 - Message was too short (< 3 bytes)    */
59   NDEF_MSG_NO_MSG_BEGIN,      /* 3 - No 'begin' flag at start of message  */
60   NDEF_MSG_NO_MSG_END,        /* 4 - No 'end' flag at end of message      */
61   NDEF_MSG_EXTRA_MSG_BEGIN,   /* 5 - 'begin' flag after start of message  */
62   NDEF_MSG_UNEXPECTED_CHUNK,  /* 6 - Unexpected chunk found               */
63   NDEF_MSG_INVALID_EMPTY_REC, /* 7 - Empty record with non-zero contents  */
64   NDEF_MSG_INVALID_CHUNK,     /* 8 - Invalid chunk found                  */
65   NDEF_MSG_LENGTH_MISMATCH,   /* 9 - Overall message length doesn't match */
66   NDEF_MSG_INSUFFICIENT_MEM,  /* 10 - Insuffiecient memory to add record  */
67   NDEF_MSG_INVALID_TYPE       /* 11 - TYPE field contains invalid characters  */
68 };
69 typedef uint8_t tNDEF_STATUS;
70 
71 /* Functions to parse a received NDEF Message
72 */
73 /*******************************************************************************
74 **
75 ** Function         NDEF_MsgValidate
76 **
77 ** Description      This function validates an NDEF message.
78 **
79 ** Returns          TRUE if all OK, or FALSE if the message is invalid.
80 **
81 *******************************************************************************/
82 extern tNDEF_STATUS NDEF_MsgValidate(uint8_t* p_msg, uint32_t msg_len,
83                                      bool b_allow_chunks);
84 
85 /*******************************************************************************
86 **
87 ** Function         NDEF_MsgGetNumRecs
88 **
89 ** Description      This function gets the number of records in the given NDEF
90 **                  message.
91 **
92 ** Returns          The record count, or 0 if the message is invalid.
93 **
94 *******************************************************************************/
95 extern int32_t NDEF_MsgGetNumRecs(uint8_t* p_msg);
96 
97 /*******************************************************************************
98 **
99 ** Function         NDEF_MsgGetRecLength
100 **
101 ** Description      This function returns length of the current record in the
102 **                  given NDEF message.
103 **
104 ** Returns          Length of record
105 **
106 *******************************************************************************/
107 extern uint32_t NDEF_MsgGetRecLength(uint8_t* p_cur_rec);
108 
109 /*******************************************************************************
110 **
111 ** Function         NDEF_MsgGetNextRec
112 **
113 ** Description      This function gets a pointer to the next record after the
114 **                  current one.
115 **
116 ** Returns          Pointer to the start of the record, or NULL if no more
117 **
118 *******************************************************************************/
119 extern uint8_t* NDEF_MsgGetNextRec(uint8_t* p_cur_rec);
120 
121 /*******************************************************************************
122 **
123 ** Function         NDEF_MsgGetRecByIndex
124 **
125 ** Description      This function gets a pointer to the record with the given
126 **                  index (0-based index) in the given NDEF message.
127 **
128 ** Returns          Pointer to the start of the record, or NULL
129 **
130 *******************************************************************************/
131 extern uint8_t* NDEF_MsgGetRecByIndex(uint8_t* p_msg, int32_t index);
132 
133 /*******************************************************************************
134 **
135 ** Function         NDEF_MsgGetLastRecInMsg
136 **
137 ** Description      This function gets a pointer to the last record in the
138 **                  given NDEF message.
139 **
140 ** Returns          Pointer to the start of the last record, or NULL if some
141 **                  problem
142 **
143 *******************************************************************************/
144 extern uint8_t* NDEF_MsgGetLastRecInMsg(uint8_t* p_msg);
145 
146 /*******************************************************************************
147 **
148 ** Function         NDEF_MsgGetFirstRecByType
149 **
150 ** Description      This function gets a pointer to the first record with the
151 **                  given record type in the given NDEF message.
152 **
153 ** Returns          Pointer to the start of the record, or NULL
154 **
155 *******************************************************************************/
156 extern uint8_t* NDEF_MsgGetFirstRecByType(uint8_t* p_msg, uint8_t tnf,
157                                           uint8_t* p_type, uint8_t tlen);
158 
159 /*******************************************************************************
160 **
161 ** Function         NDEF_MsgGetNextRecByType
162 **
163 ** Description      This function gets a pointer to the next record with the
164 **                  given record type in the given NDEF message.
165 **
166 ** Returns          Pointer to the start of the record, or NULL
167 **
168 *******************************************************************************/
169 extern uint8_t* NDEF_MsgGetNextRecByType(uint8_t* p_cur_rec, uint8_t tnf,
170                                          uint8_t* p_type, uint8_t tlen);
171 
172 /*******************************************************************************
173 **
174 ** Function         NDEF_MsgGetFirstRecById
175 **
176 ** Description      This function gets a pointer to the first record with the
177 **                  given record id in the given NDEF message.
178 **
179 ** Returns          Pointer to the start of the record, or NULL
180 **
181 *******************************************************************************/
182 extern uint8_t* NDEF_MsgGetFirstRecById(uint8_t* p_msg, uint8_t* p_id,
183                                         uint8_t ilen);
184 
185 /*******************************************************************************
186 **
187 ** Function         NDEF_MsgGetNextRecById
188 **
189 ** Description      This function gets a pointer to the next record with the
190 **                  given record id in the given NDEF message.
191 **
192 ** Returns          Pointer to the start of the record, or NULL
193 **
194 *******************************************************************************/
195 extern uint8_t* NDEF_MsgGetNextRecById(uint8_t* p_cur_rec, uint8_t* p_id,
196                                        uint8_t ilen);
197 
198 /*******************************************************************************
199 **
200 ** Function         NDEF_RecGetType
201 **
202 ** Description      This function gets a pointer to the record type for the
203 **                  given NDEF record.
204 **
205 ** Returns          Pointer to Type (NULL if none). TNF and len are filled in.
206 **
207 *******************************************************************************/
208 extern uint8_t* NDEF_RecGetType(uint8_t* p_rec, uint8_t* p_tnf,
209                                 uint8_t* p_type_len);
210 
211 /*******************************************************************************
212 **
213 ** Function         NDEF_RecGetId
214 **
215 ** Description      This function gets a pointer to the record id for the given
216 **                  NDEF record.
217 **
218 ** Returns          Pointer to Id (NULL if none). ID Len is filled in.
219 **
220 *******************************************************************************/
221 extern uint8_t* NDEF_RecGetId(uint8_t* p_rec, uint8_t* p_id_len);
222 
223 /*******************************************************************************
224 **
225 ** Function         NDEF_RecGetPayload
226 **
227 ** Description      This function gets a pointer to the payload for the given
228 **                  NDEF record.
229 **
230 ** Returns          a pointer to the payload (NULL if none). Payload len filled
231 **                  in.
232 **
233 *******************************************************************************/
234 extern uint8_t* NDEF_RecGetPayload(uint8_t* p_rec, uint32_t* p_payload_len);
235 
236 /* Functions to build an NDEF Message
237 */
238 /*******************************************************************************
239 **
240 ** Function         NDEF_MsgInit
241 **
242 ** Description      This function initializes an NDEF message.
243 **
244 ** Returns          void
245 **                  *p_cur_size is initialized to 0
246 **
247 *******************************************************************************/
248 extern void NDEF_MsgInit(uint8_t* p_msg, uint32_t max_size,
249                          uint32_t* p_cur_size);
250 
251 /*******************************************************************************
252 **
253 ** Function         NDEF_MsgAddRec
254 **
255 ** Description      This function adds an NDEF record to the end of an NDEF
256 **                  message.
257 **
258 ** Returns          OK, or error if the record did not fit
259 **                  *p_cur_size is updated
260 **
261 *******************************************************************************/
262 extern tNDEF_STATUS NDEF_MsgAddRec(uint8_t* p_msg, uint32_t max_size,
263                                    uint32_t* p_cur_size, uint8_t tnf,
264                                    uint8_t* p_type, uint8_t type_len,
265                                    uint8_t* p_id, uint8_t id_len,
266                                    uint8_t* p_payload, uint32_t payload_len);
267 
268 /*******************************************************************************
269 **
270 ** Function         NDEF_MsgAppendPayload
271 **
272 ** Description      This function appends extra payload to a specific record in
273 **                  the given NDEF message
274 **
275 ** Returns          OK, or error if the extra payload did not fit
276 **                  *p_cur_size is updated
277 **
278 *******************************************************************************/
279 extern tNDEF_STATUS NDEF_MsgAppendPayload(uint8_t* p_msg, uint32_t max_size,
280                                           uint32_t* p_cur_size, uint8_t* p_rec,
281                                           uint8_t* p_add_pl,
282                                           uint32_t add_pl_len);
283 
284 /*******************************************************************************
285 **
286 ** Function         NDEF_MsgReplacePayload
287 **
288 ** Description      This function replaces the payload of a specific record in
289 **                  the given NDEF message
290 **
291 ** Returns          OK, or error if the new payload did not fit
292 **                  *p_cur_size is updated
293 **
294 *******************************************************************************/
295 extern tNDEF_STATUS NDEF_MsgReplacePayload(uint8_t* p_msg, uint32_t max_size,
296                                            uint32_t* p_cur_size, uint8_t* p_rec,
297                                            uint8_t* p_new_pl,
298                                            uint32_t new_pl_len);
299 
300 /*******************************************************************************
301 **
302 ** Function         NDEF_MsgReplaceType
303 **
304 ** Description      This function replaces the type field of a specific record
305 **                  in the given NDEF message
306 **
307 ** Returns          OK, or error if the new type field did not fit
308 **                  *p_cur_size is updated
309 **
310 *******************************************************************************/
311 extern tNDEF_STATUS NDEF_MsgReplaceType(uint8_t* p_msg, uint32_t max_size,
312                                         uint32_t* p_cur_size, uint8_t* p_rec,
313                                         uint8_t* p_new_type,
314                                         uint8_t new_type_len);
315 
316 /*******************************************************************************
317 **
318 ** Function         NDEF_MsgReplaceId
319 **
320 ** Description      This function replaces the ID field of a specific record in
321 **                  the given NDEF message
322 **
323 ** Returns          OK, or error if the new ID field did not fit
324 **                  *p_cur_size is updated
325 **
326 *******************************************************************************/
327 extern tNDEF_STATUS NDEF_MsgReplaceId(uint8_t* p_msg, uint32_t max_size,
328                                       uint32_t* p_cur_size, uint8_t* p_rec,
329                                       uint8_t* p_new_id, uint8_t new_id_len);
330 
331 /*******************************************************************************
332 **
333 ** Function         NDEF_MsgRemoveRec
334 **
335 ** Description      This function removes the record at the given
336 **                  index in the given NDEF message.
337 **
338 ** Returns          OK, or error if the index was invalid
339 **                  *p_cur_size is updated
340 **
341 *******************************************************************************/
342 extern tNDEF_STATUS NDEF_MsgRemoveRec(uint8_t* p_msg, uint32_t* p_cur_size,
343                                       int32_t index);
344 
345 /*******************************************************************************
346 **
347 ** Function         NDEF_MsgCopyAndDechunk
348 **
349 ** Description      This function copies and de-chunks an NDEF message.
350 **                  It is assumed that the destination is at least as large
351 **                  as the source, since the source may not actually contain
352 **                  any chunks.
353 **
354 ** Returns          The output byte count
355 **
356 *******************************************************************************/
357 extern tNDEF_STATUS NDEF_MsgCopyAndDechunk(uint8_t* p_src, uint32_t src_len,
358                                            uint8_t* p_dest,
359                                            uint32_t* p_out_len);
360 #endif /* NDEF_UTILS_H */
361