1 /******************************************************************************
2 *
3 * Copyright (C) 2010-2013 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 *
22 * This file contains the implementation for Type 1 tag NDEF operation in
23 * Reader/Writer mode.
24 *
25 ******************************************************************************/
26 #include <string.h>
27 #include "nfc_target.h"
28
29 #if (NFC_INCLUDED == TRUE)
30 #include "nfc_api.h"
31 #include "nci_hmsgs.h"
32 #include "rw_api.h"
33 #include "rw_int.h"
34 #include "nfc_int.h"
35 #include "gki.h"
36
37 #if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
38
39 /* Local Functions */
40 static tNFC_STATUS rw_t1t_handle_rall_rsp (BOOLEAN *p_notify,UINT8 *p_data);
41 static tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data);
42 static tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data);
43 static tNFC_STATUS rw_t1t_handle_read_rsp (BOOLEAN *p_callback, UINT8 *p_data);
44 static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data);
45 static tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data);
46 static tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data);
47 static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp (void);
48 static tNFC_STATUS rw_t1t_ndef_write_first_block (void);
49 static tNFC_STATUS rw_t1t_next_ndef_write_block (void);
50 static tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len);
51 static tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block);
52 static UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len);
53 static UINT8 rw_t1t_get_ndef_flags (void);
54 static UINT16 rw_t1t_get_ndef_max_size (void);
55 static BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index);
56 static BOOLEAN rw_t1t_is_read_only_byte (UINT16 index);
57 static UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte);
58 static void rw_t1t_update_attributes (void);
59 static void rw_t1t_update_lock_attributes (void);
60 static void rw_t1t_extract_lock_bytes (UINT8 *p_data);
61 static void rw_t1t_update_tag_state (void);
62
63 const UINT8 rw_t1t_mask_bits[8] =
64 {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
65
66 /*******************************************************************************
67 **
68 ** Function rw_t1t_handle_rsp
69 **
70 ** Description This function handles the response received for all commands
71 ** sent to tag
72 **
73 ** Returns event to be sent to application
74 **
75 *******************************************************************************/
rw_t1t_handle_rsp(const tT1T_CMD_RSP_INFO * p_info,BOOLEAN * p_notify,UINT8 * p_data,tNFC_STATUS * p_status)76 tRW_EVENT rw_t1t_handle_rsp (const tT1T_CMD_RSP_INFO * p_info, BOOLEAN *p_notify, UINT8 *p_data, tNFC_STATUS *p_status)
77 {
78 tRW_EVENT rw_event;
79 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
80 UINT8 adds;
81
82 if( (p_t1t->state == RW_T1T_STATE_READ)
83 ||(p_t1t->state == RW_T1T_STATE_WRITE) )
84 {
85 return t1t_info_to_evt (p_info);
86 }
87
88 rw_event = rw_t1t_info_to_event (p_info);
89
90 if (p_info->opcode == T1T_CMD_RALL)
91 {
92 *p_status = rw_t1t_handle_rall_rsp (p_notify,p_data);
93 }
94 else if (p_info->opcode == T1T_CMD_RSEG)
95 {
96 adds = *p_data;
97 if (adds == 0)
98 {
99 p_t1t->b_rseg = TRUE;
100 rw_t1t_update_tag_state ();
101 rw_t1t_update_attributes ();
102 rw_t1t_update_lock_attributes ();
103 memcpy (p_t1t->mem, (UINT8 *) (p_data + T1T_ADD_LEN), T1T_SEGMENT_SIZE);
104 }
105 *p_status = rw_t1t_handle_dyn_read_rsp (p_notify,p_data);
106 }
107 else if (p_info->opcode == T1T_CMD_READ8)
108 {
109 *p_status = rw_t1t_handle_dyn_read_rsp (p_notify,p_data);
110 }
111 else
112 {
113 *p_status = rw_t1t_handle_write_rsp (p_notify,p_data);
114 }
115 return rw_event;
116 }
117
118 /*******************************************************************************
119 **
120 ** Function rw_t1t_info_to_event
121 **
122 ** Description This function returns RW event code based on the current state
123 **
124 ** Returns RW event code
125 **
126 *******************************************************************************/
rw_t1t_info_to_event(const tT1T_CMD_RSP_INFO * p_info)127 tRW_EVENT rw_t1t_info_to_event (const tT1T_CMD_RSP_INFO * p_info)
128 {
129 tRW_EVENT rw_event;
130 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
131
132 switch (p_t1t->state)
133 {
134 case RW_T1T_STATE_TLV_DETECT:
135 if (p_t1t->tlv_detect == TAG_NDEF_TLV)
136 rw_event = RW_T1T_NDEF_DETECT_EVT;
137 else
138 rw_event = RW_T1T_TLV_DETECT_EVT;
139 break;
140
141 case RW_T1T_STATE_READ_NDEF:
142 rw_event = RW_T1T_NDEF_READ_EVT;
143 break;
144
145 case RW_T1T_STATE_WRITE_NDEF:
146 rw_event = RW_T1T_NDEF_WRITE_EVT;
147 break;
148
149 case RW_T1T_STATE_SET_TAG_RO:
150 rw_event = RW_T1T_SET_TAG_RO_EVT;
151 break;
152
153 case RW_T1T_STATE_CHECK_PRESENCE:
154 rw_event = RW_T1T_PRESENCE_CHECK_EVT;
155 break;
156
157 case RW_T1T_STATE_FORMAT_TAG:
158 rw_event = RW_T1T_FORMAT_CPLT_EVT;
159 break;
160
161 default:
162 rw_event = t1t_info_to_evt (p_info);
163 break;
164 }
165 return rw_event;
166 }
167
168 /*******************************************************************************
169 **
170 ** Function rw_t1t_extract_lock_bytes
171 **
172 ** Description This function will extract lock bytes if any present in the
173 ** response data
174 **
175 ** Parameters p_data: Data bytes in the response of RSEG/READ8/RALL command
176 **
177 ** Returns None
178 **
179 *******************************************************************************/
rw_t1t_extract_lock_bytes(UINT8 * p_data)180 void rw_t1t_extract_lock_bytes (UINT8 *p_data)
181 {
182 UINT16 end;
183 UINT16 start;
184 UINT8 num_locks;
185 UINT16 lock_offset = 0;
186 UINT16 offset;
187 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
188 tT1T_CMD_RSP_INFO *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
189
190 num_locks = 0;
191 /* Based on the Command used to read Tag, calculate the offset of the tag read */
192 if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG)
193 {
194 start = p_t1t->segment * T1T_SEGMENT_SIZE;
195 end = start + T1T_SEGMENT_SIZE;
196 }
197 else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8)
198 {
199 start = p_t1t->block_read * T1T_BLOCK_SIZE;
200 end = start + T1T_BLOCK_SIZE;
201 }
202 else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL)
203 {
204 start = 0;
205 end = T1T_STATIC_SIZE;
206 }
207 else
208 return;
209
210 /* Collect lock bytes that are present in the part of the data read from Tag */
211 while (num_locks < p_t1t->num_lockbytes)
212 {
213 if (p_t1t->lockbyte[num_locks].b_lock_read == FALSE)
214 {
215 /* Get the exact offset of the dynamic lock byte in the tag */
216 offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
217 if ( (offset < end)
218 &&(offset >= start) )
219
220 {
221 /* This dynamic lock byte is in the response */
222 if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG)
223 {
224 lock_offset = (offset % T1T_SEGMENT_SIZE);
225 }
226 else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8)
227 {
228 lock_offset = (offset % T1T_BLOCK_SIZE);
229 }
230 else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL)
231 {
232 lock_offset = offset;
233 }
234
235 p_t1t->lockbyte[num_locks].lock_byte = p_data[lock_offset];
236 p_t1t->lockbyte[num_locks].b_lock_read = TRUE;
237 }
238 else
239 break;
240 }
241 num_locks++;
242 }
243 }
244
245 /*******************************************************************************
246 **
247 ** Function rw_t1t_update_tag_attributes
248 **
249 ** Description This function will update tag attributes based on cc, ndef
250 ** message length
251 **
252 ** Returns None
253 **
254 *******************************************************************************/
rw_t1t_update_tag_state(void)255 void rw_t1t_update_tag_state (void)
256 {
257 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
258
259 /* Set Tag state based on CC value and NDEF Message length */
260 if ( ((p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN) || (p_t1t->mem[T1T_CC_NMN_BYTE] == 0))
261 &&((p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_VNO) || (p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_LEGACY_VNO))
262 &&((p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW) || (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO)) )
263 {
264 /* Valid CC value, so Tag is initialized */
265 if (p_t1t->ndef_msg_len > 0)
266 {
267 if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO)
268 {
269 /* NDEF Message presence, CC indication sets Tag as READ ONLY */
270 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_ONLY;
271 }
272 else if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW)
273 {
274 /* NDEF Message presence, CC indication sets Tag as READ WRITE */
275 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
276 }
277 }
278 else
279 {
280 /* If NDEF is not yet detected then Tag remains in Initialized state
281 * after NDEF Detection the Tag state may be updated */
282 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
283 }
284 }
285 else
286 {
287 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_UNKNOWN;
288 }
289 }
290
291 /*******************************************************************************
292 **
293 ** Function rw_t1t_read_locks
294 **
295 ** Description This function will send command to read next unread locks
296 **
297 ** Returns NFC_STATUS_OK, if all locks are read successfully
298 ** NFC_STATUS_FAILED, if reading locks failed
299 ** NFC_STATUS_CONTINUE, if reading locks is in progress
300 **
301 *******************************************************************************/
rw_t1t_read_locks(void)302 tNFC_STATUS rw_t1t_read_locks (void)
303 {
304 UINT8 num_locks = 0;
305 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
306 tNFC_STATUS status = NFC_STATUS_CONTINUE;
307 UINT16 offset;
308
309 while (num_locks < p_t1t->num_lockbytes)
310 {
311 if (p_t1t->lockbyte[num_locks].b_lock_read == FALSE)
312 {
313 offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
314 if (offset < T1T_STATIC_SIZE)
315 {
316 p_t1t->lockbyte[num_locks].lock_byte = p_t1t->mem[offset];
317 p_t1t->lockbyte[num_locks].b_lock_read = TRUE;
318 }
319 else if (offset < (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE)
320 {
321 /* send READ8 command */
322 p_t1t->block_read = (UINT8) (offset/T1T_BLOCK_SIZE);
323 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK)
324 {
325 /* Reading Locks */
326 status = NFC_STATUS_CONTINUE;
327 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_LOCKS;
328 }
329 break;
330 }
331 else
332 {
333 /* Read locks failed */
334 status = NFC_STATUS_FAILED;
335 break;
336 }
337 }
338 num_locks++;
339 }
340 if (num_locks == p_t1t->num_lockbytes)
341 {
342 /* All locks are read */
343 status = NFC_STATUS_OK;
344 }
345
346 return status;
347 }
348
349 /*******************************************************************************
350 **
351 ** Function rw_t1t_handle_write_rsp
352 **
353 ** Description This function handles response received for WRITE_E8,
354 ** WRITE_NE8, WRITE_E, WRITE_NE commands
355 **
356 ** Returns status of the current NDEF/TLV Operation
357 **
358 *******************************************************************************/
rw_t1t_handle_write_rsp(BOOLEAN * p_notify,UINT8 * p_data)359 static tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data)
360 {
361 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
362 tNFC_STATUS status = NFC_STATUS_OK;
363 UINT8 num_locks;
364 UINT8 lock_count;
365 UINT8 value;
366 UINT8 addr;
367 UINT8 write_block[T1T_BLOCK_SIZE];
368 UINT16 offset;
369 UINT16 next_offset;
370 UINT8 num_bits;
371 UINT8 next_num_bits;
372
373 *p_notify = FALSE;
374
375 switch (p_t1t->state)
376 {
377 case RW_T1T_STATE_WRITE:
378 *p_notify = TRUE;
379 break;
380
381 case RW_T1T_STATE_FORMAT_TAG:
382 if (p_t1t->substate == RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF)
383 {
384 if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
385 *p_notify = TRUE;
386 else
387 {
388 if (p_t1t->work_offset < (T1T_BLOCK_SIZE - 1))
389 {
390 p_t1t->work_offset++;
391 /* send WRITE-E command */
392 RW_T1T_BLD_ADD ((addr), 1, (UINT8) p_t1t->work_offset);
393
394 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[(UINT8) p_t1t->work_offset])) != NFC_STATUS_OK)
395 *p_notify = TRUE;
396 }
397 else
398 *p_notify = TRUE;
399 }
400
401 }
402 else
403 {
404 /* send WRITE-E8 command */
405 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 2, p_t1t->ndef_final_block)) != NFC_STATUS_OK)
406 *p_notify = TRUE;
407 else
408 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
409 }
410 break;
411
412 case RW_T1T_STATE_SET_TAG_RO:
413 switch (p_t1t->substate)
414 {
415 case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
416
417 if (!p_t1t->b_hard_lock)
418 {
419 status = NFC_STATUS_OK;
420 *p_notify = TRUE;
421 break;
422 }
423
424 if ((p_t1t->hr[0] & 0x0F) != 1)
425 {
426 memset (write_block,0,T1T_BLOCK_SIZE);
427 write_block[0] = 0xFF;
428 write_block[1] = 0xFF;
429
430 /* send WRITE-NE8 command */
431 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, T1T_LOCK_BLOCK, write_block)) != NFC_STATUS_OK)
432 *p_notify = TRUE;
433 else
434 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
435 }
436 else
437 {
438 /* send WRITE-NE command */
439 RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (0));
440 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK)
441 *p_notify = TRUE;
442 else
443 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
444 }
445 break;
446
447 case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
448
449 /* send WRITE-NE command */
450 RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (1));
451 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK)
452 *p_notify = TRUE;
453 else
454 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
455
456 break;
457
458 case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
459 num_locks = 0;
460 while (num_locks < p_t1t->num_lockbytes)
461 {
462 if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_UPDATE_INITIATED)
463 {
464 p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATED;
465 }
466 num_locks++;
467 }
468
469 num_locks = 0;
470 while (num_locks < p_t1t->num_lockbytes)
471 {
472 if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_NOT_UPDATED)
473 {
474 offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
475 num_bits = ((p_t1t->lockbyte[num_locks].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits % 8;
476
477 if ((p_t1t->hr[0] & 0x0F) != 1)
478 {
479 memset (write_block,0,T1T_BLOCK_SIZE);
480
481 write_block[(UINT8) (offset%T1T_BLOCK_SIZE)] |= tags_pow (2,num_bits) - 1;
482 lock_count = num_locks + 1;
483 while (lock_count < p_t1t->num_lockbytes)
484 {
485 next_offset = p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].offset + p_t1t->lockbyte[lock_count].byte_index;
486 next_num_bits = ((p_t1t->lockbyte[lock_count].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits % 8;
487
488 if (next_offset/T1T_BLOCK_SIZE == offset/T1T_BLOCK_SIZE)
489 {
490 write_block[(UINT8) (next_offset%T1T_BLOCK_SIZE)] |= tags_pow (2,next_num_bits) - 1;
491 }
492 else
493 break;
494 lock_count ++;
495 }
496
497 /* send WRITE-NE8 command */
498 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, (UINT8) (offset/T1T_BLOCK_SIZE), write_block)) == NFC_STATUS_OK)
499 {
500 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
501 while (lock_count > num_locks)
502 {
503 p_t1t->lockbyte[lock_count - 1].lock_status = RW_T1T_LOCK_UPDATE_INITIATED;
504 lock_count --;
505 }
506 }
507 else
508 *p_notify = TRUE;
509 }
510 else
511 {
512 /* send WRITE-NE command */
513 RW_T1T_BLD_ADD ((addr), ((UINT8) (offset/T1T_BLOCK_SIZE)), ((UINT8) (offset%T1T_BLOCK_SIZE)));
514 value = (UINT8) (tags_pow (2,num_bits) - 1);
515 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, value)) == NFC_STATUS_OK)
516 {
517 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
518 p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATE_INITIATED;
519 }
520 else
521 *p_notify = TRUE;
522 }
523 break;
524 }
525 num_locks++;
526 }
527 if (num_locks == p_t1t->num_lockbytes)
528 {
529 rw_t1t_update_lock_attributes ();
530 status = NFC_STATUS_OK;
531 *p_notify = TRUE;
532 }
533 break;
534 }
535 break;
536
537 case RW_T1T_STATE_WRITE_NDEF:
538 switch (p_t1t->substate)
539 {
540 case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
541 p_t1t->ndef_msg_len = p_t1t->new_ndef_msg_len;
542 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
543 *p_notify = TRUE;
544 break;
545
546 case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
547 status = rw_t1t_handle_ndef_write_rsp (p_data);
548 if (status == NFC_STATUS_OK)
549 {
550 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF;
551 }
552 else if (status == NFC_STATUS_FAILED)
553 {
554 /* Send Negative response to upper layer */
555 *p_notify = TRUE;
556 }
557 break;
558
559 case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
560 status = rw_t1t_handle_ndef_write_rsp (p_data);
561
562 if (status == NFC_STATUS_FAILED)
563 {
564 /* Send Negative response to upper layer */
565 *p_notify = TRUE;
566 }
567 else if (status == NFC_STATUS_OK)
568 {
569 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
570 }
571 break;
572
573 case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
574 status = rw_t1t_handle_ndef_write_rsp (p_data);
575 if (status == NFC_STATUS_FAILED)
576 {
577 /* Send Negative response to upper layer */
578 *p_notify = TRUE;
579 }
580 else if (status == NFC_STATUS_CONTINUE)
581 {
582 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_WRITE;
583 }
584 else
585 {
586 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
587 }
588 break;
589 }
590 break;
591 }
592 return status;
593 }
594
595 /*******************************************************************************
596 **
597 ** Function rw_t1t_handle_read_rsp
598 **
599 ** Description This function handle the data bytes excluding ADD(S)/ADD8 field
600 ** received as part of RSEG, RALL, READ8 command response
601 **
602 ** Returns status of the current NDEF/TLV Operation
603 **
604 *******************************************************************************/
rw_t1t_handle_read_rsp(BOOLEAN * p_notify,UINT8 * p_data)605 tNFC_STATUS rw_t1t_handle_read_rsp (BOOLEAN *p_notify, UINT8 *p_data)
606 {
607 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
608 tNFC_STATUS status = NFC_STATUS_OK;
609 tRW_DETECT_NDEF_DATA ndef_data;
610 tRW_DETECT_TLV_DATA tlv_data;
611 UINT8 count;
612 tRW_READ_DATA evt_data;
613
614 *p_notify = FALSE;
615 /* Handle the response based on the current state */
616 switch (p_t1t->state)
617 {
618 case RW_T1T_STATE_READ:
619 *p_notify = TRUE;
620 break;
621
622 case RW_T1T_STATE_READ_NDEF:
623 status = rw_t1t_handle_ndef_rall_rsp ();
624 if (status != NFC_STATUS_CONTINUE)
625 {
626 evt_data.status = status;
627 evt_data.p_data = NULL;
628 rw_t1t_handle_op_complete ();
629 (*rw_cb.p_cback) (RW_T1T_NDEF_READ_EVT, (tRW_DATA *) &evt_data);
630 }
631 break;
632
633 case RW_T1T_STATE_TLV_DETECT:
634 switch (p_t1t->substate)
635 {
636 case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
637 status = rw_t1t_read_locks ();
638 if (status != NFC_STATUS_CONTINUE)
639 {
640 rw_t1t_update_lock_attributes ();
641 /* Send positive response to upper layer */
642 if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
643 {
644 tlv_data.protocol = NFC_PROTOCOL_T1T;
645 tlv_data.num_bytes = p_t1t->num_lockbytes;
646 tlv_data.status = status;
647 rw_t1t_handle_op_complete ();
648 (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
649 }
650 else if (p_t1t->tlv_detect == TAG_NDEF_TLV)
651 {
652 ndef_data.protocol = NFC_PROTOCOL_T1T;
653 ndef_data.flags = rw_t1t_get_ndef_flags ();
654 ndef_data.flags |= RW_NDEF_FL_FORMATED;
655 ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size ();
656 ndef_data.cur_size = p_t1t->ndef_msg_len;
657
658 if (ndef_data.max_size < ndef_data.cur_size)
659 {
660 ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
661 ndef_data.max_size = ndef_data.cur_size;
662 }
663
664 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
665 {
666 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
667 if (status == NFC_STATUS_OK)
668 ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
669 }
670 ndef_data.status = status;
671 rw_t1t_handle_op_complete ();
672 (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data);
673 }
674 }
675 break;
676
677 case RW_T1T_SUBSTATE_NONE:
678 if (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
679 {
680 tlv_data.status = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
681 tlv_data.protocol = NFC_PROTOCOL_T1T;
682 tlv_data.num_bytes = 0;
683 count = 0;
684 while (count < p_t1t->num_mem_tlvs)
685 {
686 tlv_data.num_bytes += p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes;
687 count++;
688 }
689 rw_t1t_handle_op_complete ();
690 /* Send response to upper layer */
691 (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
692 }
693 else if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
694 {
695 tlv_data.status = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
696 tlv_data.protocol = NFC_PROTOCOL_T1T;
697 tlv_data.num_bytes = p_t1t->num_lockbytes;
698
699 if (tlv_data.status == NFC_STATUS_FAILED)
700 {
701 rw_t1t_handle_op_complete ();
702
703 /* Send Negative response to upper layer */
704 (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *)&tlv_data);
705 }
706 else
707 {
708 rw_t1t_extract_lock_bytes (p_data);
709 status = rw_t1t_read_locks ();
710 if (status != NFC_STATUS_CONTINUE)
711 {
712 /* Send positive response to upper layer */
713 tlv_data.status = status;
714 rw_t1t_handle_op_complete ();
715
716 (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
717 }
718 }
719 }
720 else if (p_t1t->tlv_detect == TAG_NDEF_TLV)
721 {
722 ndef_data.protocol = NFC_PROTOCOL_T1T;
723 ndef_data.flags = rw_t1t_get_ndef_flags ();
724
725 if (p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN)
726 {
727 ndef_data.status = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
728
729 ndef_data.cur_size = p_t1t->ndef_msg_len;
730 if (ndef_data.status == NFC_STATUS_FAILED)
731 {
732 ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size ();
733 if (ndef_data.max_size < ndef_data.cur_size)
734 {
735 ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
736 ndef_data.max_size = ndef_data.cur_size;
737 }
738 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
739 {
740 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
741 }
742 /* Send Negative response to upper layer */
743 rw_t1t_handle_op_complete ();
744
745 (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
746 }
747 else
748 {
749 ndef_data.flags |= RW_NDEF_FL_FORMATED;
750 rw_t1t_extract_lock_bytes (p_data);
751 status = rw_t1t_read_locks ();
752 if (status != NFC_STATUS_CONTINUE)
753 {
754 ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size ();
755 if (ndef_data.max_size < ndef_data.cur_size)
756 {
757 ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
758 ndef_data.max_size = ndef_data.cur_size;
759 }
760
761 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
762 {
763 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
764 if (status == NFC_STATUS_OK)
765 ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
766 }
767 /* Send positive response to upper layer */
768 ndef_data.status = status;
769 rw_t1t_handle_op_complete ();
770
771 (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data);
772 }
773 }
774 }
775 else
776 {
777 /* Send Negative response to upper layer */
778 ndef_data.status = NFC_STATUS_FAILED;
779 ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size ();
780 ndef_data.cur_size = p_t1t->ndef_msg_len;
781 if (ndef_data.max_size < ndef_data.cur_size)
782 {
783 ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
784 ndef_data.max_size = ndef_data.cur_size;
785 }
786 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
787 {
788 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
789 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
790 }
791 rw_t1t_handle_op_complete ();
792
793 (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
794 }
795 }
796 break;
797 }
798 break;
799 }
800 return status;
801 }
802
803 /*******************************************************************************
804 **
805 ** Function rw_t1t_handle_dyn_read_rsp
806 **
807 ** Description This function handles response received for READ8, RSEG
808 ** commands based on the current state
809 **
810 ** Returns status of the current NDEF/TLV Operation
811 **
812 *******************************************************************************/
rw_t1t_handle_dyn_read_rsp(BOOLEAN * p_notify,UINT8 * p_data)813 static tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data)
814 {
815 tNFC_STATUS status = NFC_STATUS_OK;
816 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
817
818 *p_notify = FALSE;
819
820 p_data += T1T_ADD_LEN;
821
822 rw_t1t_extract_lock_bytes (p_data);
823
824 if (p_t1t->state == RW_T1T_STATE_READ_NDEF)
825 {
826 status = rw_t1t_handle_ndef_read_rsp (p_data);
827 if ( (status == NFC_STATUS_FAILED)
828 ||(status == NFC_STATUS_OK) )
829 {
830 /* Send response to upper layer */
831 *p_notify = TRUE;
832 }
833 }
834 else if (p_t1t->state == RW_T1T_STATE_WRITE_NDEF)
835 {
836 status = rw_t1t_handle_ndef_write_rsp (p_data);
837 if (status == NFC_STATUS_FAILED)
838 {
839 /* Send response to upper layer */
840 *p_notify = TRUE;
841 }
842 else if (status == NFC_STATUS_CONTINUE)
843 {
844 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
845 }
846 }
847 else
848 {
849 status = rw_t1t_handle_read_rsp (p_notify, p_data);
850 }
851 return status;
852 }
853
854 /*****************************************************************************
855 **
856 ** Function rw_t1t_handle_rall_rsp
857 **
858 ** Description Handle response to RALL - Collect CC, set Tag state
859 **
860 ** Returns None
861 **
862 *****************************************************************************/
rw_t1t_handle_rall_rsp(BOOLEAN * p_notify,UINT8 * p_data)863 static tNFC_STATUS rw_t1t_handle_rall_rsp (BOOLEAN *p_notify,UINT8 *p_data)
864 {
865 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
866
867 p_data += T1T_HR_LEN; /* skip HR */
868 memcpy (p_t1t->mem, (UINT8 *) p_data, T1T_STATIC_SIZE);
869 p_t1t->segment = 0;
870 rw_t1t_extract_lock_bytes (p_data);
871
872 p_data += T1T_UID_LEN + T1T_RES_BYTE_LEN; /* skip Block 0, UID and Reserved byte */
873
874 RW_TRACE_DEBUG0 ("rw_t1t_handle_rall_rsp ()");
875
876 rw_t1t_update_tag_state ();
877 rw_t1t_update_attributes ();
878 rw_t1t_update_lock_attributes ();
879 p_t1t->b_update = TRUE;
880 return (rw_t1t_handle_read_rsp (p_notify, p_t1t->mem));
881 }
882
883 /*******************************************************************************
884 **
885 ** Function rw_t1t_handle_tlv_detect_rsp
886 **
887 ** Description Handle response to the last command sent while
888 ** detecting tlv
889 **
890 ** Returns NFC_STATUS_OK, if tlv detect is complete & success
891 ** NFC_STATUS_FAILED,if tlv detect failed
892 **
893 *******************************************************************************/
rw_t1t_handle_tlv_detect_rsp(UINT8 * p_data)894 static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data)
895 {
896 UINT16 offset;
897 UINT16 len;
898 UINT8 xx;
899 UINT8 *p_readbytes;
900 UINT8 index;
901 UINT8 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
902 UINT8 found_tlv = TAG_NULL_TLV;
903 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
904 BOOLEAN failed = FALSE;
905 BOOLEAN found = FALSE;
906 UINT8 count = 0;
907 tNFC_STATUS status = NFC_STATUS_FAILED;
908 UINT8 start_offset = T1T_UID_LEN + T1T_CC_LEN + T1T_RES_BYTE_LEN;
909 UINT8 end_offset = T1T_STATIC_SIZE - (2*T1T_BLOCK_SIZE);
910 UINT8 bytes_read = T1T_STATIC_SIZE;
911 UINT8 tlv_value[T1T_DEFAULT_TLV_LEN];
912 UINT16 bytes_count = 0;
913
914 p_readbytes = p_data;
915
916 for (offset = start_offset; offset < end_offset && !failed && !found;)
917 {
918 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == TRUE)
919 {
920 offset++;
921 continue;
922 }
923 switch (tlv_detect_state)
924 {
925 case RW_T1T_SUBSTATE_WAIT_TLV_DETECT:
926 /* Search for the tag */
927 found_tlv = p_readbytes[offset++];
928 switch (found_tlv)
929 {
930 case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */
931 break;
932
933 case TAG_NDEF_TLV:
934 if (p_t1t->tlv_detect == TAG_NDEF_TLV)
935 {
936 index = (offset % T1T_BLOCK_SIZE);
937 /* Backup ndef first block */
938 memcpy (&p_t1t->ndef_first_block[0],&p_readbytes[offset-index],index);
939 memcpy (&p_t1t->ndef_first_block[index],&p_readbytes[offset],T1T_BLOCK_SIZE - index);
940 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
941 }
942 else if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
943 {
944 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
945 }
946 else if ( ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
947 ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0)) )
948 {
949 found = TRUE;
950 }
951 else
952 {
953 failed = TRUE;
954 }
955 break;
956
957 case TAG_LOCK_CTRL_TLV:
958 case TAG_MEM_CTRL_TLV:
959 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
960 break;
961
962 case TAG_PROPRIETARY_TLV:
963 if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
964 {
965 index = (offset % T1T_BLOCK_SIZE);
966 /* Backup ndef first block */
967 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
968 }
969 else
970 {
971 /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we continue searching, skiping proprietary tlv */
972 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
973 }
974 break;
975
976 case TAG_TERMINATOR_TLV: /* Last TLV block in the data area. Must be no NDEF nessage */
977 if ( ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
978 ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0)) )
979 {
980 found = TRUE;
981 }
982 else
983 {
984 failed = TRUE;
985 }
986 break;
987 default:
988 failed = TRUE;
989 }
990 break;
991
992 case RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
993 len = p_readbytes[offset];
994 switch (found_tlv)
995 {
996 case TAG_NDEF_TLV:
997 p_t1t->ndef_header_offset = offset + p_t1t->work_offset;
998 if (len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)
999 {
1000 /* The next two bytes constitute length bytes */
1001 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
1002 }
1003 else
1004 {
1005 /* one byte length field */
1006 p_t1t->ndef_msg_len = len;
1007 bytes_count = p_t1t->ndef_msg_len;
1008 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
1009 }
1010 break;
1011
1012 case TAG_PROPRIETARY_TLV:
1013 if (len == 0xFF)
1014 {
1015 /* The next two bytes constitute length bytes */
1016 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
1017 }
1018 else
1019 {
1020 /* one byte length field */
1021 bytes_count = len;
1022 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
1023 }
1024 break;
1025 }
1026 offset++;
1027 break;
1028
1029 case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0:
1030 switch (found_tlv)
1031 {
1032 case TAG_LOCK_CTRL_TLV:
1033 case TAG_MEM_CTRL_TLV:
1034
1035 len = p_readbytes[offset];
1036 if (len == T1T_DEFAULT_TLV_LEN)
1037 {
1038 /* Valid Lock control TLV */
1039 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
1040 bytes_count = T1T_DEFAULT_TLV_LEN;
1041 }
1042 else if ( ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
1043 ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0)) )
1044 {
1045 found = TRUE;
1046 }
1047 else
1048 {
1049 failed = TRUE;
1050 }
1051 break;
1052
1053 case TAG_NDEF_TLV:
1054 case TAG_PROPRIETARY_TLV:
1055 /* The first length byte */
1056 bytes_count = (UINT8) p_readbytes[offset];
1057 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1;
1058 break;
1059 }
1060 offset++;
1061 break;
1062
1063 case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1:
1064 bytes_count = (bytes_count << 8) + p_readbytes[offset];
1065 if (found_tlv == TAG_NDEF_TLV)
1066 {
1067 p_t1t->ndef_msg_len = bytes_count;
1068 }
1069 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
1070 offset++;
1071 break;
1072
1073 case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
1074 switch (found_tlv)
1075 {
1076 case TAG_NDEF_TLV:
1077 if ((bytes_count == p_t1t->ndef_msg_len) && (p_t1t->tlv_detect == TAG_NDEF_TLV))
1078 {
1079 /* The first byte offset after length field */
1080 p_t1t->ndef_msg_offset = offset + p_t1t->work_offset;
1081 }
1082 if (bytes_count > 0)
1083 bytes_count--;
1084
1085 if (p_t1t->tlv_detect == TAG_NDEF_TLV)
1086 {
1087 if (p_t1t->ndef_msg_len > 0)
1088 {
1089 rw_t1t_update_tag_state ();
1090 }
1091 else
1092 {
1093 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED_NDEF;
1094 }
1095 found = TRUE;
1096 }
1097 else if (bytes_count == 0)
1098 {
1099 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1100 }
1101 break;
1102
1103 case TAG_LOCK_CTRL_TLV:
1104 bytes_count--;
1105 if ( (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
1106 ||(p_t1t->tlv_detect == TAG_NDEF_TLV) )
1107 {
1108 tlv_value[2 - bytes_count] = p_readbytes[offset];
1109 if (bytes_count == 0)
1110 {
1111 if (p_t1t->num_lock_tlvs < RW_T1T_MAX_LOCK_TLVS)
1112 {
1113 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset = (tlv_value[0] >> 4) & 0x0F;
1114 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F);
1115 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset += tlv_value[0] & 0x0F;
1116 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].bytes_locked_per_bit = (UINT8) tags_pow (2, ((tlv_value[2] & 0xF0) >> 4));
1117 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].num_bits = tlv_value[1];
1118 count = tlv_value[1] / 8 + ((tlv_value[1] % 8 != 0)? 1:0);
1119 xx = 0;
1120 while (xx < count)
1121 {
1122 if (p_t1t->num_lockbytes < RW_T1T_MAX_LOCK_BYTES)
1123 {
1124 p_t1t->lockbyte[p_t1t->num_lockbytes].tlv_index = p_t1t->num_lock_tlvs;
1125 p_t1t->lockbyte[p_t1t->num_lockbytes].byte_index = xx;
1126 p_t1t->lockbyte[p_t1t->num_lockbytes].b_lock_read = FALSE;
1127 p_t1t->num_lockbytes++;
1128 }
1129 else
1130 RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock bytes=0x%02X", RW_T1T_MAX_LOCK_BYTES);
1131 xx++;
1132 }
1133 p_t1t->num_lock_tlvs++;
1134 rw_t1t_update_attributes ();
1135 }
1136 else
1137 RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock tlvs=0x%02X", RW_T1T_MAX_LOCK_TLVS);
1138
1139 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1140 }
1141 }
1142 else
1143 {
1144 if (bytes_count == 0)
1145 {
1146 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1147 }
1148 }
1149 break;
1150
1151 case TAG_MEM_CTRL_TLV:
1152 bytes_count--;
1153 if ( (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
1154 ||(p_t1t->tlv_detect == TAG_NDEF_TLV) )
1155 {
1156 tlv_value[2 - bytes_count] = p_readbytes[offset];
1157 if (bytes_count == 0)
1158 {
1159 if (p_t1t->num_mem_tlvs >= RW_T1T_MAX_MEM_TLVS)
1160 {
1161 RW_TRACE_ERROR0 ("rw_t1t_handle_tlv_detect_rsp - Maximum buffer allocated for Memory tlv has reached");
1162 failed = TRUE;
1163 }
1164 else
1165 {
1166 /* Extract dynamic reserved bytes */
1167 p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset = (tlv_value[0] >> 4) & 0x0F;
1168 p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F);
1169 p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset += tlv_value[0] & 0x0F;
1170 p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes = tlv_value[1];
1171 p_t1t->num_mem_tlvs++;
1172 rw_t1t_update_attributes ();
1173 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1174 }
1175 }
1176 }
1177 else
1178 {
1179 if (bytes_count == 0)
1180 {
1181 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1182 }
1183 }
1184 break;
1185
1186 case TAG_PROPRIETARY_TLV:
1187 bytes_count--;
1188 if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
1189 found = TRUE;
1190 else
1191 {
1192 if (bytes_count == 0)
1193 {
1194 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1195 }
1196 }
1197 break;
1198 }
1199 offset++;
1200 break;
1201 }
1202 }
1203
1204 p_t1t->work_offset += bytes_read;
1205
1206 /* NDEF/Lock/Mem TLV to be found in segment 0, if not assume detection failed */
1207 if (!found && !failed)
1208 {
1209 if ( ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
1210 ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0)) )
1211 {
1212 found = TRUE;
1213 }
1214 else
1215 {
1216 if (p_t1t->tlv_detect == TAG_NDEF_TLV)
1217 {
1218 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
1219 }
1220 failed = TRUE;
1221 }
1222 }
1223
1224
1225 status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1226 return status;
1227 }
1228
1229 /*******************************************************************************
1230 **
1231 ** Function rw_t1t_handle_ndef_rall_rsp
1232 **
1233 ** Description Handle response to RALL command sent while reading an
1234 ** NDEF message
1235 **
1236 ** Returns NFC_STATUS_CONTINUE, if NDEF read operation is not complete
1237 ** NFC_STATUS_OK, if NDEF read is successfull
1238 ** NFC_STATUS_FAILED,if NDEF read failed
1239 **
1240 *******************************************************************************/
rw_t1t_handle_ndef_rall_rsp(void)1241 static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp (void)
1242 {
1243 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1244 tNFC_STATUS status = NFC_STATUS_CONTINUE;
1245 UINT8 count;
1246 UINT8 adds;
1247
1248 count = (UINT8) p_t1t->ndef_msg_offset;
1249 p_t1t->work_offset = 0;
1250 p_t1t->segment = 0;
1251
1252 while (count < T1T_STATIC_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
1253 {
1254 if (rw_t1t_is_lock_reserved_otp_byte (count) == FALSE)
1255 {
1256 p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_t1t->mem[count];
1257 p_t1t->work_offset++;
1258 }
1259 count++;
1260 }
1261 if (p_t1t->work_offset != p_t1t->ndef_msg_len)
1262 {
1263 if ((p_t1t->hr[0] & 0x0F) != 1)
1264 {
1265 if (p_t1t->work_offset == 0)
1266 return NFC_STATUS_FAILED;
1267
1268 else
1269 {
1270 p_t1t->block_read = T1T_STATIC_BLOCKS + 1;
1271 p_t1t->segment++;
1272 }
1273 if (p_t1t->ndef_msg_len - p_t1t->work_offset <= 8)
1274 {
1275 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK)
1276 {
1277 p_t1t->tlv_detect = TAG_NDEF_TLV;
1278 p_t1t->state = RW_T1T_STATE_READ_NDEF;
1279 status = NFC_STATUS_CONTINUE;
1280 }
1281 }
1282 else
1283 {
1284 /* send RSEG command */
1285 RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
1286 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
1287 {
1288 p_t1t->state = RW_T1T_STATE_READ_NDEF;
1289 status = NFC_STATUS_CONTINUE;
1290 }
1291 }
1292 }
1293 else
1294 {
1295 RW_TRACE_ERROR1 ("RW_T1tReadNDef - Invalid NDEF len: %u or NDEF corrupted", p_t1t->ndef_msg_len);
1296 status = NFC_STATUS_FAILED;
1297 }
1298 }
1299 else
1300 {
1301 status = NFC_STATUS_OK;
1302 }
1303 return status;
1304 }
1305
1306 /*******************************************************************************
1307 **
1308 ** Function rw_t1t_handle_ndef_read_rsp
1309 **
1310 ** Description Handle response to commands sent while reading an
1311 ** NDEF message
1312 **
1313 ** Returns NFC_STATUS_CONTINUE, if tlv read is not yet complete
1314 ** NFC_STATUS_OK, if tlv read is complete & success
1315 ** NFC_STATUS_FAILED,if tlv read failed
1316 **
1317 *******************************************************************************/
rw_t1t_handle_ndef_read_rsp(UINT8 * p_data)1318 static tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data)
1319 {
1320 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1321 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1322 UINT8 index;
1323 UINT8 adds;
1324 tT1T_CMD_RSP_INFO *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
1325
1326 /* The Response received could be for Read8 or Read Segment command */
1327 switch(p_cmd_rsp_info->opcode)
1328 {
1329 case T1T_CMD_READ8:
1330 if (p_t1t->work_offset == 0)
1331 {
1332 index = p_t1t->ndef_msg_offset % T1T_BLOCK_SIZE;
1333 }
1334 else
1335 {
1336 index = 0;
1337 }
1338 p_t1t->segment = (p_t1t->block_read * T1T_BLOCK_SIZE)/T1T_SEGMENT_SIZE;
1339 while (index < T1T_BLOCK_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
1340 {
1341 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((p_t1t->block_read * T1T_BLOCK_SIZE) + index)) == FALSE)
1342 {
1343 p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index];
1344 p_t1t->work_offset++;
1345 }
1346 index++;
1347 }
1348 break;
1349
1350 case T1T_CMD_RSEG:
1351 if (p_t1t->work_offset == 0)
1352 {
1353 index = p_t1t->ndef_msg_offset % T1T_SEGMENT_SIZE;
1354 }
1355 else
1356 {
1357 index = 0;
1358 }
1359 p_t1t->block_read = ((p_t1t->segment + 1) * T1T_BLOCKS_PER_SEGMENT) - 1;
1360
1361 while (index < T1T_SEGMENT_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
1362 {
1363 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (index)) == FALSE)
1364 {
1365 p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index];
1366 p_t1t->work_offset++;
1367 }
1368 index++;
1369 }
1370 break;
1371
1372 default:
1373 break;
1374 }
1375 if (p_t1t->work_offset < p_t1t->ndef_msg_len)
1376 {
1377 if ((p_t1t->hr[0] & 0x0F) != 1)
1378 {
1379 if ((p_t1t->ndef_msg_len - p_t1t->work_offset) <= T1T_BLOCK_SIZE)
1380 {
1381 p_t1t->block_read++;
1382 if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, (UINT8) (p_t1t->block_read), NULL)) == NFC_STATUS_OK)
1383 {
1384 ndef_status = NFC_STATUS_CONTINUE;
1385 }
1386 }
1387 else
1388 {
1389 p_t1t->segment++;
1390 /* send RSEG command */
1391 RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
1392 if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
1393 {
1394 ndef_status = NFC_STATUS_CONTINUE;
1395 }
1396 }
1397 }
1398 }
1399 else
1400 {
1401 ndef_status = NFC_STATUS_OK;
1402 }
1403 return ndef_status;
1404 }
1405
1406 /*******************************************************************************
1407 **
1408 ** Function rw_t1t_next_ndef_write_block
1409 **
1410 ** Description This function prepare and writes ndef blocks
1411 **
1412 ** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
1413 ** NFC_STATUS_OK, if tlv write is complete & success
1414 ** NFC_STATUS_FAILED,if tlv write failed
1415 **
1416 *******************************************************************************/
rw_t1t_next_ndef_write_block(void)1417 static tNFC_STATUS rw_t1t_next_ndef_write_block (void)
1418 {
1419 BOOLEAN b_block_write_cmd = FALSE;
1420 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1421 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1422 UINT8 write_block[8];
1423 UINT8 block;
1424 UINT8 index;
1425 UINT8 new_lengthfield_len;
1426 UINT8 length_field[3];
1427 UINT16 initial_offset;
1428 UINT8 count;
1429 /* Write NDEF Message */
1430 new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
1431
1432 /* Identify the command to use for NDEF write operation */
1433 if ((p_t1t->hr[0] & 0x0F) != 1)
1434 {
1435 /* Dynamic memory structure */
1436 b_block_write_cmd = FALSE;
1437 block = p_t1t->ndef_block_written + 1;
1438 p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
1439
1440 count = 0;
1441 while (block <= p_t1t->mem[T1T_CC_TMS_BYTE])
1442 {
1443 index = 0;
1444 if (block == p_t1t->num_ndef_finalblock)
1445 {
1446 /* T1T_CMD_WRITE_E8 Command */
1447 b_block_write_cmd = TRUE;
1448 break;
1449 }
1450 while (index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + new_lengthfield_len))
1451 {
1452 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + index)) == FALSE)
1453 {
1454 count++;
1455 }
1456 index++;
1457 }
1458 if (count == T1T_BLOCK_SIZE)
1459 {
1460 /* T1T_CMD_WRITE_E8 Command */
1461 b_block_write_cmd = TRUE;
1462 break;
1463 }
1464 else if (count == 0)
1465 {
1466 index = 0;
1467 block++;
1468 if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE)
1469 {
1470 p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
1471 }
1472 }
1473 else
1474 {
1475 /* T1T_CMD_WRITE_E Command */
1476 b_block_write_cmd = FALSE;
1477 break;
1478 }
1479 }
1480 }
1481 else
1482 {
1483 /* Static memory structure */
1484 block = p_t1t->ndef_block_written;
1485 b_block_write_cmd = FALSE;
1486 }
1487
1488 new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
1489 if (new_lengthfield_len == 3)
1490 {
1491 length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
1492 length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8);
1493 length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len);
1494 }
1495 else
1496 {
1497 length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len);
1498 }
1499
1500 if (b_block_write_cmd)
1501 {
1502 /* Dynamic memory structure */
1503 index = 0;
1504 p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
1505
1506 initial_offset = p_t1t->work_offset;
1507 block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, FALSE, block, new_lengthfield_len);
1508 if (p_t1t->work_offset == initial_offset)
1509 {
1510 ndef_status = NFC_STATUS_FAILED;
1511 }
1512 else
1513 {
1514 /* Send WRITE_E8 command */
1515 ndef_status = rw_t1t_send_ndef_block (write_block, block);
1516 }
1517 }
1518 else
1519 {
1520 /* Static memory structure */
1521 if (p_t1t->write_byte + 1 >= T1T_BLOCK_SIZE)
1522 {
1523 index = 0;
1524 block++;
1525 }
1526 else
1527 {
1528 index = p_t1t->write_byte + 1;
1529 }
1530 initial_offset = p_t1t->work_offset;
1531 block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len);
1532 if (p_t1t->work_offset == initial_offset)
1533 {
1534 ndef_status = NFC_STATUS_FAILED;
1535 }
1536 else
1537 {
1538 /* send WRITE-E command */
1539 ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len);
1540 }
1541 }
1542 return ndef_status;
1543
1544 }
1545
1546 /*******************************************************************************
1547 **
1548 ** Function rw_t1t_ndef_write_first_block
1549 **
1550 ** Description This function writes ndef first block
1551 **
1552 ** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
1553 ** NFC_STATUS_OK, if tlv write is complete & success
1554 ** NFC_STATUS_FAILED,if tlv write failed
1555 **
1556 *******************************************************************************/
rw_t1t_ndef_write_first_block(void)1557 static tNFC_STATUS rw_t1t_ndef_write_first_block (void)
1558 {
1559 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1560 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1561 UINT8 block;
1562 UINT8 index;
1563 UINT8 new_lengthfield_len;
1564 UINT8 length_field[3];
1565 UINT8 write_block[8];
1566
1567 /* handle positive response to invalidating existing NDEF Message */
1568 p_t1t->work_offset = 0;
1569 new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
1570 if (new_lengthfield_len == 3)
1571 {
1572 length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
1573 length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8);
1574 length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len);
1575 }
1576 else
1577 {
1578 length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len);
1579 }
1580 /* updating ndef_first_block with new ndef message */
1581 memcpy(write_block,p_t1t->ndef_first_block,T1T_BLOCK_SIZE);
1582 index = p_t1t->ndef_header_offset % T1T_BLOCK_SIZE;
1583 block = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
1584 p_t1t->segment = (UINT8) (p_t1t->ndef_header_offset/T1T_SEGMENT_SIZE);
1585
1586 if ((p_t1t->hr[0] & 0x0F) != 1)
1587 {
1588 /* Dynamic Memory structure */
1589 block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, FALSE, block, new_lengthfield_len);
1590
1591 if (p_t1t->work_offset == 0)
1592 {
1593 ndef_status = NFC_STATUS_FAILED;
1594 }
1595 else
1596 {
1597 /* Send WRITE-E8 command based on the prepared write_block */
1598 ndef_status = rw_t1t_send_ndef_block (write_block, block);
1599 }
1600 }
1601 else
1602 {
1603 /* Static Memory structure */
1604 block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len);
1605 if (p_t1t->work_offset == 0)
1606 {
1607 ndef_status = NFC_STATUS_FAILED;
1608 }
1609 else
1610 {
1611 /* send WRITE-E command */
1612 ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len);
1613 }
1614 }
1615
1616 return ndef_status;
1617 }
1618
1619 /*******************************************************************************
1620 **
1621 ** Function rw_t1t_send_ndef_byte
1622 **
1623 ** Description Sends ndef message or length field byte and update
1624 ** status
1625 **
1626 ** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
1627 ** NFC_STATUS_OK, if tlv write is complete & success
1628 ** NFC_STATUS_FAILED,if tlv write failed
1629 **
1630 *******************************************************************************/
rw_t1t_send_ndef_byte(UINT8 data,UINT8 block,UINT8 index,UINT8 msg_len)1631 static tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len)
1632 {
1633 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1634 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1635 UINT8 addr;
1636
1637 /* send WRITE-E command */
1638 RW_T1T_BLD_ADD ((addr), (block), (index));
1639 if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, data))
1640 {
1641 p_t1t->write_byte = index;
1642 p_t1t->ndef_block_written = block;
1643 if (p_t1t->work_offset == p_t1t->new_ndef_msg_len + msg_len)
1644 {
1645 ndef_status = NFC_STATUS_OK;
1646 }
1647 else
1648 {
1649 ndef_status = NFC_STATUS_CONTINUE;
1650 }
1651 }
1652 else
1653 {
1654 ndef_status = NFC_STATUS_FAILED;
1655 }
1656 return ndef_status;
1657 }
1658
1659 /*******************************************************************************
1660 **
1661 ** Function rw_t1t_prepare_ndef_bytes
1662 **
1663 ** Description prepares ndef block to write
1664 **
1665 ** Returns block number where to write
1666 **
1667 *******************************************************************************/
rw_t1t_prepare_ndef_bytes(UINT8 * p_data,UINT8 * p_length_field,UINT8 * p_index,BOOLEAN b_one_byte,UINT8 block,UINT8 lengthfield_len)1668 static UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len)
1669 {
1670 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1671 UINT8 first_block = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
1672 UINT16 initial_offset = p_t1t->work_offset;
1673
1674 while (p_t1t->work_offset == initial_offset && block <= p_t1t->mem[T1T_CC_TMS_BYTE])
1675 {
1676 if ( (block == p_t1t->num_ndef_finalblock)
1677 &&(block != first_block) )
1678 {
1679 memcpy (p_data,p_t1t->ndef_final_block,T1T_BLOCK_SIZE);
1680 }
1681 /* Update length field */
1682 while ( (*p_index < T1T_BLOCK_SIZE)
1683 &&(p_t1t->work_offset < lengthfield_len) )
1684 {
1685 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE)
1686 {
1687 p_data[*p_index] = p_length_field[p_t1t->work_offset];
1688 p_t1t->work_offset++;
1689 if (b_one_byte)
1690 return block;
1691 }
1692 (*p_index)++;
1693 if (p_t1t->work_offset == lengthfield_len)
1694 {
1695 break;
1696 }
1697 }
1698 /* Update ndef message field */
1699 while (*p_index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + lengthfield_len))
1700 {
1701 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE)
1702 {
1703 p_data[*p_index] = p_t1t->p_ndef_buffer[p_t1t->work_offset - lengthfield_len];
1704 p_t1t->work_offset++;
1705 if (b_one_byte)
1706 return block;
1707 }
1708 (*p_index)++;
1709 }
1710 if (p_t1t->work_offset == initial_offset)
1711 {
1712 *p_index = 0;
1713 block++;
1714 if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE)
1715 {
1716 p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
1717 }
1718 }
1719 }
1720 return block;
1721 }
1722
1723 /*******************************************************************************
1724 **
1725 ** Function rw_t1t_send_ndef_block
1726 **
1727 ** Description Sends ndef block and update status
1728 **
1729 ** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
1730 ** NFC_STATUS_OK, if tlv write is complete & success
1731 ** NFC_STATUS_FAILED,if tlv write failed
1732 **
1733 *******************************************************************************/
rw_t1t_send_ndef_block(UINT8 * p_data,UINT8 block)1734 static tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block)
1735 {
1736 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1737 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1738
1739 if (NFC_STATUS_OK == rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, block, p_data))
1740 {
1741 p_t1t->ndef_block_written = block;
1742 if (p_t1t->ndef_block_written == p_t1t->num_ndef_finalblock)
1743 {
1744 ndef_status = NFC_STATUS_OK;
1745 }
1746 else
1747 {
1748 ndef_status = NFC_STATUS_CONTINUE;
1749 }
1750 }
1751 else
1752 {
1753 ndef_status = NFC_STATUS_FAILED;
1754 }
1755 return ndef_status;
1756 }
1757
1758 /*******************************************************************************
1759 **
1760 ** Function rw_t1t_get_ndef_flags
1761 **
1762 ** Description Prepare NDEF Flags
1763 **
1764 ** Returns NDEF Flag value
1765 **
1766 *******************************************************************************/
rw_t1t_get_ndef_flags(void)1767 static UINT8 rw_t1t_get_ndef_flags (void)
1768 {
1769 UINT8 flags = 0;
1770 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1771
1772 if ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
1773 flags |= RW_NDEF_FL_SUPPORTED;
1774
1775 if (t1t_tag_init_data (p_t1t->hr[0]) != NULL)
1776 flags |= RW_NDEF_FL_FORMATABLE;
1777
1778 if ((p_t1t->mem[T1T_CC_RWA_BYTE] & 0x0F) == T1T_CC_RWA_RO)
1779 flags |=RW_NDEF_FL_READ_ONLY;
1780
1781 return flags;
1782 }
1783
1784 /*******************************************************************************
1785 **
1786 ** Function rw_t1t_get_ndef_max_size
1787 **
1788 ** Description Calculate maximum size of NDEF message that can be written
1789 ** on to the tag
1790 **
1791 ** Returns Maximum size of NDEF Message
1792 **
1793 *******************************************************************************/
rw_t1t_get_ndef_max_size(void)1794 static UINT16 rw_t1t_get_ndef_max_size (void)
1795 {
1796 UINT16 offset;
1797 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1798 UINT16 tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] +1)* T1T_BLOCK_SIZE;
1799 const tT1T_INIT_TAG *p_ret;
1800 UINT8 init_segment = p_t1t->segment;
1801
1802 p_t1t->max_ndef_msg_len = 0;
1803 offset = p_t1t->ndef_msg_offset;
1804 p_t1t->segment = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE);
1805
1806 if ( (tag_size < T1T_STATIC_SIZE)
1807 ||(tag_size > (T1T_SEGMENT_SIZE * T1T_MAX_SEGMENTS))
1808 ||((p_t1t->mem[T1T_CC_NMN_BYTE] != T1T_CC_NMN) && (p_t1t->mem[T1T_CC_NMN_BYTE] != 0)) )
1809 {
1810 /* Tag not formated, determine maximum NDEF size from HR */
1811 if ( ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
1812 &&((p_ret = t1t_tag_init_data (p_t1t->hr[0])) != NULL) )
1813 {
1814 p_t1t->max_ndef_msg_len = ((p_ret->tms +1)* T1T_BLOCK_SIZE) - T1T_OTP_LOCK_RES_BYTES - T1T_UID_LEN - T1T_ADD_LEN - T1T_CC_LEN - T1T_TLV_TYPE_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN;
1815 if (p_ret->b_dynamic)
1816 {
1817 p_t1t->max_ndef_msg_len -= (T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN + T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN);
1818 p_t1t->max_ndef_msg_len -= T1T_DYNAMIC_LOCK_BYTES;
1819 }
1820 offset = tag_size;
1821 }
1822 else
1823 {
1824 p_t1t->segment = init_segment;
1825 return p_t1t->max_ndef_msg_len;
1826 }
1827 }
1828
1829 /* Starting from NDEF Message offset find the first locked data byte */
1830 while (offset < tag_size)
1831 {
1832 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == FALSE)
1833 {
1834 if (rw_t1t_is_read_only_byte ((UINT16) offset) == TRUE)
1835 break;
1836 p_t1t->max_ndef_msg_len++;
1837 }
1838 offset++;
1839 if (offset % T1T_SEGMENT_SIZE == 0)
1840 {
1841 p_t1t->segment = (UINT8) (offset / T1T_SEGMENT_SIZE);
1842 }
1843 }
1844 /* NDEF Length field length changes based on NDEF size */
1845 if ( (p_t1t->max_ndef_msg_len >= T1T_LONG_NDEF_LEN_FIELD_BYTE0)
1846 &&((p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset) == T1T_SHORT_NDEF_LEN_FIELD_LEN) )
1847 {
1848 p_t1t->max_ndef_msg_len -= (p_t1t->max_ndef_msg_len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)? 1 : (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
1849 }
1850
1851 p_t1t->segment = init_segment;
1852 return p_t1t->max_ndef_msg_len;
1853 }
1854
1855 /*******************************************************************************
1856 **
1857 ** Function rw_t1t_handle_ndef_write_rsp
1858 **
1859 ** Description Handle response to commands sent while writing an
1860 ** NDEF message
1861 **
1862 ** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
1863 ** NFC_STATUS_OK, if tlv write is complete & success
1864 ** NFC_STATUS_FAILED,if tlv write failed
1865 **
1866 *******************************************************************************/
rw_t1t_handle_ndef_write_rsp(UINT8 * p_data)1867 static tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data)
1868 {
1869 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1870 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1871 UINT8 addr;
1872
1873 switch (p_t1t->substate)
1874 {
1875 case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
1876 /* Backup ndef_final_block */
1877 memcpy (p_t1t->ndef_final_block, p_data, T1T_BLOCK_SIZE);
1878 /* Invalidate existing NDEF Message */
1879 RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
1880 if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0))
1881 {
1882 ndef_status = NFC_STATUS_CONTINUE;
1883 p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
1884 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
1885 }
1886 else
1887 {
1888 ndef_status = NFC_STATUS_FAILED;
1889 }
1890 break;
1891
1892 case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
1893 ndef_status = rw_t1t_ndef_write_first_block ();
1894 break;
1895
1896 case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
1897 ndef_status = rw_t1t_next_ndef_write_block ();
1898 break;
1899
1900 case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
1901 /* Validate new NDEF Message */
1902 RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
1903 if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, T1T_CC_NMN))
1904 {
1905 ndef_status = NFC_STATUS_OK;
1906 }
1907 else
1908 {
1909 ndef_status = NFC_STATUS_FAILED;
1910 }
1911 break;
1912 default:
1913 break;
1914 }
1915
1916 return ndef_status;
1917 }
1918
1919 /*******************************************************************************
1920 **
1921 ** Function rw_t1t_update_attributes
1922 **
1923 ** Description This function will prepare attributes for the current
1924 ** segment. Every bit in the attribute refers to one byte of
1925 ** tag content.The bit corresponding to a tag byte will be set
1926 ** to '1' when the Tag byte is read only,otherwise will be set
1927 ** to '0'
1928 **
1929 ** Returns None
1930 **
1931 *******************************************************************************/
rw_t1t_update_attributes(void)1932 static void rw_t1t_update_attributes (void)
1933 {
1934 UINT8 count = 0;
1935 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
1936 UINT16 lower_offset;
1937 UINT16 upper_offset;
1938 UINT8 num_bytes;
1939 UINT16 offset;
1940 UINT8 bits_per_byte = 8;
1941
1942 count = 0;
1943 while (count < T1T_BLOCKS_PER_SEGMENT)
1944 {
1945 p_t1t->attr[count] = 0x00;
1946 count++;
1947 }
1948
1949 lower_offset = p_t1t->segment * T1T_SEGMENT_SIZE;
1950 upper_offset = (p_t1t->segment + 1)* T1T_SEGMENT_SIZE;
1951
1952 if (p_t1t->segment == 0)
1953 {
1954 /* UID/Lock/Reserved/OTP bytes */
1955 p_t1t->attr[0x00] = 0xFF; /* Uid bytes */
1956 p_t1t->attr[0x0D] = 0xFF; /* Reserved bytes */
1957 p_t1t->attr[0x0E] = 0xFF; /* lock/otp bytes */
1958 p_t1t->attr[0x0F] = 0xFF; /* lock/otp bytes */
1959 }
1960
1961 /* update attr based on lock control and mem control tlvs */
1962 count = 0;
1963 while (count < p_t1t->num_lockbytes)
1964 {
1965 offset = p_t1t->lock_tlv[p_t1t->lockbyte[count].tlv_index].offset + p_t1t->lockbyte[count].byte_index;
1966 if (offset >= lower_offset && offset < upper_offset)
1967 {
1968 /* Set the corresponding bit in attr to indicate - lock byte */
1969 p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
1970 }
1971 count++;
1972 }
1973 count = 0;
1974 while (count < p_t1t->num_mem_tlvs)
1975 {
1976 num_bytes = 0;
1977 while (num_bytes < p_t1t->mem_tlv[count].num_bytes)
1978 {
1979 offset = p_t1t->mem_tlv[count].offset + num_bytes;
1980 if (offset >= lower_offset && offset < upper_offset)
1981 {
1982 /* Set the corresponding bit in attr to indicate - reserved byte */
1983 p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
1984 }
1985 num_bytes++;
1986 }
1987 count++;
1988 }
1989 }
1990
1991 /*******************************************************************************
1992 **
1993 ** Function rw_t1t_get_lock_bits_for_segment
1994 **
1995 ** Description This function will identify the index of the dynamic lock
1996 ** byte that covers the current segment
1997 **
1998 ** Parameters: segment, segment number
1999 ** p_start_byte, pointer to hold the first lock byte index
2000 ** p_start_bit, pointer to hold the first lock bit index
2001 ** p_end_byte, pointer to hold the last lock byte index
2002 **
2003 ** Returns Total lock bits that covers the specified segment
2004 **
2005 *******************************************************************************/
rw_t1t_get_lock_bits_for_segment(UINT8 segment,UINT8 * p_start_byte,UINT8 * p_start_bit,UINT8 * p_end_byte)2006 static UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte)
2007 {
2008 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
2009 UINT16 byte_count = T1T_SEGMENT_SIZE;
2010 UINT8 total_bits = 0;
2011 UINT8 num_dynamic_locks = 0;
2012 UINT8 bit_count = 0;
2013 UINT16 tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] +1) * T1T_BLOCK_SIZE;
2014 UINT16 lower_offset;
2015 UINT16 upper_offset;
2016 BOOLEAN b_all_bits_are_locks = TRUE;
2017 UINT8 bytes_locked_per_bit;
2018 UINT8 num_bits;
2019
2020 upper_offset = (segment + 1) * T1T_SEGMENT_SIZE;
2021
2022 if (upper_offset > tag_size)
2023 upper_offset = tag_size;
2024
2025 lower_offset = segment * T1T_SEGMENT_SIZE;
2026 *p_start_byte = num_dynamic_locks;
2027 *p_start_bit = 0;
2028
2029 while ( (byte_count <= lower_offset)
2030 &&(num_dynamic_locks < p_t1t->num_lockbytes) )
2031 {
2032 bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
2033 /* Number of bits in the current lock byte */
2034 b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
2035 num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
2036
2037 /* Skip lock bits that covers all previous segments */
2038 if (bytes_locked_per_bit * num_bits + byte_count <= lower_offset)
2039 {
2040 byte_count += bytes_locked_per_bit * num_bits;
2041 num_dynamic_locks++;
2042 }
2043 else
2044 {
2045 /* The first lock bit that covers this segment is present in this segment */
2046 bit_count = 0;
2047 while (bit_count < num_bits)
2048 {
2049 byte_count += bytes_locked_per_bit;
2050 if (byte_count > lower_offset)
2051 {
2052 *p_start_byte = num_dynamic_locks;
2053 *p_end_byte = num_dynamic_locks;
2054 *p_start_bit = bit_count;
2055 bit_count++;
2056 total_bits = 1;
2057 break;
2058 }
2059 bit_count++;
2060 }
2061 }
2062 }
2063 if (num_dynamic_locks == p_t1t->num_lockbytes)
2064 {
2065 return 0;
2066 }
2067 while ( (byte_count < upper_offset)
2068 &&(num_dynamic_locks < p_t1t->num_lockbytes) )
2069 {
2070 bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
2071
2072 /* Number of bits in the current lock byte */
2073 b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
2074 num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
2075
2076 /* Collect all lock bits that covers the current segment */
2077 if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count < upper_offset)
2078 {
2079 byte_count += bytes_locked_per_bit * (num_bits - bit_count);
2080 total_bits += num_bits - bit_count;
2081 bit_count = 0;
2082 *p_end_byte = num_dynamic_locks;
2083 num_dynamic_locks++;
2084 }
2085 else
2086 {
2087 /* The last lock byte that covers the current segment */
2088 bit_count = 0;
2089 while (bit_count < num_bits)
2090 {
2091 byte_count += bytes_locked_per_bit;
2092 if (byte_count >= upper_offset)
2093 {
2094 *p_end_byte = num_dynamic_locks;
2095 total_bits += (bit_count + 1);
2096 break;
2097 }
2098 bit_count++;
2099 }
2100 }
2101 }
2102 return total_bits;
2103 }
2104
2105 /*******************************************************************************
2106 **
2107 ** Function rw_t1t_update_lock_attributes
2108 **
2109 ** Description This function will check if the tag index passed as
2110 ** argument is a locked byte and return
2111 ** TRUE or FALSE
2112 **
2113 ** Parameters: index, the index of the byte in the tag
2114 **
2115 **
2116 ** Returns TRUE, if the specified index in the tag is a locked or
2117 ** reserved or otp byte
2118 ** FALSE, otherwise
2119 **
2120 *******************************************************************************/
rw_t1t_update_lock_attributes(void)2121 static void rw_t1t_update_lock_attributes (void)
2122 {
2123 UINT8 xx = 0;
2124 UINT8 bytes_locked_per_lock_bit;
2125 UINT8 num_static_lock_bytes = 0;
2126 UINT8 num_dynamic_lock_bytes = 0;
2127 UINT8 bits_covered = 0;
2128 UINT8 bytes_covered = 0;
2129 UINT8 block_count = 0;
2130 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
2131 UINT8 start_lock_byte;
2132 UINT8 start_lock_bit;
2133 UINT8 end_lock_byte;
2134 UINT8 num_lock_bits;
2135 UINT8 total_bits;
2136
2137
2138 block_count = 0;
2139 while (block_count < T1T_BLOCKS_PER_SEGMENT)
2140 {
2141 p_t1t->lock_attr[block_count] = 0x00;
2142 block_count++;
2143 }
2144
2145 /* update lock_attr based on static lock bytes */
2146 if (p_t1t->segment == 0)
2147 {
2148 xx = 0;
2149 num_static_lock_bytes = 0;
2150 block_count = 0;
2151 num_lock_bits = 8;
2152
2153 while (num_static_lock_bytes < T1T_NUM_STATIC_LOCK_BYTES)
2154 {
2155 /* Update lock attribute based on 2 static locks */
2156 while (xx < num_lock_bits)
2157 {
2158 p_t1t->lock_attr[block_count] = 0x00;
2159
2160 if (p_t1t->mem[T1T_LOCK_0_OFFSET + num_static_lock_bytes] & rw_t1t_mask_bits[xx++])
2161 {
2162 /* If the bit is set then 1 block is locked */
2163 p_t1t->lock_attr[block_count] = 0xFF;
2164 }
2165
2166 block_count++;
2167 }
2168 num_static_lock_bytes++;
2169 xx = 0;
2170 }
2171 /* Locked bytes */
2172 p_t1t->lock_attr[0x00] = 0xFF;
2173 p_t1t->lock_attr[0x0D] = 0xFF;
2174 }
2175 else
2176 {
2177 /* update lock_attr based on segment and using dynamic lock bytes */
2178 if ((total_bits = rw_t1t_get_lock_bits_for_segment (p_t1t->segment,&start_lock_byte, &start_lock_bit,&end_lock_byte)) != 0)
2179 {
2180 xx = start_lock_bit;
2181 num_dynamic_lock_bytes = start_lock_byte;
2182 bits_covered = 0;
2183 bytes_covered = 0;
2184 block_count = 0;
2185 num_lock_bits = 8;
2186
2187 p_t1t->lock_attr[block_count] = 0;
2188
2189 while (num_dynamic_lock_bytes <= end_lock_byte)
2190 {
2191 bytes_locked_per_lock_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_lock_bytes].tlv_index].bytes_locked_per_bit;
2192 if (num_dynamic_lock_bytes == end_lock_byte)
2193 {
2194 num_lock_bits = (total_bits % 8 == 0)? 8:total_bits % 8;
2195 }
2196 while (xx < num_lock_bits)
2197 {
2198 bytes_covered = 0;
2199 while (bytes_covered < bytes_locked_per_lock_bit)
2200 {
2201 /* Set/clear lock_attr byte bits based on whether a particular lock bit is set or not
2202 * each bit in lock_attr represents one byte in Tag read only attribute */
2203 if (p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte & rw_t1t_mask_bits[xx])
2204 {
2205 p_t1t->lock_attr[block_count] |= 0x01 << bits_covered;
2206 }
2207 bytes_covered++;
2208 bits_covered++;
2209 if (bits_covered == 8)
2210 {
2211 bits_covered = 0;
2212 block_count++;
2213 if (block_count < T1T_BLOCKS_PER_SEGMENT)
2214 p_t1t->lock_attr[block_count] = 0;
2215 }
2216 }
2217 xx++;
2218 }
2219 num_dynamic_lock_bytes++;
2220 xx = 0;
2221 }
2222 }
2223 }
2224 }
2225
2226 /*******************************************************************************
2227 **
2228 ** Function rw_t1t_is_lock_reserved_otp_byte
2229 **
2230 ** Description This function will check if the tag index passed as
2231 ** argument is a lock or reserved or otp byte
2232 **
2233 ** Parameters: index, the index of the byte in the tag's current segment
2234 **
2235 **
2236 ** Returns TRUE, if the specified index in the tag is a locked or
2237 ** reserved or otp byte
2238 ** FALSE, otherwise
2239 **
2240 *******************************************************************************/
rw_t1t_is_lock_reserved_otp_byte(UINT16 index)2241 static BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index)
2242 {
2243 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
2244
2245 if (p_t1t->attr_seg != p_t1t->segment)
2246 {
2247 /* Update p_t1t->attr to reflect the current segment */
2248 rw_t1t_update_attributes ();
2249 p_t1t->attr_seg = p_t1t->segment;
2250 }
2251 index = index % T1T_SEGMENT_SIZE;
2252
2253 /* Every bit in p_t1t->attr indicates one specific byte of the tag is either a lock/reserved/otp byte or not
2254 * So, each array element in p_t1t->attr covers one block in the tag as T1 block size and array element size is 8
2255 * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
2256 * p_t1t->attr[block] is set or not. If the bit is set then it is a lock/reserved/otp byte, otherwise not */
2257
2258 return ((p_t1t->attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
2259 }
2260
2261 /*******************************************************************************
2262 **
2263 ** Function rw_t1t_is_read_only_byte
2264 **
2265 ** Description This function will check if the tag index passed as
2266 ** argument is a read only byte
2267 **
2268 ** Parameters: index, the index of the byte in the tag's current segment
2269 **
2270 **
2271 ** Returns TRUE, if the specified index in the tag is a locked or
2272 ** reserved or otp byte
2273 ** FALSE, otherwise
2274 **
2275 *******************************************************************************/
rw_t1t_is_read_only_byte(UINT16 index)2276 static BOOLEAN rw_t1t_is_read_only_byte (UINT16 index)
2277 {
2278 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
2279
2280 if (p_t1t->lock_attr_seg != p_t1t->segment)
2281 {
2282 /* Update p_t1t->lock_attr to reflect the current segment */
2283 rw_t1t_update_lock_attributes ();
2284 p_t1t->lock_attr_seg = p_t1t->segment;
2285 }
2286
2287 index = index % T1T_SEGMENT_SIZE;
2288 /* Every bit in p_t1t->lock_attr indicates one specific byte of the tag is a read only byte or read write byte
2289 * So, each array element in p_t1t->lock_attr covers one block in the tag as T1 block size and array element size is 8
2290 * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
2291 * p_t1t->lock_attr[block] is set or not. If the bit is set then it is a read only byte, otherwise read write byte */
2292
2293 return ((p_t1t->lock_attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
2294 }
2295
2296 /*****************************************************************************
2297 **
2298 ** Function RW_T1tFormatNDef
2299 **
2300 ** Description
2301 ** Format Tag content
2302 **
2303 ** Returns
2304 ** NFC_STATUS_OK, Command sent to format Tag
2305 ** NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag
2306 ** NFC_STATUS_FAILED: other error
2307 **
2308 *****************************************************************************/
RW_T1tFormatNDef(void)2309 tNFC_STATUS RW_T1tFormatNDef (void)
2310 {
2311 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
2312 tNFC_STATUS status = NFC_STATUS_FAILED;
2313 const tT1T_INIT_TAG *p_ret;
2314 UINT8 addr;
2315 UINT8 *p;
2316
2317 if (p_t1t->state != RW_T1T_STATE_IDLE)
2318 {
2319 RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Tag not initialized/ Busy! State: %u", p_t1t->state);
2320 return (NFC_STATUS_FAILED);
2321 }
2322
2323 if ((p_t1t->hr[0] & 0xF0) != T1T_NDEF_SUPPORTED)
2324 {
2325 RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Cannot format tag as NDEF not supported. HR0: %u", p_t1t->hr[0]);
2326 return (NFC_STATUS_REJECTED);
2327 }
2328
2329 if ((p_ret = t1t_tag_init_data (p_t1t->hr[0])) == NULL)
2330 {
2331 RW_TRACE_WARNING2 ("RW_T1tFormatNDef - Invalid HR - HR0: %u, HR1: %u", p_t1t->hr[0], p_t1t->hr[1]);
2332 return (NFC_STATUS_REJECTED);
2333 }
2334
2335 memset (p_t1t->ndef_first_block, 0, T1T_BLOCK_SIZE);
2336 memset (p_t1t->ndef_final_block, 0, T1T_BLOCK_SIZE);
2337 p = p_t1t->ndef_first_block;
2338
2339 /* Prepare Capability Container */
2340 UINT8_TO_BE_STREAM (p, T1T_CC_NMN);
2341 UINT8_TO_BE_STREAM (p, T1T_CC_VNO);
2342 UINT8_TO_BE_STREAM (p, p_ret->tms);
2343 UINT8_TO_BE_STREAM (p, T1T_CC_RWA_RW);
2344 if (p_ret->b_dynamic)
2345 {
2346 /* Prepare Lock and Memory TLV */
2347 UINT8_TO_BE_STREAM (p, TAG_LOCK_CTRL_TLV);
2348 UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN);
2349 UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[0]);
2350 UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[1]);
2351 p = p_t1t->ndef_final_block;
2352 UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[2]);
2353 UINT8_TO_BE_STREAM (p, TAG_MEM_CTRL_TLV);
2354 UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN);
2355 UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[0]);
2356 UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[1]);
2357 UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[2]);
2358 }
2359 /* Prepare NULL NDEF TLV */
2360 UINT8_TO_BE_STREAM (p, TAG_NDEF_TLV);
2361 UINT8_TO_BE_STREAM (p, 0);
2362
2363 if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
2364 {
2365 /* send WRITE-E8 command */
2366 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 1, p_t1t->ndef_first_block)) == NFC_STATUS_OK)
2367 {
2368 p_t1t->state = RW_T1T_STATE_FORMAT_TAG;
2369 p_t1t->b_update = FALSE;
2370 p_t1t->b_rseg = FALSE;
2371 if (p_ret->b_dynamic)
2372 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC;
2373 else
2374 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
2375 }
2376 }
2377 else
2378 {
2379 /* send WRITE-E command */
2380 RW_T1T_BLD_ADD ((addr), 1, 0);
2381
2382 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[0])) == NFC_STATUS_OK)
2383 {
2384 p_t1t->work_offset = 0;
2385 p_t1t->state = RW_T1T_STATE_FORMAT_TAG;
2386 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
2387 p_t1t->b_update = FALSE;
2388 p_t1t->b_rseg = FALSE;
2389 }
2390 }
2391
2392 return status;
2393 }
2394
2395 /*******************************************************************************
2396 **
2397 ** Function RW_T1tLocateTlv
2398 **
2399 ** Description This function is called to find the start of the given TLV
2400 **
2401 ** Parameters: tlv_type, Type of TLV to find
2402 **
2403 ** Returns NCI_STATUS_OK, if detection was started. Otherwise, error status.
2404 **
2405 *******************************************************************************/
RW_T1tLocateTlv(UINT8 tlv_type)2406 tNFC_STATUS RW_T1tLocateTlv (UINT8 tlv_type)
2407 {
2408 tNFC_STATUS status = NFC_STATUS_FAILED;
2409 tRW_T1T_CB *p_t1t= &rw_cb.tcb.t1t;
2410 UINT8 adds;
2411
2412 if (p_t1t->state != RW_T1T_STATE_IDLE)
2413 {
2414 RW_TRACE_WARNING1 ("RW_T1tLocateTlv - Busy - State: %u", p_t1t->state);
2415 return (NFC_STATUS_FAILED);
2416 }
2417 p_t1t->tlv_detect = tlv_type;
2418
2419 if( (p_t1t->tlv_detect == TAG_NDEF_TLV)
2420 &&(((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED) )
2421 {
2422 RW_TRACE_ERROR0 ("RW_T1tLocateTlv - Error: NDEF not supported by the tag");
2423 return (NFC_STATUS_REFUSED);
2424 }
2425
2426 if ( (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
2427 ||(p_t1t->tlv_detect == TAG_NDEF_TLV) )
2428 {
2429 p_t1t->num_mem_tlvs = 0;
2430 }
2431
2432 if ( (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
2433 ||(p_t1t->tlv_detect == TAG_NDEF_TLV) )
2434 {
2435 p_t1t->num_lockbytes = 0;
2436 p_t1t->num_lock_tlvs = 0;
2437 }
2438
2439 /* Start reading memory, looking for the TLV */
2440 p_t1t->segment = 0;
2441 if ((p_t1t->hr[0] & 0x0F) != 1)
2442 {
2443 /* send RSEG command */
2444 RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
2445 status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL);
2446 }
2447 else
2448 {
2449 status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0);
2450 }
2451 if (status == NFC_STATUS_OK)
2452 {
2453 p_t1t->tlv_detect = tlv_type;
2454 p_t1t->work_offset = 0;
2455 p_t1t->state = RW_T1T_STATE_TLV_DETECT;
2456 p_t1t->substate = RW_T1T_SUBSTATE_NONE;
2457 }
2458
2459 return status;
2460 }
2461
2462 /*****************************************************************************
2463 **
2464 ** Function RW_T1tDetectNDef
2465 **
2466 ** Description
2467 ** This function is used to perform NDEF detection on a Type 1 tag, and
2468 ** retrieve the tag's NDEF attribute information (block 0).
2469 **
2470 ** Before using this API, the application must call RW_SelectTagType to
2471 ** indicate that a Type 1 tag has been activated.
2472 **
2473 ** Returns
2474 ** NFC_STATUS_OK: ndef detection procedure started
2475 ** NFC_STATUS_WRONG_PROTOCOL: type 1 tag not activated
2476 ** NFC_STATUS_BUSY: another command is already in progress
2477 ** NFC_STATUS_FAILED: other error
2478 **
2479 *****************************************************************************/
RW_T1tDetectNDef(void)2480 tNFC_STATUS RW_T1tDetectNDef (void)
2481 {
2482 return RW_T1tLocateTlv (TAG_NDEF_TLV);
2483 }
2484
2485 /*******************************************************************************
2486 **
2487 ** Function RW_T1tReadNDef
2488 **
2489 ** Description This function can be called to read the NDEF message on the tag.
2490 **
2491 ** Parameters: p_buffer: The buffer into which to read the NDEF message
2492 ** buf_len: The length of the buffer
2493 **
2494 ** Returns NCI_STATUS_OK, if read was started. Otherwise, error status.
2495 **
2496 *******************************************************************************/
RW_T1tReadNDef(UINT8 * p_buffer,UINT16 buf_len)2497 tNFC_STATUS RW_T1tReadNDef (UINT8 *p_buffer, UINT16 buf_len)
2498 {
2499 tNFC_STATUS status = NFC_STATUS_FAILED;
2500 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
2501 BOOLEAN b_notify;
2502 UINT8 adds;
2503 const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rall = t1t_cmd_to_rsp_info (T1T_CMD_RALL);
2504 const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rseg = t1t_cmd_to_rsp_info (T1T_CMD_RSEG);
2505
2506
2507
2508 if (p_t1t->state != RW_T1T_STATE_IDLE)
2509 {
2510 RW_TRACE_WARNING1 ("RW_T1tReadNDef - Busy - State: %u", p_t1t->state);
2511 return (NFC_STATUS_FAILED);
2512 }
2513
2514 /* Check HR0 if NDEF supported by the tag */
2515 if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)
2516 {
2517 RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF not supported by the tag");
2518 return (NFC_STATUS_REFUSED);
2519 }
2520
2521 if (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF)
2522 {
2523 RW_TRACE_WARNING1 ("RW_T1tReadNDef - NDEF Message length is zero, NDEF Length : %u ", p_t1t->ndef_msg_len);
2524 return (NFC_STATUS_NOT_INITIALIZED);
2525 }
2526
2527 if ( (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE)
2528 &&(p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_ONLY) )
2529 {
2530 RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF detection not performed yet/ Tag is in Initialized state");
2531 return (NFC_STATUS_FAILED);
2532 }
2533
2534 if (buf_len < p_t1t->ndef_msg_len)
2535 {
2536 RW_TRACE_WARNING2 ("RW_T1tReadNDef - buffer size: %u less than NDEF msg sise: %u", buf_len, p_t1t->ndef_msg_len);
2537 return (NFC_STATUS_FAILED);
2538 }
2539 p_t1t->p_ndef_buffer = p_buffer;
2540
2541 if (p_t1t->b_rseg == TRUE)
2542 {
2543 /* If already got response to RSEG 0 */
2544 p_t1t->state = RW_T1T_STATE_READ_NDEF;
2545 p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *)p_cmd_rsp_info_rseg;
2546
2547 rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
2548 status = NFC_STATUS_OK;
2549 }
2550 else if (p_t1t->b_update == TRUE)
2551 {
2552 /* If already got response to RALL */
2553 p_t1t->state = RW_T1T_STATE_READ_NDEF;
2554 p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info_rall;
2555
2556 rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
2557 status = NFC_STATUS_OK;
2558
2559 }
2560 else
2561 {
2562 p_t1t->segment = 0;
2563 p_t1t->work_offset = 0;
2564 if ((p_t1t->hr[0] & 0x0F) != 1)
2565 {
2566 /* send RSEG command */
2567 RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
2568 status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL);
2569 }
2570 else
2571 {
2572 status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0);
2573 }
2574 if (status == NFC_STATUS_OK)
2575 p_t1t->state = RW_T1T_STATE_READ_NDEF;
2576
2577 }
2578
2579 return status;
2580 }
2581
2582 /*******************************************************************************
2583 **
2584 ** Function RW_T1tWriteNDef
2585 **
2586 ** Description This function can be called to write an NDEF message to the tag.
2587 **
2588 ** Parameters: msg_len: The length of the buffer
2589 ** p_msg: The NDEF message to write
2590 **
2591 ** Returns NCI_STATUS_OK, if write was started. Otherwise, error status.
2592 **
2593 *******************************************************************************/
RW_T1tWriteNDef(UINT16 msg_len,UINT8 * p_msg)2594 tNFC_STATUS RW_T1tWriteNDef (UINT16 msg_len, UINT8 *p_msg)
2595 {
2596 tNFC_STATUS status = NFC_STATUS_FAILED;
2597 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
2598 UINT16 num_ndef_bytes;
2599 UINT16 offset;
2600 UINT8 addr;
2601 UINT8 init_lengthfield_len;
2602 UINT8 new_lengthfield_len;
2603 UINT16 init_ndef_msg_offset;
2604
2605 if (p_t1t->state != RW_T1T_STATE_IDLE)
2606 {
2607 RW_TRACE_WARNING1 ("RW_T1tWriteNDef - Busy - State: %u", p_t1t->state);
2608 return (NFC_STATUS_FAILED);
2609 }
2610
2611 /* Check HR0 if NDEF supported by the tag */
2612 if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)
2613 {
2614 RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Error: NDEF not supported by the tag");
2615 return (NFC_STATUS_REFUSED);
2616 }
2617
2618 if ( (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE)
2619 &&(p_t1t->tag_attribute != RW_T1_TAG_ATTRB_INITIALIZED_NDEF) )
2620 {
2621 RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Tag cannot update NDEF");
2622 return (NFC_STATUS_REFUSED);
2623 }
2624
2625 if (msg_len > p_t1t->max_ndef_msg_len)
2626 {
2627 RW_TRACE_ERROR1 ("RW_T1tWriteNDef - Cannot write NDEF of size greater than %u bytes", p_t1t->max_ndef_msg_len);
2628 return (NFC_STATUS_REFUSED);
2629 }
2630
2631 p_t1t->p_ndef_buffer = p_msg;
2632 p_t1t->new_ndef_msg_len = msg_len;
2633 new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
2634 init_lengthfield_len = (UINT8) (p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset);
2635 init_ndef_msg_offset = p_t1t->ndef_msg_offset;
2636
2637 /* ndef_msg_offset should reflect the new ndef message offset */
2638 if (init_lengthfield_len > new_lengthfield_len)
2639 {
2640 p_t1t->ndef_msg_offset = init_ndef_msg_offset - (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
2641 }
2642 else if (init_lengthfield_len < new_lengthfield_len)
2643 {
2644 p_t1t->ndef_msg_offset = init_ndef_msg_offset + (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
2645 }
2646
2647 num_ndef_bytes = 0;
2648 offset = p_t1t->ndef_msg_offset;
2649 p_t1t->segment = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE);
2650
2651 /* Locate NDEF final block based on the size of new NDEF Message */
2652 while (num_ndef_bytes < p_t1t->new_ndef_msg_len)
2653 {
2654 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) offset) == FALSE)
2655 num_ndef_bytes++;
2656
2657 offset++;
2658 if (offset % T1T_SEGMENT_SIZE == 0)
2659 {
2660 p_t1t->segment = (UINT8) (offset / T1T_SEGMENT_SIZE);
2661 }
2662 }
2663
2664 p_t1t->b_update = FALSE;
2665 p_t1t->b_rseg = FALSE;
2666
2667 if ((p_t1t->hr[0] & 0x0F) != 1)
2668 {
2669 /* Dynamic data structure */
2670 p_t1t->block_read = (UINT8) ((offset - 1)/T1T_BLOCK_SIZE);
2671 /* Read NDEF final block before updating */
2672 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK)
2673 {
2674 p_t1t->num_ndef_finalblock = p_t1t->block_read;
2675 p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
2676 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK;
2677 }
2678 }
2679 else
2680 {
2681 /* NDEF detected and Static memory structure so send WRITE-E command */
2682 RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
2683 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0)) == NFC_STATUS_OK)
2684 {
2685 p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
2686 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
2687 }
2688
2689 }
2690
2691 if (status != NFC_STATUS_OK)
2692 {
2693 /* if status failed, reset ndef_msg_offset to initial message */
2694 p_t1t->ndef_msg_offset = init_ndef_msg_offset;
2695 }
2696 return status;
2697 }
2698
2699 /*******************************************************************************
2700 **
2701 ** Function RW_T1tSetTagReadOnly
2702 **
2703 ** Description This function can be called to set t1 tag as read only.
2704 **
2705 ** Parameters: None
2706 **
2707 ** Returns NCI_STATUS_OK, if setting tag as read only was started.
2708 ** Otherwise, error status.
2709 **
2710 *******************************************************************************/
RW_T1tSetTagReadOnly(BOOLEAN b_hard_lock)2711 tNFC_STATUS RW_T1tSetTagReadOnly (BOOLEAN b_hard_lock)
2712 {
2713 tNFC_STATUS status = NFC_STATUS_FAILED;
2714 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
2715 UINT8 addr;
2716 UINT8 num_locks;
2717
2718 if (p_t1t->state != RW_T1T_STATE_IDLE)
2719 {
2720 RW_TRACE_WARNING1 ("RW_T1tSetTagReadOnly - Busy - State: %u", p_t1t->state);
2721 return (NFC_STATUS_BUSY);
2722 }
2723
2724 p_t1t->b_hard_lock = b_hard_lock;
2725
2726 if ( (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_WRITE)
2727 ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED)
2728 ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF) )
2729 {
2730 /* send WRITE-NE command */
2731 RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_RWA_OFFSET));
2732 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0x0F)) == NFC_STATUS_OK)
2733 {
2734 p_t1t->b_update = FALSE;
2735 p_t1t->b_rseg = FALSE;
2736
2737 if (p_t1t->b_hard_lock)
2738 {
2739 num_locks = 0;
2740 while (num_locks < p_t1t->num_lockbytes)
2741 {
2742 p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_NOT_UPDATED;
2743 num_locks++;
2744 }
2745 }
2746 p_t1t->state = RW_T1T_STATE_SET_TAG_RO;
2747 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO;
2748 }
2749 }
2750
2751 return status;
2752 }
2753
2754 #if (BT_TRACE_VERBOSE == TRUE)
2755 /*******************************************************************************
2756 **
2757 ** Function rw_t1t_get_sub_state_name
2758 **
2759 ** Description This function returns the sub_state name.
2760 **
2761 ** NOTE conditionally compiled to save memory.
2762 **
2763 ** Returns pointer to the name
2764 **
2765 *******************************************************************************/
rw_t1t_get_sub_state_name(UINT8 sub_state)2766 static char *rw_t1t_get_sub_state_name (UINT8 sub_state)
2767 {
2768 switch (sub_state)
2769 {
2770 case RW_T1T_SUBSTATE_NONE:
2771 return ("NONE");
2772 case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
2773 return ("EXTRACT_TLV_VALUE");
2774 case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
2775 return ("READING_LOCKS");
2776 case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
2777 return ("READ_NDEF_FINAL_BLOCK");
2778 case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
2779 return ("INVALIDATING_NDEF");
2780 case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
2781 return ("WRITE_NDEF_TLV_MESSAGE");
2782 case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
2783 return ("WAITING_RSP_FOR_LAST_NDEF_WRITE");
2784 case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
2785 return ("VALIDATING_NDEF");
2786 case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
2787 return ("SET_RWA_RO");
2788 case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
2789 return ("SET_STATIC_LOCK_BITS");
2790 case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
2791 return ("SET_DYNAMIC_LOCK_BITS");
2792
2793 default:
2794 return ("???? UNKNOWN SUBSTATE");
2795 }
2796 }
2797 #endif /* (BT_TRACE_VERBOSE == TRUE) */
2798
2799 #endif /* (defined ((RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) */
2800
2801 #endif /* (NFC_INCLUDED == TRUE) */
2802