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