1*7eba2f3bSAndroid Build Coastguard Worker /******************************************************************************
2*7eba2f3bSAndroid Build Coastguard Worker *
3*7eba2f3bSAndroid Build Coastguard Worker * Copyright (C) 2010-2014 Broadcom Corporation
4*7eba2f3bSAndroid Build Coastguard Worker *
5*7eba2f3bSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*7eba2f3bSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*7eba2f3bSAndroid Build Coastguard Worker * You may obtain a copy of the License at:
8*7eba2f3bSAndroid Build Coastguard Worker *
9*7eba2f3bSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*7eba2f3bSAndroid Build Coastguard Worker *
11*7eba2f3bSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*7eba2f3bSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*7eba2f3bSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*7eba2f3bSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*7eba2f3bSAndroid Build Coastguard Worker * limitations under the License.
16*7eba2f3bSAndroid Build Coastguard Worker *
17*7eba2f3bSAndroid Build Coastguard Worker ******************************************************************************/
18*7eba2f3bSAndroid Build Coastguard Worker
19*7eba2f3bSAndroid Build Coastguard Worker /******************************************************************************
20*7eba2f3bSAndroid Build Coastguard Worker *
21*7eba2f3bSAndroid Build Coastguard Worker * This file contains source code for some utility functions to help parse
22*7eba2f3bSAndroid Build Coastguard Worker * and build NFC Data Exchange Format (NDEF) messages
23*7eba2f3bSAndroid Build Coastguard Worker *
24*7eba2f3bSAndroid Build Coastguard Worker ******************************************************************************/
25*7eba2f3bSAndroid Build Coastguard Worker #include "ndef_utils.h"
26*7eba2f3bSAndroid Build Coastguard Worker
27*7eba2f3bSAndroid Build Coastguard Worker #include <log/log.h>
28*7eba2f3bSAndroid Build Coastguard Worker #include <string.h>
29*7eba2f3bSAndroid Build Coastguard Worker
30*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
31*7eba2f3bSAndroid Build Coastguard Worker **
32*7eba2f3bSAndroid Build Coastguard Worker ** Static Local Functions
33*7eba2f3bSAndroid Build Coastguard Worker **
34*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
35*7eba2f3bSAndroid Build Coastguard Worker
36*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
37*7eba2f3bSAndroid Build Coastguard Worker **
38*7eba2f3bSAndroid Build Coastguard Worker ** Function shiftdown
39*7eba2f3bSAndroid Build Coastguard Worker **
40*7eba2f3bSAndroid Build Coastguard Worker ** Description shift memory down (to make space to insert a record)
41*7eba2f3bSAndroid Build Coastguard Worker **
42*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
shiftdown(uint8_t * p_mem,uint32_t len,uint32_t shift_amount)43*7eba2f3bSAndroid Build Coastguard Worker static void shiftdown(uint8_t* p_mem, uint32_t len, uint32_t shift_amount) {
44*7eba2f3bSAndroid Build Coastguard Worker uint8_t* ps = p_mem + len - 1;
45*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pd = ps + shift_amount;
46*7eba2f3bSAndroid Build Coastguard Worker uint32_t xx;
47*7eba2f3bSAndroid Build Coastguard Worker
48*7eba2f3bSAndroid Build Coastguard Worker for (xx = 0; xx < len; xx++) *pd-- = *ps--;
49*7eba2f3bSAndroid Build Coastguard Worker }
50*7eba2f3bSAndroid Build Coastguard Worker
51*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
52*7eba2f3bSAndroid Build Coastguard Worker **
53*7eba2f3bSAndroid Build Coastguard Worker ** Function shiftup
54*7eba2f3bSAndroid Build Coastguard Worker **
55*7eba2f3bSAndroid Build Coastguard Worker ** Description shift memory up (to delete a record)
56*7eba2f3bSAndroid Build Coastguard Worker **
57*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
shiftup(uint8_t * p_dest,uint8_t * p_src,uint32_t len)58*7eba2f3bSAndroid Build Coastguard Worker static void shiftup(uint8_t* p_dest, uint8_t* p_src, uint32_t len) {
59*7eba2f3bSAndroid Build Coastguard Worker uint8_t* ps = p_src;
60*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pd = p_dest;
61*7eba2f3bSAndroid Build Coastguard Worker uint32_t xx;
62*7eba2f3bSAndroid Build Coastguard Worker
63*7eba2f3bSAndroid Build Coastguard Worker for (xx = 0; xx < len; xx++) *pd++ = *ps++;
64*7eba2f3bSAndroid Build Coastguard Worker }
65*7eba2f3bSAndroid Build Coastguard Worker
66*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
67*7eba2f3bSAndroid Build Coastguard Worker **
68*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgValidate
69*7eba2f3bSAndroid Build Coastguard Worker **
70*7eba2f3bSAndroid Build Coastguard Worker ** Description This function validates an NDEF message.
71*7eba2f3bSAndroid Build Coastguard Worker **
72*7eba2f3bSAndroid Build Coastguard Worker ** Returns TRUE if all OK, or FALSE if the message is invalid.
73*7eba2f3bSAndroid Build Coastguard Worker **
74*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgValidate(uint8_t * p_msg,uint32_t msg_len,bool b_allow_chunks)75*7eba2f3bSAndroid Build Coastguard Worker tNDEF_STATUS NDEF_MsgValidate(uint8_t* p_msg, uint32_t msg_len,
76*7eba2f3bSAndroid Build Coastguard Worker bool b_allow_chunks) {
77*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec = p_msg;
78*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_end = p_msg + msg_len;
79*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_new;
80*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr = 0, type_len, id_len;
81*7eba2f3bSAndroid Build Coastguard Worker int count;
82*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
83*7eba2f3bSAndroid Build Coastguard Worker bool bInChunk = false;
84*7eba2f3bSAndroid Build Coastguard Worker
85*7eba2f3bSAndroid Build Coastguard Worker if ((p_msg == nullptr) || (msg_len < 3)) return (NDEF_MSG_TOO_SHORT);
86*7eba2f3bSAndroid Build Coastguard Worker
87*7eba2f3bSAndroid Build Coastguard Worker /* The first record must have the MB bit set */
88*7eba2f3bSAndroid Build Coastguard Worker if ((*p_msg & NDEF_MB_MASK) == 0) return (NDEF_MSG_NO_MSG_BEGIN);
89*7eba2f3bSAndroid Build Coastguard Worker
90*7eba2f3bSAndroid Build Coastguard Worker /* The first record cannot be a chunk */
91*7eba2f3bSAndroid Build Coastguard Worker if ((*p_msg & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
92*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_UNEXPECTED_CHUNK);
93*7eba2f3bSAndroid Build Coastguard Worker
94*7eba2f3bSAndroid Build Coastguard Worker for (count = 0; p_rec < p_end; count++) {
95*7eba2f3bSAndroid Build Coastguard Worker /* if less than short record header */
96*7eba2f3bSAndroid Build Coastguard Worker if (p_rec + 3 > p_end) return (NDEF_MSG_TOO_SHORT);
97*7eba2f3bSAndroid Build Coastguard Worker
98*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
99*7eba2f3bSAndroid Build Coastguard Worker
100*7eba2f3bSAndroid Build Coastguard Worker /* header should have a valid TNF */
101*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_MASK)
102*7eba2f3bSAndroid Build Coastguard Worker return NDEF_MSG_INVALID_CHUNK;
103*7eba2f3bSAndroid Build Coastguard Worker
104*7eba2f3bSAndroid Build Coastguard Worker /* The second and all subsequent records must NOT have the MB bit set */
105*7eba2f3bSAndroid Build Coastguard Worker if ((count > 0) && (rec_hdr & NDEF_MB_MASK))
106*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_EXTRA_MSG_BEGIN);
107*7eba2f3bSAndroid Build Coastguard Worker
108*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
109*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
110*7eba2f3bSAndroid Build Coastguard Worker
111*7eba2f3bSAndroid Build Coastguard Worker /* If the record is chunked, first record must contain the type unless
112*7eba2f3bSAndroid Build Coastguard Worker * it's Type Name Format is Unknown */
113*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_CF_MASK) && (rec_hdr & NDEF_MB_MASK) && type_len == 0 &&
114*7eba2f3bSAndroid Build Coastguard Worker (rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNKNOWN)
115*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INVALID_CHUNK);
116*7eba2f3bSAndroid Build Coastguard Worker
117*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
118*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
119*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_rec++;
120*7eba2f3bSAndroid Build Coastguard Worker else {
121*7eba2f3bSAndroid Build Coastguard Worker /* if less than 4 bytes payload length */
122*7eba2f3bSAndroid Build Coastguard Worker if (p_rec + 4 > p_end) return (NDEF_MSG_TOO_SHORT);
123*7eba2f3bSAndroid Build Coastguard Worker
124*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_rec);
125*7eba2f3bSAndroid Build Coastguard Worker }
126*7eba2f3bSAndroid Build Coastguard Worker
127*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
128*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK) {
129*7eba2f3bSAndroid Build Coastguard Worker /* if less than 1 byte ID field length */
130*7eba2f3bSAndroid Build Coastguard Worker if (p_rec + 1 > p_end) return (NDEF_MSG_TOO_SHORT);
131*7eba2f3bSAndroid Build Coastguard Worker
132*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_rec++;
133*7eba2f3bSAndroid Build Coastguard Worker } else {
134*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
135*7eba2f3bSAndroid Build Coastguard Worker /* Empty record must have the id_len */
136*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EMPTY)
137*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INVALID_EMPTY_REC);
138*7eba2f3bSAndroid Build Coastguard Worker }
139*7eba2f3bSAndroid Build Coastguard Worker
140*7eba2f3bSAndroid Build Coastguard Worker /* A chunk must have type "unchanged", and no type or ID fields */
141*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_CF_MASK) {
142*7eba2f3bSAndroid Build Coastguard Worker if (!b_allow_chunks) return (NDEF_MSG_UNEXPECTED_CHUNK);
143*7eba2f3bSAndroid Build Coastguard Worker
144*7eba2f3bSAndroid Build Coastguard Worker /* Inside a chunk, the type must be unchanged and no type or ID field i
145*7eba2f3bSAndroid Build Coastguard Worker * sallowed */
146*7eba2f3bSAndroid Build Coastguard Worker if (bInChunk) {
147*7eba2f3bSAndroid Build Coastguard Worker if ((type_len != 0) || (id_len != 0) ||
148*7eba2f3bSAndroid Build Coastguard Worker ((rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNCHANGED))
149*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INVALID_CHUNK);
150*7eba2f3bSAndroid Build Coastguard Worker } else {
151*7eba2f3bSAndroid Build Coastguard Worker /* First record of a chunk must NOT have type "unchanged" */
152*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
153*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INVALID_CHUNK);
154*7eba2f3bSAndroid Build Coastguard Worker
155*7eba2f3bSAndroid Build Coastguard Worker bInChunk = true;
156*7eba2f3bSAndroid Build Coastguard Worker }
157*7eba2f3bSAndroid Build Coastguard Worker } else {
158*7eba2f3bSAndroid Build Coastguard Worker /* This may be the last guy in a chunk. */
159*7eba2f3bSAndroid Build Coastguard Worker if (bInChunk) {
160*7eba2f3bSAndroid Build Coastguard Worker if ((type_len != 0) || (id_len != 0) ||
161*7eba2f3bSAndroid Build Coastguard Worker ((rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNCHANGED))
162*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INVALID_CHUNK);
163*7eba2f3bSAndroid Build Coastguard Worker
164*7eba2f3bSAndroid Build Coastguard Worker bInChunk = false;
165*7eba2f3bSAndroid Build Coastguard Worker } else {
166*7eba2f3bSAndroid Build Coastguard Worker /* If not in a chunk, the record must NOT have type "unchanged" */
167*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
168*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INVALID_CHUNK);
169*7eba2f3bSAndroid Build Coastguard Worker }
170*7eba2f3bSAndroid Build Coastguard Worker }
171*7eba2f3bSAndroid Build Coastguard Worker
172*7eba2f3bSAndroid Build Coastguard Worker /* An empty record must NOT have a type, ID or payload */
173*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EMPTY) {
174*7eba2f3bSAndroid Build Coastguard Worker if ((type_len != 0) || (id_len != 0) || (payload_len != 0))
175*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INVALID_EMPTY_REC);
176*7eba2f3bSAndroid Build Coastguard Worker }
177*7eba2f3bSAndroid Build Coastguard Worker
178*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNKNOWN) {
179*7eba2f3bSAndroid Build Coastguard Worker if (type_len != 0) return (NDEF_MSG_LENGTH_MISMATCH);
180*7eba2f3bSAndroid Build Coastguard Worker }
181*7eba2f3bSAndroid Build Coastguard Worker
182*7eba2f3bSAndroid Build Coastguard Worker /* External type should have non-zero type length */
183*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EXT) {
184*7eba2f3bSAndroid Build Coastguard Worker if (type_len == 0) return (NDEF_MSG_LENGTH_MISMATCH);
185*7eba2f3bSAndroid Build Coastguard Worker }
186*7eba2f3bSAndroid Build Coastguard Worker
187*7eba2f3bSAndroid Build Coastguard Worker /* External type and Well Known types should have valid characters
188*7eba2f3bSAndroid Build Coastguard Worker in the TYPE field */
189*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EXT ||
190*7eba2f3bSAndroid Build Coastguard Worker (rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_WKT) {
191*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec_type = p_rec;
192*7eba2f3bSAndroid Build Coastguard Worker if ((p_rec_type + type_len) > p_end) return (NDEF_MSG_TOO_SHORT);
193*7eba2f3bSAndroid Build Coastguard Worker
194*7eba2f3bSAndroid Build Coastguard Worker for (int type_index = 0; type_index < type_len; type_index++) {
195*7eba2f3bSAndroid Build Coastguard Worker if (p_rec_type[type_index] < NDEF_RTD_VALID_START ||
196*7eba2f3bSAndroid Build Coastguard Worker p_rec_type[type_index] > NDEF_RTD_VALID_END)
197*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INVALID_TYPE);
198*7eba2f3bSAndroid Build Coastguard Worker }
199*7eba2f3bSAndroid Build Coastguard Worker }
200*7eba2f3bSAndroid Build Coastguard Worker
201*7eba2f3bSAndroid Build Coastguard Worker /* Check for OOB */
202*7eba2f3bSAndroid Build Coastguard Worker if (payload_len + type_len + id_len < payload_len ||
203*7eba2f3bSAndroid Build Coastguard Worker payload_len + type_len + id_len > msg_len) {
204*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_LENGTH_MISMATCH);
205*7eba2f3bSAndroid Build Coastguard Worker }
206*7eba2f3bSAndroid Build Coastguard Worker p_new = p_rec + (payload_len + type_len + id_len);
207*7eba2f3bSAndroid Build Coastguard Worker if (p_rec > p_new || p_end < p_new) {
208*7eba2f3bSAndroid Build Coastguard Worker android_errorWriteLog(0x534e4554, "126200054");
209*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_LENGTH_MISMATCH);
210*7eba2f3bSAndroid Build Coastguard Worker }
211*7eba2f3bSAndroid Build Coastguard Worker
212*7eba2f3bSAndroid Build Coastguard Worker /* Point to next record */
213*7eba2f3bSAndroid Build Coastguard Worker p_rec += (payload_len + type_len + id_len);
214*7eba2f3bSAndroid Build Coastguard Worker
215*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_ME_MASK) break;
216*7eba2f3bSAndroid Build Coastguard Worker
217*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = 0;
218*7eba2f3bSAndroid Build Coastguard Worker }
219*7eba2f3bSAndroid Build Coastguard Worker
220*7eba2f3bSAndroid Build Coastguard Worker /* The last record should have the ME bit set */
221*7eba2f3bSAndroid Build Coastguard Worker if ((rec_hdr & NDEF_ME_MASK) == 0) return (NDEF_MSG_NO_MSG_END);
222*7eba2f3bSAndroid Build Coastguard Worker
223*7eba2f3bSAndroid Build Coastguard Worker /* p_rec should equal p_end if all the length fields were correct */
224*7eba2f3bSAndroid Build Coastguard Worker if (p_rec != p_end) return (NDEF_MSG_LENGTH_MISMATCH);
225*7eba2f3bSAndroid Build Coastguard Worker
226*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_OK);
227*7eba2f3bSAndroid Build Coastguard Worker }
228*7eba2f3bSAndroid Build Coastguard Worker
229*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
230*7eba2f3bSAndroid Build Coastguard Worker **
231*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgGetNumRecs
232*7eba2f3bSAndroid Build Coastguard Worker **
233*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets the number of records in the given NDEF
234*7eba2f3bSAndroid Build Coastguard Worker ** message.
235*7eba2f3bSAndroid Build Coastguard Worker **
236*7eba2f3bSAndroid Build Coastguard Worker ** Returns The record count, or 0 if the message is invalid.
237*7eba2f3bSAndroid Build Coastguard Worker **
238*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgGetNumRecs(uint8_t * p_msg)239*7eba2f3bSAndroid Build Coastguard Worker int32_t NDEF_MsgGetNumRecs(uint8_t* p_msg) {
240*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec = p_msg;
241*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
242*7eba2f3bSAndroid Build Coastguard Worker int count;
243*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
244*7eba2f3bSAndroid Build Coastguard Worker
245*7eba2f3bSAndroid Build Coastguard Worker for (count = 0;;) {
246*7eba2f3bSAndroid Build Coastguard Worker count++;
247*7eba2f3bSAndroid Build Coastguard Worker
248*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
249*7eba2f3bSAndroid Build Coastguard Worker
250*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_ME_MASK) break;
251*7eba2f3bSAndroid Build Coastguard Worker
252*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
253*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
254*7eba2f3bSAndroid Build Coastguard Worker
255*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
256*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
257*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_rec++;
258*7eba2f3bSAndroid Build Coastguard Worker else
259*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_rec);
260*7eba2f3bSAndroid Build Coastguard Worker
261*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
262*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
263*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_rec++;
264*7eba2f3bSAndroid Build Coastguard Worker else
265*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
266*7eba2f3bSAndroid Build Coastguard Worker
267*7eba2f3bSAndroid Build Coastguard Worker /* Point to next record */
268*7eba2f3bSAndroid Build Coastguard Worker p_rec += (payload_len + type_len + id_len);
269*7eba2f3bSAndroid Build Coastguard Worker }
270*7eba2f3bSAndroid Build Coastguard Worker
271*7eba2f3bSAndroid Build Coastguard Worker /* Return the number of records found */
272*7eba2f3bSAndroid Build Coastguard Worker return (count);
273*7eba2f3bSAndroid Build Coastguard Worker }
274*7eba2f3bSAndroid Build Coastguard Worker
275*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
276*7eba2f3bSAndroid Build Coastguard Worker **
277*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgGetRecLength
278*7eba2f3bSAndroid Build Coastguard Worker **
279*7eba2f3bSAndroid Build Coastguard Worker ** Description This function returns length of the current record in the
280*7eba2f3bSAndroid Build Coastguard Worker ** given NDEF message.
281*7eba2f3bSAndroid Build Coastguard Worker **
282*7eba2f3bSAndroid Build Coastguard Worker ** Returns Length of record
283*7eba2f3bSAndroid Build Coastguard Worker **
284*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgGetRecLength(uint8_t * p_cur_rec)285*7eba2f3bSAndroid Build Coastguard Worker uint32_t NDEF_MsgGetRecLength(uint8_t* p_cur_rec) {
286*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
287*7eba2f3bSAndroid Build Coastguard Worker uint32_t rec_len = 0;
288*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
289*7eba2f3bSAndroid Build Coastguard Worker
290*7eba2f3bSAndroid Build Coastguard Worker /* Get the current record's header */
291*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_cur_rec++;
292*7eba2f3bSAndroid Build Coastguard Worker rec_len++;
293*7eba2f3bSAndroid Build Coastguard Worker
294*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
295*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_cur_rec++;
296*7eba2f3bSAndroid Build Coastguard Worker rec_len++;
297*7eba2f3bSAndroid Build Coastguard Worker
298*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
299*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK) {
300*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_cur_rec++;
301*7eba2f3bSAndroid Build Coastguard Worker rec_len++;
302*7eba2f3bSAndroid Build Coastguard Worker } else {
303*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_cur_rec);
304*7eba2f3bSAndroid Build Coastguard Worker rec_len += 4;
305*7eba2f3bSAndroid Build Coastguard Worker }
306*7eba2f3bSAndroid Build Coastguard Worker
307*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
308*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK) {
309*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_cur_rec++;
310*7eba2f3bSAndroid Build Coastguard Worker rec_len++;
311*7eba2f3bSAndroid Build Coastguard Worker } else
312*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
313*7eba2f3bSAndroid Build Coastguard Worker
314*7eba2f3bSAndroid Build Coastguard Worker /* Total length of record */
315*7eba2f3bSAndroid Build Coastguard Worker rec_len += (payload_len + type_len + id_len);
316*7eba2f3bSAndroid Build Coastguard Worker
317*7eba2f3bSAndroid Build Coastguard Worker return (rec_len);
318*7eba2f3bSAndroid Build Coastguard Worker }
319*7eba2f3bSAndroid Build Coastguard Worker
320*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
321*7eba2f3bSAndroid Build Coastguard Worker **
322*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgGetNextRec
323*7eba2f3bSAndroid Build Coastguard Worker **
324*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the next record in the given
325*7eba2f3bSAndroid Build Coastguard Worker ** NDEF message. If the current record pointer is NULL, a
326*7eba2f3bSAndroid Build Coastguard Worker ** pointer to the first record is returned.
327*7eba2f3bSAndroid Build Coastguard Worker **
328*7eba2f3bSAndroid Build Coastguard Worker ** Returns Pointer to the start of the record, or NULL if no more
329*7eba2f3bSAndroid Build Coastguard Worker **
330*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgGetNextRec(uint8_t * p_cur_rec)331*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_MsgGetNextRec(uint8_t* p_cur_rec) {
332*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
333*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
334*7eba2f3bSAndroid Build Coastguard Worker
335*7eba2f3bSAndroid Build Coastguard Worker /* Get the current record's header */
336*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_cur_rec++;
337*7eba2f3bSAndroid Build Coastguard Worker
338*7eba2f3bSAndroid Build Coastguard Worker /* If this is the last record, return NULL */
339*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_ME_MASK) return (nullptr);
340*7eba2f3bSAndroid Build Coastguard Worker
341*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
342*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_cur_rec++;
343*7eba2f3bSAndroid Build Coastguard Worker
344*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
345*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
346*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_cur_rec++;
347*7eba2f3bSAndroid Build Coastguard Worker else
348*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_cur_rec);
349*7eba2f3bSAndroid Build Coastguard Worker
350*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
351*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
352*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_cur_rec++;
353*7eba2f3bSAndroid Build Coastguard Worker else
354*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
355*7eba2f3bSAndroid Build Coastguard Worker
356*7eba2f3bSAndroid Build Coastguard Worker /* Point to next record */
357*7eba2f3bSAndroid Build Coastguard Worker p_cur_rec += (payload_len + type_len + id_len);
358*7eba2f3bSAndroid Build Coastguard Worker
359*7eba2f3bSAndroid Build Coastguard Worker return (p_cur_rec);
360*7eba2f3bSAndroid Build Coastguard Worker }
361*7eba2f3bSAndroid Build Coastguard Worker
362*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
363*7eba2f3bSAndroid Build Coastguard Worker **
364*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgGetRecByIndex
365*7eba2f3bSAndroid Build Coastguard Worker **
366*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the record with the given
367*7eba2f3bSAndroid Build Coastguard Worker ** index (0-based index) in the given NDEF message.
368*7eba2f3bSAndroid Build Coastguard Worker **
369*7eba2f3bSAndroid Build Coastguard Worker ** Returns Pointer to the start of the record, or NULL
370*7eba2f3bSAndroid Build Coastguard Worker **
371*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgGetRecByIndex(uint8_t * p_msg,int32_t index)372*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_MsgGetRecByIndex(uint8_t* p_msg, int32_t index) {
373*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec = p_msg;
374*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
375*7eba2f3bSAndroid Build Coastguard Worker int32_t count;
376*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
377*7eba2f3bSAndroid Build Coastguard Worker
378*7eba2f3bSAndroid Build Coastguard Worker for (count = 0;; count++) {
379*7eba2f3bSAndroid Build Coastguard Worker if (count == index) return (p_rec);
380*7eba2f3bSAndroid Build Coastguard Worker
381*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
382*7eba2f3bSAndroid Build Coastguard Worker
383*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_ME_MASK) return (nullptr);
384*7eba2f3bSAndroid Build Coastguard Worker
385*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
386*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
387*7eba2f3bSAndroid Build Coastguard Worker
388*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
389*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
390*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_rec++;
391*7eba2f3bSAndroid Build Coastguard Worker else
392*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_rec);
393*7eba2f3bSAndroid Build Coastguard Worker
394*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
395*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
396*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_rec++;
397*7eba2f3bSAndroid Build Coastguard Worker else
398*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
399*7eba2f3bSAndroid Build Coastguard Worker
400*7eba2f3bSAndroid Build Coastguard Worker /* Point to next record */
401*7eba2f3bSAndroid Build Coastguard Worker p_rec += (payload_len + type_len + id_len);
402*7eba2f3bSAndroid Build Coastguard Worker }
403*7eba2f3bSAndroid Build Coastguard Worker
404*7eba2f3bSAndroid Build Coastguard Worker /* If here, there is no record of that index */
405*7eba2f3bSAndroid Build Coastguard Worker return (nullptr);
406*7eba2f3bSAndroid Build Coastguard Worker }
407*7eba2f3bSAndroid Build Coastguard Worker
408*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
409*7eba2f3bSAndroid Build Coastguard Worker **
410*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgGetLastRecInMsg
411*7eba2f3bSAndroid Build Coastguard Worker **
412*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the last record in the
413*7eba2f3bSAndroid Build Coastguard Worker ** given NDEF message.
414*7eba2f3bSAndroid Build Coastguard Worker **
415*7eba2f3bSAndroid Build Coastguard Worker ** Returns Pointer to the start of the last record, or NULL if some
416*7eba2f3bSAndroid Build Coastguard Worker ** problem
417*7eba2f3bSAndroid Build Coastguard Worker **
418*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgGetLastRecInMsg(uint8_t * p_msg)419*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_MsgGetLastRecInMsg(uint8_t* p_msg) {
420*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec = p_msg;
421*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pRecStart;
422*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
423*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
424*7eba2f3bSAndroid Build Coastguard Worker
425*7eba2f3bSAndroid Build Coastguard Worker for (;;) {
426*7eba2f3bSAndroid Build Coastguard Worker pRecStart = p_rec;
427*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
428*7eba2f3bSAndroid Build Coastguard Worker
429*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_ME_MASK) break;
430*7eba2f3bSAndroid Build Coastguard Worker
431*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
432*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
433*7eba2f3bSAndroid Build Coastguard Worker
434*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
435*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
436*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_rec++;
437*7eba2f3bSAndroid Build Coastguard Worker else
438*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_rec);
439*7eba2f3bSAndroid Build Coastguard Worker
440*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
441*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
442*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_rec++;
443*7eba2f3bSAndroid Build Coastguard Worker else
444*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
445*7eba2f3bSAndroid Build Coastguard Worker
446*7eba2f3bSAndroid Build Coastguard Worker /* Point to next record */
447*7eba2f3bSAndroid Build Coastguard Worker p_rec += (payload_len + type_len + id_len);
448*7eba2f3bSAndroid Build Coastguard Worker }
449*7eba2f3bSAndroid Build Coastguard Worker
450*7eba2f3bSAndroid Build Coastguard Worker return (pRecStart);
451*7eba2f3bSAndroid Build Coastguard Worker }
452*7eba2f3bSAndroid Build Coastguard Worker
453*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
454*7eba2f3bSAndroid Build Coastguard Worker **
455*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgGetFirstRecByType
456*7eba2f3bSAndroid Build Coastguard Worker **
457*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the first record with the
458*7eba2f3bSAndroid Build Coastguard Worker ** given record type in the given NDEF message.
459*7eba2f3bSAndroid Build Coastguard Worker **
460*7eba2f3bSAndroid Build Coastguard Worker ** Returns Pointer to the start of the record, or NULL
461*7eba2f3bSAndroid Build Coastguard Worker **
462*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgGetFirstRecByType(uint8_t * p_msg,uint8_t tnf,uint8_t * p_type,uint8_t tlen)463*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_MsgGetFirstRecByType(uint8_t* p_msg, uint8_t tnf, uint8_t* p_type,
464*7eba2f3bSAndroid Build Coastguard Worker uint8_t tlen) {
465*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec = p_msg;
466*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pRecStart;
467*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
468*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
469*7eba2f3bSAndroid Build Coastguard Worker
470*7eba2f3bSAndroid Build Coastguard Worker for (;;) {
471*7eba2f3bSAndroid Build Coastguard Worker pRecStart = p_rec;
472*7eba2f3bSAndroid Build Coastguard Worker
473*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
474*7eba2f3bSAndroid Build Coastguard Worker
475*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
476*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
477*7eba2f3bSAndroid Build Coastguard Worker
478*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
479*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
480*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_rec++;
481*7eba2f3bSAndroid Build Coastguard Worker else
482*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_rec);
483*7eba2f3bSAndroid Build Coastguard Worker
484*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
485*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
486*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_rec++;
487*7eba2f3bSAndroid Build Coastguard Worker else
488*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
489*7eba2f3bSAndroid Build Coastguard Worker
490*7eba2f3bSAndroid Build Coastguard Worker /* At this point, p_rec points to the start of the type field. We need to */
491*7eba2f3bSAndroid Build Coastguard Worker /* compare the type of the type, the length of the type and the data */
492*7eba2f3bSAndroid Build Coastguard Worker if (((rec_hdr & NDEF_TNF_MASK) == tnf) && (type_len == tlen) &&
493*7eba2f3bSAndroid Build Coastguard Worker (!memcmp(p_rec, p_type, tlen)))
494*7eba2f3bSAndroid Build Coastguard Worker return (pRecStart);
495*7eba2f3bSAndroid Build Coastguard Worker
496*7eba2f3bSAndroid Build Coastguard Worker /* If this was the last record, return NULL */
497*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_ME_MASK) return (nullptr);
498*7eba2f3bSAndroid Build Coastguard Worker
499*7eba2f3bSAndroid Build Coastguard Worker /* Point to next record */
500*7eba2f3bSAndroid Build Coastguard Worker p_rec += (payload_len + type_len + id_len);
501*7eba2f3bSAndroid Build Coastguard Worker }
502*7eba2f3bSAndroid Build Coastguard Worker
503*7eba2f3bSAndroid Build Coastguard Worker /* If here, there is no record of that type */
504*7eba2f3bSAndroid Build Coastguard Worker return (nullptr);
505*7eba2f3bSAndroid Build Coastguard Worker }
506*7eba2f3bSAndroid Build Coastguard Worker
507*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
508*7eba2f3bSAndroid Build Coastguard Worker **
509*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgGetNextRecByType
510*7eba2f3bSAndroid Build Coastguard Worker **
511*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the next record with the
512*7eba2f3bSAndroid Build Coastguard Worker ** given record type in the given NDEF message.
513*7eba2f3bSAndroid Build Coastguard Worker **
514*7eba2f3bSAndroid Build Coastguard Worker ** Returns Pointer to the start of the record, or NULL
515*7eba2f3bSAndroid Build Coastguard Worker **
516*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgGetNextRecByType(uint8_t * p_cur_rec,uint8_t tnf,uint8_t * p_type,uint8_t tlen)517*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_MsgGetNextRecByType(uint8_t* p_cur_rec, uint8_t tnf,
518*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_type, uint8_t tlen) {
519*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec;
520*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pRecStart;
521*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
522*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
523*7eba2f3bSAndroid Build Coastguard Worker
524*7eba2f3bSAndroid Build Coastguard Worker /* If this is the last record in the message, return NULL */
525*7eba2f3bSAndroid Build Coastguard Worker p_rec = NDEF_MsgGetNextRec(p_cur_rec);
526*7eba2f3bSAndroid Build Coastguard Worker if (p_rec == nullptr) return (nullptr);
527*7eba2f3bSAndroid Build Coastguard Worker
528*7eba2f3bSAndroid Build Coastguard Worker for (;;) {
529*7eba2f3bSAndroid Build Coastguard Worker pRecStart = p_rec;
530*7eba2f3bSAndroid Build Coastguard Worker
531*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
532*7eba2f3bSAndroid Build Coastguard Worker
533*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
534*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
535*7eba2f3bSAndroid Build Coastguard Worker
536*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
537*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
538*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_rec++;
539*7eba2f3bSAndroid Build Coastguard Worker else
540*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_rec);
541*7eba2f3bSAndroid Build Coastguard Worker
542*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
543*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
544*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_rec++;
545*7eba2f3bSAndroid Build Coastguard Worker else
546*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
547*7eba2f3bSAndroid Build Coastguard Worker
548*7eba2f3bSAndroid Build Coastguard Worker /* At this point, p_rec points to the start of the type field. We need to */
549*7eba2f3bSAndroid Build Coastguard Worker /* compare the type of the type, the length of the type and the data */
550*7eba2f3bSAndroid Build Coastguard Worker if (((rec_hdr & NDEF_TNF_MASK) == tnf) && (type_len == tlen) &&
551*7eba2f3bSAndroid Build Coastguard Worker (!memcmp(p_rec, p_type, tlen)))
552*7eba2f3bSAndroid Build Coastguard Worker return (pRecStart);
553*7eba2f3bSAndroid Build Coastguard Worker
554*7eba2f3bSAndroid Build Coastguard Worker /* If this was the last record, return NULL */
555*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_ME_MASK) break;
556*7eba2f3bSAndroid Build Coastguard Worker
557*7eba2f3bSAndroid Build Coastguard Worker /* Point to next record */
558*7eba2f3bSAndroid Build Coastguard Worker p_rec += (payload_len + type_len + id_len);
559*7eba2f3bSAndroid Build Coastguard Worker }
560*7eba2f3bSAndroid Build Coastguard Worker
561*7eba2f3bSAndroid Build Coastguard Worker /* If here, there is no record of that type */
562*7eba2f3bSAndroid Build Coastguard Worker return (nullptr);
563*7eba2f3bSAndroid Build Coastguard Worker }
564*7eba2f3bSAndroid Build Coastguard Worker
565*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
566*7eba2f3bSAndroid Build Coastguard Worker **
567*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgGetFirstRecById
568*7eba2f3bSAndroid Build Coastguard Worker **
569*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the first record with the
570*7eba2f3bSAndroid Build Coastguard Worker ** given record id in the given NDEF message.
571*7eba2f3bSAndroid Build Coastguard Worker **
572*7eba2f3bSAndroid Build Coastguard Worker ** Returns Pointer to the start of the record, or NULL
573*7eba2f3bSAndroid Build Coastguard Worker **
574*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgGetFirstRecById(uint8_t * p_msg,uint8_t * p_id,uint8_t ilen)575*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_MsgGetFirstRecById(uint8_t* p_msg, uint8_t* p_id, uint8_t ilen) {
576*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec = p_msg;
577*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pRecStart;
578*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
579*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
580*7eba2f3bSAndroid Build Coastguard Worker
581*7eba2f3bSAndroid Build Coastguard Worker for (;;) {
582*7eba2f3bSAndroid Build Coastguard Worker pRecStart = p_rec;
583*7eba2f3bSAndroid Build Coastguard Worker
584*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
585*7eba2f3bSAndroid Build Coastguard Worker
586*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
587*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
588*7eba2f3bSAndroid Build Coastguard Worker
589*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
590*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
591*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_rec++;
592*7eba2f3bSAndroid Build Coastguard Worker else
593*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_rec);
594*7eba2f3bSAndroid Build Coastguard Worker
595*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
596*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
597*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_rec++;
598*7eba2f3bSAndroid Build Coastguard Worker else
599*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
600*7eba2f3bSAndroid Build Coastguard Worker
601*7eba2f3bSAndroid Build Coastguard Worker /* At this point, p_rec points to the start of the type field. Skip it */
602*7eba2f3bSAndroid Build Coastguard Worker p_rec += type_len;
603*7eba2f3bSAndroid Build Coastguard Worker
604*7eba2f3bSAndroid Build Coastguard Worker /* At this point, p_rec points to the start of the ID field. Compare length
605*7eba2f3bSAndroid Build Coastguard Worker * and data */
606*7eba2f3bSAndroid Build Coastguard Worker if ((id_len == ilen) && (!memcmp(p_rec, p_id, ilen))) return (pRecStart);
607*7eba2f3bSAndroid Build Coastguard Worker
608*7eba2f3bSAndroid Build Coastguard Worker /* If this was the last record, return NULL */
609*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_ME_MASK) return (nullptr);
610*7eba2f3bSAndroid Build Coastguard Worker
611*7eba2f3bSAndroid Build Coastguard Worker /* Point to next record */
612*7eba2f3bSAndroid Build Coastguard Worker p_rec += (id_len + payload_len);
613*7eba2f3bSAndroid Build Coastguard Worker }
614*7eba2f3bSAndroid Build Coastguard Worker
615*7eba2f3bSAndroid Build Coastguard Worker /* If here, there is no record of that ID */
616*7eba2f3bSAndroid Build Coastguard Worker return (nullptr);
617*7eba2f3bSAndroid Build Coastguard Worker }
618*7eba2f3bSAndroid Build Coastguard Worker
619*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
620*7eba2f3bSAndroid Build Coastguard Worker **
621*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgGetNextRecById
622*7eba2f3bSAndroid Build Coastguard Worker **
623*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the next record with the
624*7eba2f3bSAndroid Build Coastguard Worker ** given record id in the given NDEF message.
625*7eba2f3bSAndroid Build Coastguard Worker **
626*7eba2f3bSAndroid Build Coastguard Worker ** Returns Pointer to the start of the record, or NULL
627*7eba2f3bSAndroid Build Coastguard Worker **
628*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgGetNextRecById(uint8_t * p_cur_rec,uint8_t * p_id,uint8_t ilen)629*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_MsgGetNextRecById(uint8_t* p_cur_rec, uint8_t* p_id,
630*7eba2f3bSAndroid Build Coastguard Worker uint8_t ilen) {
631*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec;
632*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pRecStart;
633*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
634*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
635*7eba2f3bSAndroid Build Coastguard Worker
636*7eba2f3bSAndroid Build Coastguard Worker /* If this is the last record in the message, return NULL */
637*7eba2f3bSAndroid Build Coastguard Worker p_rec = NDEF_MsgGetNextRec(p_cur_rec);
638*7eba2f3bSAndroid Build Coastguard Worker if (p_rec == nullptr) return (nullptr);
639*7eba2f3bSAndroid Build Coastguard Worker
640*7eba2f3bSAndroid Build Coastguard Worker for (;;) {
641*7eba2f3bSAndroid Build Coastguard Worker pRecStart = p_rec;
642*7eba2f3bSAndroid Build Coastguard Worker
643*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
644*7eba2f3bSAndroid Build Coastguard Worker
645*7eba2f3bSAndroid Build Coastguard Worker /* Type field length */
646*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
647*7eba2f3bSAndroid Build Coastguard Worker
648*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
649*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
650*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_rec++;
651*7eba2f3bSAndroid Build Coastguard Worker else
652*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_rec);
653*7eba2f3bSAndroid Build Coastguard Worker
654*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
655*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
656*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_rec++;
657*7eba2f3bSAndroid Build Coastguard Worker else
658*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
659*7eba2f3bSAndroid Build Coastguard Worker
660*7eba2f3bSAndroid Build Coastguard Worker /* At this point, p_rec points to the start of the type field. Skip it */
661*7eba2f3bSAndroid Build Coastguard Worker p_rec += type_len;
662*7eba2f3bSAndroid Build Coastguard Worker
663*7eba2f3bSAndroid Build Coastguard Worker /* At this point, p_rec points to the start of the ID field. Compare length
664*7eba2f3bSAndroid Build Coastguard Worker * and data */
665*7eba2f3bSAndroid Build Coastguard Worker if ((id_len == ilen) && (!memcmp(p_rec, p_id, ilen))) return (pRecStart);
666*7eba2f3bSAndroid Build Coastguard Worker
667*7eba2f3bSAndroid Build Coastguard Worker /* If this was the last record, return NULL */
668*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_ME_MASK) break;
669*7eba2f3bSAndroid Build Coastguard Worker
670*7eba2f3bSAndroid Build Coastguard Worker /* Point to next record */
671*7eba2f3bSAndroid Build Coastguard Worker p_rec += (id_len + payload_len);
672*7eba2f3bSAndroid Build Coastguard Worker }
673*7eba2f3bSAndroid Build Coastguard Worker
674*7eba2f3bSAndroid Build Coastguard Worker /* If here, there is no record of that ID */
675*7eba2f3bSAndroid Build Coastguard Worker return (nullptr);
676*7eba2f3bSAndroid Build Coastguard Worker }
677*7eba2f3bSAndroid Build Coastguard Worker
678*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
679*7eba2f3bSAndroid Build Coastguard Worker **
680*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_RecGetType
681*7eba2f3bSAndroid Build Coastguard Worker **
682*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the record type for the
683*7eba2f3bSAndroid Build Coastguard Worker ** given NDEF record.
684*7eba2f3bSAndroid Build Coastguard Worker **
685*7eba2f3bSAndroid Build Coastguard Worker ** Returns Pointer to Type (NULL if none). TNF and len are filled in.
686*7eba2f3bSAndroid Build Coastguard Worker **
687*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_RecGetType(uint8_t * p_rec,uint8_t * p_tnf,uint8_t * p_type_len)688*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_RecGetType(uint8_t* p_rec, uint8_t* p_tnf, uint8_t* p_type_len) {
689*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len;
690*7eba2f3bSAndroid Build Coastguard Worker
691*7eba2f3bSAndroid Build Coastguard Worker /* First byte is the record header */
692*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
693*7eba2f3bSAndroid Build Coastguard Worker
694*7eba2f3bSAndroid Build Coastguard Worker /* Next byte is the type field length */
695*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
696*7eba2f3bSAndroid Build Coastguard Worker
697*7eba2f3bSAndroid Build Coastguard Worker /* Skip the payload length */
698*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
699*7eba2f3bSAndroid Build Coastguard Worker p_rec += 1;
700*7eba2f3bSAndroid Build Coastguard Worker else
701*7eba2f3bSAndroid Build Coastguard Worker p_rec += 4;
702*7eba2f3bSAndroid Build Coastguard Worker
703*7eba2f3bSAndroid Build Coastguard Worker /* Skip ID field Length, if present */
704*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK) p_rec++;
705*7eba2f3bSAndroid Build Coastguard Worker
706*7eba2f3bSAndroid Build Coastguard Worker /* At this point, p_rec points to the start of the type field. */
707*7eba2f3bSAndroid Build Coastguard Worker *p_type_len = type_len;
708*7eba2f3bSAndroid Build Coastguard Worker *p_tnf = rec_hdr & NDEF_TNF_MASK;
709*7eba2f3bSAndroid Build Coastguard Worker
710*7eba2f3bSAndroid Build Coastguard Worker if (type_len == 0)
711*7eba2f3bSAndroid Build Coastguard Worker return (nullptr);
712*7eba2f3bSAndroid Build Coastguard Worker else
713*7eba2f3bSAndroid Build Coastguard Worker return (p_rec);
714*7eba2f3bSAndroid Build Coastguard Worker }
715*7eba2f3bSAndroid Build Coastguard Worker
716*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
717*7eba2f3bSAndroid Build Coastguard Worker **
718*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_RecGetId
719*7eba2f3bSAndroid Build Coastguard Worker **
720*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the record id for the given
721*7eba2f3bSAndroid Build Coastguard Worker ** NDEF record.
722*7eba2f3bSAndroid Build Coastguard Worker **
723*7eba2f3bSAndroid Build Coastguard Worker ** Returns Pointer to Id (NULL if none). ID Len is filled in.
724*7eba2f3bSAndroid Build Coastguard Worker **
725*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_RecGetId(uint8_t * p_rec,uint8_t * p_id_len)726*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_RecGetId(uint8_t* p_rec, uint8_t* p_id_len) {
727*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len;
728*7eba2f3bSAndroid Build Coastguard Worker
729*7eba2f3bSAndroid Build Coastguard Worker /* First byte is the record header */
730*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
731*7eba2f3bSAndroid Build Coastguard Worker
732*7eba2f3bSAndroid Build Coastguard Worker /* Next byte is the type field length */
733*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
734*7eba2f3bSAndroid Build Coastguard Worker
735*7eba2f3bSAndroid Build Coastguard Worker /* Skip the payload length */
736*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
737*7eba2f3bSAndroid Build Coastguard Worker p_rec++;
738*7eba2f3bSAndroid Build Coastguard Worker else
739*7eba2f3bSAndroid Build Coastguard Worker p_rec += 4;
740*7eba2f3bSAndroid Build Coastguard Worker
741*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
742*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
743*7eba2f3bSAndroid Build Coastguard Worker *p_id_len = *p_rec++;
744*7eba2f3bSAndroid Build Coastguard Worker else
745*7eba2f3bSAndroid Build Coastguard Worker *p_id_len = 0;
746*7eba2f3bSAndroid Build Coastguard Worker
747*7eba2f3bSAndroid Build Coastguard Worker /* p_rec now points to the start of the type field. The ID field follows it */
748*7eba2f3bSAndroid Build Coastguard Worker if (*p_id_len == 0)
749*7eba2f3bSAndroid Build Coastguard Worker return (nullptr);
750*7eba2f3bSAndroid Build Coastguard Worker else
751*7eba2f3bSAndroid Build Coastguard Worker return (p_rec + type_len);
752*7eba2f3bSAndroid Build Coastguard Worker }
753*7eba2f3bSAndroid Build Coastguard Worker
754*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
755*7eba2f3bSAndroid Build Coastguard Worker **
756*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_RecGetPayload
757*7eba2f3bSAndroid Build Coastguard Worker **
758*7eba2f3bSAndroid Build Coastguard Worker ** Description This function gets a pointer to the payload for the given
759*7eba2f3bSAndroid Build Coastguard Worker ** NDEF record.
760*7eba2f3bSAndroid Build Coastguard Worker **
761*7eba2f3bSAndroid Build Coastguard Worker ** Returns a pointer to the payload (or NULL none). Payload len filled
762*7eba2f3bSAndroid Build Coastguard Worker ** in.
763*7eba2f3bSAndroid Build Coastguard Worker **
764*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_RecGetPayload(uint8_t * p_rec,uint32_t * p_payload_len)765*7eba2f3bSAndroid Build Coastguard Worker uint8_t* NDEF_RecGetPayload(uint8_t* p_rec, uint32_t* p_payload_len) {
766*7eba2f3bSAndroid Build Coastguard Worker uint8_t rec_hdr, type_len, id_len;
767*7eba2f3bSAndroid Build Coastguard Worker uint32_t payload_len;
768*7eba2f3bSAndroid Build Coastguard Worker
769*7eba2f3bSAndroid Build Coastguard Worker /* First byte is the record header */
770*7eba2f3bSAndroid Build Coastguard Worker rec_hdr = *p_rec++;
771*7eba2f3bSAndroid Build Coastguard Worker
772*7eba2f3bSAndroid Build Coastguard Worker /* Next byte is the type field length */
773*7eba2f3bSAndroid Build Coastguard Worker type_len = *p_rec++;
774*7eba2f3bSAndroid Build Coastguard Worker
775*7eba2f3bSAndroid Build Coastguard Worker /* Next is the payload length (1 or 4 bytes) */
776*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_SR_MASK)
777*7eba2f3bSAndroid Build Coastguard Worker payload_len = *p_rec++;
778*7eba2f3bSAndroid Build Coastguard Worker else
779*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(payload_len, p_rec);
780*7eba2f3bSAndroid Build Coastguard Worker
781*7eba2f3bSAndroid Build Coastguard Worker *p_payload_len = payload_len;
782*7eba2f3bSAndroid Build Coastguard Worker
783*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
784*7eba2f3bSAndroid Build Coastguard Worker if (rec_hdr & NDEF_IL_MASK)
785*7eba2f3bSAndroid Build Coastguard Worker id_len = *p_rec++;
786*7eba2f3bSAndroid Build Coastguard Worker else
787*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
788*7eba2f3bSAndroid Build Coastguard Worker
789*7eba2f3bSAndroid Build Coastguard Worker /* p_rec now points to the start of the type field. The ID field follows it,
790*7eba2f3bSAndroid Build Coastguard Worker * then the payload */
791*7eba2f3bSAndroid Build Coastguard Worker if (payload_len == 0)
792*7eba2f3bSAndroid Build Coastguard Worker return (nullptr);
793*7eba2f3bSAndroid Build Coastguard Worker else
794*7eba2f3bSAndroid Build Coastguard Worker return (p_rec + type_len + id_len);
795*7eba2f3bSAndroid Build Coastguard Worker }
796*7eba2f3bSAndroid Build Coastguard Worker
797*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
798*7eba2f3bSAndroid Build Coastguard Worker **
799*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgInit
800*7eba2f3bSAndroid Build Coastguard Worker **
801*7eba2f3bSAndroid Build Coastguard Worker ** Description This function initializes an NDEF message.
802*7eba2f3bSAndroid Build Coastguard Worker **
803*7eba2f3bSAndroid Build Coastguard Worker ** Returns void
804*7eba2f3bSAndroid Build Coastguard Worker ** *p_cur_size is initialized to 0
805*7eba2f3bSAndroid Build Coastguard Worker **
806*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgInit(uint8_t * p_msg,uint32_t max_size,uint32_t * p_cur_size)807*7eba2f3bSAndroid Build Coastguard Worker void NDEF_MsgInit(uint8_t* p_msg, uint32_t max_size, uint32_t* p_cur_size) {
808*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size = 0;
809*7eba2f3bSAndroid Build Coastguard Worker memset(p_msg, 0, max_size);
810*7eba2f3bSAndroid Build Coastguard Worker }
811*7eba2f3bSAndroid Build Coastguard Worker
812*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
813*7eba2f3bSAndroid Build Coastguard Worker **
814*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgAddRec
815*7eba2f3bSAndroid Build Coastguard Worker **
816*7eba2f3bSAndroid Build Coastguard Worker ** Description This function adds an NDEF record to the end of an NDEF
817*7eba2f3bSAndroid Build Coastguard Worker ** message.
818*7eba2f3bSAndroid Build Coastguard Worker **
819*7eba2f3bSAndroid Build Coastguard Worker ** Returns OK, or error if the record did not fit
820*7eba2f3bSAndroid Build Coastguard Worker ** *p_cur_size is updated
821*7eba2f3bSAndroid Build Coastguard Worker **
822*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgAddRec(uint8_t * p_msg,uint32_t max_size,uint32_t * p_cur_size,uint8_t tnf,uint8_t * p_type,uint8_t type_len,uint8_t * p_id,uint8_t id_len,uint8_t * p_payload,uint32_t payload_len)823*7eba2f3bSAndroid Build Coastguard Worker extern tNDEF_STATUS NDEF_MsgAddRec(uint8_t* p_msg, uint32_t max_size,
824*7eba2f3bSAndroid Build Coastguard Worker uint32_t* p_cur_size, uint8_t tnf,
825*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_type, uint8_t type_len,
826*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_id, uint8_t id_len,
827*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_payload, uint32_t payload_len) {
828*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec = p_msg + *p_cur_size;
829*7eba2f3bSAndroid Build Coastguard Worker uint32_t recSize;
830*7eba2f3bSAndroid Build Coastguard Worker int plen = (payload_len < 256) ? 1 : 4;
831*7eba2f3bSAndroid Build Coastguard Worker int ilen = (id_len == 0) ? 0 : 1;
832*7eba2f3bSAndroid Build Coastguard Worker
833*7eba2f3bSAndroid Build Coastguard Worker if (tnf > NDEF_TNF_RESERVED) {
834*7eba2f3bSAndroid Build Coastguard Worker tnf = NDEF_TNF_UNKNOWN;
835*7eba2f3bSAndroid Build Coastguard Worker type_len = 0;
836*7eba2f3bSAndroid Build Coastguard Worker }
837*7eba2f3bSAndroid Build Coastguard Worker
838*7eba2f3bSAndroid Build Coastguard Worker /* First, make sure the record will fit. we need at least 2 bytes for header
839*7eba2f3bSAndroid Build Coastguard Worker * and type length */
840*7eba2f3bSAndroid Build Coastguard Worker recSize = payload_len + 2 + type_len + plen + ilen + id_len;
841*7eba2f3bSAndroid Build Coastguard Worker
842*7eba2f3bSAndroid Build Coastguard Worker if ((*p_cur_size + recSize) > max_size) return (NDEF_MSG_INSUFFICIENT_MEM);
843*7eba2f3bSAndroid Build Coastguard Worker
844*7eba2f3bSAndroid Build Coastguard Worker /* Construct the record header. For the first record, set both begin and end
845*7eba2f3bSAndroid Build Coastguard Worker * bits */
846*7eba2f3bSAndroid Build Coastguard Worker if (*p_cur_size == 0)
847*7eba2f3bSAndroid Build Coastguard Worker *p_rec = tnf | NDEF_MB_MASK | NDEF_ME_MASK;
848*7eba2f3bSAndroid Build Coastguard Worker else {
849*7eba2f3bSAndroid Build Coastguard Worker /* Find the previous last and clear his 'Message End' bit */
850*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pLast = NDEF_MsgGetLastRecInMsg(p_msg);
851*7eba2f3bSAndroid Build Coastguard Worker
852*7eba2f3bSAndroid Build Coastguard Worker if (!pLast) return (NDEF_MSG_NO_MSG_END);
853*7eba2f3bSAndroid Build Coastguard Worker
854*7eba2f3bSAndroid Build Coastguard Worker *pLast &= ~NDEF_ME_MASK;
855*7eba2f3bSAndroid Build Coastguard Worker *p_rec = tnf | NDEF_ME_MASK;
856*7eba2f3bSAndroid Build Coastguard Worker }
857*7eba2f3bSAndroid Build Coastguard Worker
858*7eba2f3bSAndroid Build Coastguard Worker if (plen == 1) *p_rec |= NDEF_SR_MASK;
859*7eba2f3bSAndroid Build Coastguard Worker
860*7eba2f3bSAndroid Build Coastguard Worker if (ilen != 0) *p_rec |= NDEF_IL_MASK;
861*7eba2f3bSAndroid Build Coastguard Worker
862*7eba2f3bSAndroid Build Coastguard Worker p_rec++;
863*7eba2f3bSAndroid Build Coastguard Worker
864*7eba2f3bSAndroid Build Coastguard Worker /* The next byte is the type field length */
865*7eba2f3bSAndroid Build Coastguard Worker *p_rec++ = type_len;
866*7eba2f3bSAndroid Build Coastguard Worker
867*7eba2f3bSAndroid Build Coastguard Worker /* Payload length - can be 1 or 4 bytes */
868*7eba2f3bSAndroid Build Coastguard Worker if (plen == 1)
869*7eba2f3bSAndroid Build Coastguard Worker *p_rec++ = (uint8_t)payload_len;
870*7eba2f3bSAndroid Build Coastguard Worker else
871*7eba2f3bSAndroid Build Coastguard Worker UINT32_TO_BE_STREAM(p_rec, payload_len);
872*7eba2f3bSAndroid Build Coastguard Worker
873*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length (optional) */
874*7eba2f3bSAndroid Build Coastguard Worker if (ilen > 0) *p_rec++ = id_len;
875*7eba2f3bSAndroid Build Coastguard Worker
876*7eba2f3bSAndroid Build Coastguard Worker /* Next comes the type */
877*7eba2f3bSAndroid Build Coastguard Worker if (type_len) {
878*7eba2f3bSAndroid Build Coastguard Worker if (p_type) memcpy(p_rec, p_type, type_len);
879*7eba2f3bSAndroid Build Coastguard Worker
880*7eba2f3bSAndroid Build Coastguard Worker p_rec += type_len;
881*7eba2f3bSAndroid Build Coastguard Worker }
882*7eba2f3bSAndroid Build Coastguard Worker
883*7eba2f3bSAndroid Build Coastguard Worker /* Next comes the ID */
884*7eba2f3bSAndroid Build Coastguard Worker if (id_len) {
885*7eba2f3bSAndroid Build Coastguard Worker if (p_id) memcpy(p_rec, p_id, id_len);
886*7eba2f3bSAndroid Build Coastguard Worker
887*7eba2f3bSAndroid Build Coastguard Worker p_rec += id_len;
888*7eba2f3bSAndroid Build Coastguard Worker }
889*7eba2f3bSAndroid Build Coastguard Worker
890*7eba2f3bSAndroid Build Coastguard Worker /* And lastly the payload. If NULL, the app just wants to reserve memory */
891*7eba2f3bSAndroid Build Coastguard Worker if (p_payload) memcpy(p_rec, p_payload, payload_len);
892*7eba2f3bSAndroid Build Coastguard Worker
893*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size += recSize;
894*7eba2f3bSAndroid Build Coastguard Worker
895*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_OK);
896*7eba2f3bSAndroid Build Coastguard Worker }
897*7eba2f3bSAndroid Build Coastguard Worker
898*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
899*7eba2f3bSAndroid Build Coastguard Worker **
900*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgAppendPayload
901*7eba2f3bSAndroid Build Coastguard Worker **
902*7eba2f3bSAndroid Build Coastguard Worker ** Description This function appends extra payload to a specific record in
903*7eba2f3bSAndroid Build Coastguard Worker ** the given NDEF message
904*7eba2f3bSAndroid Build Coastguard Worker **
905*7eba2f3bSAndroid Build Coastguard Worker ** Returns OK, or error if the extra payload did not fit
906*7eba2f3bSAndroid Build Coastguard Worker ** *p_cur_size is updated
907*7eba2f3bSAndroid Build Coastguard Worker **
908*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgAppendPayload(uint8_t * p_msg,uint32_t max_size,uint32_t * p_cur_size,uint8_t * p_rec,uint8_t * p_add_pl,uint32_t add_pl_len)909*7eba2f3bSAndroid Build Coastguard Worker tNDEF_STATUS NDEF_MsgAppendPayload(uint8_t* p_msg, uint32_t max_size,
910*7eba2f3bSAndroid Build Coastguard Worker uint32_t* p_cur_size, uint8_t* p_rec,
911*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_add_pl, uint32_t add_pl_len) {
912*7eba2f3bSAndroid Build Coastguard Worker uint32_t prev_paylen, new_paylen;
913*7eba2f3bSAndroid Build Coastguard Worker uint8_t *p_prev_pl, *pp;
914*7eba2f3bSAndroid Build Coastguard Worker uint8_t incr_lenfld = 0;
915*7eba2f3bSAndroid Build Coastguard Worker uint8_t type_len, id_len;
916*7eba2f3bSAndroid Build Coastguard Worker
917*7eba2f3bSAndroid Build Coastguard Worker /* Skip header */
918*7eba2f3bSAndroid Build Coastguard Worker pp = p_rec + 1;
919*7eba2f3bSAndroid Build Coastguard Worker
920*7eba2f3bSAndroid Build Coastguard Worker /* Next byte is the type field length */
921*7eba2f3bSAndroid Build Coastguard Worker type_len = *pp++;
922*7eba2f3bSAndroid Build Coastguard Worker
923*7eba2f3bSAndroid Build Coastguard Worker /* Next is the payload length (1 or 4 bytes) */
924*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_SR_MASK)
925*7eba2f3bSAndroid Build Coastguard Worker prev_paylen = *pp++;
926*7eba2f3bSAndroid Build Coastguard Worker else
927*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(prev_paylen, pp);
928*7eba2f3bSAndroid Build Coastguard Worker
929*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
930*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_IL_MASK)
931*7eba2f3bSAndroid Build Coastguard Worker id_len = *pp++;
932*7eba2f3bSAndroid Build Coastguard Worker else
933*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
934*7eba2f3bSAndroid Build Coastguard Worker
935*7eba2f3bSAndroid Build Coastguard Worker p_prev_pl = pp + type_len + id_len;
936*7eba2f3bSAndroid Build Coastguard Worker
937*7eba2f3bSAndroid Build Coastguard Worker new_paylen = prev_paylen + add_pl_len;
938*7eba2f3bSAndroid Build Coastguard Worker
939*7eba2f3bSAndroid Build Coastguard Worker /* Previous payload may be < 256, and this addition may make it larger than
940*7eba2f3bSAndroid Build Coastguard Worker * 256 */
941*7eba2f3bSAndroid Build Coastguard Worker /* If that were to happen, the payload length field goes from 1 byte to 4
942*7eba2f3bSAndroid Build Coastguard Worker * bytes */
943*7eba2f3bSAndroid Build Coastguard Worker if ((prev_paylen < 256) && (new_paylen > 255)) incr_lenfld = 3;
944*7eba2f3bSAndroid Build Coastguard Worker
945*7eba2f3bSAndroid Build Coastguard Worker /* Check that it all fits */
946*7eba2f3bSAndroid Build Coastguard Worker if ((*p_cur_size + add_pl_len + incr_lenfld) > max_size)
947*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INSUFFICIENT_MEM);
948*7eba2f3bSAndroid Build Coastguard Worker
949*7eba2f3bSAndroid Build Coastguard Worker /* Point to payload length field */
950*7eba2f3bSAndroid Build Coastguard Worker pp = p_rec + 2;
951*7eba2f3bSAndroid Build Coastguard Worker
952*7eba2f3bSAndroid Build Coastguard Worker /* If we need to increase the length field from 1 to 4 bytes, do it first */
953*7eba2f3bSAndroid Build Coastguard Worker if (incr_lenfld) {
954*7eba2f3bSAndroid Build Coastguard Worker shiftdown(pp + 1, (uint32_t)(*p_cur_size - (pp - p_msg) - 1), 3);
955*7eba2f3bSAndroid Build Coastguard Worker p_prev_pl += 3;
956*7eba2f3bSAndroid Build Coastguard Worker }
957*7eba2f3bSAndroid Build Coastguard Worker
958*7eba2f3bSAndroid Build Coastguard Worker /* Store in the new length */
959*7eba2f3bSAndroid Build Coastguard Worker if (new_paylen > 255) {
960*7eba2f3bSAndroid Build Coastguard Worker *p_rec &= ~NDEF_SR_MASK;
961*7eba2f3bSAndroid Build Coastguard Worker UINT32_TO_BE_STREAM(pp, new_paylen);
962*7eba2f3bSAndroid Build Coastguard Worker } else
963*7eba2f3bSAndroid Build Coastguard Worker *pp = (uint8_t)new_paylen;
964*7eba2f3bSAndroid Build Coastguard Worker
965*7eba2f3bSAndroid Build Coastguard Worker /* Point to the end of the previous payload */
966*7eba2f3bSAndroid Build Coastguard Worker pp = p_prev_pl + prev_paylen;
967*7eba2f3bSAndroid Build Coastguard Worker
968*7eba2f3bSAndroid Build Coastguard Worker /* If we are not the last record, make space for the extra payload */
969*7eba2f3bSAndroid Build Coastguard Worker if ((*p_rec & NDEF_ME_MASK) == 0)
970*7eba2f3bSAndroid Build Coastguard Worker shiftdown(pp, (uint32_t)(*p_cur_size - (pp - p_msg)), add_pl_len);
971*7eba2f3bSAndroid Build Coastguard Worker
972*7eba2f3bSAndroid Build Coastguard Worker /* Now copy in the additional payload data */
973*7eba2f3bSAndroid Build Coastguard Worker memcpy(pp, p_add_pl, add_pl_len);
974*7eba2f3bSAndroid Build Coastguard Worker
975*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size += add_pl_len + incr_lenfld;
976*7eba2f3bSAndroid Build Coastguard Worker
977*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_OK);
978*7eba2f3bSAndroid Build Coastguard Worker }
979*7eba2f3bSAndroid Build Coastguard Worker
980*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
981*7eba2f3bSAndroid Build Coastguard Worker **
982*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgReplacePayload
983*7eba2f3bSAndroid Build Coastguard Worker **
984*7eba2f3bSAndroid Build Coastguard Worker ** Description This function replaces the payload of a specific record in
985*7eba2f3bSAndroid Build Coastguard Worker ** the given NDEF message
986*7eba2f3bSAndroid Build Coastguard Worker **
987*7eba2f3bSAndroid Build Coastguard Worker ** Returns OK, or error if the new payload did not fit
988*7eba2f3bSAndroid Build Coastguard Worker ** *p_cur_size is updated
989*7eba2f3bSAndroid Build Coastguard Worker **
990*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgReplacePayload(uint8_t * p_msg,uint32_t max_size,uint32_t * p_cur_size,uint8_t * p_rec,uint8_t * p_new_pl,uint32_t new_pl_len)991*7eba2f3bSAndroid Build Coastguard Worker tNDEF_STATUS NDEF_MsgReplacePayload(uint8_t* p_msg, uint32_t max_size,
992*7eba2f3bSAndroid Build Coastguard Worker uint32_t* p_cur_size, uint8_t* p_rec,
993*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_new_pl, uint32_t new_pl_len) {
994*7eba2f3bSAndroid Build Coastguard Worker uint32_t prev_paylen;
995*7eba2f3bSAndroid Build Coastguard Worker uint8_t *p_prev_pl, *pp;
996*7eba2f3bSAndroid Build Coastguard Worker uint32_t paylen_delta;
997*7eba2f3bSAndroid Build Coastguard Worker uint8_t type_len, id_len;
998*7eba2f3bSAndroid Build Coastguard Worker
999*7eba2f3bSAndroid Build Coastguard Worker /* Skip header */
1000*7eba2f3bSAndroid Build Coastguard Worker pp = p_rec + 1;
1001*7eba2f3bSAndroid Build Coastguard Worker
1002*7eba2f3bSAndroid Build Coastguard Worker /* Next byte is the type field length */
1003*7eba2f3bSAndroid Build Coastguard Worker type_len = *pp++;
1004*7eba2f3bSAndroid Build Coastguard Worker
1005*7eba2f3bSAndroid Build Coastguard Worker /* Next is the payload length (1 or 4 bytes) */
1006*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_SR_MASK)
1007*7eba2f3bSAndroid Build Coastguard Worker prev_paylen = *pp++;
1008*7eba2f3bSAndroid Build Coastguard Worker else
1009*7eba2f3bSAndroid Build Coastguard Worker BE_STREAM_TO_UINT32(prev_paylen, pp);
1010*7eba2f3bSAndroid Build Coastguard Worker
1011*7eba2f3bSAndroid Build Coastguard Worker /* ID field Length */
1012*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_IL_MASK)
1013*7eba2f3bSAndroid Build Coastguard Worker id_len = *pp++;
1014*7eba2f3bSAndroid Build Coastguard Worker else
1015*7eba2f3bSAndroid Build Coastguard Worker id_len = 0;
1016*7eba2f3bSAndroid Build Coastguard Worker
1017*7eba2f3bSAndroid Build Coastguard Worker p_prev_pl = pp + type_len + id_len;
1018*7eba2f3bSAndroid Build Coastguard Worker
1019*7eba2f3bSAndroid Build Coastguard Worker /* Point to payload length field again */
1020*7eba2f3bSAndroid Build Coastguard Worker pp = p_rec + 2;
1021*7eba2f3bSAndroid Build Coastguard Worker
1022*7eba2f3bSAndroid Build Coastguard Worker if (new_pl_len > prev_paylen) {
1023*7eba2f3bSAndroid Build Coastguard Worker /* New payload is larger than the previous */
1024*7eba2f3bSAndroid Build Coastguard Worker paylen_delta = new_pl_len - prev_paylen;
1025*7eba2f3bSAndroid Build Coastguard Worker
1026*7eba2f3bSAndroid Build Coastguard Worker /* If the previous payload length was < 256, and new is > 255 */
1027*7eba2f3bSAndroid Build Coastguard Worker /* the payload length field goes from 1 byte to 4 bytes */
1028*7eba2f3bSAndroid Build Coastguard Worker if ((prev_paylen < 256) && (new_pl_len > 255)) {
1029*7eba2f3bSAndroid Build Coastguard Worker if ((*p_cur_size + paylen_delta + 3) > max_size)
1030*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INSUFFICIENT_MEM);
1031*7eba2f3bSAndroid Build Coastguard Worker
1032*7eba2f3bSAndroid Build Coastguard Worker shiftdown(pp + 1, (uint32_t)(*p_cur_size - (pp - p_msg) - 1), 3);
1033*7eba2f3bSAndroid Build Coastguard Worker p_prev_pl += 3;
1034*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size += 3;
1035*7eba2f3bSAndroid Build Coastguard Worker *p_rec &= ~NDEF_SR_MASK;
1036*7eba2f3bSAndroid Build Coastguard Worker } else if ((*p_cur_size + paylen_delta) > max_size)
1037*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INSUFFICIENT_MEM);
1038*7eba2f3bSAndroid Build Coastguard Worker
1039*7eba2f3bSAndroid Build Coastguard Worker /* Store in the new length */
1040*7eba2f3bSAndroid Build Coastguard Worker if (new_pl_len > 255) {
1041*7eba2f3bSAndroid Build Coastguard Worker UINT32_TO_BE_STREAM(pp, new_pl_len);
1042*7eba2f3bSAndroid Build Coastguard Worker } else
1043*7eba2f3bSAndroid Build Coastguard Worker *pp = (uint8_t)new_pl_len;
1044*7eba2f3bSAndroid Build Coastguard Worker
1045*7eba2f3bSAndroid Build Coastguard Worker /* Point to the end of the previous payload */
1046*7eba2f3bSAndroid Build Coastguard Worker pp = p_prev_pl + prev_paylen;
1047*7eba2f3bSAndroid Build Coastguard Worker
1048*7eba2f3bSAndroid Build Coastguard Worker /* If we are not the last record, make space for the extra payload */
1049*7eba2f3bSAndroid Build Coastguard Worker if ((*p_rec & NDEF_ME_MASK) == 0)
1050*7eba2f3bSAndroid Build Coastguard Worker shiftdown(pp, (uint32_t)(*p_cur_size - (pp - p_msg)), paylen_delta);
1051*7eba2f3bSAndroid Build Coastguard Worker
1052*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size += paylen_delta;
1053*7eba2f3bSAndroid Build Coastguard Worker } else if (new_pl_len < prev_paylen) {
1054*7eba2f3bSAndroid Build Coastguard Worker /* New payload is smaller than the previous */
1055*7eba2f3bSAndroid Build Coastguard Worker paylen_delta = prev_paylen - new_pl_len;
1056*7eba2f3bSAndroid Build Coastguard Worker
1057*7eba2f3bSAndroid Build Coastguard Worker /* If the previous payload was > 256, and new is less than 256 */
1058*7eba2f3bSAndroid Build Coastguard Worker /* the payload length field goes from 4 bytes to 1 byte */
1059*7eba2f3bSAndroid Build Coastguard Worker if ((prev_paylen > 255) && (new_pl_len < 256)) {
1060*7eba2f3bSAndroid Build Coastguard Worker shiftup(pp + 1, pp + 4, (uint32_t)(*p_cur_size - (pp - p_msg) - 3));
1061*7eba2f3bSAndroid Build Coastguard Worker p_prev_pl -= 3;
1062*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size -= 3;
1063*7eba2f3bSAndroid Build Coastguard Worker *p_rec |= NDEF_SR_MASK;
1064*7eba2f3bSAndroid Build Coastguard Worker }
1065*7eba2f3bSAndroid Build Coastguard Worker
1066*7eba2f3bSAndroid Build Coastguard Worker /* Store in the new length */
1067*7eba2f3bSAndroid Build Coastguard Worker if (new_pl_len > 255) {
1068*7eba2f3bSAndroid Build Coastguard Worker UINT32_TO_BE_STREAM(pp, new_pl_len);
1069*7eba2f3bSAndroid Build Coastguard Worker } else
1070*7eba2f3bSAndroid Build Coastguard Worker *pp = (uint8_t)new_pl_len;
1071*7eba2f3bSAndroid Build Coastguard Worker
1072*7eba2f3bSAndroid Build Coastguard Worker /* Point to the end of the previous payload */
1073*7eba2f3bSAndroid Build Coastguard Worker pp = p_prev_pl + prev_paylen;
1074*7eba2f3bSAndroid Build Coastguard Worker
1075*7eba2f3bSAndroid Build Coastguard Worker /* If we are not the last record, remove the extra space from the previous
1076*7eba2f3bSAndroid Build Coastguard Worker * payload */
1077*7eba2f3bSAndroid Build Coastguard Worker if ((*p_rec & NDEF_ME_MASK) == 0)
1078*7eba2f3bSAndroid Build Coastguard Worker shiftup(pp - paylen_delta, pp, (uint32_t)(*p_cur_size - (pp - p_msg)));
1079*7eba2f3bSAndroid Build Coastguard Worker
1080*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size -= paylen_delta;
1081*7eba2f3bSAndroid Build Coastguard Worker }
1082*7eba2f3bSAndroid Build Coastguard Worker
1083*7eba2f3bSAndroid Build Coastguard Worker /* Now copy in the new payload data */
1084*7eba2f3bSAndroid Build Coastguard Worker if (p_new_pl) memcpy(p_prev_pl, p_new_pl, new_pl_len);
1085*7eba2f3bSAndroid Build Coastguard Worker
1086*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_OK);
1087*7eba2f3bSAndroid Build Coastguard Worker }
1088*7eba2f3bSAndroid Build Coastguard Worker
1089*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
1090*7eba2f3bSAndroid Build Coastguard Worker **
1091*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgReplaceType
1092*7eba2f3bSAndroid Build Coastguard Worker **
1093*7eba2f3bSAndroid Build Coastguard Worker ** Description This function replaces the type field of a specific record
1094*7eba2f3bSAndroid Build Coastguard Worker ** in the given NDEF message
1095*7eba2f3bSAndroid Build Coastguard Worker **
1096*7eba2f3bSAndroid Build Coastguard Worker ** Returns OK, or error if the new type field did not fit
1097*7eba2f3bSAndroid Build Coastguard Worker ** *p_cur_size is updated
1098*7eba2f3bSAndroid Build Coastguard Worker **
1099*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgReplaceType(uint8_t * p_msg,uint32_t max_size,uint32_t * p_cur_size,uint8_t * p_rec,uint8_t * p_new_type,uint8_t new_type_len)1100*7eba2f3bSAndroid Build Coastguard Worker tNDEF_STATUS NDEF_MsgReplaceType(uint8_t* p_msg, uint32_t max_size,
1101*7eba2f3bSAndroid Build Coastguard Worker uint32_t* p_cur_size, uint8_t* p_rec,
1102*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_new_type, uint8_t new_type_len) {
1103*7eba2f3bSAndroid Build Coastguard Worker uint8_t typelen_delta;
1104*7eba2f3bSAndroid Build Coastguard Worker uint8_t *p_prev_type, prev_type_len;
1105*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pp;
1106*7eba2f3bSAndroid Build Coastguard Worker
1107*7eba2f3bSAndroid Build Coastguard Worker /* Skip header */
1108*7eba2f3bSAndroid Build Coastguard Worker pp = p_rec + 1;
1109*7eba2f3bSAndroid Build Coastguard Worker
1110*7eba2f3bSAndroid Build Coastguard Worker /* Next byte is the type field length */
1111*7eba2f3bSAndroid Build Coastguard Worker prev_type_len = *pp++;
1112*7eba2f3bSAndroid Build Coastguard Worker
1113*7eba2f3bSAndroid Build Coastguard Worker /* Skip the payload length */
1114*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_SR_MASK)
1115*7eba2f3bSAndroid Build Coastguard Worker pp += 1;
1116*7eba2f3bSAndroid Build Coastguard Worker else
1117*7eba2f3bSAndroid Build Coastguard Worker pp += 4;
1118*7eba2f3bSAndroid Build Coastguard Worker
1119*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_IL_MASK) pp++;
1120*7eba2f3bSAndroid Build Coastguard Worker
1121*7eba2f3bSAndroid Build Coastguard Worker /* Save pointer to the start of the type field */
1122*7eba2f3bSAndroid Build Coastguard Worker p_prev_type = pp;
1123*7eba2f3bSAndroid Build Coastguard Worker
1124*7eba2f3bSAndroid Build Coastguard Worker if (new_type_len > prev_type_len) {
1125*7eba2f3bSAndroid Build Coastguard Worker /* New type is larger than the previous */
1126*7eba2f3bSAndroid Build Coastguard Worker typelen_delta = new_type_len - prev_type_len;
1127*7eba2f3bSAndroid Build Coastguard Worker
1128*7eba2f3bSAndroid Build Coastguard Worker if ((*p_cur_size + typelen_delta) > max_size)
1129*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INSUFFICIENT_MEM);
1130*7eba2f3bSAndroid Build Coastguard Worker
1131*7eba2f3bSAndroid Build Coastguard Worker /* Point to the end of the previous type, and make space for the extra data
1132*7eba2f3bSAndroid Build Coastguard Worker */
1133*7eba2f3bSAndroid Build Coastguard Worker pp = p_prev_type + prev_type_len;
1134*7eba2f3bSAndroid Build Coastguard Worker shiftdown(pp, (uint32_t)(*p_cur_size - (pp - p_msg)), typelen_delta);
1135*7eba2f3bSAndroid Build Coastguard Worker
1136*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size += typelen_delta;
1137*7eba2f3bSAndroid Build Coastguard Worker } else if (new_type_len < prev_type_len) {
1138*7eba2f3bSAndroid Build Coastguard Worker /* New type field is smaller than the previous */
1139*7eba2f3bSAndroid Build Coastguard Worker typelen_delta = prev_type_len - new_type_len;
1140*7eba2f3bSAndroid Build Coastguard Worker
1141*7eba2f3bSAndroid Build Coastguard Worker /* Point to the end of the previous type, and shift up to fill the the
1142*7eba2f3bSAndroid Build Coastguard Worker * unused space */
1143*7eba2f3bSAndroid Build Coastguard Worker pp = p_prev_type + prev_type_len;
1144*7eba2f3bSAndroid Build Coastguard Worker shiftup(pp - typelen_delta, pp, (uint32_t)(*p_cur_size - (pp - p_msg)));
1145*7eba2f3bSAndroid Build Coastguard Worker
1146*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size -= typelen_delta;
1147*7eba2f3bSAndroid Build Coastguard Worker }
1148*7eba2f3bSAndroid Build Coastguard Worker
1149*7eba2f3bSAndroid Build Coastguard Worker /* Save in new type length */
1150*7eba2f3bSAndroid Build Coastguard Worker p_rec[1] = new_type_len;
1151*7eba2f3bSAndroid Build Coastguard Worker
1152*7eba2f3bSAndroid Build Coastguard Worker /* Now copy in the new type field data */
1153*7eba2f3bSAndroid Build Coastguard Worker if (p_new_type) memcpy(p_prev_type, p_new_type, new_type_len);
1154*7eba2f3bSAndroid Build Coastguard Worker
1155*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_OK);
1156*7eba2f3bSAndroid Build Coastguard Worker }
1157*7eba2f3bSAndroid Build Coastguard Worker
1158*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
1159*7eba2f3bSAndroid Build Coastguard Worker **
1160*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgReplaceId
1161*7eba2f3bSAndroid Build Coastguard Worker **
1162*7eba2f3bSAndroid Build Coastguard Worker ** Description This function replaces the ID field of a specific record in
1163*7eba2f3bSAndroid Build Coastguard Worker ** the given NDEF message
1164*7eba2f3bSAndroid Build Coastguard Worker **
1165*7eba2f3bSAndroid Build Coastguard Worker ** Returns OK, or error if the new ID field did not fit
1166*7eba2f3bSAndroid Build Coastguard Worker ** *p_cur_size is updated
1167*7eba2f3bSAndroid Build Coastguard Worker **
1168*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgReplaceId(uint8_t * p_msg,uint32_t max_size,uint32_t * p_cur_size,uint8_t * p_rec,uint8_t * p_new_id,uint8_t new_id_len)1169*7eba2f3bSAndroid Build Coastguard Worker tNDEF_STATUS NDEF_MsgReplaceId(uint8_t* p_msg, uint32_t max_size,
1170*7eba2f3bSAndroid Build Coastguard Worker uint32_t* p_cur_size, uint8_t* p_rec,
1171*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_new_id, uint8_t new_id_len) {
1172*7eba2f3bSAndroid Build Coastguard Worker uint8_t idlen_delta;
1173*7eba2f3bSAndroid Build Coastguard Worker uint8_t *p_prev_id, *p_idlen_field;
1174*7eba2f3bSAndroid Build Coastguard Worker uint8_t prev_id_len, type_len;
1175*7eba2f3bSAndroid Build Coastguard Worker uint8_t* pp;
1176*7eba2f3bSAndroid Build Coastguard Worker
1177*7eba2f3bSAndroid Build Coastguard Worker /* Skip header */
1178*7eba2f3bSAndroid Build Coastguard Worker pp = p_rec + 1;
1179*7eba2f3bSAndroid Build Coastguard Worker
1180*7eba2f3bSAndroid Build Coastguard Worker /* Next byte is the type field length */
1181*7eba2f3bSAndroid Build Coastguard Worker type_len = *pp++;
1182*7eba2f3bSAndroid Build Coastguard Worker
1183*7eba2f3bSAndroid Build Coastguard Worker /* Skip the payload length */
1184*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_SR_MASK)
1185*7eba2f3bSAndroid Build Coastguard Worker pp += 1;
1186*7eba2f3bSAndroid Build Coastguard Worker else
1187*7eba2f3bSAndroid Build Coastguard Worker pp += 4;
1188*7eba2f3bSAndroid Build Coastguard Worker
1189*7eba2f3bSAndroid Build Coastguard Worker p_idlen_field = pp;
1190*7eba2f3bSAndroid Build Coastguard Worker
1191*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_IL_MASK)
1192*7eba2f3bSAndroid Build Coastguard Worker prev_id_len = *pp++;
1193*7eba2f3bSAndroid Build Coastguard Worker else
1194*7eba2f3bSAndroid Build Coastguard Worker prev_id_len = 0;
1195*7eba2f3bSAndroid Build Coastguard Worker
1196*7eba2f3bSAndroid Build Coastguard Worker /* Save pointer to the start of the ID field (right after the type field) */
1197*7eba2f3bSAndroid Build Coastguard Worker p_prev_id = pp + type_len;
1198*7eba2f3bSAndroid Build Coastguard Worker
1199*7eba2f3bSAndroid Build Coastguard Worker if (new_id_len > prev_id_len) {
1200*7eba2f3bSAndroid Build Coastguard Worker /* New ID field is larger than the previous */
1201*7eba2f3bSAndroid Build Coastguard Worker idlen_delta = new_id_len - prev_id_len;
1202*7eba2f3bSAndroid Build Coastguard Worker
1203*7eba2f3bSAndroid Build Coastguard Worker /* If the previous ID length was 0, we need to add a 1-byte ID length */
1204*7eba2f3bSAndroid Build Coastguard Worker if (prev_id_len == 0) {
1205*7eba2f3bSAndroid Build Coastguard Worker if ((*p_cur_size + idlen_delta + 1) > max_size)
1206*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INSUFFICIENT_MEM);
1207*7eba2f3bSAndroid Build Coastguard Worker
1208*7eba2f3bSAndroid Build Coastguard Worker shiftdown(p_idlen_field,
1209*7eba2f3bSAndroid Build Coastguard Worker (uint32_t)(*p_cur_size - (p_idlen_field - p_msg)), 1);
1210*7eba2f3bSAndroid Build Coastguard Worker p_prev_id += 1;
1211*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size += 1;
1212*7eba2f3bSAndroid Build Coastguard Worker *p_rec |= NDEF_IL_MASK;
1213*7eba2f3bSAndroid Build Coastguard Worker } else if ((*p_cur_size + idlen_delta) > max_size)
1214*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_MSG_INSUFFICIENT_MEM);
1215*7eba2f3bSAndroid Build Coastguard Worker
1216*7eba2f3bSAndroid Build Coastguard Worker /* Point to the end of the previous ID field, and make space for the extra
1217*7eba2f3bSAndroid Build Coastguard Worker * data */
1218*7eba2f3bSAndroid Build Coastguard Worker pp = p_prev_id + prev_id_len;
1219*7eba2f3bSAndroid Build Coastguard Worker shiftdown(pp, (uint32_t)(*p_cur_size - (pp - p_msg)), idlen_delta);
1220*7eba2f3bSAndroid Build Coastguard Worker
1221*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size += idlen_delta;
1222*7eba2f3bSAndroid Build Coastguard Worker } else if (new_id_len < prev_id_len) {
1223*7eba2f3bSAndroid Build Coastguard Worker /* New ID field is smaller than the previous */
1224*7eba2f3bSAndroid Build Coastguard Worker idlen_delta = prev_id_len - new_id_len;
1225*7eba2f3bSAndroid Build Coastguard Worker
1226*7eba2f3bSAndroid Build Coastguard Worker /* Point to the end of the previous ID, and shift up to fill the the unused
1227*7eba2f3bSAndroid Build Coastguard Worker * space */
1228*7eba2f3bSAndroid Build Coastguard Worker pp = p_prev_id + prev_id_len;
1229*7eba2f3bSAndroid Build Coastguard Worker shiftup(pp - idlen_delta, pp, (uint32_t)(*p_cur_size - (pp - p_msg)));
1230*7eba2f3bSAndroid Build Coastguard Worker
1231*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size -= idlen_delta;
1232*7eba2f3bSAndroid Build Coastguard Worker
1233*7eba2f3bSAndroid Build Coastguard Worker /* If removing the ID, make sure that length field is also removed */
1234*7eba2f3bSAndroid Build Coastguard Worker if (new_id_len == 0) {
1235*7eba2f3bSAndroid Build Coastguard Worker shiftup(p_idlen_field, p_idlen_field + 1,
1236*7eba2f3bSAndroid Build Coastguard Worker (uint32_t)(*p_cur_size - (p_idlen_field - p_msg - (uint32_t)1)));
1237*7eba2f3bSAndroid Build Coastguard Worker *p_rec &= ~NDEF_IL_MASK;
1238*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size -= 1;
1239*7eba2f3bSAndroid Build Coastguard Worker }
1240*7eba2f3bSAndroid Build Coastguard Worker }
1241*7eba2f3bSAndroid Build Coastguard Worker
1242*7eba2f3bSAndroid Build Coastguard Worker /* Save in new ID length and data */
1243*7eba2f3bSAndroid Build Coastguard Worker if (new_id_len) {
1244*7eba2f3bSAndroid Build Coastguard Worker *p_idlen_field = new_id_len;
1245*7eba2f3bSAndroid Build Coastguard Worker
1246*7eba2f3bSAndroid Build Coastguard Worker if (p_new_id) memcpy(p_prev_id, p_new_id, new_id_len);
1247*7eba2f3bSAndroid Build Coastguard Worker }
1248*7eba2f3bSAndroid Build Coastguard Worker
1249*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_OK);
1250*7eba2f3bSAndroid Build Coastguard Worker }
1251*7eba2f3bSAndroid Build Coastguard Worker
1252*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
1253*7eba2f3bSAndroid Build Coastguard Worker **
1254*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgRemoveRec
1255*7eba2f3bSAndroid Build Coastguard Worker **
1256*7eba2f3bSAndroid Build Coastguard Worker ** Description This function removes the record at the given
1257*7eba2f3bSAndroid Build Coastguard Worker ** index in the given NDEF message.
1258*7eba2f3bSAndroid Build Coastguard Worker **
1259*7eba2f3bSAndroid Build Coastguard Worker ** Returns TRUE if OK, FALSE if the index was invalid
1260*7eba2f3bSAndroid Build Coastguard Worker ** *p_cur_size is updated
1261*7eba2f3bSAndroid Build Coastguard Worker **
1262*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgRemoveRec(uint8_t * p_msg,uint32_t * p_cur_size,int32_t index)1263*7eba2f3bSAndroid Build Coastguard Worker tNDEF_STATUS NDEF_MsgRemoveRec(uint8_t* p_msg, uint32_t* p_cur_size,
1264*7eba2f3bSAndroid Build Coastguard Worker int32_t index) {
1265*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec = NDEF_MsgGetRecByIndex(p_msg, index);
1266*7eba2f3bSAndroid Build Coastguard Worker uint8_t *pNext, *pPrev;
1267*7eba2f3bSAndroid Build Coastguard Worker
1268*7eba2f3bSAndroid Build Coastguard Worker if (!p_rec) return (NDEF_REC_NOT_FOUND);
1269*7eba2f3bSAndroid Build Coastguard Worker
1270*7eba2f3bSAndroid Build Coastguard Worker /* If this is the first record in the message... */
1271*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_MB_MASK) {
1272*7eba2f3bSAndroid Build Coastguard Worker /* Find the second record (if any) and set his 'Message Begin' bit */
1273*7eba2f3bSAndroid Build Coastguard Worker pNext = NDEF_MsgGetRecByIndex(p_msg, 1);
1274*7eba2f3bSAndroid Build Coastguard Worker if (pNext != nullptr) {
1275*7eba2f3bSAndroid Build Coastguard Worker *pNext |= NDEF_MB_MASK;
1276*7eba2f3bSAndroid Build Coastguard Worker
1277*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size -= (uint32_t)(pNext - p_msg);
1278*7eba2f3bSAndroid Build Coastguard Worker
1279*7eba2f3bSAndroid Build Coastguard Worker shiftup(p_msg, pNext, *p_cur_size);
1280*7eba2f3bSAndroid Build Coastguard Worker } else
1281*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size = 0; /* No more records, lenght must be zero */
1282*7eba2f3bSAndroid Build Coastguard Worker
1283*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_OK);
1284*7eba2f3bSAndroid Build Coastguard Worker }
1285*7eba2f3bSAndroid Build Coastguard Worker
1286*7eba2f3bSAndroid Build Coastguard Worker /* If this is the last record in the message... */
1287*7eba2f3bSAndroid Build Coastguard Worker if (*p_rec & NDEF_ME_MASK) {
1288*7eba2f3bSAndroid Build Coastguard Worker if (index > 0) {
1289*7eba2f3bSAndroid Build Coastguard Worker /* Find the previous record and set his 'Message End' bit */
1290*7eba2f3bSAndroid Build Coastguard Worker pPrev = NDEF_MsgGetRecByIndex(p_msg, index - 1);
1291*7eba2f3bSAndroid Build Coastguard Worker if (pPrev == nullptr) return false;
1292*7eba2f3bSAndroid Build Coastguard Worker
1293*7eba2f3bSAndroid Build Coastguard Worker *pPrev |= NDEF_ME_MASK;
1294*7eba2f3bSAndroid Build Coastguard Worker }
1295*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size = (uint32_t)(p_rec - p_msg);
1296*7eba2f3bSAndroid Build Coastguard Worker
1297*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_OK);
1298*7eba2f3bSAndroid Build Coastguard Worker }
1299*7eba2f3bSAndroid Build Coastguard Worker
1300*7eba2f3bSAndroid Build Coastguard Worker /* Not the first or the last... get the address of the next record */
1301*7eba2f3bSAndroid Build Coastguard Worker pNext = NDEF_MsgGetNextRec(p_rec);
1302*7eba2f3bSAndroid Build Coastguard Worker if (pNext == nullptr) return false;
1303*7eba2f3bSAndroid Build Coastguard Worker
1304*7eba2f3bSAndroid Build Coastguard Worker /* We are removing p_rec, so shift from pNext to the end */
1305*7eba2f3bSAndroid Build Coastguard Worker shiftup(p_rec, pNext, (uint32_t)(*p_cur_size - (pNext - p_msg)));
1306*7eba2f3bSAndroid Build Coastguard Worker
1307*7eba2f3bSAndroid Build Coastguard Worker *p_cur_size -= (uint32_t)(pNext - p_rec);
1308*7eba2f3bSAndroid Build Coastguard Worker
1309*7eba2f3bSAndroid Build Coastguard Worker return (NDEF_OK);
1310*7eba2f3bSAndroid Build Coastguard Worker }
1311*7eba2f3bSAndroid Build Coastguard Worker
1312*7eba2f3bSAndroid Build Coastguard Worker /*******************************************************************************
1313*7eba2f3bSAndroid Build Coastguard Worker **
1314*7eba2f3bSAndroid Build Coastguard Worker ** Function NDEF_MsgCopyAndDechunk
1315*7eba2f3bSAndroid Build Coastguard Worker **
1316*7eba2f3bSAndroid Build Coastguard Worker ** Description This function copies and de-chunks an NDEF message.
1317*7eba2f3bSAndroid Build Coastguard Worker ** It is assumed that the destination is at least as large
1318*7eba2f3bSAndroid Build Coastguard Worker ** as the source, since the source may not actually contain
1319*7eba2f3bSAndroid Build Coastguard Worker ** any chunks.
1320*7eba2f3bSAndroid Build Coastguard Worker **
1321*7eba2f3bSAndroid Build Coastguard Worker ** Returns The output byte count
1322*7eba2f3bSAndroid Build Coastguard Worker **
1323*7eba2f3bSAndroid Build Coastguard Worker *******************************************************************************/
NDEF_MsgCopyAndDechunk(uint8_t * p_src,uint32_t src_len,uint8_t * p_dest,uint32_t * p_out_len)1324*7eba2f3bSAndroid Build Coastguard Worker tNDEF_STATUS NDEF_MsgCopyAndDechunk(uint8_t* p_src, uint32_t src_len,
1325*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_dest, uint32_t* p_out_len) {
1326*7eba2f3bSAndroid Build Coastguard Worker uint32_t out_len, max_out_len;
1327*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_rec;
1328*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p_prev_rec = p_dest;
1329*7eba2f3bSAndroid Build Coastguard Worker uint8_t *p_type, *p_id, *p_pay;
1330*7eba2f3bSAndroid Build Coastguard Worker uint8_t type_len, id_len, tnf;
1331*7eba2f3bSAndroid Build Coastguard Worker uint32_t pay_len;
1332*7eba2f3bSAndroid Build Coastguard Worker tNDEF_STATUS status;
1333*7eba2f3bSAndroid Build Coastguard Worker
1334*7eba2f3bSAndroid Build Coastguard Worker /* First, validate the source */
1335*7eba2f3bSAndroid Build Coastguard Worker status = NDEF_MsgValidate(p_src, src_len, true);
1336*7eba2f3bSAndroid Build Coastguard Worker if (status != NDEF_OK) return (status);
1337*7eba2f3bSAndroid Build Coastguard Worker
1338*7eba2f3bSAndroid Build Coastguard Worker /* The output buffer must be at least as large as the input buffer */
1339*7eba2f3bSAndroid Build Coastguard Worker max_out_len = src_len;
1340*7eba2f3bSAndroid Build Coastguard Worker
1341*7eba2f3bSAndroid Build Coastguard Worker /* Initialize output */
1342*7eba2f3bSAndroid Build Coastguard Worker NDEF_MsgInit(p_dest, max_out_len, &out_len);
1343*7eba2f3bSAndroid Build Coastguard Worker
1344*7eba2f3bSAndroid Build Coastguard Worker p_rec = p_src;
1345*7eba2f3bSAndroid Build Coastguard Worker
1346*7eba2f3bSAndroid Build Coastguard Worker /* Now, copy record by record */
1347*7eba2f3bSAndroid Build Coastguard Worker while ((p_rec != nullptr) && (status == NDEF_OK)) {
1348*7eba2f3bSAndroid Build Coastguard Worker p_type = NDEF_RecGetType(p_rec, &tnf, &type_len);
1349*7eba2f3bSAndroid Build Coastguard Worker p_id = NDEF_RecGetId(p_rec, &id_len);
1350*7eba2f3bSAndroid Build Coastguard Worker p_pay = NDEF_RecGetPayload(p_rec, &pay_len);
1351*7eba2f3bSAndroid Build Coastguard Worker
1352*7eba2f3bSAndroid Build Coastguard Worker /* If this is the continuation of a chunk, append the payload to the
1353*7eba2f3bSAndroid Build Coastguard Worker * previous */
1354*7eba2f3bSAndroid Build Coastguard Worker if (tnf == NDEF_TNF_UNCHANGED) {
1355*7eba2f3bSAndroid Build Coastguard Worker if (p_pay) {
1356*7eba2f3bSAndroid Build Coastguard Worker status = NDEF_MsgAppendPayload(p_dest, max_out_len, &out_len,
1357*7eba2f3bSAndroid Build Coastguard Worker p_prev_rec, p_pay, pay_len);
1358*7eba2f3bSAndroid Build Coastguard Worker }
1359*7eba2f3bSAndroid Build Coastguard Worker } else {
1360*7eba2f3bSAndroid Build Coastguard Worker p_prev_rec = p_dest + out_len;
1361*7eba2f3bSAndroid Build Coastguard Worker
1362*7eba2f3bSAndroid Build Coastguard Worker status = NDEF_MsgAddRec(p_dest, max_out_len, &out_len, tnf, p_type,
1363*7eba2f3bSAndroid Build Coastguard Worker type_len, p_id, id_len, p_pay, pay_len);
1364*7eba2f3bSAndroid Build Coastguard Worker }
1365*7eba2f3bSAndroid Build Coastguard Worker
1366*7eba2f3bSAndroid Build Coastguard Worker p_rec = NDEF_MsgGetNextRec(p_rec);
1367*7eba2f3bSAndroid Build Coastguard Worker }
1368*7eba2f3bSAndroid Build Coastguard Worker
1369*7eba2f3bSAndroid Build Coastguard Worker *p_out_len = out_len;
1370*7eba2f3bSAndroid Build Coastguard Worker
1371*7eba2f3bSAndroid Build Coastguard Worker return (status);
1372*7eba2f3bSAndroid Build Coastguard Worker }
1373