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