1 /******************************************************************************
2 *
3 * Copyright (C) 2010-2014 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains the implementation for Type 2 tag NDEF operation in
22 * Reader/Writer mode.
23 *
24 ******************************************************************************/
25 #include <log/log.h>
26 #include <string.h>
27 #include "nfc_target.h"
28
29 #include "gki.h"
30 #include "nci_hmsgs.h"
31 #include "nfc_api.h"
32 #include "nfc_int.h"
33 #include "rw_api.h"
34 #include "rw_int.h"
35
36 #if (RW_NDEF_INCLUDED == TRUE)
37
38 /* Local static functions */
39 static void rw_t2t_handle_cc_read_rsp(void);
40 static void rw_t2t_handle_lock_read_rsp(uint8_t* p_data);
41 static void rw_t2t_handle_tlv_detect_rsp(uint8_t* p_data);
42 static void rw_t2t_handle_ndef_read_rsp(uint8_t* p_data);
43 static void rw_t2t_handle_ndef_write_rsp(uint8_t* p_data);
44 static void rw_t2t_handle_format_tag_rsp(uint8_t* p_data);
45 static void rw_t2t_handle_config_tag_readonly(uint8_t* p_data);
46 static uint8_t rw_t2t_get_tag_size(uint8_t* p_data);
47 static void rw_t2t_extract_default_locks_info(void);
48 static void rw_t2t_update_cb(uint16_t block, uint8_t* p_write_block,
49 bool b_update_len);
50 static uint8_t rw_t2t_get_ndef_flags(void);
51 static uint16_t rw_t2t_get_ndef_max_size(void);
52 static tNFC_STATUS rw_t2t_read_locks(void);
53 static tNFC_STATUS rw_t2t_read_ndef_last_block(void);
54 static void rw_t2t_update_attributes(void);
55 static void rw_t2t_update_lock_attributes(void);
56 static bool rw_t2t_is_lock_res_byte(uint16_t index);
57 static bool rw_t2t_is_read_only_byte(uint16_t index);
58 static tNFC_STATUS rw_t2t_write_ndef_first_block(uint16_t msg_len,
59 bool b_update_len);
60 static tNFC_STATUS rw_t2t_write_ndef_next_block(uint16_t block,
61 uint16_t msg_len,
62 bool b_update_len);
63 static tNFC_STATUS rw_t2t_read_ndef_next_block(uint16_t block);
64 static tNFC_STATUS rw_t2t_add_terminator_tlv(void);
65 static bool rw_t2t_is_read_before_write_block(uint16_t block,
66 uint16_t* p_block_to_read);
67 static tNFC_STATUS rw_t2t_set_cc(uint8_t tms);
68 static tNFC_STATUS rw_t2t_set_lock_tlv(uint16_t addr, uint8_t num_dyn_lock_bits,
69 uint16_t locked_area_size);
70 static tNFC_STATUS rw_t2t_format_tag(void);
71 static tNFC_STATUS rw_t2t_soft_lock_tag(void);
72 static tNFC_STATUS rw_t2t_set_dynamic_lock_bits(uint8_t* p_data);
73 static void rw_t2t_ntf_tlv_detect_complete(tNFC_STATUS status);
74
75 const uint8_t rw_t2t_mask_bits[8] = {0x01, 0x02, 0x04, 0x08,
76 0x10, 0x20, 0x40, 0x80};
77
78 /*******************************************************************************
79 **
80 ** Function rw_t2t_handle_rsp
81 **
82 ** Description This function handles response to command sent during
83 ** NDEF and other tlv operation
84 **
85 ** Returns None
86 **
87 *******************************************************************************/
rw_t2t_handle_rsp(uint8_t * p_data)88 void rw_t2t_handle_rsp(uint8_t* p_data) {
89 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
90
91 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
92 p_t2t->b_read_hdr = true;
93 memcpy(p_t2t->tag_hdr, p_data, T2T_READ_DATA_LEN);
94 }
95
96 switch (p_t2t->state) {
97 case RW_T2T_STATE_DETECT_TLV:
98 if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV) {
99 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
100 rw_t2t_handle_cc_read_rsp();
101 } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) {
102 rw_t2t_handle_lock_read_rsp(p_data);
103 } else {
104 rw_t2t_handle_tlv_detect_rsp(p_data);
105 }
106 } else if (p_t2t->tlv_detect == TAG_NDEF_TLV) {
107 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
108 if (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] == T2T_CC0_NMN) {
109 rw_t2t_handle_cc_read_rsp();
110 } else {
111 RW_TRACE_WARNING3(
112 "NDEF Detection failed!, CC[0]: 0x%02x, CC[1]: 0x%02x, CC[3]: "
113 "0x%02x",
114 p_t2t->tag_hdr[T2T_CC0_NMN_BYTE],
115 p_t2t->tag_hdr[T2T_CC1_VNO_BYTE],
116 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
117 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
118 }
119 } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) {
120 rw_t2t_handle_lock_read_rsp(p_data);
121 } else {
122 rw_t2t_handle_tlv_detect_rsp(p_data);
123 }
124 } else {
125 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
126 rw_t2t_handle_cc_read_rsp();
127 } else {
128 rw_t2t_handle_tlv_detect_rsp(p_data);
129 }
130 }
131 break;
132
133 case RW_T2T_STATE_SET_TAG_RO:
134 rw_t2t_handle_config_tag_readonly(p_data);
135 break;
136
137 case RW_T2T_STATE_FORMAT_TAG:
138 rw_t2t_handle_format_tag_rsp(p_data);
139 break;
140
141 case RW_T2T_STATE_READ_NDEF:
142 rw_t2t_handle_ndef_read_rsp(p_data);
143 break;
144
145 case RW_T2T_STATE_WRITE_NDEF:
146 rw_t2t_handle_ndef_write_rsp(p_data);
147 break;
148 }
149 }
150
151 /*******************************************************************************
152 **
153 ** Function rw_t2t_info_to_event
154 **
155 ** Description This function returns RW event code based on the current
156 ** state
157 **
158 ** Returns RW event code
159 **
160 *******************************************************************************/
rw_t2t_info_to_event(const tT2T_CMD_RSP_INFO * p_info)161 tRW_EVENT rw_t2t_info_to_event(const tT2T_CMD_RSP_INFO* p_info) {
162 tRW_EVENT rw_event;
163 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
164
165 switch (p_t2t->state) {
166 case RW_T2T_STATE_DETECT_TLV:
167 if (p_t2t->tlv_detect == TAG_NDEF_TLV)
168 rw_event = RW_T2T_NDEF_DETECT_EVT;
169 else
170 rw_event = RW_T2T_TLV_DETECT_EVT;
171
172 break;
173
174 case RW_T2T_STATE_READ_NDEF:
175 rw_event = RW_T2T_NDEF_READ_EVT;
176 break;
177
178 case RW_T2T_STATE_WRITE_NDEF:
179 rw_event = RW_T2T_NDEF_WRITE_EVT;
180 break;
181
182 case RW_T2T_STATE_SET_TAG_RO:
183 rw_event = RW_T2T_SET_TAG_RO_EVT;
184 break;
185
186 case RW_T2T_STATE_CHECK_PRESENCE:
187 rw_event = RW_T2T_PRESENCE_CHECK_EVT;
188 break;
189
190 case RW_T2T_STATE_FORMAT_TAG:
191 rw_event = RW_T2T_FORMAT_CPLT_EVT;
192 break;
193
194 default:
195 rw_event = t2t_info_to_evt(p_info);
196 break;
197 }
198 return rw_event;
199 }
200
201 /*******************************************************************************
202 **
203 ** Function rw_t2t_handle_cc_read_rsp
204 **
205 ** Description Handle read cc bytes
206 **
207 ** Returns none
208 **
209 *******************************************************************************/
rw_t2t_handle_cc_read_rsp(void)210 static void rw_t2t_handle_cc_read_rsp(void) {
211 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
212
213 if (((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) &&
214 (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RO)) ||
215 ((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) &&
216 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) &&
217 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO))) {
218 /* Invalid Version number or RWA byte */
219 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
220 return;
221 }
222
223 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
224
225 if (rw_t2t_read((uint16_t)T2T_FIRST_DATA_BLOCK) != NFC_STATUS_OK) {
226 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
227 }
228 }
229
230 /*******************************************************************************
231 **
232 ** Function rw_t2t_ntf_tlv_detect_complete
233 **
234 ** Description Notify TLV detection complete to upper layer
235 **
236 ** Returns none
237 **
238 *******************************************************************************/
rw_t2t_ntf_tlv_detect_complete(tNFC_STATUS status)239 static void rw_t2t_ntf_tlv_detect_complete(tNFC_STATUS status) {
240 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
241 tRW_DETECT_NDEF_DATA ndef_data = {
242 0,
243 };
244 tRW_DETECT_TLV_DATA tlv_data;
245 tRW_T2T_DETECT evt_data;
246 uint8_t xx;
247
248 if (p_t2t->tlv_detect == TAG_NDEF_TLV) {
249 /* Notify upper layer the result of NDEF detect op */
250 ndef_data.status = status;
251 ndef_data.protocol = NFC_PROTOCOL_T2T;
252 ndef_data.flags = rw_t2t_get_ndef_flags();
253 ndef_data.cur_size = p_t2t->ndef_msg_len;
254
255 if (status == NFC_STATUS_OK) ndef_data.flags |= RW_NDEF_FL_FORMATED;
256
257 if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] == T2T_CC3_RWA_RW)
258 ndef_data.max_size = (uint32_t)rw_t2t_get_ndef_max_size();
259 else
260 ndef_data.max_size = ndef_data.cur_size;
261
262 if (ndef_data.max_size < ndef_data.cur_size) {
263 ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
264 ndef_data.max_size = ndef_data.cur_size;
265 }
266
267 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
268 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
269 if (status == NFC_STATUS_OK) ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
270 }
271
272 rw_t2t_handle_op_complete();
273 (*rw_cb.p_cback)(RW_T2T_NDEF_DETECT_EVT, (tRW_DATA*)&ndef_data);
274 } else if (p_t2t->tlv_detect == TAG_PROPRIETARY_TLV) {
275 evt_data.msg_len = p_t2t->prop_msg_len;
276 evt_data.status = status;
277 rw_t2t_handle_op_complete();
278 (*rw_cb.p_cback)(RW_T2T_TLV_DETECT_EVT, (tRW_DATA*)&evt_data);
279 } else {
280 /* Notify upper layer the result of Lock/Mem TLV detect op */
281 tlv_data.protocol = NFC_PROTOCOL_T2T;
282 if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV) {
283 tlv_data.num_bytes = p_t2t->num_lockbytes;
284 } else {
285 tlv_data.num_bytes = 0;
286 for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++) {
287 tlv_data.num_bytes += p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes;
288 }
289 }
290 tlv_data.status = status;
291 rw_t2t_handle_op_complete();
292 (*rw_cb.p_cback)(RW_T2T_TLV_DETECT_EVT, (tRW_DATA*)&tlv_data);
293 }
294 }
295
296 /*******************************************************************************
297 **
298 ** Function rw_t2t_handle_lock_read_rsp
299 **
300 ** Description Handle response to reading lock bytes
301 **
302 ** Returns none
303 **
304 *******************************************************************************/
rw_t2t_handle_lock_read_rsp(uint8_t * p_data)305 static void rw_t2t_handle_lock_read_rsp(uint8_t* p_data) {
306 uint8_t updated_lock_byte;
307 uint8_t num_locks;
308 uint8_t offset = 0;
309 uint16_t lock_offset;
310 uint16_t base_lock_offset = 0;
311 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
312 uint16_t block;
313
314 /* Prepare NDEF/TLV attributes (based on current op) for sending response to
315 * upper layer */
316
317 num_locks = 0;
318 updated_lock_byte = 0;
319
320 /* Extract all lock bytes present in the read 16 bytes
321 * but atleast one lock byte (base lock) should be present in the read 16
322 * bytes */
323
324 while (num_locks < p_t2t->num_lockbytes) {
325 if (p_t2t->lockbyte[num_locks].b_lock_read == false) {
326 lock_offset =
327 p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
328 p_t2t->lockbyte[num_locks].byte_index;
329 if (updated_lock_byte == 0) {
330 /* The offset of the first lock byte present in the 16 bytes read using
331 * READ command */
332 base_lock_offset = lock_offset;
333 /* Block number used to read may not be the block where lock offset is
334 * present */
335 offset = (uint8_t)(lock_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
336 /* Update the lock byte value in the control block */
337 p_t2t->lockbyte[num_locks].lock_byte = p_data[offset];
338 p_t2t->lockbyte[num_locks].b_lock_read = true;
339 updated_lock_byte++;
340 } else if (lock_offset > base_lock_offset) {
341 /* Atleast one lock byte will get updated in the control block */
342 if ((lock_offset - base_lock_offset + offset) < T2T_READ_DATA_LEN) {
343 /* And this lock byte is also present in the read data */
344 p_t2t->lockbyte[num_locks].lock_byte =
345 p_data[lock_offset - base_lock_offset + offset];
346 p_t2t->lockbyte[num_locks].b_lock_read = true;
347 updated_lock_byte++;
348 } else {
349 /* This lock byte is not present in the read data */
350 block = (uint16_t)(lock_offset / T2T_BLOCK_LEN);
351 block -= block % T2T_READ_BLOCKS;
352 /* send READ command to read this lock byte */
353 if (NFC_STATUS_OK != rw_t2t_read((uint16_t)block)) {
354 /* Unable to send Read command, notify failure status to upper layer
355 */
356 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
357 }
358 break;
359 }
360 } else {
361 /* This Lock byte is not present in the read 16 bytes
362 * send READ command to read the lock byte */
363 if (NFC_STATUS_OK !=
364 rw_t2t_read((uint16_t)(lock_offset / T2T_BLOCK_LEN))) {
365 /* Unable to send Read command, notify failure status to upper layer
366 */
367 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
368 }
369 break;
370 }
371 }
372 num_locks++;
373 }
374 if (num_locks == p_t2t->num_lockbytes) {
375 /* All locks are read, notify upper layer */
376 rw_t2t_update_lock_attributes();
377 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_OK);
378 }
379 }
380
381 /*******************************************************************************
382 **
383 ** Function rw_t2t_handle_tlv_detect_rsp
384 **
385 ** Description Handle TLV detection.
386 **
387 ** Returns none
388 **
389 *******************************************************************************/
rw_t2t_handle_tlv_detect_rsp(uint8_t * p_data)390 static void rw_t2t_handle_tlv_detect_rsp(uint8_t* p_data) {
391 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
392 uint16_t offset;
393 uint16_t len = 0;
394 bool failed = false;
395 bool found = false;
396 tRW_EVENT event;
397 uint8_t index;
398 uint8_t count = 0;
399 uint8_t xx;
400 tNFC_STATUS status;
401 tT2T_CMD_RSP_INFO* p_cmd_rsp_info =
402 (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info;
403 uint8_t tlvtype = p_t2t->tlv_detect;
404
405 if (p_t2t->work_offset == 0) {
406 /* Skip UID,Static Lock block,CC*/
407 p_t2t->work_offset = T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN;
408 p_t2t->b_read_data = true;
409 memcpy(p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
410 }
411
412 p_t2t->segment = 0;
413
414 for (offset = 0; offset < T2T_READ_DATA_LEN && !failed && !found;) {
415 if (rw_t2t_is_lock_res_byte((uint16_t)(p_t2t->work_offset + offset)) ==
416 true) {
417 /* Skip locks, reserved bytes while searching for TLV */
418 offset++;
419 continue;
420 }
421 switch (p_t2t->substate) {
422 case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
423 /* Search for the tlv */
424 p_t2t->found_tlv = p_data[offset++];
425 switch (p_t2t->found_tlv) {
426 case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */
427 break;
428
429 case TAG_NDEF_TLV:
430 if (tlvtype == TAG_NDEF_TLV) {
431 /* NDEF Detected, now collect NDEF Attributes including NDEF
432 * Length */
433 index = (offset % T2T_BLOCK_SIZE);
434 /* Backup ndef first block */
435 memcpy(p_t2t->ndef_first_block, &p_data[offset - index], index);
436 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
437 } else if (tlvtype == TAG_PROPRIETARY_TLV) {
438 /* Proprietary TLV can exist after NDEF Tlv so we continue
439 * searching */
440 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
441 } else if (((tlvtype == TAG_LOCK_CTRL_TLV) &&
442 (p_t2t->num_lockbytes > 0)) ||
443 ((tlvtype == TAG_MEM_CTRL_TLV) &&
444 (p_t2t->num_mem_tlvs > 0))) {
445 /* Lock / Memory control tlv cannot exist after NDEF TLV
446 * So when NDEF is found, we stop searching for Lock and Memory
447 * control tlv */
448 found = true;
449 } else {
450 /* While searching for Lock / Memory control tlv, if NDEF TLV is
451 * found
452 * first then our search for Lock /Memory control tlv failed and
453 * we stop here */
454 failed = true;
455 }
456 break;
457
458 case TAG_LOCK_CTRL_TLV:
459 case TAG_MEM_CTRL_TLV:
460 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
461 break;
462
463 case TAG_PROPRIETARY_TLV:
464 if (tlvtype == TAG_PROPRIETARY_TLV) {
465 index = (offset % T2T_BLOCK_SIZE);
466 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
467 } else {
468 /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we
469 * continue searching, skiping proprietary tlv */
470 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
471 }
472 break;
473
474 case TAG_TERMINATOR_TLV: /* Last TLV block in the data area. Must be
475 no NDEF nessage */
476 if (((tlvtype == TAG_LOCK_CTRL_TLV) &&
477 (p_t2t->num_lockbytes > 0)) ||
478 ((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))) {
479 /* No more Lock/Memory TLV control tlv in the tag, so stop
480 * searching */
481 found = true;
482 } else {
483 /* NDEF/Lock/Memory/Proprietary TLV cannot exist after Terminator
484 * Tlv */
485 failed = true;
486 }
487 break;
488 default:
489 failed = true;
490 }
491 break;
492
493 case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
494 len = p_data[offset];
495 switch (p_t2t->found_tlv) {
496 case TAG_NDEF_TLV:
497 p_t2t->ndef_header_offset = offset + p_t2t->work_offset;
498 if (len == TAG_LONG_NDEF_LEN_FIELD_BYTE0) {
499 /* The next two bytes constitute length bytes */
500 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
501 } else {
502 /* one byte length field */
503 p_t2t->ndef_msg_len = len;
504 p_t2t->bytes_count = p_t2t->ndef_msg_len;
505 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
506 }
507 break;
508
509 case TAG_PROPRIETARY_TLV:
510 if (len == T2T_LONG_NDEF_LEN_FIELD_BYTE0) {
511 /* The next two bytes constitute length bytes */
512 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
513 } else {
514 /* one byte length field */
515 p_t2t->prop_msg_len = len;
516 p_t2t->bytes_count = p_t2t->prop_msg_len;
517 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
518 }
519 break;
520 }
521 offset++;
522 break;
523
524 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
525 switch (p_t2t->found_tlv) {
526 case TAG_LOCK_CTRL_TLV:
527 case TAG_MEM_CTRL_TLV:
528
529 len = p_data[offset];
530 if (len == TAG_DEFAULT_TLV_LEN) {
531 /* Valid Lock control TLV */
532 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
533 p_t2t->bytes_count = TAG_DEFAULT_TLV_LEN;
534 } else if (((tlvtype == TAG_LOCK_CTRL_TLV) &&
535 (p_t2t->num_lockbytes > 0)) ||
536 ((tlvtype == TAG_MEM_CTRL_TLV) &&
537 (p_t2t->num_mem_tlvs > 0))) {
538 /* Stop searching for Lock/ Memory control tlv */
539 found = true;
540 } else {
541 failed = true;
542 }
543 break;
544
545 case TAG_NDEF_TLV:
546 case TAG_PROPRIETARY_TLV:
547 /* The first length byte */
548 p_t2t->bytes_count = (uint8_t)p_data[offset];
549 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1;
550 break;
551 }
552 offset++;
553 break;
554
555 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
556 /* Prepare NDEF Message length */
557 p_t2t->bytes_count = (p_t2t->bytes_count << 8) + p_data[offset];
558 if (p_t2t->found_tlv == TAG_NDEF_TLV) {
559 p_t2t->ndef_msg_len = p_t2t->bytes_count;
560 } else if (p_t2t->found_tlv == TAG_PROPRIETARY_TLV) {
561 p_t2t->prop_msg_len = p_t2t->bytes_count;
562 }
563 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
564 offset++;
565 break;
566
567 case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
568 switch (p_t2t->found_tlv) {
569 case TAG_NDEF_TLV:
570 if ((p_t2t->bytes_count == p_t2t->ndef_msg_len) &&
571 (tlvtype == TAG_NDEF_TLV)) {
572 /* The first byte offset after length field */
573 p_t2t->ndef_msg_offset = offset + p_t2t->work_offset;
574 }
575 /* Reduce number of NDEF bytes remaining to pass over NDEF TLV */
576 if (p_t2t->bytes_count > 0) p_t2t->bytes_count--;
577
578 if (tlvtype == TAG_NDEF_TLV) {
579 found = true;
580 p_t2t->ndef_status = T2T_NDEF_DETECTED;
581 } else if (p_t2t->bytes_count == 0) {
582 /* Next byte could be a different TLV */
583 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
584 }
585 break;
586
587 case TAG_LOCK_CTRL_TLV:
588 if (p_t2t->bytes_count > 0) {
589 p_t2t->bytes_count--;
590 } else {
591 RW_TRACE_ERROR0("Underflow p_t2t->bytes_count!");
592 android_errorWriteLog(0x534e4554, "120506143");
593 }
594 if ((tlvtype == TAG_LOCK_CTRL_TLV) || (tlvtype == TAG_NDEF_TLV)) {
595 if (p_t2t->num_lockbytes > 0) {
596 RW_TRACE_ERROR0("Malformed tag!");
597 android_errorWriteLog(0x534e4554, "147309942");
598 failed = true;
599 break;
600 }
601 /* Collect Lock TLV */
602 p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
603 if (p_t2t->bytes_count == 0) {
604 /* Lock TLV is collected and buffered in tlv_value, now decode
605 * it */
606 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset =
607 (p_t2t->tlv_value[0] >> 4) & 0x0F;
608 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset *=
609 (uint8_t)tags_pow(2, p_t2t->tlv_value[2] & 0x0F);
610 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset +=
611 p_t2t->tlv_value[0] & 0x0F;
612 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit =
613 (uint8_t)tags_pow(2, ((p_t2t->tlv_value[2] & 0xF0) >> 4));
614 /* Note: 0 value in DLA_NbrLockBits means 256 */
615 count = p_t2t->tlv_value[1];
616 /* Set it to max value that can be stored in lockbytes */
617 if (count == 0) {
618 #if RW_T2T_MAX_LOCK_BYTES > 0x1F
619 count = UCHAR_MAX;
620 #else
621 count = RW_T2T_MAX_LOCK_BYTES * TAG_BITS_PER_BYTE;
622 #endif
623 }
624 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = count;
625 count = count / TAG_BITS_PER_BYTE +
626 ((count % TAG_BITS_PER_BYTE != 0) ? 1 : 0);
627
628 /* Extract lockbytes info addressed by this Lock TLV */
629 xx = 0;
630 if (count > RW_T2T_MAX_LOCK_BYTES) {
631 count = RW_T2T_MAX_LOCK_BYTES;
632 android_errorWriteLog(0x534e4554, "112161557");
633 }
634 while (xx < count) {
635 p_t2t->lockbyte[p_t2t->num_lockbytes].tlv_index =
636 p_t2t->num_lock_tlvs;
637 p_t2t->lockbyte[p_t2t->num_lockbytes].byte_index = xx;
638 p_t2t->lockbyte[p_t2t->num_lockbytes].b_lock_read = false;
639 xx++;
640 p_t2t->num_lockbytes++;
641 }
642 p_t2t->num_lock_tlvs++;
643 rw_t2t_update_attributes();
644 /* Next byte could be a different TLV */
645 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
646 }
647 } else {
648 /* If not looking for lock/ndef tlv, just skip this Lock TLV */
649 if (p_t2t->bytes_count == 0) {
650 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
651 }
652 }
653 break;
654
655 case TAG_MEM_CTRL_TLV:
656 if (p_t2t->bytes_count > 0) {
657 p_t2t->bytes_count--;
658 } else {
659 RW_TRACE_ERROR0("bytes_count underflow!");
660 android_errorWriteLog(0x534e4554, "120506143");
661 }
662 if ((tlvtype == TAG_MEM_CTRL_TLV) || (tlvtype == TAG_NDEF_TLV)) {
663 p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
664 if (p_t2t->bytes_count == 0) {
665 if (p_t2t->num_mem_tlvs >= RW_T2T_MAX_MEM_TLVS) {
666 RW_TRACE_ERROR0(
667 "rw_t2t_handle_tlv_detect_rsp - Maximum buffer allocated "
668 "for Memory tlv has reached");
669 failed = true;
670 } else {
671 /* Extract memory control tlv */
672 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset =
673 (p_t2t->tlv_value[0] >> 4) & 0x0F;
674 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset *=
675 (uint8_t)tags_pow(2, p_t2t->tlv_value[2] & 0x0F);
676 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset +=
677 p_t2t->tlv_value[0] & 0x0F;
678 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes =
679 p_t2t->tlv_value[1];
680 p_t2t->num_mem_tlvs++;
681 rw_t2t_update_attributes();
682 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
683 }
684 }
685 } else {
686 if (p_t2t->bytes_count == 0) {
687 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
688 }
689 }
690 break;
691
692 case TAG_PROPRIETARY_TLV:
693 if (p_t2t->bytes_count > 0) {
694 p_t2t->bytes_count--;
695 } else {
696 RW_TRACE_ERROR0("bytes_count underflow!");
697 android_errorWriteLog(0x534e4554, "120506143");
698 }
699 if (tlvtype == TAG_PROPRIETARY_TLV) {
700 found = true;
701 p_t2t->prop_msg_len = len;
702 } else {
703 if (p_t2t->bytes_count == 0) {
704 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
705 }
706 }
707 break;
708 }
709 offset++;
710 break;
711 }
712 }
713
714 p_t2t->work_offset += T2T_READ_DATA_LEN;
715
716 event = rw_t2t_info_to_event(p_cmd_rsp_info);
717
718 /* If not found and not failed, read next block and search tlv */
719 if (!found && !failed) {
720 if (p_t2t->work_offset >=
721 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR)) {
722 if (((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0)) ||
723 ((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))) {
724 found = true;
725 } else {
726 failed = true;
727 }
728 } else {
729 if (rw_t2t_read((uint16_t)((p_t2t->work_offset / T2T_BLOCK_LEN) +
730 T2T_FIRST_DATA_BLOCK)) != NFC_STATUS_OK)
731 failed = true;
732 }
733 }
734
735 if (failed || found) {
736 if (tlvtype == TAG_LOCK_CTRL_TLV) {
737 /* Incase no Lock control tlv is present then look for default dynamic
738 * lock bytes */
739 rw_t2t_extract_default_locks_info();
740
741 /* Send command to read the dynamic lock bytes */
742 status = rw_t2t_read_locks();
743
744 if (status != NFC_STATUS_CONTINUE) {
745 /* If unable to read a lock/all locks read, notify upper layer */
746 rw_t2t_update_lock_attributes();
747 rw_t2t_ntf_tlv_detect_complete(status);
748 }
749 } else if (tlvtype == TAG_NDEF_TLV) {
750 rw_t2t_extract_default_locks_info();
751
752 if (failed) {
753 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
754 } else {
755 /* NDEF present,Send command to read the dynamic lock bytes */
756 status = rw_t2t_read_locks();
757 if (status != NFC_STATUS_CONTINUE) {
758 /* If unable to read a lock/all locks read, notify upper layer */
759 rw_t2t_update_lock_attributes();
760 rw_t2t_ntf_tlv_detect_complete(status);
761 }
762 }
763 } else {
764 /* Notify Memory/ Proprietary tlv detect result */
765 status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
766 rw_t2t_ntf_tlv_detect_complete(status);
767 }
768 }
769 }
770
771 /*******************************************************************************
772 **
773 ** Function rw_t2t_read_locks
774 **
775 ** Description This function will send command to read next unread locks
776 **
777 ** Returns NFC_STATUS_OK, if all locks are read successfully
778 ** NFC_STATUS_FAILED, if reading locks failed
779 ** NFC_STATUS_CONTINUE, if reading locks is in progress
780 **
781 *******************************************************************************/
rw_t2t_read_locks(void)782 tNFC_STATUS rw_t2t_read_locks(void) {
783 uint8_t num_locks = 0;
784 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
785 tNFC_STATUS status = NFC_STATUS_CONTINUE;
786 uint16_t offset;
787 uint16_t block;
788
789 if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) ||
790 (p_t2t->skip_dyn_locks)) {
791 /* Skip reading dynamic lock bytes if CC is set as Read only or layer above
792 * instructs to skip */
793 while (num_locks < p_t2t->num_lockbytes) {
794 p_t2t->lockbyte[num_locks].lock_byte = 0x00;
795 p_t2t->lockbyte[num_locks].b_lock_read = true;
796 num_locks++;
797 }
798 }
799
800 while (num_locks < p_t2t->num_lockbytes) {
801 if (p_t2t->lockbyte[num_locks].b_lock_read == false) {
802 /* Send Read command to read the first un read locks */
803 offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
804 p_t2t->lockbyte[num_locks].byte_index;
805
806 /* Read 16 bytes where this lock byte is present */
807 block = (uint16_t)(offset / T2T_BLOCK_LEN);
808 block -= block % T2T_READ_BLOCKS;
809
810 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_LOCKS;
811 /* send READ8 command */
812 status = rw_t2t_read((uint16_t)block);
813 if (status == NFC_STATUS_OK) {
814 /* Reading Locks */
815 status = NFC_STATUS_CONTINUE;
816 } else {
817 status = NFC_STATUS_FAILED;
818 }
819 break;
820 }
821 num_locks++;
822 }
823 if (num_locks == p_t2t->num_lockbytes) {
824 /* All locks are read */
825 status = NFC_STATUS_OK;
826 }
827
828 return status;
829 }
830
831 /*******************************************************************************
832 **
833 ** Function rw_t2t_extract_default_locks_info
834 **
835 ** Description This function will prepare lockbytes information for default
836 ** locks present in the tag in the absence of lock control tlv.
837 ** Adding a virtual lock control tlv for these lock bytes for
838 ** easier manipulation.
839 **
840 ** Returns None
841 **
842 *******************************************************************************/
rw_t2t_extract_default_locks_info(void)843 void rw_t2t_extract_default_locks_info(void) {
844 uint8_t num_dynamic_lock_bits;
845 uint8_t num_dynamic_lock_bytes;
846 uint8_t xx;
847 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
848 const tT2T_INIT_TAG* p_ret;
849 uint8_t bytes_locked_per_lock_bit = T2T_DEFAULT_LOCK_BLPB;
850
851 if ((p_t2t->num_lock_tlvs == 0) &&
852 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] > T2T_CC2_TMS_STATIC)) {
853 /* No Lock control tlv is detected. Indicates lock bytes are present in
854 * default location */
855 /* Add a virtual Lock tlv to map this default lock location */
856 p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0);
857 if (p_ret != NULL) bytes_locked_per_lock_bit = p_ret->default_lock_blpb;
858
859 num_dynamic_lock_bits =
860 ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) -
861 (T2T_STATIC_SIZE - T2T_HEADER_SIZE)) /
862 bytes_locked_per_lock_bit;
863 num_dynamic_lock_bytes = num_dynamic_lock_bits / 8;
864 num_dynamic_lock_bytes += (num_dynamic_lock_bits % 8 == 0) ? 0 : 1;
865 if (num_dynamic_lock_bytes > RW_T2T_MAX_LOCK_BYTES) {
866 RW_TRACE_ERROR2(
867 "rw_t2t_extract_default_locks_info - buffer size: %u less than "
868 "DynLock area sise: %u",
869 RW_T2T_MAX_LOCK_BYTES, num_dynamic_lock_bytes);
870 num_dynamic_lock_bytes = RW_T2T_MAX_LOCK_BYTES;
871 android_errorWriteLog(0x534e4554, "147310721");
872 }
873
874 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset =
875 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
876 (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN);
877 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit =
878 bytes_locked_per_lock_bit;
879 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = num_dynamic_lock_bits;
880
881 /* Based on tag data size the number of locks present in the default
882 * location changes */
883 for (xx = 0; xx < num_dynamic_lock_bytes; xx++) {
884 p_t2t->lockbyte[xx].tlv_index = p_t2t->num_lock_tlvs;
885 p_t2t->lockbyte[xx].byte_index = xx;
886 p_t2t->lockbyte[xx].b_lock_read = false;
887 }
888 p_t2t->num_lockbytes = num_dynamic_lock_bytes;
889 p_t2t->num_lock_tlvs = 1;
890 }
891 }
892
893 /*******************************************************************************
894 **
895 ** Function rw_t2t_read_ndef_last_block
896 **
897 ** Description This function will locate and read the last ndef block.
898 ** The last ndef block refers to the tag block where last byte
899 ** of new ndef message will reside. Also this function will
900 ** locate the offset of Terminator TLV based on the size of
901 ** new NDEF Message
902 **
903 ** Returns NCI_STATUS_OK, if able to locate last ndef block & read
904 ** started. Otherwise, error status.
905 **
906 *******************************************************************************/
rw_t2t_read_ndef_last_block(void)907 tNFC_STATUS rw_t2t_read_ndef_last_block(void) {
908 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
909 uint16_t header_len = (p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN)
910 ? T2T_LONG_NDEF_LEN_FIELD_LEN
911 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
912 uint16_t num_ndef_bytes;
913 uint16_t total_ndef_bytes;
914 uint16_t last_ndef_byte_offset;
915 uint16_t terminator_tlv_byte_index;
916 tNFC_STATUS status;
917 uint16_t block;
918
919 total_ndef_bytes = header_len + p_t2t->new_ndef_msg_len;
920 num_ndef_bytes = 0;
921 last_ndef_byte_offset = p_t2t->ndef_header_offset;
922
923 /* Locate NDEF final block based on the size of new NDEF Message */
924 while (num_ndef_bytes < total_ndef_bytes) {
925 if (rw_t2t_is_lock_res_byte((uint16_t)(last_ndef_byte_offset)) == false)
926 num_ndef_bytes++;
927
928 last_ndef_byte_offset++;
929 }
930 p_t2t->ndef_last_block_num =
931 (uint16_t)((last_ndef_byte_offset - 1) / T2T_BLOCK_SIZE);
932 block = p_t2t->ndef_last_block_num;
933
934 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK;
935 /* Read NDEF last block before updating */
936 status = rw_t2t_read(block);
937 if (status == NFC_STATUS_OK) {
938 if ((p_t2t->new_ndef_msg_len + 1) <= p_t2t->max_ndef_msg_len) {
939 /* Locate Terminator TLV Block */
940 total_ndef_bytes++;
941 terminator_tlv_byte_index = last_ndef_byte_offset;
942
943 while (num_ndef_bytes < total_ndef_bytes) {
944 if (rw_t2t_is_lock_res_byte((uint16_t)terminator_tlv_byte_index) ==
945 false)
946 num_ndef_bytes++;
947
948 terminator_tlv_byte_index++;
949 }
950
951 p_t2t->terminator_byte_index = terminator_tlv_byte_index - 1;
952 } else {
953 /* No space for Terminator TLV */
954 p_t2t->terminator_byte_index = 0x00;
955 }
956 }
957 return status;
958 }
959
960 /*******************************************************************************
961 **
962 ** Function rw_t2t_read_terminator_tlv_block
963 **
964 ** Description This function will read the block where terminator tlv will
965 ** be added later
966 **
967 ** Returns NCI_STATUS_OK, if read was started. Otherwise, error status.
968 **
969 *******************************************************************************/
rw_t2t_read_terminator_tlv_block(void)970 tNFC_STATUS rw_t2t_read_terminator_tlv_block(void) {
971 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
972 tNFC_STATUS status;
973 uint16_t block;
974
975 /* Send read command to read base block (Block % 4==0) where this block is
976 * also read as part of 16 bytes */
977 block = p_t2t->terminator_byte_index / T2T_BLOCK_SIZE;
978 block -= block % T2T_READ_BLOCKS;
979
980 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK;
981 /* Read the block where Terminator TLV may be added later during NDEF Write
982 * operation */
983 status = rw_t2t_read(block);
984 return status;
985 }
986
987 /*******************************************************************************
988 **
989 ** Function rw_t2t_read_ndef_next_block
990 **
991 ** Description This function will read the tag block passed as argument
992 **
993 ** Returns NCI_STATUS_OK, if read was started. Otherwise, error status.
994 **
995 *******************************************************************************/
rw_t2t_read_ndef_next_block(uint16_t block)996 tNFC_STATUS rw_t2t_read_ndef_next_block(uint16_t block) {
997 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
998 tNFC_STATUS status;
999
1000 /* Send read command to read base block (Block % 4==0) where this block is
1001 * also read as part of 16 bytes */
1002 block -= block % T2T_READ_BLOCKS;
1003
1004 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK;
1005 /* Read the block */
1006 status = rw_t2t_read(block);
1007
1008 return status;
1009 }
1010
1011 /*******************************************************************************
1012 **
1013 ** Function rw_t2t_is_read_before_write_block
1014 **
1015 ** Description This function will check if the block has to be read before
1016 ** writting to avoid over writting in to lock/reserved bytes
1017 ** present in the block.
1018 ** If no bytes in the block can be overwritten it moves in to
1019 ** next block and check. Finally it finds a block where part of
1020 ** ndef bytes can exist and check if the whole block can be
1021 ** updated or only part of block can be modified.
1022 **
1023 ** Returns TRUE, if the block returned should be read before writting
1024 ** FALSE, if the block need not be read as it was already
1025 ** read or during NDEF write we may completely overwrite
1026 ** the block and there is no reserved or locked bytes in
1027 ** that block
1028 **
1029 *******************************************************************************/
rw_t2t_is_read_before_write_block(uint16_t block,uint16_t * p_block_to_read)1030 static bool rw_t2t_is_read_before_write_block(uint16_t block,
1031 uint16_t* p_block_to_read) {
1032 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1033 uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1034 uint8_t count;
1035 uint8_t index;
1036 uint16_t tag_size = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1037 bool read_before_write = true;
1038
1039 if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) {
1040 /* First NDEF block is already read */
1041 read_before_write = false;
1042 memcpy(p_t2t->ndef_read_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
1043 } else if (block == p_t2t->ndef_last_block_num) {
1044 /* Last NDEF block is already read */
1045 read_before_write = false;
1046 memcpy(p_t2t->ndef_read_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
1047 } else if (block == p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) {
1048 /* Terminator tlv block is already read */
1049 read_before_write = false;
1050 memcpy(p_t2t->ndef_read_block, p_t2t->terminator_tlv_block, T2T_BLOCK_SIZE);
1051 } else {
1052 count = 0;
1053 while (block < tag_size) {
1054 index = 0;
1055
1056 while (index < T2T_BLOCK_SIZE) {
1057 /* check if it is a reserved or locked byte */
1058 if (rw_t2t_is_lock_res_byte(
1059 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1060 count++;
1061 }
1062 index++;
1063 }
1064 if (count == T2T_BLOCK_SIZE) {
1065 /* All the bytes in the block are free to NDEF write */
1066 read_before_write = false;
1067 break;
1068 } else if (count == 0) {
1069 /* The complete block is not free for NDEF write */
1070 index = 0;
1071 block++;
1072 } else {
1073 /* The block has reseved byte (s) or locked byte (s) or both */
1074 read_before_write = true;
1075 break;
1076 }
1077 }
1078 }
1079 /* Return the block to read next before NDEF write */
1080 *p_block_to_read = block;
1081 return read_before_write;
1082 }
1083
1084 /*******************************************************************************
1085 **
1086 ** Function rw_t2t_write_ndef_first_block
1087 **
1088 ** Description This function will write the first NDEF block with Length
1089 ** field reset to zero.
1090 ** Also after writting NDEF this function may be called to
1091 ** update new NDEF length
1092 **
1093 ** Returns NCI_STATUS_OK, if write was started.
1094 ** Otherwise, error status.
1095 **
1096 *******************************************************************************/
rw_t2t_write_ndef_first_block(uint16_t msg_len,bool b_update_len)1097 tNFC_STATUS rw_t2t_write_ndef_first_block(uint16_t msg_len, bool b_update_len) {
1098 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1099 uint8_t new_lengthfield_len;
1100 uint8_t write_block[4];
1101 uint8_t block;
1102 uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1103 uint16_t total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1104 tNFC_STATUS status;
1105 uint8_t length_field[3];
1106 uint8_t index;
1107
1108 p_t2t->work_offset = 0;
1109 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1110 ? T2T_LONG_NDEF_LEN_FIELD_LEN
1111 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1112 if (new_lengthfield_len == 3) {
1113 /* New NDEF is Long NDEF */
1114 if (msg_len == 0) {
1115 /* Clear NDEF length field */
1116 length_field[0] = 0x00;
1117 length_field[1] = 0x00;
1118 length_field[2] = 0x00;
1119 } else {
1120 /* Update NDEF length field with new NDEF Msg len */
1121 length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
1122 length_field[1] = (uint8_t)(msg_len >> 8);
1123 length_field[2] = (uint8_t)(msg_len);
1124 }
1125 } else {
1126 /* New NDEF is Short NDEF */
1127 length_field[0] = (uint8_t)(msg_len);
1128 }
1129
1130 /* updating ndef_first_block with new ndef message */
1131 memcpy(write_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
1132
1133 index = p_t2t->ndef_header_offset % T2T_BLOCK_SIZE;
1134 block = (uint8_t)(p_t2t->ndef_header_offset / T2T_BLOCK_SIZE);
1135
1136 while (p_t2t->work_offset == 0 && block < total_blocks) {
1137 /* update length field */
1138 while (index < T2T_BLOCK_SIZE &&
1139 p_t2t->work_offset < p_t2t->new_ndef_msg_len) {
1140 if (rw_t2t_is_lock_res_byte(
1141 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1142 write_block[index] = length_field[p_t2t->work_offset];
1143 p_t2t->work_offset++;
1144 }
1145 index++;
1146 if (p_t2t->work_offset == new_lengthfield_len) {
1147 break;
1148 }
1149 }
1150 /* If more space in this block then add ndef message */
1151 while (index < T2T_BLOCK_SIZE &&
1152 p_t2t->work_offset <
1153 (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
1154 if (rw_t2t_is_lock_res_byte(
1155 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1156 write_block[index] =
1157 p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1158 p_t2t->work_offset++;
1159 }
1160 index++;
1161 }
1162 if (p_t2t->work_offset == 0) {
1163 /* If no bytes are written move to next block */
1164 index = 0;
1165 block++;
1166 if (block == p_t2t->ndef_last_block_num) {
1167 memcpy(write_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
1168 }
1169 }
1170 }
1171 if (p_t2t->work_offset == 0) {
1172 status = NFC_STATUS_FAILED;
1173 } else {
1174 rw_t2t_update_cb(block, write_block, b_update_len);
1175 /* Update the identified block with newly prepared data */
1176 status = rw_t2t_write(block, write_block);
1177 if (status == NFC_STATUS_OK) {
1178 p_t2t->b_read_data = false;
1179 }
1180 }
1181 return status;
1182 }
1183
1184 /*******************************************************************************
1185 **
1186 ** Function rw_t2t_write_ndef_next_block
1187 **
1188 ** Description This function can be called to write an NDEF message block
1189 **
1190 ** Returns NCI_STATUS_OK, if write was started.
1191 ** Otherwise, error status.
1192 **
1193 *******************************************************************************/
rw_t2t_write_ndef_next_block(uint16_t block,uint16_t msg_len,bool b_update_len)1194 tNFC_STATUS rw_t2t_write_ndef_next_block(uint16_t block, uint16_t msg_len,
1195 bool b_update_len) {
1196 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1197 uint8_t new_lengthfield_len;
1198 uint8_t write_block[4];
1199 uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1200 uint16_t total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1201 uint16_t initial_offset;
1202 uint8_t length_field[3];
1203 uint8_t index;
1204 tNFC_STATUS status;
1205
1206 /* Write NDEF Message */
1207 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1208 ? T2T_LONG_NDEF_LEN_FIELD_LEN
1209 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1210
1211 index = 0;
1212
1213 memcpy(write_block, p_t2t->ndef_read_block, T2T_BLOCK_SIZE);
1214
1215 if (p_t2t->work_offset >= new_lengthfield_len) {
1216 /* Length field is updated, write ndef message field */
1217 initial_offset = p_t2t->work_offset;
1218 while (p_t2t->work_offset == initial_offset && block < total_blocks) {
1219 while (index < T2T_BLOCK_SIZE &&
1220 p_t2t->work_offset <
1221 (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
1222 if (rw_t2t_is_lock_res_byte(
1223 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1224 write_block[index] =
1225 p_t2t
1226 ->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1227 p_t2t->work_offset++;
1228 }
1229 index++;
1230 }
1231 if (p_t2t->work_offset == initial_offset) {
1232 index = 0;
1233 block++;
1234 }
1235 }
1236 } else {
1237 /* Complete writting Length field and then write ndef message */
1238 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1239 ? T2T_LONG_NDEF_LEN_FIELD_LEN
1240 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1241 if (new_lengthfield_len == 3) {
1242 /* New NDEF is Long NDEF */
1243 if (msg_len == 0) {
1244 length_field[0] = 0x00;
1245 length_field[1] = 0x00;
1246 length_field[2] = 0x00;
1247 } else {
1248 length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
1249 length_field[1] = (uint8_t)(msg_len >> 8);
1250 length_field[2] = (uint8_t)(msg_len);
1251 }
1252 } else {
1253 /* New NDEF is short NDEF */
1254 length_field[0] = (uint8_t)(msg_len);
1255 }
1256 initial_offset = p_t2t->work_offset;
1257 while (p_t2t->work_offset == initial_offset && block < total_blocks) {
1258 /* Update length field */
1259 while (index < T2T_BLOCK_SIZE &&
1260 p_t2t->work_offset < p_t2t->new_ndef_msg_len) {
1261 if (rw_t2t_is_lock_res_byte(
1262 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1263 write_block[index] = length_field[p_t2t->work_offset];
1264 p_t2t->work_offset++;
1265 }
1266 index++;
1267 if (p_t2t->work_offset == new_lengthfield_len) {
1268 break;
1269 }
1270 }
1271 /* Update ndef message field */
1272 while (index < T2T_BLOCK_SIZE &&
1273 p_t2t->work_offset <
1274 (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
1275 if (rw_t2t_is_lock_res_byte(
1276 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1277 write_block[index] =
1278 p_t2t
1279 ->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1280 p_t2t->work_offset++;
1281 }
1282 index++;
1283 }
1284 if (p_t2t->work_offset == initial_offset) {
1285 index = 0;
1286 block++;
1287 }
1288 }
1289 }
1290 if (p_t2t->work_offset == initial_offset) {
1291 status = NFC_STATUS_FAILED;
1292 } else {
1293 rw_t2t_update_cb(block, write_block, b_update_len);
1294 /* Write the NDEF Block */
1295 status = rw_t2t_write(block, write_block);
1296 }
1297
1298 return status;
1299 }
1300
1301 /*******************************************************************************
1302 **
1303 ** Function rw_t2t_update_cb
1304 **
1305 ** Description This function can be called to write an NDEF message block
1306 **
1307 ** Returns NCI_STATUS_OK, if write was started.
1308 ** Otherwise, error status.
1309 **
1310 *******************************************************************************/
rw_t2t_update_cb(uint16_t block,uint8_t * p_write_block,bool b_update_len)1311 static void rw_t2t_update_cb(uint16_t block, uint8_t* p_write_block,
1312 bool b_update_len) {
1313 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1314 uint8_t new_lengthfield_len;
1315
1316 /* Write NDEF Message */
1317 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1318 ? T2T_LONG_NDEF_LEN_FIELD_LEN
1319 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1320
1321 if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) {
1322 /* Update ndef first block if the 'block' points to ndef first block */
1323 memcpy(p_t2t->ndef_first_block, p_write_block, T2T_BLOCK_SIZE);
1324 }
1325 if (p_t2t->terminator_byte_index / T2T_BLOCK_SIZE == block) {
1326 /* Update terminator block if the 'block' points to terminator tlv block */
1327 memcpy(p_t2t->terminator_tlv_block, p_write_block, T2T_BLOCK_LEN);
1328 }
1329 if (b_update_len == false) {
1330 if (block == p_t2t->ndef_last_block_num) {
1331 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK;
1332 p_t2t->work_offset = 0;
1333 /* Update ndef final block if the 'block' points to ndef final block */
1334 memcpy(p_t2t->ndef_last_block, p_write_block, T2T_BLOCK_SIZE);
1335 } else {
1336 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK;
1337 }
1338 } else {
1339 if (block == p_t2t->ndef_last_block_num) {
1340 /* Update the backup of Ndef final block TLV block */
1341 memcpy(p_t2t->ndef_last_block, p_write_block, T2T_BLOCK_SIZE);
1342 }
1343
1344 if (p_t2t->work_offset >= new_lengthfield_len) {
1345 if (p_t2t->terminator_byte_index != 0) {
1346 /* Add Terminator TLV as part of NDEF Write operation */
1347 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK;
1348 } else {
1349 /* Skip adding Terminator TLV */
1350 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1351 }
1352 } else {
1353 /* Part of NDEF Message Len should be added in the next block */
1354 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK;
1355 }
1356 }
1357 }
1358
1359 /*******************************************************************************
1360 **
1361 ** Function rw_t2t_get_ndef_flags
1362 **
1363 ** Description Prepare NDEF Flags
1364 **
1365 ** Returns NDEF Flag value
1366 **
1367 *******************************************************************************/
rw_t2t_get_ndef_flags(void)1368 static uint8_t rw_t2t_get_ndef_flags(void) {
1369 uint8_t flags = 0;
1370 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1371 const tT2T_INIT_TAG* p_ret;
1372
1373 flags |= RW_NDEF_FL_SUPPORTED;
1374
1375 if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC) ||
1376 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == 0))
1377 flags |= RW_NDEF_FL_FORMATABLE;
1378
1379 if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
1380 flags |= RW_NDEF_FL_READ_ONLY;
1381
1382 if (((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != NULL) &&
1383 (p_ret->b_otp)) {
1384 /* Set otp flag */
1385 flags |= RW_NDEF_FL_OTP;
1386
1387 /* Set Read only flag if otp tag already has NDEF Message */
1388 if (p_t2t->ndef_msg_len) flags |= RW_NDEF_FL_READ_ONLY;
1389 }
1390 return flags;
1391 }
1392
1393 /*******************************************************************************
1394 **
1395 ** Function rw_t2t_get_ndef_max_size
1396 **
1397 ** Description Calculate maximum size of NDEF message that can be written
1398 ** on to the tag
1399 **
1400 ** Returns Maximum size of NDEF Message
1401 **
1402 *******************************************************************************/
rw_t2t_get_ndef_max_size(void)1403 static uint16_t rw_t2t_get_ndef_max_size(void) {
1404 uint16_t offset;
1405 uint8_t xx;
1406 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1407 uint16_t tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
1408 (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN) +
1409 p_t2t->num_lockbytes;
1410
1411 for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
1412 tag_size += p_t2t->mem_tlv[xx].num_bytes;
1413
1414 offset = p_t2t->ndef_msg_offset;
1415 p_t2t->max_ndef_msg_len = 0;
1416
1417 if ((tag_size < T2T_STATIC_SIZE) ||
1418 (tag_size > (T2T_SECTOR_SIZE * T2T_MAX_SECTOR)) ||
1419 ((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN) &&
1420 (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0))) {
1421 /* Tag not formated, assume static tag */
1422 p_t2t->max_ndef_msg_len = T2T_STATIC_SIZE - T2T_HEADER_SIZE -
1423 T2T_TLV_TYPE_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN;
1424 return p_t2t->max_ndef_msg_len;
1425 }
1426
1427 /* Starting from NDEF Message offset find the first locked data byte */
1428 while (offset < tag_size) {
1429 if (rw_t2t_is_lock_res_byte((uint16_t)offset) == false) {
1430 if (rw_t2t_is_read_only_byte((uint16_t)offset) == true) break;
1431 p_t2t->max_ndef_msg_len++;
1432 }
1433 offset++;
1434 }
1435 /* NDEF Length field length changes based on NDEF size */
1436 if ((p_t2t->max_ndef_msg_len >= T2T_LONG_NDEF_LEN_FIELD_BYTE0) &&
1437 ((p_t2t->ndef_msg_offset - p_t2t->ndef_header_offset) ==
1438 T2T_SHORT_NDEF_LEN_FIELD_LEN)) {
1439 p_t2t->max_ndef_msg_len -=
1440 (p_t2t->max_ndef_msg_len == T2T_LONG_NDEF_LEN_FIELD_BYTE0)
1441 ? 1
1442 : (T2T_LONG_NDEF_LEN_FIELD_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN);
1443 }
1444 return p_t2t->max_ndef_msg_len;
1445 }
1446
1447 /*******************************************************************************
1448 **
1449 ** Function rw_t2t_add_terminator_tlv
1450 **
1451 ** Description This function will add terminator TLV after NDEF Message
1452 **
1453 ** Returns NCI_STATUS_OK, if write was started.
1454 ** Otherwise, error status.
1455 **
1456 *******************************************************************************/
rw_t2t_add_terminator_tlv(void)1457 tNFC_STATUS rw_t2t_add_terminator_tlv(void) {
1458 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1459 tNFC_STATUS status;
1460 uint16_t block;
1461
1462 /* Add Terminator TLV after NDEF Message */
1463 p_t2t->terminator_tlv_block[p_t2t->terminator_byte_index % T2T_BLOCK_LEN] =
1464 TAG_TERMINATOR_TLV;
1465 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1466
1467 block = p_t2t->terminator_byte_index / T2T_BLOCK_LEN;
1468 status = rw_t2t_write(block, p_t2t->terminator_tlv_block);
1469
1470 return status;
1471 }
1472
1473 /*******************************************************************************
1474 **
1475 ** Function rw_t2t_handle_ndef_read_rsp
1476 **
1477 ** Description This function handles reading an NDEF message.
1478 **
1479 ** Returns none
1480 **
1481 *******************************************************************************/
rw_t2t_handle_ndef_read_rsp(uint8_t * p_data)1482 static void rw_t2t_handle_ndef_read_rsp(uint8_t* p_data) {
1483 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1484 tRW_READ_DATA evt_data;
1485 uint16_t len;
1486 uint16_t offset;
1487 bool failed = false;
1488 bool done = false;
1489
1490 /* On the first read, adjust for any partial block offset */
1491 offset = 0;
1492 len = T2T_READ_DATA_LEN;
1493
1494 if (p_t2t->work_offset == 0) {
1495 /* The Ndef Message offset may be present in the read 16 bytes */
1496 offset = (p_t2t->ndef_msg_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
1497 }
1498
1499 /* Skip all reserved and lock bytes */
1500 while ((offset < len) && (p_t2t->work_offset < p_t2t->ndef_msg_len))
1501
1502 {
1503 if (rw_t2t_is_lock_res_byte(
1504 (uint16_t)(offset + p_t2t->block_read * T2T_BLOCK_LEN)) == false) {
1505 /* Collect the NDEF Message */
1506 p_t2t->p_ndef_buffer[p_t2t->work_offset] = p_data[offset];
1507 p_t2t->work_offset++;
1508 }
1509 offset++;
1510 }
1511
1512 if (p_t2t->work_offset >= p_t2t->ndef_msg_len) {
1513 done = true;
1514 p_t2t->ndef_status = T2T_NDEF_READ;
1515 } else {
1516 /* Read next 4 blocks */
1517 if (rw_t2t_read((uint16_t)(p_t2t->block_read + T2T_READ_BLOCKS)) !=
1518 NFC_STATUS_OK)
1519 failed = true;
1520 }
1521
1522 if (failed || done) {
1523 evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1524 evt_data.p_data = NULL;
1525 rw_t2t_handle_op_complete();
1526 (*rw_cb.p_cback)(RW_T2T_NDEF_READ_EVT, (tRW_DATA*)&evt_data);
1527 }
1528 }
1529
1530 /*******************************************************************************
1531 **
1532 ** Function rw_t2t_handle_ndef_write_rsp
1533 **
1534 ** Description Handle response received to reading (or part of) NDEF
1535 ** message.
1536 **
1537 ** Returns none
1538 **
1539 *******************************************************************************/
rw_t2t_handle_ndef_write_rsp(uint8_t * p_data)1540 static void rw_t2t_handle_ndef_write_rsp(uint8_t* p_data) {
1541 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1542 tRW_READ_DATA evt_data;
1543 bool failed = false;
1544 bool done = false;
1545 uint16_t block;
1546 uint8_t offset;
1547
1548 switch (p_t2t->substate) {
1549 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
1550
1551 /* Backup the read NDEF first block */
1552 memcpy(p_t2t->ndef_first_block, p_data, T2T_BLOCK_LEN);
1553 /* Read ndef final block */
1554 if (rw_t2t_read_ndef_last_block() != NFC_STATUS_OK) failed = true;
1555 break;
1556
1557 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
1558
1559 offset = (uint8_t)(p_t2t->ndef_last_block_num - p_t2t->block_read) *
1560 T2T_BLOCK_SIZE;
1561 /* Backup the read NDEF final block */
1562 memcpy(p_t2t->ndef_last_block, &p_data[offset], T2T_BLOCK_LEN);
1563 if ((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) ==
1564 p_t2t->ndef_last_block_num) {
1565 /* If Terminator TLV will reside on the NDEF Final block */
1566 memcpy(p_t2t->terminator_tlv_block, p_t2t->ndef_last_block,
1567 T2T_BLOCK_LEN);
1568 if (rw_t2t_write_ndef_first_block(0x0000, false) != NFC_STATUS_OK)
1569 failed = true;
1570 } else if (p_t2t->terminator_byte_index != 0) {
1571 /* If there is space for Terminator TLV and if it will reside outside
1572 * NDEF Final block */
1573 if (rw_t2t_read_terminator_tlv_block() != NFC_STATUS_OK) failed = true;
1574 } else {
1575 if (rw_t2t_write_ndef_first_block(0x0000, false) != NFC_STATUS_OK)
1576 failed = true;
1577 }
1578 break;
1579
1580 case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
1581
1582 offset = (uint8_t)(((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) -
1583 p_t2t->block_read) *
1584 T2T_BLOCK_SIZE);
1585 /* Backup the read Terminator TLV block */
1586 memcpy(p_t2t->terminator_tlv_block, &p_data[offset], T2T_BLOCK_LEN);
1587
1588 /* Write the first block for new NDEF Message */
1589 if (rw_t2t_write_ndef_first_block(0x0000, false) != NFC_STATUS_OK)
1590 failed = true;
1591 break;
1592
1593 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
1594
1595 offset = (uint8_t)(p_t2t->ndef_read_block_num - p_t2t->block_read) *
1596 T2T_BLOCK_SIZE;
1597 /* Backup read block */
1598 memcpy(p_t2t->ndef_read_block, &p_data[offset], T2T_BLOCK_LEN);
1599
1600 /* Update the block with new NDEF Message */
1601 if (rw_t2t_write_ndef_next_block(p_t2t->ndef_read_block_num, 0x0000,
1602 false) != NFC_STATUS_OK)
1603 failed = true;
1604 break;
1605
1606 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
1607 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
1608 if (rw_t2t_is_read_before_write_block(
1609 (uint16_t)(p_t2t->block_written + 1), &block) == true) {
1610 p_t2t->ndef_read_block_num = block;
1611 /* If only part of the block is going to be updated read the block to
1612 retain previous data for
1613 unchanged part of the block */
1614 if (rw_t2t_read_ndef_next_block(block) != NFC_STATUS_OK) failed = true;
1615 } else {
1616 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK) {
1617 /* Directly write the block with new NDEF contents as whole block is
1618 * going to be updated */
1619 if (rw_t2t_write_ndef_next_block(block, p_t2t->new_ndef_msg_len,
1620 true) != NFC_STATUS_OK)
1621 failed = true;
1622 } else {
1623 /* Directly write the block with new NDEF contents as whole block is
1624 * going to be updated */
1625 if (rw_t2t_write_ndef_next_block(block, 0x0000, false) !=
1626 NFC_STATUS_OK)
1627 failed = true;
1628 }
1629 }
1630 break;
1631
1632 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
1633 /* Write the next block for new NDEF Message */
1634 p_t2t->ndef_write_block = p_t2t->ndef_header_offset / T2T_BLOCK_SIZE;
1635 if (rw_t2t_is_read_before_write_block((uint16_t)(p_t2t->ndef_write_block),
1636 &block) == true) {
1637 /* If only part of the block is going to be updated read the block to
1638 retain previous data for
1639 part of the block thats not going to be changed */
1640 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK;
1641 if (rw_t2t_read(block) != NFC_STATUS_OK) failed = true;
1642
1643 } else {
1644 /* Update NDEF Message Length in the Tag */
1645 if (rw_t2t_write_ndef_first_block(p_t2t->new_ndef_msg_len, true) !=
1646 NFC_STATUS_OK)
1647 failed = true;
1648 }
1649 break;
1650
1651 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
1652 /* Backup read block */
1653 memcpy(p_t2t->ndef_read_block, p_data, T2T_BLOCK_LEN);
1654
1655 /* Update the block with new NDEF Message */
1656 if (rw_t2t_write_ndef_next_block(p_t2t->block_read,
1657 p_t2t->new_ndef_msg_len,
1658 true) == NFC_STATUS_OK)
1659 p_t2t->ndef_write_block = p_t2t->block_read + 1;
1660 else
1661 failed = true;
1662
1663 break;
1664
1665 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
1666 if (rw_t2t_add_terminator_tlv() != NFC_STATUS_OK) failed = true;
1667 break;
1668
1669 case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
1670 done = true;
1671 break;
1672
1673 default:
1674 break;
1675 }
1676
1677 if (failed || done) {
1678 evt_data.p_data = NULL;
1679 /* NDEF WRITE Operation is done, inform up the stack */
1680 evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1681 if (done) {
1682 if ((p_t2t->ndef_msg_len >= 0x00FF) &&
1683 (p_t2t->new_ndef_msg_len < 0x00FF)) {
1684 p_t2t->ndef_msg_offset -= 2;
1685 } else if ((p_t2t->new_ndef_msg_len >= 0x00FF) &&
1686 (p_t2t->ndef_msg_len < 0x00FF)) {
1687 p_t2t->ndef_msg_offset += 2;
1688 }
1689 p_t2t->ndef_msg_len = p_t2t->new_ndef_msg_len;
1690 }
1691 rw_t2t_handle_op_complete();
1692 (*rw_cb.p_cback)(RW_T2T_NDEF_WRITE_EVT, (tRW_DATA*)&evt_data);
1693 }
1694 }
1695
1696 /*******************************************************************************
1697 **
1698 ** Function rw_t2t_get_tag_size
1699 **
1700 ** Description This function calculates tag data area size from data read
1701 ** from block with version number
1702 **
1703 ** Returns TMS of the tag
1704 **
1705 *******************************************************************************/
rw_t2t_get_tag_size(uint8_t * p_data)1706 static uint8_t rw_t2t_get_tag_size(uint8_t* p_data) {
1707 uint16_t LchunkSize = 0;
1708 uint16_t Num_LChuncks = 0;
1709 uint16_t tms = 0;
1710
1711 LchunkSize = (uint16_t)p_data[2] << 8 | p_data[3];
1712 Num_LChuncks = (uint16_t)p_data[4] << 8 | p_data[5];
1713
1714 tms = (uint16_t)(LchunkSize * Num_LChuncks);
1715
1716 tms += (T2T_STATIC_SIZE - T2T_HEADER_SIZE);
1717
1718 tms /= 0x08;
1719
1720 return (uint8_t)tms;
1721 }
1722
1723 /*******************************************************************************
1724 **
1725 ** Function rw_t2t_handle_config_tag_readonly
1726 **
1727 ** Description This function handles configure type 2 tag as read only
1728 **
1729 ** Returns none
1730 **
1731 *******************************************************************************/
rw_t2t_handle_config_tag_readonly(uint8_t * p_data)1732 static void rw_t2t_handle_config_tag_readonly(uint8_t* p_data) {
1733 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1734 tNFC_STATUS status = NFC_STATUS_FAILED;
1735 bool b_notify = false;
1736 uint8_t write_block[T2T_BLOCK_SIZE];
1737 tRW_DATA evt;
1738 bool b_pending = false;
1739 uint8_t read_lock = 0;
1740 uint8_t num_locks = 0;
1741 uint16_t offset;
1742
1743 switch (p_t2t->substate) {
1744 case RW_T2T_SUBSTATE_WAIT_READ_CC:
1745
1746 /* First soft lock the tag */
1747 rw_t2t_soft_lock_tag();
1748
1749 break;
1750
1751 case RW_T2T_SUBSTATE_WAIT_SET_CC_RO:
1752
1753 /* Successfully soft locked! Update Tag header for future reference */
1754 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] = T2T_CC3_RWA_RO;
1755 if (!p_t2t->b_hard_lock) {
1756 /* Tag configuration complete */
1757 status = NFC_STATUS_OK;
1758 b_notify = true;
1759 break;
1760 }
1761
1762 /* Coverity: [FALSE-POSITIVE error] intended fall through */
1763 /* Missing break statement between cases in switch statement */
1764 /* fall through */
1765 case RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
1766
1767 num_locks = 0;
1768
1769 while (num_locks < p_t2t->num_lockbytes) {
1770 if (p_t2t->lockbyte[num_locks].lock_status ==
1771 RW_T2T_LOCK_UPDATE_INITIATED) {
1772 /* Update control block as one or more dynamic lock byte (s) are set
1773 */
1774 p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_UPDATED;
1775 }
1776 if (!b_pending &&
1777 p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) {
1778 /* One or more dynamic lock bits are not set */
1779 b_pending = true;
1780 read_lock = num_locks;
1781 }
1782 num_locks++;
1783 }
1784
1785 if (b_pending) {
1786 /* Read the block where dynamic lock bits are present to avoid writing
1787 * to NDEF bytes in the same block */
1788 offset = p_t2t->lock_tlv[p_t2t->lockbyte[read_lock].tlv_index].offset +
1789 p_t2t->lockbyte[read_lock].byte_index;
1790 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK;
1791 status = rw_t2t_read((uint16_t)(offset / T2T_BLOCK_LEN));
1792 } else {
1793 /* Now set Static lock bits as no more dynamic lock bits to set */
1794
1795 /* Copy the internal bytes */
1796 memcpy(write_block,
1797 &p_t2t->tag_hdr[T2T_STATIC_LOCK0 - T2T_INTERNAL_BYTES_LEN],
1798 T2T_INTERNAL_BYTES_LEN);
1799 /* Set all Static lock bits */
1800 write_block[T2T_STATIC_LOCK0 % T2T_BLOCK_SIZE] = 0xFF;
1801 write_block[T2T_STATIC_LOCK1 % T2T_BLOCK_SIZE] = 0xFF;
1802 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
1803 status = rw_t2t_write((T2T_STATIC_LOCK0 / T2T_BLOCK_SIZE), write_block);
1804 }
1805 break;
1806
1807 case RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK:
1808 /* Now set the dynamic lock bits present in the block read now */
1809 status = rw_t2t_set_dynamic_lock_bits(p_data);
1810 break;
1811
1812 case RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
1813 /* Tag configuration complete */
1814 status = NFC_STATUS_OK;
1815 b_notify = true;
1816 break;
1817 }
1818
1819 if (status != NFC_STATUS_OK || b_notify) {
1820 /* Notify upper layer the result of Configuring Tag as Read only */
1821 evt.status = status;
1822 rw_t2t_handle_op_complete();
1823 (*rw_cb.p_cback)(RW_T2T_SET_TAG_RO_EVT, (tRW_DATA*)&evt);
1824 }
1825 }
1826
1827 /*******************************************************************************
1828 **
1829 ** Function rw_t2t_handle_format_tag_rsp
1830 **
1831 ** Description This function handles formating a type 2 tag
1832 **
1833 ** Returns none
1834 **
1835 *******************************************************************************/
rw_t2t_handle_format_tag_rsp(uint8_t * p_data)1836 static void rw_t2t_handle_format_tag_rsp(uint8_t* p_data) {
1837 tRW_DATA evt;
1838 uint8_t* p;
1839 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1840 tNFC_STATUS status = NFC_STATUS_FAILED;
1841 uint16_t version_no;
1842 const tT2T_INIT_TAG* p_ret;
1843 uint8_t tms;
1844 uint8_t next_block = T2T_FIRST_DATA_BLOCK + 1;
1845 uint16_t addr, locked_area;
1846 bool b_notify = false;
1847
1848 p = p_t2t->ndef_final_block;
1849 UINT8_TO_BE_STREAM(p, p_t2t->tlv_value[2]);
1850
1851 switch (p_t2t->substate) {
1852 case RW_T2T_SUBSTATE_WAIT_READ_CC:
1853 /* Start format operation */
1854 status = rw_t2t_format_tag();
1855 break;
1856
1857 case RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO:
1858
1859 memcpy(p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
1860 p_t2t->b_read_data = true;
1861 version_no = (uint16_t)p_data[0] << 8 | p_data[1];
1862 p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], true, version_no);
1863 if (p_ret != NULL) {
1864 /* Valid Version Number */
1865 if (p_ret->b_calc_cc) /* Calculate tag size from Version Information */
1866 tms = rw_t2t_get_tag_size(p_data);
1867
1868 else
1869 /* Tag size from Look up table */
1870 tms = p_ret->tms;
1871
1872 /* Set CC with the Tag size from look up table or from calculated value
1873 */
1874 status = rw_t2t_set_cc(tms);
1875 }
1876 break;
1877
1878 case RW_T2T_SUBSTATE_WAIT_SET_CC:
1879
1880 version_no = (uint16_t)p_t2t->tag_data[0] << 8 | p_t2t->tag_data[1];
1881 if ((version_no == 0) ||
1882 ((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], true, version_no)) ==
1883 NULL) ||
1884 (!p_ret->b_multi_version) || (!p_ret->b_calc_cc)) {
1885 /* Currently Formating a non blank tag or a blank tag with manufacturer
1886 * has only one variant of tag. Set Null NDEF TLV and complete Format
1887 * Operation */
1888 next_block = T2T_FIRST_DATA_BLOCK;
1889 p = p_t2t->ndef_final_block;
1890 } else {
1891 addr = (uint16_t)(
1892 ((uint16_t)p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) *
1893 ((uint16_t)p_t2t->tag_data[4] << 8 | p_t2t->tag_data[5]) +
1894 T2T_STATIC_SIZE);
1895 locked_area = ((uint16_t)p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) *
1896 ((uint16_t)p_t2t->tag_data[6]);
1897
1898 status = rw_t2t_set_lock_tlv(addr, p_t2t->tag_data[7], locked_area);
1899 if (status == NFC_STATUS_REJECTED) {
1900 /* Cannot calculate Lock TLV. Set Null NDEF TLV and complete Format
1901 * Operation */
1902 next_block = T2T_FIRST_DATA_BLOCK;
1903 p = p_t2t->ndef_final_block;
1904 } else
1905 break;
1906 }
1907
1908 /* falls through */
1909 case RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV:
1910
1911 /* Prepare NULL NDEF TLV, TERMINATOR_TLV */
1912 UINT8_TO_BE_STREAM(p, TAG_NDEF_TLV);
1913 UINT8_TO_BE_STREAM(p, 0);
1914
1915 if (((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != NULL) &&
1916 (!p_ret->b_otp)) {
1917 UINT8_TO_BE_STREAM(p, TAG_TERMINATOR_TLV);
1918 } else
1919 UINT8_TO_BE_STREAM(p, 0);
1920
1921 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF;
1922 /* send WRITE-E8 command */
1923 status = rw_t2t_write(next_block, p_t2t->ndef_final_block);
1924 if (status == NFC_STATUS_OK) p_t2t->b_read_data = false;
1925 break;
1926
1927 case RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF:
1928 /* Tag Formated successfully */
1929 status = NFC_STATUS_OK;
1930 b_notify = true;
1931 break;
1932
1933 default:
1934 break;
1935 }
1936
1937 if (status != NFC_STATUS_OK || b_notify) {
1938 /* Notify upper layer the result of Format op */
1939 evt.status = status;
1940 rw_t2t_handle_op_complete();
1941 (*rw_cb.p_cback)(RW_T2T_FORMAT_CPLT_EVT, (tRW_DATA*)&evt);
1942 }
1943 }
1944
1945 /*******************************************************************************
1946 **
1947 ** Function rw_t2t_update_attributes
1948 **
1949 ** Description This function will update attribute for the current segment
1950 ** based on lock and reserved bytes
1951 **
1952 ** Returns None
1953 **
1954 *******************************************************************************/
rw_t2t_update_attributes(void)1955 static void rw_t2t_update_attributes(void) {
1956 uint8_t count = 0;
1957 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1958 uint16_t lower_offset;
1959 uint16_t upper_offset;
1960 uint16_t offset;
1961 uint8_t num_bytes;
1962
1963 /* Prepare attr for the current segment */
1964 memset(p_t2t->attr, 0, RW_T2T_SEGMENT_SIZE * sizeof(uint8_t));
1965
1966 /* calculate offset where the current segment starts in the tag */
1967 lower_offset = p_t2t->segment * RW_T2T_SEGMENT_BYTES;
1968 /* calculate offset where the current segment ends in the tag */
1969 upper_offset = (p_t2t->segment + 1) * RW_T2T_SEGMENT_BYTES;
1970
1971 /* check offset of lock bytes in the tag and update p_t2t->attr
1972 * for every lock byte that is present in the current segment */
1973 count = 0;
1974 while (count < p_t2t->num_lockbytes) {
1975 offset = p_t2t->lock_tlv[p_t2t->lockbyte[count].tlv_index].offset +
1976 p_t2t->lockbyte[count].byte_index;
1977 if (offset >= lower_offset && offset < upper_offset) {
1978 /* Calculate offset in the current segment as p_t2t->attr is prepared for
1979 * one segment only */
1980 offset %= RW_T2T_SEGMENT_BYTES;
1981 /* Every bit in p_t2t->attr indicates one byte of the tag is either a
1982 * lock/reserved byte or not
1983 * So, each array element in p_t2t->attr covers two blocks in the tag as
1984 * T2 block size is 4 and array element size is 8
1985 * Set the corresponding bit in attr to indicate - reserved byte */
1986 p_t2t->attr[offset / TAG_BITS_PER_BYTE] |=
1987 rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
1988 }
1989 count++;
1990 }
1991
1992 /* Search reserved bytes identified by all memory tlvs present in the tag */
1993 count = 0;
1994 while (count < p_t2t->num_mem_tlvs) {
1995 /* check the offset of reserved bytes in the tag and update p_t2t->attr
1996 * for every reserved byte that is present in the current segment */
1997 num_bytes = 0;
1998 while (num_bytes < p_t2t->mem_tlv[count].num_bytes) {
1999 offset = p_t2t->mem_tlv[count].offset + num_bytes;
2000 if (offset >= lower_offset && offset < upper_offset) {
2001 /* Let offset represents offset in the current segment as p_t2t->attr is
2002 * prepared for one segment only */
2003 offset %= RW_T2T_SEGMENT_BYTES;
2004 /* Every bit in p_t2t->attr indicates one byte of the tag is either a
2005 * lock/reserved byte or not
2006 * So, each array element in p_t2t->attr covers two blocks in the tag as
2007 * T2 block size is 4 and array element size is 8
2008 * Set the corresponding bit in attr to indicate - reserved byte */
2009 p_t2t->attr[offset / TAG_BITS_PER_BYTE] |=
2010 rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
2011 }
2012 num_bytes++;
2013 }
2014 count++;
2015 }
2016 }
2017
2018 /*******************************************************************************
2019 **
2020 ** Function rw_t2t_get_lock_bits_for_segment
2021 **
2022 ** Description This function returns the offset of lock bits associated for
2023 ** the specified segment
2024 **
2025 ** Parameters: segment: The segment number to which lock bits are
2026 ** associated
2027 ** p_start_byte: The offset of lock byte that contains the
2028 ** first lock bit for the segment
2029 ** p_start_bit: The offset of the lock bit in the lock byte
2030 **
2031 ** p_end_byte: The offset of the last bit associcated to the
2032 ** segment
2033 **
2034 ** Returns Total number of lock bits assigned to the specified segment
2035 **
2036 *******************************************************************************/
rw_t2t_get_lock_bits_for_segment(uint8_t segment,uint8_t * p_start_byte,uint8_t * p_start_bit,uint8_t * p_end_byte)2037 static uint8_t rw_t2t_get_lock_bits_for_segment(uint8_t segment,
2038 uint8_t* p_start_byte,
2039 uint8_t* p_start_bit,
2040 uint8_t* p_end_byte) {
2041 uint8_t total_bits = 0;
2042 uint16_t byte_count = 0;
2043 uint16_t lower_offset, upper_offset;
2044 uint8_t num_dynamic_locks = 0;
2045 uint8_t bit_count = 0;
2046 uint8_t bytes_locked_per_bit;
2047 uint8_t num_bits;
2048 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2049 bool b_all_bits_are_locks = true;
2050 uint16_t tag_size;
2051 uint8_t xx;
2052
2053 tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
2054 (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_SIZE) + p_t2t->num_lockbytes;
2055
2056 for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
2057 tag_size += p_t2t->mem_tlv[xx].num_bytes;
2058
2059 lower_offset = segment * RW_T2T_SEGMENT_BYTES;
2060 if (segment == 0) {
2061 lower_offset += T2T_STATIC_SIZE;
2062 }
2063 upper_offset = (segment + 1) * RW_T2T_SEGMENT_BYTES;
2064
2065 byte_count = T2T_STATIC_SIZE;
2066 if (tag_size < upper_offset) {
2067 upper_offset = tag_size;
2068 }
2069
2070 *p_start_byte = num_dynamic_locks;
2071 *p_start_bit = 0;
2072
2073 while ((byte_count <= lower_offset) &&
2074 (num_dynamic_locks < p_t2t->num_lockbytes)) {
2075 bytes_locked_per_bit =
2076 p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2077 .bytes_locked_per_bit;
2078 /* Number of bits in the current lock byte */
2079 b_all_bits_are_locks =
2080 ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) *
2081 TAG_BITS_PER_BYTE <=
2082 p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2083 .num_bits);
2084 num_bits =
2085 b_all_bits_are_locks
2086 ? TAG_BITS_PER_BYTE
2087 : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2088 .num_bits %
2089 TAG_BITS_PER_BYTE;
2090
2091 if (((bytes_locked_per_bit * num_bits) + byte_count) <= lower_offset) {
2092 /* Skip this lock byte as it covers different segment */
2093 byte_count += bytes_locked_per_bit * num_bits;
2094 num_dynamic_locks++;
2095 } else {
2096 bit_count = 0;
2097 while (bit_count < num_bits) {
2098 byte_count += bytes_locked_per_bit;
2099 if (byte_count > lower_offset) {
2100 /* First lock bit that is used to lock this segment */
2101 *p_start_byte = num_dynamic_locks;
2102 *p_end_byte = num_dynamic_locks;
2103 *p_start_bit = bit_count;
2104 bit_count++;
2105 total_bits = 1;
2106 break;
2107 }
2108 bit_count++;
2109 }
2110 }
2111 }
2112 if (num_dynamic_locks == p_t2t->num_lockbytes) {
2113 return 0;
2114 }
2115 while ((byte_count < upper_offset) &&
2116 (num_dynamic_locks < p_t2t->num_lockbytes)) {
2117 bytes_locked_per_bit =
2118 p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2119 .bytes_locked_per_bit;
2120 /* Number of bits in the current lock byte */
2121 b_all_bits_are_locks =
2122 ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) *
2123 TAG_BITS_PER_BYTE <=
2124 p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2125 .num_bits);
2126 num_bits =
2127 b_all_bits_are_locks
2128 ? TAG_BITS_PER_BYTE
2129 : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2130 .num_bits %
2131 TAG_BITS_PER_BYTE;
2132
2133 if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count <
2134 upper_offset) {
2135 /* Collect all lock bits that covers the current segment */
2136 byte_count += bytes_locked_per_bit * (num_bits - bit_count);
2137 total_bits += num_bits - bit_count;
2138 bit_count = 0;
2139 *p_end_byte = num_dynamic_locks;
2140 num_dynamic_locks++;
2141 } else {
2142 /* The last lock byte that covers the current segment */
2143 bit_count = 0;
2144 while (bit_count < num_bits) {
2145 /* The last lock bit that is used to lock this segment */
2146 byte_count += bytes_locked_per_bit;
2147 if (byte_count >= upper_offset) {
2148 *p_end_byte = num_dynamic_locks;
2149 total_bits += (bit_count + 1);
2150 break;
2151 }
2152 bit_count++;
2153 }
2154 }
2155 }
2156 return total_bits;
2157 }
2158
2159 /*******************************************************************************
2160 **
2161 ** Function rw_t2t_update_lock_attributes
2162 **
2163 ** Description This function will check if the tag index passed as
2164 ** argument is a locked byte and return TRUE or FALSE
2165 **
2166 ** Parameters: index, the index of the byte in the tag
2167 **
2168 **
2169 ** Returns TRUE, if the specified index in the tag is a locked or
2170 ** reserved or otp byte
2171 ** FALSE, otherwise
2172 **
2173 *******************************************************************************/
rw_t2t_update_lock_attributes(void)2174 static void rw_t2t_update_lock_attributes(void) {
2175 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2176 uint8_t xx = 0;
2177 uint8_t num_static_lock_bytes = 0;
2178 uint8_t num_dyn_lock_bytes = 0;
2179 uint8_t bits_covered = 0;
2180 uint8_t bytes_covered = 0;
2181 uint8_t block_count = 0;
2182 bool b_all_bits_are_locks = true;
2183 uint8_t bytes_locked_per_lock_bit;
2184 uint8_t start_lock_byte;
2185 uint8_t start_lock_bit;
2186 uint8_t end_lock_byte;
2187 uint8_t num_lock_bits;
2188 uint8_t total_bits;
2189
2190 /* Prepare lock_attr for the current segment */
2191 memset(p_t2t->lock_attr, 0, RW_T2T_SEGMENT_SIZE * sizeof(uint8_t));
2192
2193 block_count = 0;
2194 if (p_t2t->segment == 0) {
2195 /* Update lock_attributes based on static lock bytes */
2196 xx = 0;
2197 num_static_lock_bytes = 0;
2198 block_count = 0;
2199 num_lock_bits =
2200 TAG_BITS_PER_BYTE - 1; /* the inner while loop increases xx by 2. need
2201 (-1) to avoid coverity overrun error */
2202
2203 while (num_static_lock_bytes < T2T_NUM_STATIC_LOCK_BYTES) {
2204 /* Update lock attribute based on 2 static locks */
2205 while (xx < num_lock_bits) {
2206 p_t2t->lock_attr[block_count] = 0x00;
2207
2208 if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] &
2209 rw_t2t_mask_bits[xx++]) {
2210 /* If the bit is set then 1 block is locked */
2211 p_t2t->lock_attr[block_count] = 0x0F;
2212 }
2213
2214 if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] &
2215 rw_t2t_mask_bits[xx++]) {
2216 /* If the bit is set then 1 block is locked */
2217 p_t2t->lock_attr[block_count] |= 0xF0;
2218 }
2219 block_count++;
2220 }
2221 num_static_lock_bytes++;
2222 xx = 0;
2223 }
2224 /* UID is always locked, irrespective of the lock value */
2225 p_t2t->lock_attr[0x00] = 0xFF;
2226 }
2227
2228 /* Get lock bits applicable for the current segment */
2229 total_bits = rw_t2t_get_lock_bits_for_segment(
2230 p_t2t->segment, &start_lock_byte, &start_lock_bit, &end_lock_byte);
2231 if (total_bits != 0) {
2232 /* update lock_attributes based on current segment using dynamic lock bytes
2233 */
2234 xx = start_lock_bit;
2235 num_dyn_lock_bytes = start_lock_byte;
2236 bits_covered = 0;
2237 bytes_covered = 0;
2238 num_lock_bits = TAG_BITS_PER_BYTE;
2239 p_t2t->lock_attr[block_count] = 0;
2240
2241 while (num_dyn_lock_bytes <= end_lock_byte) {
2242 bytes_locked_per_lock_bit =
2243 p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
2244 .bytes_locked_per_bit;
2245 /* Find number of bits in the byte are lock bits */
2246 b_all_bits_are_locks =
2247 ((p_t2t->lockbyte[num_dyn_lock_bytes].byte_index + 1) *
2248 TAG_BITS_PER_BYTE <=
2249 p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
2250 .num_bits);
2251 num_lock_bits =
2252 b_all_bits_are_locks
2253 ? TAG_BITS_PER_BYTE
2254 : p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
2255 .num_bits %
2256 TAG_BITS_PER_BYTE;
2257
2258 while (xx < num_lock_bits) {
2259 bytes_covered = 0;
2260 while (bytes_covered < bytes_locked_per_lock_bit) {
2261 if (p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte &
2262 rw_t2t_mask_bits[xx]) {
2263 /* If the bit is set then it is locked */
2264 if (block_count < RW_T2T_SEGMENT_SIZE)
2265 p_t2t->lock_attr[block_count] |= 0x01 << bits_covered;
2266 }
2267 bytes_covered++;
2268 bits_covered++;
2269 if (bits_covered == TAG_BITS_PER_BYTE) {
2270 /* Move to next 8 bytes */
2271 bits_covered = 0;
2272 block_count++;
2273 /* Assume unlocked before updating using locks */
2274 if (block_count < RW_T2T_SEGMENT_SIZE)
2275 p_t2t->lock_attr[block_count] = 0;
2276 }
2277 }
2278 xx++;
2279 }
2280 num_dyn_lock_bytes++;
2281 xx = 0;
2282 }
2283 }
2284 }
2285
2286 /*******************************************************************************
2287 **
2288 ** Function rw_t2t_is_lock_res_byte
2289 **
2290 ** Description This function will check if the tag index passed as
2291 ** argument is a lock or reserved or otp byte and return
2292 ** TRUE or FALSE
2293 **
2294 ** Parameters: index, the index of the byte in the tag
2295 **
2296 **
2297 ** Returns TRUE, if the specified index in the tag is a locked or
2298 ** reserved or otp byte
2299 ** FALSE, otherwise
2300 **
2301 *******************************************************************************/
rw_t2t_is_lock_res_byte(uint16_t index)2302 static bool rw_t2t_is_lock_res_byte(uint16_t index) {
2303 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2304
2305 p_t2t->segment = (uint8_t)(index / RW_T2T_SEGMENT_BYTES);
2306
2307 if (p_t2t->attr_seg != p_t2t->segment) {
2308 /* Update attributes for the current segment */
2309 rw_t2t_update_attributes();
2310 p_t2t->attr_seg = p_t2t->segment;
2311 }
2312
2313 index = index % RW_T2T_SEGMENT_BYTES;
2314 /* Every bit in p_t2t->attr indicates one specific byte of the tag is either a
2315 * lock/reserved byte or not
2316 * So, each array element in p_t2t->attr covers two blocks in the tag as T2
2317 * block size is 4 and array element size is 8
2318 * Find the block and offset for the index (passed as argument) and Check if
2319 * the offset bit in the
2320 * p_t2t->attr[block/2] is set or not. If the bit is set then it is a
2321 * lock/reserved byte, otherwise not */
2322
2323 return ((p_t2t->attr[index / 8] & rw_t2t_mask_bits[index % 8]) == 0) ? false
2324 : true;
2325 }
2326
2327 /*******************************************************************************
2328 **
2329 ** Function rw_t2t_is_read_only_byte
2330 **
2331 ** Description This function will check if the tag index passed as
2332 ** argument is a locked and return
2333 ** TRUE or FALSE
2334 **
2335 ** Parameters: index, the index of the byte in the tag
2336 **
2337 **
2338 ** Returns TRUE, if the specified index in the tag is a locked or
2339 ** reserved or otp byte
2340 ** FALSE, otherwise
2341 **
2342 *******************************************************************************/
rw_t2t_is_read_only_byte(uint16_t index)2343 static bool rw_t2t_is_read_only_byte(uint16_t index) {
2344 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2345
2346 p_t2t->segment = (uint8_t)(index / RW_T2T_SEGMENT_BYTES);
2347
2348 if (p_t2t->lock_attr_seg != p_t2t->segment) {
2349 /* Update lock attributes for the current segment */
2350 rw_t2t_update_lock_attributes();
2351 p_t2t->lock_attr_seg = p_t2t->segment;
2352 }
2353
2354 index = index % RW_T2T_SEGMENT_BYTES;
2355 /* Every bit in p_t2t->lock_attr indicates one specific byte of the tag is a
2356 * read only byte or read write byte
2357 * So, each array element in p_t2t->lock_attr covers two blocks of the tag as
2358 * T2 block size is 4 and array element size is 8
2359 * Find the block and offset for the index (passed as argument) and Check if
2360 * the offset bit in
2361 * p_t2t->lock_attr[block/2] is set or not. If the bit is set then it is a
2362 * read only byte, otherwise read write byte */
2363
2364 return ((p_t2t->lock_attr[index / 8] & rw_t2t_mask_bits[index % 8]) == 0)
2365 ? false
2366 : true;
2367 }
2368
2369 /*******************************************************************************
2370 **
2371 ** Function rw_t2t_set_dynamic_lock_bits
2372 **
2373 ** Description This function will set dynamic lock bits as part of
2374 ** configuring tag as read only
2375 **
2376 ** Returns
2377 ** NFC_STATUS_OK, Command sent to set dynamic lock bits
2378 ** NFC_STATUS_FAILED: otherwise
2379 **
2380 *******************************************************************************/
rw_t2t_set_dynamic_lock_bits(uint8_t * p_data)2381 tNFC_STATUS rw_t2t_set_dynamic_lock_bits(uint8_t* p_data) {
2382 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2383 uint8_t write_block[T2T_BLOCK_SIZE];
2384 uint16_t offset;
2385 uint16_t next_offset;
2386 uint8_t num_bits;
2387 uint8_t next_num_bits;
2388 tNFC_STATUS status = NFC_STATUS_FAILED;
2389 uint8_t num_locks;
2390 uint8_t lock_count;
2391 bool b_all_bits_are_locks = true;
2392
2393 num_locks = 0;
2394
2395 memcpy(write_block, p_data, T2T_BLOCK_SIZE);
2396 while (num_locks < p_t2t->num_lockbytes) {
2397 if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) {
2398 offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
2399 p_t2t->lockbyte[num_locks].byte_index;
2400
2401 /* Check if all bits are lock bits in the byte */
2402 b_all_bits_are_locks =
2403 ((p_t2t->lockbyte[num_locks].byte_index + 1) * TAG_BITS_PER_BYTE <=
2404 p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits);
2405 num_bits =
2406 b_all_bits_are_locks
2407 ? TAG_BITS_PER_BYTE
2408 : p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits %
2409 TAG_BITS_PER_BYTE;
2410
2411 write_block[(uint8_t)(offset % T2T_BLOCK_SIZE)] |=
2412 tags_pow(2, num_bits) - 1;
2413 lock_count = num_locks + 1;
2414
2415 /* Set all the lock bits in the block using a sing block write command */
2416 while (lock_count < p_t2t->num_lockbytes) {
2417 next_offset =
2418 p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].offset +
2419 p_t2t->lockbyte[lock_count].byte_index;
2420
2421 /* Check if all bits are lock bits in the byte */
2422 b_all_bits_are_locks =
2423 ((p_t2t->lockbyte[lock_count].byte_index + 1) * TAG_BITS_PER_BYTE <=
2424 p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits);
2425 next_num_bits =
2426 b_all_bits_are_locks
2427 ? TAG_BITS_PER_BYTE
2428 : p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index]
2429 .num_bits %
2430 TAG_BITS_PER_BYTE;
2431
2432 if (next_offset / T2T_BLOCK_SIZE == offset / T2T_BLOCK_SIZE) {
2433 write_block[(uint8_t)(next_offset % T2T_BLOCK_SIZE)] |=
2434 tags_pow(2, next_num_bits) - 1;
2435 } else
2436 break;
2437 lock_count++;
2438 }
2439
2440 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
2441 /* send WRITE command to set dynamic lock bits */
2442 status = rw_t2t_write((uint16_t)(offset / T2T_BLOCK_SIZE), write_block);
2443 if (status == NFC_STATUS_OK) {
2444 while (lock_count > num_locks) {
2445 /* Set update initiated flag to indicate a write command is sent to
2446 * set dynamic lock bits of the block */
2447 p_t2t->lockbyte[lock_count - 1].lock_status =
2448 RW_T2T_LOCK_UPDATE_INITIATED;
2449 lock_count--;
2450 }
2451 } else
2452 status = NFC_STATUS_FAILED;
2453
2454 break;
2455 }
2456 num_locks++;
2457 }
2458
2459 return status;
2460 }
2461
2462 /*******************************************************************************
2463 **
2464 ** Function rw_t2t_set_lock_tlv
2465 **
2466 ** Description This function will set lock control tlv on the blank
2467 ** activated type 2 tag based on values read from version block
2468 **
2469 ** Parameters: TAG data memory size
2470 **
2471 ** Returns
2472 ** NFC_STATUS_OK, Command sent to set Lock TLV
2473 ** NFC_STATUS_FAILED: otherwise
2474 **
2475 *******************************************************************************/
rw_t2t_set_lock_tlv(uint16_t addr,uint8_t num_dyn_lock_bits,uint16_t locked_area_size)2476 tNFC_STATUS rw_t2t_set_lock_tlv(uint16_t addr, uint8_t num_dyn_lock_bits,
2477 uint16_t locked_area_size) {
2478 tNFC_STATUS status = NFC_STATUS_FAILED;
2479 int8_t PageAddr = 0;
2480 int8_t BytePerPage = 0;
2481 int8_t ByteOffset = 0;
2482 uint8_t a;
2483 uint8_t data_block[T2T_BLOCK_SIZE];
2484 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2485 uint8_t* p;
2486 uint8_t xx;
2487
2488 for (xx = 15; xx > 0; xx--) {
2489 a = (uint8_t)(addr / xx);
2490 a += (addr % xx) ? 1 : 0;
2491
2492 BytePerPage = (int8_t)tags_log2(a);
2493 ByteOffset = (int8_t)(addr - xx * tags_pow(2, BytePerPage));
2494
2495 if (ByteOffset < 16) {
2496 PageAddr = xx;
2497 break;
2498 }
2499 }
2500
2501 if ((ByteOffset < 16) && (BytePerPage < 16) && (PageAddr < 16)) {
2502 memset(data_block, 0, T2T_BLOCK_SIZE);
2503 p = data_block;
2504 UINT8_TO_BE_STREAM(p, T2T_TLV_TYPE_LOCK_CTRL);
2505 UINT8_TO_BE_STREAM(p, T2T_TLEN_LOCK_CTRL_TLV);
2506 UINT8_TO_BE_STREAM(p, (PageAddr << 4 | ByteOffset));
2507 UINT8_TO_BE_STREAM(p, num_dyn_lock_bits);
2508
2509 p_t2t->tlv_value[0] = PageAddr << 4 | ByteOffset;
2510 p_t2t->tlv_value[1] = num_dyn_lock_bits;
2511 p_t2t->tlv_value[2] =
2512 (uint8_t)(BytePerPage << 4 | tags_log2(locked_area_size));
2513
2514 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV;
2515
2516 /* send WRITE-E8 command */
2517 status = rw_t2t_write(T2T_FIRST_DATA_BLOCK, data_block);
2518 if (status == NFC_STATUS_OK) {
2519 p_t2t->b_read_data = false;
2520 } else
2521 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2522 } else
2523 status = NFC_STATUS_REJECTED;
2524
2525 return status;
2526 }
2527
2528 /*******************************************************************************
2529 **
2530 ** Function rw_t2t_set_cc
2531 **
2532 ** Description This function will set Capability Container on the activated
2533 ** type 2 tag with default values of CC0, CC1, CC4 and
2534 ** specified CC3 value
2535 **
2536 ** Parameters: CC3 value of the tag
2537 **
2538 ** Returns
2539 ** NFC_STATUS_OK, Command sent to set CC
2540 ** NFC_STATUS_FAILED: otherwise
2541 **
2542 *******************************************************************************/
rw_t2t_set_cc(uint8_t tms)2543 tNFC_STATUS rw_t2t_set_cc(uint8_t tms) {
2544 uint8_t cc_block[T2T_BLOCK_SIZE];
2545 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2546 tNFC_STATUS status = NFC_STATUS_FAILED;
2547 uint8_t* p;
2548
2549 memset(cc_block, 0, T2T_BLOCK_SIZE);
2550 memset(p_t2t->ndef_final_block, 0, T2T_BLOCK_SIZE);
2551 p = cc_block;
2552
2553 /* Prepare Capability Container */
2554 UINT8_TO_BE_STREAM(p, T2T_CC0_NMN);
2555 UINT8_TO_BE_STREAM(p, T2T_CC1_VNO);
2556 UINT8_TO_BE_STREAM(p, tms);
2557 UINT8_TO_BE_STREAM(p, T2T_CC3_RWA_RW);
2558
2559 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC;
2560
2561 /* send WRITE-E8 command */
2562 status = rw_t2t_write(T2T_CC_BLOCK, cc_block);
2563 if (status == NFC_STATUS_OK) {
2564 p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2565 p_t2t->b_read_hdr = false;
2566 } else
2567 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2568
2569 return status;
2570 }
2571
2572 /*******************************************************************************
2573 **
2574 ** Function rw_t2t_format_tag
2575 **
2576 ** Description This function will format tag based on Manufacturer ID
2577 **
2578 ** Returns
2579 ** NFC_STATUS_OK, Command sent to format Tag
2580 ** NFC_STATUS_FAILED: otherwise
2581 **
2582 *******************************************************************************/
rw_t2t_format_tag(void)2583 tNFC_STATUS rw_t2t_format_tag(void) {
2584 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2585 const tT2T_INIT_TAG* p_ret;
2586 uint8_t tms;
2587 tNFC_STATUS status = NFC_STATUS_FAILED;
2588 bool b_blank_tag = true;
2589
2590 p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0);
2591 if (p_ret == NULL) {
2592 RW_TRACE_WARNING1(
2593 "rw_t2t_format_tag - Unknown Manufacturer ID: %u, Cannot Format the "
2594 "tag!",
2595 p_t2t->tag_hdr[0]);
2596 return (NFC_STATUS_FAILED);
2597 }
2598
2599 if (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != 0) {
2600 /* If OTP tag has valid NDEF Message, cannot format the tag */
2601 if ((p_t2t->ndef_msg_len > 0) && (p_ret->b_otp)) {
2602 RW_TRACE_WARNING0(
2603 "rw_t2t_format_tag - Cannot Format a OTP tag with NDEF Message!");
2604 return (NFC_STATUS_FAILED);
2605 }
2606
2607 if (((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0) &&
2608 (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)) ||
2609 ((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != 0) &&
2610 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) &&
2611 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) &&
2612 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO))) {
2613 RW_TRACE_WARNING0("rw_t2t_format_tag - Tag not blank to Format!");
2614 return (NFC_STATUS_FAILED);
2615 } else {
2616 tms = p_t2t->tag_hdr[T2T_CC2_TMS_BYTE];
2617 b_blank_tag = false;
2618 }
2619 } else
2620 tms = p_ret->tms;
2621
2622 memset(p_t2t->tag_data, 0, T2T_READ_DATA_LEN);
2623
2624 if (!b_blank_tag || !p_ret->b_multi_version) {
2625 status = rw_t2t_set_cc(tms);
2626 } else if (p_ret->version_block != 0) {
2627 /* If Version number is not read, READ it now */
2628 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
2629
2630 status = rw_t2t_read(p_ret->version_block);
2631 if (status == NFC_STATUS_OK)
2632 p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2633 else
2634 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2635 } else {
2636 /* UID block is the version block */
2637 p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2638 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
2639 rw_t2t_handle_format_tag_rsp(p_t2t->tag_hdr);
2640 }
2641
2642 return status;
2643 }
2644
2645 /*******************************************************************************
2646 **
2647 ** Function rw_t2t_soft_lock_tag
2648 **
2649 ** Description This function will soft lock the tag after validating CC.
2650 **
2651 ** Returns
2652 ** NFC_STATUS_OK, Command sent to soft lock the tag
2653 ** NFC_STATUS_FAILED: otherwise
2654 **
2655 *******************************************************************************/
rw_t2t_soft_lock_tag(void)2656 tNFC_STATUS rw_t2t_soft_lock_tag(void) {
2657 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2658 tNFC_STATUS status = NFC_STATUS_FAILED;
2659 uint8_t write_block[T2T_BLOCK_SIZE];
2660 uint8_t num_locks;
2661
2662 /* If CC block is read and cc3 is soft locked, reject the command */
2663 if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO) {
2664 RW_TRACE_ERROR1(
2665 "rw_t2t_soft_lock_tag: Error: Type 2 tag is in Read only state, CC3: "
2666 "%u",
2667 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2668 return (NFC_STATUS_FAILED);
2669 }
2670
2671 if (p_t2t->b_hard_lock) {
2672 /* Should have performed NDEF Detection on dynamic memory structure tag,
2673 * before permanently converting to Read only
2674 * Even when no lock control tlv is present, default lock bytes should be
2675 * present */
2676
2677 if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != T2T_CC2_TMS_STATIC) &&
2678 (p_t2t->num_lockbytes == 0)) {
2679 RW_TRACE_ERROR0(
2680 "rw_t2t_soft_lock_tag: Error: Lock TLV not detected! Cannot hard "
2681 "lock the tag");
2682 return (NFC_STATUS_FAILED);
2683 }
2684
2685 /* On dynamic memory structure tag, reset all lock bytes status to 'Not
2686 * Updated' if not in Updated status */
2687 num_locks = 0;
2688 while (num_locks < p_t2t->num_lockbytes) {
2689 if (p_t2t->lockbyte[num_locks].lock_status != RW_T2T_LOCK_UPDATED)
2690 p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_NOT_UPDATED;
2691 num_locks++;
2692 }
2693 }
2694
2695 memcpy(write_block, &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], T2T_BLOCK_SIZE);
2696 write_block[(T2T_CC3_RWA_BYTE % T2T_BLOCK_SIZE)] = T2T_CC3_RWA_RO;
2697
2698 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC_RO;
2699 /* First Soft lock the tag */
2700 status = rw_t2t_write(T2T_CC_BLOCK, write_block);
2701 if (status == NFC_STATUS_OK) {
2702 p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
2703 p_t2t->b_read_hdr = false;
2704 } else {
2705 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2706 }
2707 return status;
2708 }
2709
2710 /*****************************************************************************
2711 **
2712 ** Function RW_T2tFormatNDef
2713 **
2714 ** Description
2715 ** Format Tag content
2716 **
2717 ** Returns
2718 ** NFC_STATUS_OK, Command sent to format Tag
2719 ** NFC_STATUS_FAILED: otherwise
2720 **
2721 *****************************************************************************/
RW_T2tFormatNDef(void)2722 tNFC_STATUS RW_T2tFormatNDef(void) {
2723 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2724 tNFC_STATUS status = NFC_STATUS_FAILED;
2725
2726 if (p_t2t->state != RW_T2T_STATE_IDLE) {
2727 RW_TRACE_WARNING1("RW_T2tFormatNDef - Tag not initialized/ Busy! State: %u",
2728 p_t2t->state);
2729 return (NFC_STATUS_FAILED);
2730 }
2731
2732 if (!p_t2t->b_read_hdr) {
2733 /* If UID is not read, READ it now */
2734 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
2735
2736 status = rw_t2t_read(0);
2737 if (status == NFC_STATUS_OK)
2738 p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2739 else
2740 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2741 } else {
2742 status = rw_t2t_format_tag();
2743 if (status != NFC_STATUS_OK) p_t2t->b_read_hdr = false;
2744 }
2745 return status;
2746 }
2747
2748 /*******************************************************************************
2749 **
2750 ** Function RW_T2tLocateTlv
2751 **
2752 ** Description This function is used to perform TLV detection on a Type 2
2753 ** tag, and retrieve the tag's TLV attribute information.
2754 **
2755 ** Before using this API, the application must call
2756 ** RW_SelectTagType to indicate that a Type 2 tag has been
2757 ** activated.
2758 **
2759 ** Parameters: tlv_type : TLV to detect
2760 **
2761 ** Returns NCI_STATUS_OK, if detection was started. Otherwise, error
2762 ** status.
2763 **
2764 *******************************************************************************/
RW_T2tLocateTlv(uint8_t tlv_type)2765 tNFC_STATUS RW_T2tLocateTlv(uint8_t tlv_type) {
2766 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2767 tNFC_STATUS status;
2768 uint16_t block;
2769
2770 if (p_t2t->state != RW_T2T_STATE_IDLE) {
2771 RW_TRACE_ERROR1("Error: Type 2 tag not activated or Busy - State: %u",
2772 p_t2t->state);
2773 return (NFC_STATUS_BUSY);
2774 }
2775
2776 if ((tlv_type != TAG_LOCK_CTRL_TLV) && (tlv_type != TAG_MEM_CTRL_TLV) &&
2777 (tlv_type != TAG_NDEF_TLV) && (tlv_type != TAG_PROPRIETARY_TLV)) {
2778 RW_TRACE_API1("RW_T2tLocateTlv - Cannot search TLV: 0x%02x", tlv_type);
2779 return (NFC_STATUS_FAILED);
2780 }
2781
2782 if ((tlv_type == TAG_LOCK_CTRL_TLV) && (p_t2t->b_read_hdr) &&
2783 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC)) {
2784 p_t2t->b_read_hdr = false;
2785 RW_TRACE_API1(
2786 "RW_T2tLocateTlv - No Lock tlv in static structure tag, CC[0]: 0x%02x",
2787 p_t2t->tag_hdr[T2T_CC2_TMS_BYTE]);
2788 return (NFC_STATUS_FAILED);
2789 }
2790
2791 if ((tlv_type == TAG_NDEF_TLV) && (p_t2t->b_read_hdr) &&
2792 (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)) {
2793 p_t2t->b_read_hdr = false;
2794 RW_TRACE_WARNING3(
2795 "RW_T2tLocateTlv - Invalid NDEF Magic Number!, CC[0]: 0x%02x, CC[1]: "
2796 "0x%02x, CC[3]: 0x%02x",
2797 p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE],
2798 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2799 return (NFC_STATUS_FAILED);
2800 }
2801
2802 p_t2t->work_offset = 0;
2803 p_t2t->tlv_detect = tlv_type;
2804
2805 /* Reset control block variables based on type of tlv to detect */
2806 if (tlv_type == TAG_LOCK_CTRL_TLV) {
2807 p_t2t->num_lockbytes = 0;
2808 p_t2t->num_lock_tlvs = 0;
2809 } else if (tlv_type == TAG_MEM_CTRL_TLV) {
2810 p_t2t->num_mem_tlvs = 0;
2811 } else if (tlv_type == TAG_NDEF_TLV) {
2812 p_t2t->ndef_msg_offset = 0;
2813 p_t2t->num_lockbytes = 0;
2814 p_t2t->num_lock_tlvs = 0;
2815 p_t2t->num_mem_tlvs = 0;
2816 p_t2t->ndef_msg_len = 0;
2817 p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED;
2818 } else {
2819 p_t2t->prop_msg_len = 0;
2820 }
2821
2822 if (!p_t2t->b_read_hdr) {
2823 /* First read CC block */
2824 block = 0;
2825 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
2826 } else {
2827 /* Read first data block */
2828 block = T2T_FIRST_DATA_BLOCK;
2829 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
2830 }
2831
2832 /* Start reading tag, looking for the specified TLV */
2833 status = rw_t2t_read((uint16_t)block);
2834 if (status == NFC_STATUS_OK) {
2835 p_t2t->state = RW_T2T_STATE_DETECT_TLV;
2836 } else {
2837 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2838 }
2839 return (status);
2840 }
2841
2842 /*******************************************************************************
2843 **
2844 ** Function RW_T2tDetectNDef
2845 **
2846 ** Description This function is used to perform NDEF detection on a Type 2
2847 ** tag, and retrieve the tag's NDEF attribute information.
2848 **
2849 ** Before using this API, the application must call
2850 ** RW_SelectTagType to indicate that a Type 2 tag has been
2851 ** activated.
2852 **
2853 ** Parameters: none
2854 **
2855 ** Returns NCI_STATUS_OK,if detect op started.Otherwise,error status.
2856 **
2857 *******************************************************************************/
RW_T2tDetectNDef(bool skip_dyn_locks)2858 tNFC_STATUS RW_T2tDetectNDef(bool skip_dyn_locks) {
2859 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2860
2861 p_t2t->skip_dyn_locks = skip_dyn_locks;
2862
2863 return RW_T2tLocateTlv(TAG_NDEF_TLV);
2864 }
2865
2866 /*******************************************************************************
2867 **
2868 ** Function RW_T2tReadNDef
2869 **
2870 ** Description Retrieve NDEF contents from a Type2 tag.
2871 **
2872 ** The RW_T2T_NDEF_READ_EVT event is used to notify the
2873 ** application after reading the NDEF message.
2874 **
2875 ** Before using this API, the RW_T2tDetectNDef function must
2876 ** be called to verify that the tag contains NDEF data, and to
2877 ** retrieve the NDEF attributes.
2878 **
2879 ** Internally, this command will be separated into multiple
2880 ** Tag2 Read commands (if necessary) - depending on the NDEF
2881 ** Msg size
2882 **
2883 ** Parameters: p_buffer: The buffer into which to read the NDEF message
2884 ** buf_len: The length of the buffer
2885 **
2886 ** Returns NCI_STATUS_OK, if read was started. Otherwise, error status.
2887 **
2888 *******************************************************************************/
RW_T2tReadNDef(uint8_t * p_buffer,uint16_t buf_len)2889 tNFC_STATUS RW_T2tReadNDef(uint8_t* p_buffer, uint16_t buf_len) {
2890 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2891 tNFC_STATUS status = NFC_STATUS_OK;
2892 uint16_t block;
2893
2894 if (p_t2t->state != RW_T2T_STATE_IDLE) {
2895 RW_TRACE_ERROR1("Error: Type 2 tag not activated or Busy - State: %u",
2896 p_t2t->state);
2897 return (NFC_STATUS_FAILED);
2898 }
2899
2900 if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) {
2901 RW_TRACE_ERROR0("RW_T2tReadNDef - Error: NDEF detection not performed yet");
2902 return (NFC_STATUS_FAILED);
2903 }
2904
2905 if (buf_len < p_t2t->ndef_msg_len) {
2906 RW_TRACE_WARNING2(
2907 "RW_T2tReadNDef - buffer size: %u less than NDEF msg sise: %u",
2908 buf_len, p_t2t->ndef_msg_len);
2909 return (NFC_STATUS_FAILED);
2910 }
2911
2912 if (!p_t2t->ndef_msg_len) {
2913 RW_TRACE_WARNING1("RW_T2tReadNDef - NDEF Message length is zero ",
2914 p_t2t->ndef_msg_len);
2915 return (NFC_STATUS_NOT_INITIALIZED);
2916 }
2917
2918 p_t2t->p_ndef_buffer = p_buffer;
2919 p_t2t->work_offset = 0;
2920
2921 block = (uint16_t)(p_t2t->ndef_msg_offset / T2T_BLOCK_LEN);
2922 block -= block % T2T_READ_BLOCKS;
2923
2924 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2925
2926 if ((block == T2T_FIRST_DATA_BLOCK) && (p_t2t->b_read_data)) {
2927 p_t2t->state = RW_T2T_STATE_READ_NDEF;
2928 p_t2t->block_read = T2T_FIRST_DATA_BLOCK;
2929 rw_t2t_handle_ndef_read_rsp(p_t2t->tag_data);
2930 } else {
2931 /* Start reading NDEF Message */
2932 status = rw_t2t_read(block);
2933 if (status == NFC_STATUS_OK) {
2934 p_t2t->state = RW_T2T_STATE_READ_NDEF;
2935 }
2936 }
2937
2938 return (status);
2939 }
2940
2941 /*******************************************************************************
2942 **
2943 ** Function RW_T2tWriteNDef
2944 **
2945 ** Description Write NDEF contents to a Type2 tag.
2946 **
2947 ** Before using this API, the RW_T2tDetectNDef
2948 ** function must be called to verify that the tag contains
2949 ** NDEF data, and to retrieve the NDEF attributes.
2950 **
2951 ** The RW_T2T_NDEF_WRITE_EVT callback event will be used to
2952 ** notify the application of the response.
2953 **
2954 ** Internally, this command will be separated into multiple
2955 ** Tag2 Write commands (if necessary) - depending on the NDEF
2956 ** Msg size
2957 **
2958 ** Parameters: msg_len: The length of the buffer
2959 ** p_msg: The NDEF message to write
2960 **
2961 ** Returns NCI_STATUS_OK,if write was started. Otherwise, error status
2962 **
2963 *******************************************************************************/
RW_T2tWriteNDef(uint16_t msg_len,uint8_t * p_msg)2964 tNFC_STATUS RW_T2tWriteNDef(uint16_t msg_len, uint8_t* p_msg) {
2965 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2966 uint16_t block;
2967 const tT2T_INIT_TAG* p_ret;
2968
2969 tNFC_STATUS status = NFC_STATUS_OK;
2970
2971 if (p_t2t->state != RW_T2T_STATE_IDLE) {
2972 RW_TRACE_ERROR1("Error: Type 2 tag not activated or Busy - State: %u",
2973 p_t2t->state);
2974 return (NFC_STATUS_FAILED);
2975 }
2976
2977 if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) {
2978 RW_TRACE_ERROR0("RW_T2tWriteNDef - Error: NDEF detection not performed!");
2979 return (NFC_STATUS_FAILED);
2980 }
2981
2982 if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) {
2983 RW_TRACE_ERROR1("RW_T2tWriteNDef - Write access not granted - CC3: %u",
2984 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2985 return (NFC_STATUS_REFUSED);
2986 }
2987
2988 /* Check if there is enough memory on the tag */
2989 if (msg_len > p_t2t->max_ndef_msg_len) {
2990 RW_TRACE_ERROR1(
2991 "RW_T2tWriteNDef - Cannot write NDEF of size greater than %u bytes",
2992 p_t2t->max_ndef_msg_len);
2993 return (NFC_STATUS_FAILED);
2994 }
2995
2996 /* If OTP tag and tag has valid NDEF Message, stop writting new NDEF Message
2997 * as it may corrupt the tag */
2998 if ((p_t2t->ndef_msg_len > 0) &&
2999 ((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != NULL) &&
3000 (p_ret->b_otp)) {
3001 RW_TRACE_WARNING0(
3002 "RW_T2tWriteNDef - Cannot Overwrite NDEF Message on a OTP tag!");
3003 return (NFC_STATUS_FAILED);
3004 }
3005 p_t2t->p_new_ndef_buffer = p_msg;
3006 p_t2t->new_ndef_msg_len = msg_len;
3007 p_t2t->work_offset = 0;
3008
3009 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK;
3010 /* Read first NDEF Block before updating NDEF */
3011
3012 block = (uint16_t)(p_t2t->ndef_header_offset / T2T_BLOCK_LEN);
3013
3014 if ((block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS)) &&
3015 (p_t2t->b_read_data)) {
3016 p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
3017 p_t2t->block_read = block;
3018 rw_t2t_handle_ndef_write_rsp(
3019 &p_t2t->tag_data[(block - T2T_FIRST_DATA_BLOCK) * T2T_BLOCK_LEN]);
3020 } else {
3021 status = rw_t2t_read(block);
3022 if (status == NFC_STATUS_OK)
3023 p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
3024 else
3025 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
3026 }
3027
3028 return status;
3029 }
3030
3031 /*******************************************************************************
3032 **
3033 ** Function RW_T2tSetTagReadOnly
3034 **
3035 ** Description This function can be called to set T2 tag as read only.
3036 **
3037 ** Parameters: b_hard_lock: To indicate hard lock the tag or not
3038 **
3039 ** Returns NCI_STATUS_OK, if setting tag as read only was started.
3040 ** Otherwise, error status.
3041 **
3042 *******************************************************************************/
RW_T2tSetTagReadOnly(bool b_hard_lock)3043 tNFC_STATUS RW_T2tSetTagReadOnly(bool b_hard_lock) {
3044 tNFC_STATUS status = NFC_STATUS_FAILED;
3045 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
3046
3047 if (p_t2t->state != RW_T2T_STATE_IDLE) {
3048 RW_TRACE_ERROR1(
3049 "RW_T2tSetTagReadOnly: Error: Type 2 tag not activated or Busy - "
3050 "State: %u",
3051 p_t2t->state);
3052 return (NFC_STATUS_FAILED);
3053 }
3054
3055 p_t2t->b_hard_lock = b_hard_lock;
3056
3057 if (!p_t2t->b_read_hdr) {
3058 /* Read CC block before configuring tag as Read only */
3059 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
3060 status = rw_t2t_read((uint16_t)0);
3061 if (status == NFC_STATUS_OK) {
3062 p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
3063 } else
3064 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
3065 } else {
3066 status = rw_t2t_soft_lock_tag();
3067 if (status != NFC_STATUS_OK) p_t2t->b_read_hdr = false;
3068 }
3069
3070 return status;
3071 }
3072
3073 #endif /* (RW_NDEF_INCLUDED == TRUE) */
3074