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