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