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