• 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   uint16_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                     (uint16_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                     (uint16_t)tags_pow(2, ((p_t2t->tlv_value[2] & 0xF0) >> 4));
623                 /* Note: 0 value in DLA_NbrLockBits means 256 bits */
624                 count = p_t2t->tlv_value[1];
625                 /* Set it to max value that can be stored in lockbytes */
626                 if (count == 0) {
627                   count = RW_T2T_MAX_LOCK_BYTES * TAG_BITS_PER_BYTE;
628                 }
629                 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = count;
630                 count = count / TAG_BITS_PER_BYTE +
631                         ((count % TAG_BITS_PER_BYTE != 0) ? 1 : 0);
632 
633                 /* Extract lockbytes info addressed by this Lock TLV */
634                 xx = 0;
635                 if (count > RW_T2T_MAX_LOCK_BYTES) {
636                   count = RW_T2T_MAX_LOCK_BYTES;
637                   android_errorWriteLog(0x534e4554, "112161557");
638                 }
639                 while (xx < count) {
640                   p_t2t->lockbyte[p_t2t->num_lockbytes].tlv_index =
641                       p_t2t->num_lock_tlvs;
642                   p_t2t->lockbyte[p_t2t->num_lockbytes].byte_index = xx;
643                   p_t2t->lockbyte[p_t2t->num_lockbytes].b_lock_read = false;
644                   xx++;
645                   p_t2t->num_lockbytes++;
646                 }
647                 p_t2t->num_lock_tlvs++;
648                 rw_t2t_update_attributes();
649                 /* Next byte could be a different TLV */
650                 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
651               }
652             } else {
653               /* If not looking for lock/ndef tlv, just skip this Lock TLV */
654               if (p_t2t->bytes_count == 0) {
655                 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
656               }
657             }
658             break;
659 
660           case TAG_MEM_CTRL_TLV:
661             if (p_t2t->bytes_count > 0) {
662               p_t2t->bytes_count--;
663             } else {
664               LOG(ERROR) << StringPrintf("bytes_count underflow!");
665               android_errorWriteLog(0x534e4554, "120506143");
666             }
667             if ((tlvtype == TAG_MEM_CTRL_TLV) || (tlvtype == TAG_NDEF_TLV)) {
668               p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
669               if (p_t2t->bytes_count == 0) {
670                 if (p_t2t->num_mem_tlvs >= RW_T2T_MAX_MEM_TLVS) {
671                   LOG(ERROR) << StringPrintf(
672                       "rw_t2t_handle_tlv_detect_rsp - Maximum buffer allocated "
673                       "for Memory tlv has reached");
674                   failed = true;
675                 } else {
676                   /* Extract memory control tlv */
677                   p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset =
678                       (p_t2t->tlv_value[0] >> 4) & 0x0F;
679                   p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset *=
680                       (uint16_t)tags_pow(2, p_t2t->tlv_value[2] & 0x0F);
681 
682                   p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset +=
683                       p_t2t->tlv_value[0] & 0x0F;
684                   count = p_t2t->tlv_value[1];
685                   /* Note: 0 value in Rsvd_Area_Size means 256 bytes */
686                   if (count == 0) {
687                     count = RW_T2T_MAX_LOCK_BYTES * TAG_BITS_PER_BYTE;
688                   }
689                   p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes = count;
690 
691                   p_t2t->num_mem_tlvs++;
692                   rw_t2t_update_attributes();
693                   p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
694                 }
695               }
696             } else {
697               if (p_t2t->bytes_count == 0) {
698                 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
699               }
700             }
701             break;
702 
703           case TAG_PROPRIETARY_TLV:
704             if (p_t2t->bytes_count > 0) {
705               p_t2t->bytes_count--;
706             } else {
707               LOG(ERROR) << StringPrintf("bytes_count underflow!");
708               android_errorWriteLog(0x534e4554, "120506143");
709             }
710             if (tlvtype == TAG_PROPRIETARY_TLV) {
711               found = true;
712               p_t2t->prop_msg_len = len;
713             } else {
714               if (p_t2t->bytes_count == 0) {
715                 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
716               }
717             }
718             break;
719         }
720         offset++;
721         break;
722     }
723   }
724 
725   p_t2t->work_offset += T2T_READ_DATA_LEN;
726 
727   event = rw_t2t_info_to_event(p_cmd_rsp_info);
728 
729   /* If not found and not failed, read next block and search tlv */
730   if (!found && !failed) {
731     if (p_t2t->work_offset >=
732         (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR + T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN)) {
733       if (((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0)) ||
734           ((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))) {
735         found = true;
736       } else {
737         failed = true;
738       }
739     } else {
740       if (rw_t2t_read((uint16_t)(p_t2t->work_offset / T2T_BLOCK_LEN) ) != NFC_STATUS_OK)
741         failed = true;
742     }
743   }
744 
745   if (failed || found) {
746     if (tlvtype == TAG_LOCK_CTRL_TLV) {
747       /* Incase no Lock control tlv is present then look for default dynamic
748        * lock bytes */
749       rw_t2t_extract_default_locks_info();
750 
751       /* Send command to read the dynamic lock bytes */
752       status = rw_t2t_read_locks();
753 
754       if (status != NFC_STATUS_CONTINUE) {
755         /* If unable to read a lock/all locks read, notify upper layer */
756         rw_t2t_update_lock_attributes();
757         rw_t2t_ntf_tlv_detect_complete(status);
758       }
759     } else if (tlvtype == TAG_NDEF_TLV) {
760       rw_t2t_extract_default_locks_info();
761 
762       if (failed) {
763         rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
764       } else {
765         /* NDEF present,Send command to read the dynamic lock bytes */
766         status = rw_t2t_read_locks();
767         if (status != NFC_STATUS_CONTINUE) {
768           /* If unable to read a lock/all locks read, notify upper layer */
769           rw_t2t_update_lock_attributes();
770           rw_t2t_ntf_tlv_detect_complete(status);
771         }
772       }
773     } else {
774       /* Notify Memory/ Proprietary tlv detect result */
775       status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
776       rw_t2t_ntf_tlv_detect_complete(status);
777     }
778   }
779 }
780 
781 /*******************************************************************************
782 **
783 ** Function         rw_t2t_read_locks
784 **
785 ** Description      This function will send command to read next unread locks
786 **
787 ** Returns          NFC_STATUS_OK, if all locks are read successfully
788 **                  NFC_STATUS_FAILED, if reading locks failed
789 **                  NFC_STATUS_CONTINUE, if reading locks is in progress
790 **
791 *******************************************************************************/
rw_t2t_read_locks(void)792 tNFC_STATUS rw_t2t_read_locks(void) {
793   uint8_t num_locks = 0;
794   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
795   tNFC_STATUS status = NFC_STATUS_CONTINUE;
796   uint16_t offset;
797   uint16_t block;
798 
799   if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) ||
800       (p_t2t->skip_dyn_locks)) {
801     /* Skip reading dynamic lock bytes if CC is set as Read only or layer above
802      * instructs to skip */
803     while (num_locks < p_t2t->num_lockbytes) {
804       p_t2t->lockbyte[num_locks].lock_byte = 0x00;
805       p_t2t->lockbyte[num_locks].b_lock_read = true;
806       num_locks++;
807     }
808   }
809 
810   while (num_locks < p_t2t->num_lockbytes) {
811     if (p_t2t->lockbyte[num_locks].b_lock_read == false) {
812       /* Send Read command to read the first un read locks */
813       offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
814                p_t2t->lockbyte[num_locks].byte_index;
815 
816       /* Read 16 bytes where this lock byte is present */
817       block = (uint16_t)(offset / T2T_BLOCK_LEN);
818       block -= block % T2T_READ_BLOCKS;
819 
820       p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_LOCKS;
821       /* send READ8 command */
822       status = rw_t2t_read((uint16_t)block);
823       if (status == NFC_STATUS_OK) {
824         /* Reading Locks */
825         status = NFC_STATUS_CONTINUE;
826       } else {
827         status = NFC_STATUS_FAILED;
828       }
829       break;
830     }
831     num_locks++;
832   }
833   if (num_locks == p_t2t->num_lockbytes) {
834     /* All locks are read */
835     status = NFC_STATUS_OK;
836   }
837 
838   return status;
839 }
840 
841 /*******************************************************************************
842 **
843 ** Function         rw_t2t_extract_default_locks_info
844 **
845 ** Description      This function will prepare lockbytes information for default
846 **                  locks present in the tag in the absence of lock control tlv.
847 **                  Adding a virtual lock control tlv for these lock bytes for
848 **                  easier manipulation.
849 **
850 ** Returns          None
851 **
852 *******************************************************************************/
rw_t2t_extract_default_locks_info(void)853 void rw_t2t_extract_default_locks_info(void) {
854   uint8_t num_dynamic_lock_bits;
855   uint8_t num_dynamic_lock_bytes;
856   uint8_t xx;
857   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
858   const tT2T_INIT_TAG* p_ret;
859   uint8_t bytes_locked_per_lock_bit = T2T_DEFAULT_LOCK_BLPB;
860   uint16_t t2t_dyn_lock_area_size;
861 
862   if ((p_t2t->num_lock_tlvs == 0) &&
863       (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] > T2T_CC2_TMS_STATIC)) {
864     /* No Lock control tlv is detected. Indicates lock bytes are present in
865      * default location */
866     /* Add a virtual Lock tlv to map this default lock location */
867     p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0);
868     if (p_ret != nullptr) bytes_locked_per_lock_bit = p_ret->default_lock_blpb;
869 
870     t2t_dyn_lock_area_size =
871         ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) -
872          (T2T_STATIC_SIZE - T2T_HEADER_SIZE));
873     num_dynamic_lock_bits = t2t_dyn_lock_area_size / bytes_locked_per_lock_bit;
874     num_dynamic_lock_bits += (t2t_dyn_lock_area_size % 8 == 0) ? 0 : 1;
875 
876     num_dynamic_lock_bytes = num_dynamic_lock_bits / 8;
877     num_dynamic_lock_bytes += (num_dynamic_lock_bits % 8 == 0) ? 0 : 1;
878     if (num_dynamic_lock_bytes > RW_T2T_MAX_LOCK_BYTES) {
879       LOG(ERROR) << StringPrintf(
880           "rw_t2t_extract_default_locks_info - buffer size: %u less than "
881           "DynLock area sise: %u",
882           RW_T2T_MAX_LOCK_BYTES, num_dynamic_lock_bytes);
883       num_dynamic_lock_bytes = RW_T2T_MAX_LOCK_BYTES;
884       android_errorWriteLog(0x534e4554, "147310721");
885     }
886 
887     p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset =
888         (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
889         (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN);
890     p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit =
891         bytes_locked_per_lock_bit;
892     p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = num_dynamic_lock_bits;
893 
894     /* Based on tag data size the number of locks present in the default
895      * location changes */
896     for (xx = 0; xx < num_dynamic_lock_bytes; xx++) {
897       p_t2t->lockbyte[xx].tlv_index = p_t2t->num_lock_tlvs;
898       p_t2t->lockbyte[xx].byte_index = xx;
899       p_t2t->lockbyte[xx].b_lock_read = false;
900     }
901     p_t2t->num_lockbytes = num_dynamic_lock_bytes;
902     p_t2t->num_lock_tlvs = 1;
903   }
904 }
905 
906 /*******************************************************************************
907 **
908 ** Function         rw_t2t_read_ndef_last_block
909 **
910 ** Description      This function will locate and read the last ndef block.
911 **                  The last ndef block refers to the tag block where last byte
912 **                  of new ndef message will reside. Also this function will
913 **                  locate the offset of Terminator TLV based on the size of
914 **                  new NDEF Message
915 **
916 ** Returns          NCI_STATUS_OK, if able to locate last ndef block & read
917 **                  started. Otherwise, error status.
918 **
919 *******************************************************************************/
rw_t2t_read_ndef_last_block(void)920 tNFC_STATUS rw_t2t_read_ndef_last_block(void) {
921   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
922   uint16_t header_len = (p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN)
923                             ? T2T_LONG_NDEF_LEN_FIELD_LEN
924                             : T2T_SHORT_NDEF_LEN_FIELD_LEN;
925   uint16_t num_ndef_bytes;
926   uint16_t total_ndef_bytes;
927   uint16_t last_ndef_byte_offset;
928   uint16_t terminator_tlv_byte_index;
929   tNFC_STATUS status = NFC_STATUS_OK;
930 
931   total_ndef_bytes = header_len + p_t2t->new_ndef_msg_len;
932   num_ndef_bytes = 0;
933   last_ndef_byte_offset = p_t2t->ndef_header_offset;
934 
935   /* Locate NDEF final block based on the size of new NDEF Message */
936   while (num_ndef_bytes < total_ndef_bytes) {
937     if (rw_t2t_is_lock_res_byte((uint16_t)(last_ndef_byte_offset)) == false)
938       num_ndef_bytes++;
939 
940     last_ndef_byte_offset++;
941   }
942   p_t2t->ndef_last_block_num =
943       (uint16_t)((last_ndef_byte_offset - 1) / T2T_BLOCK_SIZE);
944 
945   if ((p_t2t->new_ndef_msg_len + 1) <= p_t2t->max_ndef_msg_len) {
946     /* Locate Terminator TLV Block */
947     terminator_tlv_byte_index = last_ndef_byte_offset;
948 
949     if (rw_t2t_is_lock_res_byte((uint16_t)terminator_tlv_byte_index) == false)
950       p_t2t->terminator_byte_index = terminator_tlv_byte_index;
951     else
952       p_t2t->terminator_byte_index = 0x00;
953   } else {
954     /* No space for Terminator TLV */
955     p_t2t->terminator_byte_index = 0x00;
956   }
957 
958   return status;
959 }
960 
961 
962 /*******************************************************************************
963 **
964 ** Function         rw_t2t_read_ndef_next_block
965 **
966 ** Description      This function will read the tag block passed as argument
967 **
968 ** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
969 **
970 *******************************************************************************/
rw_t2t_read_ndef_next_block(uint16_t block)971 tNFC_STATUS rw_t2t_read_ndef_next_block(uint16_t block) {
972   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
973   tNFC_STATUS status;
974 
975   /* Send read command to read base block (Block % 4==0) where this block is
976    * also read as part of 16 bytes */
977   block -= block % T2T_READ_BLOCKS;
978 
979   p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK;
980   /* Read the block */
981   status = rw_t2t_read(block);
982 
983   return status;
984 }
985 
986 /*******************************************************************************
987 **
988 ** Function         rw_t2t_is_read_before_write_block
989 **
990 ** Description      This function will check if the block has to be read before
991 **                  writting to avoid over writting in to lock/reserved bytes
992 **                  present in the block.
993 **                  If no bytes in the block can be overwritten it moves in to
994 **                  next block and check. Finally it finds a block where part of
995 **                  ndef bytes can exist and check if the whole block can be
996 **                  updated or only part of block can be modified.
997 **
998 ** Returns          TRUE, if the block returned should be read before writting
999 **                  FALSE, if the block need not be read as it was already
1000 **                         read or during NDEF write we may completely overwrite
1001 **                         the block and there is no reserved or locked bytes in
1002 **                         that block
1003 **
1004 *******************************************************************************/
rw_t2t_is_read_before_write_block(uint16_t block,uint16_t * p_block_to_read)1005 static bool rw_t2t_is_read_before_write_block(uint16_t block,
1006                                               uint16_t* p_block_to_read) {
1007   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1008   uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1009   uint8_t count;
1010   uint8_t index;
1011   uint16_t tag_size = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1012   bool read_before_write = true;
1013 
1014   if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) {
1015     /* First NDEF block is already read */
1016     read_before_write = false;
1017     memcpy(p_t2t->ndef_read_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
1018   } else if (block == p_t2t->ndef_last_block_num) {
1019     /* Last NDEF block is already read */
1020     read_before_write = false;
1021     memcpy(p_t2t->ndef_read_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
1022   } else if (block == p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) {
1023     /* Terminator tlv block is already read */
1024     read_before_write = false;
1025     memcpy(p_t2t->ndef_read_block, p_t2t->terminator_tlv_block, T2T_BLOCK_SIZE);
1026   } else {
1027     count = 0;
1028     while (block < tag_size) {
1029       index = 0;
1030 
1031       while (index < T2T_BLOCK_SIZE) {
1032         /* check if it is a reserved or locked byte */
1033         if (rw_t2t_is_lock_res_byte(
1034                 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1035           count++;
1036         }
1037         index++;
1038       }
1039       if (count == T2T_BLOCK_SIZE) {
1040         /* All the bytes in the block are free to NDEF write  */
1041         read_before_write = false;
1042         break;
1043       } else if (count == 0) {
1044         /* The complete block is not free for NDEF write  */
1045         index = 0;
1046         block++;
1047       } else {
1048         /* The block has reseved byte (s) or locked byte (s) or both */
1049         read_before_write = true;
1050         break;
1051       }
1052     }
1053   }
1054   /* Return the block to read next before NDEF write */
1055   *p_block_to_read = block;
1056   return read_before_write;
1057 }
1058 
1059 /*******************************************************************************
1060 **
1061 ** Function         rw_t2t_write_ndef_first_block
1062 **
1063 ** Description      This function will write the first NDEF block with Length
1064 **                  field reset to zero.
1065 **                  Also after writting NDEF this function may be called to
1066 **                  update new NDEF length
1067 **
1068 ** Returns          NCI_STATUS_OK, if write was started.
1069 **                  Otherwise, error status.
1070 **
1071 *******************************************************************************/
rw_t2t_write_ndef_first_block(uint16_t msg_len,bool b_update_len)1072 tNFC_STATUS rw_t2t_write_ndef_first_block(uint16_t msg_len, bool b_update_len) {
1073   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1074   uint8_t new_lengthfield_len;
1075   uint8_t write_block[4];
1076   uint8_t block;
1077   uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1078   uint16_t total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1079   tNFC_STATUS status;
1080   uint8_t length_field[3];
1081   uint8_t index;
1082 
1083   p_t2t->work_offset = 0;
1084   new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1085                             ? T2T_LONG_NDEF_LEN_FIELD_LEN
1086                             : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1087   if (new_lengthfield_len == 3) {
1088     /* New NDEF is Long NDEF */
1089     if (msg_len == 0) {
1090       /* Clear NDEF length field */
1091       length_field[0] = 0x00;
1092       length_field[1] = 0x00;
1093       length_field[2] = 0x00;
1094     } else {
1095       /* Update NDEF length field with new NDEF Msg len */
1096       length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
1097       length_field[1] = (uint8_t)(msg_len >> 8);
1098       length_field[2] = (uint8_t)(msg_len);
1099     }
1100   } else {
1101     /* New NDEF is Short NDEF */
1102     length_field[0] = (uint8_t)(msg_len);
1103   }
1104 
1105   /* updating ndef_first_block with new ndef message */
1106   memcpy(write_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
1107 
1108   index = p_t2t->ndef_header_offset % T2T_BLOCK_SIZE;
1109   block = (uint8_t)(p_t2t->ndef_header_offset / T2T_BLOCK_SIZE);
1110 
1111   while (p_t2t->work_offset == 0 && block < total_blocks) {
1112     /* update length field */
1113     while (index < T2T_BLOCK_SIZE &&
1114            p_t2t->work_offset < p_t2t->new_ndef_msg_len) {
1115       if (rw_t2t_is_lock_res_byte(
1116               (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1117         write_block[index] = length_field[p_t2t->work_offset];
1118         p_t2t->work_offset++;
1119       }
1120       index++;
1121       if (p_t2t->work_offset == new_lengthfield_len) {
1122         break;
1123       }
1124     }
1125     /* If more space in this block then add ndef message */
1126     while (index < T2T_BLOCK_SIZE &&
1127            p_t2t->work_offset <
1128                (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
1129       if (rw_t2t_is_lock_res_byte(
1130               (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1131         write_block[index] =
1132             p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1133         p_t2t->work_offset++;
1134       }
1135       index++;
1136     }
1137     if (p_t2t->work_offset == 0) {
1138       /* If no bytes are written move to next block */
1139       index = 0;
1140       block++;
1141       if (block == p_t2t->ndef_last_block_num) {
1142         memcpy(write_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
1143       }
1144     }
1145   }
1146   if (p_t2t->work_offset == 0) {
1147     status = NFC_STATUS_FAILED;
1148   } else {
1149     rw_t2t_update_cb(block, write_block, b_update_len);
1150     /* Update the identified block with newly prepared data */
1151     status = rw_t2t_write(block, write_block);
1152     if (status == NFC_STATUS_OK) {
1153       p_t2t->b_read_data = false;
1154     }
1155   }
1156   return status;
1157 }
1158 
1159 /*******************************************************************************
1160 **
1161 ** Function         rw_t2t_write_ndef_next_block
1162 **
1163 ** Description      This function can be called to write an NDEF message block
1164 **
1165 ** Returns          NCI_STATUS_OK, if write was started.
1166 **                  Otherwise, error status.
1167 **
1168 *******************************************************************************/
rw_t2t_write_ndef_next_block(uint16_t block,uint16_t msg_len,bool b_update_len)1169 tNFC_STATUS rw_t2t_write_ndef_next_block(uint16_t block, uint16_t msg_len,
1170                                          bool b_update_len) {
1171   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1172   uint8_t new_lengthfield_len;
1173   uint8_t write_block[4];
1174   uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1175   uint16_t total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1176   uint16_t initial_offset;
1177   uint8_t length_field[3];
1178   uint8_t index;
1179   tNFC_STATUS status;
1180 
1181   /* Write NDEF Message */
1182   new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1183                             ? T2T_LONG_NDEF_LEN_FIELD_LEN
1184                             : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1185 
1186   index = 0;
1187 
1188   memcpy(write_block, p_t2t->ndef_read_block, T2T_BLOCK_SIZE);
1189 
1190   if (p_t2t->work_offset >= new_lengthfield_len) {
1191     /* Length field is updated, write ndef message field */
1192     initial_offset = p_t2t->work_offset;
1193     while (p_t2t->work_offset == initial_offset && block < total_blocks) {
1194       while (index < T2T_BLOCK_SIZE &&
1195              p_t2t->work_offset <
1196                  (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
1197         if (rw_t2t_is_lock_res_byte(
1198                 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1199           write_block[index] =
1200               p_t2t
1201                   ->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1202           p_t2t->work_offset++;
1203         }
1204         index++;
1205       }
1206       if (p_t2t->work_offset == initial_offset) {
1207         index = 0;
1208         block++;
1209       }
1210     }
1211   } else {
1212     /* Complete writting Length field and then write ndef message */
1213     new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1214                               ? T2T_LONG_NDEF_LEN_FIELD_LEN
1215                               : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1216     if (new_lengthfield_len == 3) {
1217       /* New NDEF is Long NDEF */
1218       if (msg_len == 0) {
1219         length_field[0] = 0x00;
1220         length_field[1] = 0x00;
1221         length_field[2] = 0x00;
1222       } else {
1223         length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
1224         length_field[1] = (uint8_t)(msg_len >> 8);
1225         length_field[2] = (uint8_t)(msg_len);
1226       }
1227     } else {
1228       /* New NDEF is short NDEF */
1229       length_field[0] = (uint8_t)(msg_len);
1230     }
1231     initial_offset = p_t2t->work_offset;
1232     while (p_t2t->work_offset == initial_offset && block < total_blocks) {
1233       /* Update length field */
1234       while (index < T2T_BLOCK_SIZE &&
1235              p_t2t->work_offset < p_t2t->new_ndef_msg_len) {
1236         if (rw_t2t_is_lock_res_byte(
1237                 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1238           write_block[index] = length_field[p_t2t->work_offset];
1239           p_t2t->work_offset++;
1240         }
1241         index++;
1242         if (p_t2t->work_offset == new_lengthfield_len) {
1243           break;
1244         }
1245       }
1246       /* Update ndef message field */
1247       while (index < T2T_BLOCK_SIZE &&
1248              p_t2t->work_offset <
1249                  (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
1250         if (rw_t2t_is_lock_res_byte(
1251                 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1252           write_block[index] =
1253               p_t2t
1254                   ->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1255           p_t2t->work_offset++;
1256         }
1257         index++;
1258       }
1259       if (p_t2t->work_offset == initial_offset) {
1260         index = 0;
1261         block++;
1262       }
1263     }
1264   }
1265   if (p_t2t->work_offset == initial_offset) {
1266     status = NFC_STATUS_FAILED;
1267   } else {
1268     rw_t2t_update_cb(block, write_block, b_update_len);
1269     /* Write the NDEF Block */
1270     status = rw_t2t_write(block, write_block);
1271   }
1272 
1273   return status;
1274 }
1275 
1276 /*******************************************************************************
1277 **
1278 ** Function         rw_t2t_update_cb
1279 **
1280 ** Description      This function can be called to write an NDEF message block
1281 **
1282 ** Returns          NCI_STATUS_OK, if write was started.
1283 **                  Otherwise, error status.
1284 **
1285 *******************************************************************************/
rw_t2t_update_cb(uint16_t block,uint8_t * p_write_block,bool b_update_len)1286 static void rw_t2t_update_cb(uint16_t block, uint8_t* p_write_block,
1287                              bool b_update_len) {
1288   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1289   uint8_t new_lengthfield_len;
1290 
1291   /* Write NDEF Message */
1292   new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1293                             ? T2T_LONG_NDEF_LEN_FIELD_LEN
1294                             : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1295 
1296   if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) {
1297     /* Update ndef first block if the 'block' points to ndef first block */
1298     memcpy(p_t2t->ndef_first_block, p_write_block, T2T_BLOCK_SIZE);
1299   }
1300   if (p_t2t->terminator_byte_index / T2T_BLOCK_SIZE == block) {
1301     /* Update terminator block if the 'block' points to terminator tlv block */
1302     memcpy(p_t2t->terminator_tlv_block, p_write_block, T2T_BLOCK_LEN);
1303   }
1304   if (b_update_len == false) {
1305     if (block == p_t2t->ndef_last_block_num) {
1306       p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK;
1307       p_t2t->work_offset = 0;
1308       /* Update ndef final block if the 'block' points to ndef final block */
1309       memcpy(p_t2t->ndef_last_block, p_write_block, T2T_BLOCK_SIZE);
1310     } else {
1311       p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK;
1312     }
1313   } else {
1314     if (block == p_t2t->ndef_last_block_num) {
1315       /* Update the backup of Ndef final block TLV block */
1316       memcpy(p_t2t->ndef_last_block, p_write_block, T2T_BLOCK_SIZE);
1317     }
1318 
1319     if (p_t2t->work_offset >= new_lengthfield_len) {
1320       if (p_t2t->terminator_byte_index != 0) {
1321         /* Add Terminator TLV as part of NDEF Write operation */
1322         p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK;
1323       } else {
1324         /* Skip adding Terminator TLV */
1325         p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1326       }
1327     } else {
1328       /* Part of NDEF Message Len should be added in the next block */
1329       p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK;
1330     }
1331   }
1332 }
1333 
1334 /*******************************************************************************
1335 **
1336 ** Function         rw_t2t_get_ndef_flags
1337 **
1338 ** Description      Prepare NDEF Flags
1339 **
1340 ** Returns          NDEF Flag value
1341 **
1342 *******************************************************************************/
rw_t2t_get_ndef_flags(void)1343 static uint8_t rw_t2t_get_ndef_flags(void) {
1344   uint8_t flags = 0;
1345   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1346   const tT2T_INIT_TAG* p_ret;
1347 
1348   flags |= RW_NDEF_FL_SUPPORTED;
1349 
1350   if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC) ||
1351       (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == 0))
1352     flags |= RW_NDEF_FL_FORMATABLE;
1353 
1354   if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
1355     flags |= RW_NDEF_FL_READ_ONLY;
1356 
1357   if (((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != nullptr) &&
1358       (p_ret->b_otp)) {
1359     /* Set otp flag */
1360     flags |= RW_NDEF_FL_OTP;
1361 
1362     /* Set Read only flag if otp tag already has NDEF Message */
1363     if (p_t2t->ndef_msg_len) flags |= RW_NDEF_FL_READ_ONLY;
1364   }
1365   return flags;
1366 }
1367 
1368 /*******************************************************************************
1369 **
1370 ** Function         rw_t2t_get_ndef_max_size
1371 **
1372 ** Description      Calculate maximum size of NDEF message that can be written
1373 **                  on to the tag
1374 **
1375 ** Returns          Maximum size of NDEF Message
1376 **
1377 *******************************************************************************/
rw_t2t_get_ndef_max_size(void)1378 static uint16_t rw_t2t_get_ndef_max_size(void) {
1379   uint16_t offset;
1380   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1381   uint16_t tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR);
1382 
1383   DLOG_IF(INFO, nfc_debug_enabled)
1384       << StringPrintf("%s - T2T_Area size: %d", __func__, tag_size);
1385 
1386   /* Add header to compute max T2T NDEF data offset */
1387   tag_size += (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN);
1388 
1389   offset = p_t2t->ndef_msg_offset;
1390   p_t2t->max_ndef_msg_len = 0;
1391 
1392   if ((tag_size <= T2T_STATIC_SIZE) ||
1393       ((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN) &&
1394        (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0))) {
1395     /* Tag not formated, assume static tag */
1396     p_t2t->max_ndef_msg_len = T2T_STATIC_SIZE - T2T_HEADER_SIZE -
1397                               T2T_TLV_TYPE_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN;
1398     DLOG_IF(INFO, nfc_debug_enabled)
1399         << StringPrintf("%s - Tag assumed static : max_ndef_msg_len=%d",
1400                         __func__, p_t2t->max_ndef_msg_len);
1401     return p_t2t->max_ndef_msg_len;
1402   }
1403 
1404   /* Starting from NDEF Message offset find the first locked data byte */
1405   while (offset < tag_size) {
1406     if (rw_t2t_is_lock_res_byte((uint16_t)offset) == false) {
1407       if (rw_t2t_is_read_only_byte((uint16_t)offset) == true) break;
1408       p_t2t->max_ndef_msg_len++;
1409     }
1410     offset++;
1411   }
1412 
1413   /* NDEF Length field length changes based on NDEF size */
1414   if ((p_t2t->max_ndef_msg_len >= T2T_LONG_NDEF_LEN_FIELD_BYTE0) &&
1415       ((p_t2t->ndef_msg_offset - p_t2t->ndef_header_offset) ==
1416        T2T_SHORT_NDEF_LEN_FIELD_LEN)) {
1417     p_t2t->max_ndef_msg_len -=
1418         (T2T_LONG_NDEF_LEN_FIELD_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN);
1419   }
1420 
1421   DLOG_IF(INFO, nfc_debug_enabled)
1422       << StringPrintf("%s - Max NDEF data storage: max_ndef_msg_len=%d",
1423                       __func__, p_t2t->max_ndef_msg_len);
1424 
1425   return p_t2t->max_ndef_msg_len;
1426 }
1427 
1428 /*******************************************************************************
1429 **
1430 ** Function         rw_t2t_add_terminator_tlv
1431 **
1432 ** Description      This function will add terminator TLV after NDEF Message
1433 **
1434 ** Returns          NCI_STATUS_OK, if write was started.
1435 **                  Otherwise, error status.
1436 **
1437 *******************************************************************************/
rw_t2t_add_terminator_tlv(void)1438 tNFC_STATUS rw_t2t_add_terminator_tlv(void) {
1439   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1440   tNFC_STATUS status;
1441   uint16_t block;
1442   uint8_t term_byte_idx;
1443 
1444   /* Add Terminator TLV after NDEF Message */
1445   block = p_t2t->terminator_byte_index / T2T_BLOCK_LEN;
1446 
1447   if (block == p_t2t->ndef_last_block_num) {
1448     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1449         "%s - Terminator TLV in same block %d as last NDEF"
1450         " bytes",
1451         __func__, block);
1452 
1453     /* If Terminator TLV will reside on the NDEF Final block */
1454     memcpy(p_t2t->terminator_tlv_block, p_t2t->ndef_last_block, T2T_BLOCK_LEN);
1455 
1456     term_byte_idx = p_t2t->terminator_byte_index % T2T_BLOCK_LEN;
1457 
1458     p_t2t->terminator_tlv_block[term_byte_idx] = TAG_TERMINATOR_TLV;
1459     if (term_byte_idx < (T2T_BLOCK_LEN - 1)) {
1460       for (int i = term_byte_idx + 1; i < T2T_BLOCK_LEN; i++)
1461         p_t2t->terminator_tlv_block[i] = 0x00;
1462     }
1463 
1464     p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1465     status = rw_t2t_write(block, p_t2t->terminator_tlv_block);
1466 
1467   } else if (p_t2t->terminator_byte_index != 0) {
1468     /* If there is space for Terminator TLV and if it will reside outside
1469      * NDEF Final block */
1470     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1471         "%s - Terminator TLV in block %d following the last NDEF block",
1472         __func__, block);
1473     p_t2t->terminator_tlv_block[0] = TAG_TERMINATOR_TLV;
1474     p_t2t->terminator_tlv_block[1] = 0x00;
1475     p_t2t->terminator_tlv_block[2] = 0x00;
1476     p_t2t->terminator_tlv_block[3] = 0x00;
1477 
1478     p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1479     status = rw_t2t_write(block, p_t2t->terminator_tlv_block);
1480 
1481   } else {
1482     /* If there is no space for Terminator TLV, conclude NDEF procedure */
1483     status = NFC_STATUS_CONTINUE;
1484   }
1485 
1486   return status;
1487 }
1488 
1489 /*******************************************************************************
1490 **
1491 ** Function         rw_t2t_handle_ndef_read_rsp
1492 **
1493 ** Description      This function handles reading an NDEF message.
1494 **
1495 ** Returns          none
1496 **
1497 *******************************************************************************/
rw_t2t_handle_ndef_read_rsp(uint8_t * p_data)1498 static void rw_t2t_handle_ndef_read_rsp(uint8_t* p_data) {
1499   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1500   tRW_READ_DATA evt_data;
1501   uint16_t len;
1502   uint16_t offset;
1503   bool failed = false;
1504   bool done = false;
1505 
1506   /* On the first read, adjust for any partial block offset */
1507   offset = 0;
1508   len = T2T_READ_DATA_LEN;
1509 
1510   if (p_t2t->work_offset == 0) {
1511     /* The Ndef Message offset may be present in the read 16 bytes */
1512     offset = (p_t2t->ndef_msg_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
1513   }
1514 
1515   /* Skip all reserved and lock bytes */
1516   while ((offset < len) && (p_t2t->work_offset < p_t2t->ndef_msg_len))
1517 
1518   {
1519     if (rw_t2t_is_lock_res_byte(
1520             (uint16_t)(offset + p_t2t->block_read * T2T_BLOCK_LEN)) == false) {
1521       /* Collect the NDEF Message */
1522       p_t2t->p_ndef_buffer[p_t2t->work_offset] = p_data[offset];
1523       p_t2t->work_offset++;
1524     }
1525     offset++;
1526   }
1527 
1528   if (p_t2t->work_offset >= p_t2t->ndef_msg_len) {
1529     done = true;
1530     p_t2t->ndef_status = T2T_NDEF_READ;
1531   } else {
1532     /* Read next 4 blocks */
1533     if (rw_t2t_read((uint16_t)(p_t2t->block_read + T2T_READ_BLOCKS)) !=
1534         NFC_STATUS_OK)
1535       failed = true;
1536   }
1537 
1538   if (failed || done) {
1539     evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1540     evt_data.p_data = nullptr;
1541     rw_t2t_handle_op_complete();
1542     tRW_DATA rw_data;
1543     rw_data.data = evt_data;
1544     (*rw_cb.p_cback)(RW_T2T_NDEF_READ_EVT, &rw_data);
1545   }
1546 }
1547 
1548 /*******************************************************************************
1549 **
1550 ** Function         rw_t2t_handle_ndef_write_rsp
1551 **
1552 ** Description      Handle response received to reading (or part of) NDEF
1553 **                  message.
1554 **
1555 ** Returns          none
1556 **
1557 *******************************************************************************/
rw_t2t_handle_ndef_write_rsp(uint8_t * p_data)1558 static void rw_t2t_handle_ndef_write_rsp(uint8_t* p_data) {
1559   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1560   tRW_READ_DATA evt_data;
1561   bool failed = false;
1562   bool done = false;
1563   uint16_t block;
1564   uint8_t offset;
1565   tNFC_STATUS status = NFC_STATUS_FAILED;
1566 
1567   switch (p_t2t->substate) {
1568     case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
1569 
1570       /* Backup the read NDEF first block */
1571       memcpy(p_t2t->ndef_first_block, p_data, T2T_BLOCK_LEN);
1572       /* Read ndef final block */
1573       if (rw_t2t_read_ndef_last_block() != NFC_STATUS_OK) failed = true;
1574       memset(p_t2t->terminator_tlv_block, 0, T2T_BLOCK_LEN);
1575 
1576       if (rw_t2t_write_ndef_first_block(0x0000, false) != NFC_STATUS_OK)
1577         failed = true;
1578       break;
1579 
1580     case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
1581 
1582       offset = (uint8_t)(p_t2t->ndef_read_block_num - p_t2t->block_read) *
1583                T2T_BLOCK_SIZE;
1584       /* Backup read block */
1585       memcpy(p_t2t->ndef_read_block, &p_data[offset], T2T_BLOCK_LEN);
1586 
1587       /* Update the block with new NDEF Message */
1588       if (rw_t2t_write_ndef_next_block(p_t2t->ndef_read_block_num, 0x0000,
1589                                        false) != NFC_STATUS_OK)
1590         failed = true;
1591       break;
1592 
1593     case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
1594     case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
1595       if (rw_t2t_is_read_before_write_block(
1596               (uint16_t)(p_t2t->block_written + 1), &block) == true) {
1597         p_t2t->ndef_read_block_num = block;
1598         /* If only part of the block is going to be updated read the block to
1599            retain previous data for
1600            unchanged part of the block */
1601         if (rw_t2t_read_ndef_next_block(block) != NFC_STATUS_OK) failed = true;
1602       } else {
1603         if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK) {
1604           /* Directly write the block with new NDEF contents as whole block is
1605            * going to be updated */
1606           if (rw_t2t_write_ndef_next_block(block, p_t2t->new_ndef_msg_len,
1607                                            true) != NFC_STATUS_OK)
1608             failed = true;
1609         } else {
1610           /* Directly write the block with new NDEF contents as whole block is
1611            * going to be updated */
1612           if (rw_t2t_write_ndef_next_block(block, 0x0000, false) !=
1613               NFC_STATUS_OK)
1614             failed = true;
1615         }
1616       }
1617       break;
1618 
1619     case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
1620       /* Write the next block for new NDEF Message */
1621       p_t2t->ndef_write_block = p_t2t->ndef_header_offset / T2T_BLOCK_SIZE;
1622       if (rw_t2t_is_read_before_write_block((uint16_t)(p_t2t->ndef_write_block),
1623                                             &block) == true) {
1624         /* If only part of the block is going to be updated read the block to
1625            retain previous data for
1626            part of the block thats not going to be changed */
1627         p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK;
1628         if (rw_t2t_read(block) != NFC_STATUS_OK) failed = true;
1629 
1630       } else {
1631         /* Update NDEF Message Length in the Tag */
1632         if (rw_t2t_write_ndef_first_block(p_t2t->new_ndef_msg_len, true) !=
1633             NFC_STATUS_OK)
1634           failed = true;
1635       }
1636       break;
1637 
1638     case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
1639       /* Backup read block */
1640       memcpy(p_t2t->ndef_read_block, p_data, T2T_BLOCK_LEN);
1641 
1642       /* Update the block with new NDEF Message */
1643       if (rw_t2t_write_ndef_next_block(p_t2t->block_read,
1644                                        p_t2t->new_ndef_msg_len,
1645                                        true) == NFC_STATUS_OK)
1646         p_t2t->ndef_write_block = p_t2t->block_read + 1;
1647       else
1648         failed = true;
1649 
1650       break;
1651 
1652     case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
1653       status = rw_t2t_add_terminator_tlv();
1654       if (status == NFC_STATUS_CONTINUE)
1655         done = true;
1656       else if (status != NFC_STATUS_OK)
1657         failed = true;
1658       break;
1659 
1660     case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
1661       done = true;
1662       break;
1663 
1664     default:
1665       break;
1666   }
1667 
1668   if (failed || done) {
1669     evt_data.p_data = nullptr;
1670     /* NDEF WRITE Operation is done, inform up the stack */
1671     evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1672     if (done) {
1673       if ((p_t2t->ndef_msg_len >= 0x00FF) &&
1674           (p_t2t->new_ndef_msg_len < 0x00FF)) {
1675         p_t2t->ndef_msg_offset -= 2;
1676       } else if ((p_t2t->new_ndef_msg_len >= 0x00FF) &&
1677                  (p_t2t->ndef_msg_len < 0x00FF)) {
1678         p_t2t->ndef_msg_offset += 2;
1679       }
1680       p_t2t->ndef_msg_len = p_t2t->new_ndef_msg_len;
1681     }
1682     rw_t2t_handle_op_complete();
1683     tRW_DATA rw_data;
1684     rw_data.data = evt_data;
1685     (*rw_cb.p_cback)(RW_T2T_NDEF_WRITE_EVT, &rw_data);
1686   }
1687 }
1688 
1689 /*******************************************************************************
1690 **
1691 ** Function         rw_t2t_get_tag_size
1692 **
1693 ** Description      This function calculates tag data area size from data read
1694 **                  from block with version number
1695 **
1696 ** Returns          TMS of the tag
1697 **
1698 *******************************************************************************/
rw_t2t_get_tag_size(uint8_t * p_data)1699 static uint8_t rw_t2t_get_tag_size(uint8_t* p_data) {
1700   uint16_t LchunkSize = 0;
1701   uint16_t Num_LChuncks = 0;
1702   uint16_t tms = 0;
1703 
1704   LchunkSize = (uint16_t)p_data[2] << 8 | p_data[3];
1705   Num_LChuncks = (uint16_t)p_data[4] << 8 | p_data[5];
1706 
1707   tms = (uint16_t)(LchunkSize * Num_LChuncks);
1708 
1709   tms += (T2T_STATIC_SIZE - T2T_HEADER_SIZE);
1710 
1711   tms /= 0x08;
1712 
1713   return (uint8_t)tms;
1714 }
1715 
1716 /*******************************************************************************
1717 **
1718 ** Function         rw_t2t_handle_config_tag_readonly
1719 **
1720 ** Description      This function handles configure type 2 tag as read only
1721 **
1722 ** Returns          none
1723 **
1724 *******************************************************************************/
rw_t2t_handle_config_tag_readonly(uint8_t * p_data)1725 static void rw_t2t_handle_config_tag_readonly(uint8_t* p_data) {
1726   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1727   tNFC_STATUS status = NFC_STATUS_FAILED;
1728   bool b_notify = false;
1729   uint8_t write_block[T2T_BLOCK_SIZE];
1730   bool b_pending = false;
1731   uint8_t read_lock = 0;
1732   uint8_t num_locks = 0;
1733   uint16_t offset;
1734 
1735   switch (p_t2t->substate) {
1736     case RW_T2T_SUBSTATE_WAIT_READ_CC:
1737 
1738       /* First soft lock the tag */
1739       rw_t2t_soft_lock_tag();
1740       if (p_t2t->b_hard_lock) {
1741         /* Tag configuration not complete */
1742         status = NFC_STATUS_OK;
1743       }
1744       break;
1745 
1746     case RW_T2T_SUBSTATE_WAIT_SET_CC_RO:
1747 
1748       /* Successfully soft locked! Update Tag header for future reference */
1749       p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] = T2T_CC3_RWA_RO;
1750       if (!p_t2t->b_hard_lock) {
1751         /* Tag configuration complete */
1752         status = NFC_STATUS_OK;
1753         b_notify = true;
1754         break;
1755       } else {
1756         /* Tag configuration not complete */
1757         status = NFC_STATUS_OK;
1758         /* Copy the internal bytes */
1759         memcpy(write_block,
1760                &p_t2t->tag_hdr[T2T_STATIC_LOCK0 - T2T_INTERNAL_BYTES_LEN],
1761                T2T_INTERNAL_BYTES_LEN);
1762         /* Set all Static lock bits */
1763         write_block[T2T_STATIC_LOCK0 % T2T_BLOCK_SIZE] = 0xFF;
1764         write_block[T2T_STATIC_LOCK1 % T2T_BLOCK_SIZE] = 0xFF;
1765         p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
1766         status = rw_t2t_write((T2T_STATIC_LOCK0 / T2T_BLOCK_SIZE), write_block);
1767       }
1768       break;
1769 
1770     case RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
1771 
1772       num_locks = 0;
1773 
1774       while (num_locks < p_t2t->num_lockbytes) {
1775         if (p_t2t->lockbyte[num_locks].lock_status ==
1776             RW_T2T_LOCK_UPDATE_INITIATED) {
1777           /* Update control block as one or more dynamic lock byte (s) are set
1778            */
1779           p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_UPDATED;
1780         }
1781         if (!b_pending &&
1782             p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) {
1783           /* One or more dynamic lock bits are not set */
1784           if (num_locks == 0) {
1785             offset = p_t2t->lock_tlv[p_t2t->lockbyte[0].tlv_index].offset +
1786                      p_t2t->lockbyte[0].byte_index;
1787             if (offset % T2T_BLOCK_SIZE) {
1788               /* For backward compatibility in case the DynLock_Area is not
1789                * aligned to a block boundary, first read the block not to
1790                * overwrite possible NDEF or Reserved data
1791                */
1792               b_pending = true;
1793               read_lock = num_locks;
1794             } else {
1795               /* Write zero in internal byte */
1796               memset(write_block, 0, T2T_BLOCK_SIZE);
1797             }
1798           }
1799         }
1800         num_locks++;
1801       }
1802 
1803       if (b_pending) {
1804         /* Read the block where dynamic lock bits are present to avoid writing
1805          * to NDEF bytes in the same block */
1806         p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK;
1807         status = rw_t2t_read((uint16_t)(offset / T2T_BLOCK_LEN));
1808       } else {
1809         /* Now set the dynamic lock bits present in the block read now */
1810         status = rw_t2t_set_dynamic_lock_bits(write_block);
1811         if (status == NFC_STATUS_CONTINUE) {
1812           /* Tag configuration complete */
1813           status = NFC_STATUS_OK;
1814           b_notify = true;
1815         }
1816       }
1817 
1818       break;
1819 
1820     case RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK:
1821       /* Now set the dynamic lock bits present in the block read now */
1822       status = rw_t2t_set_dynamic_lock_bits(p_data);
1823       break;
1824   }
1825 
1826   if (status != NFC_STATUS_OK || b_notify) {
1827     /* Notify upper layer the result of Configuring Tag as Read only */
1828     tRW_DATA evt;
1829     evt.status = status;
1830     rw_t2t_handle_op_complete();
1831     (*rw_cb.p_cback)(RW_T2T_SET_TAG_RO_EVT, &evt);
1832   }
1833 }
1834 
1835 /*******************************************************************************
1836 **
1837 ** Function         rw_t2t_handle_format_tag_rsp
1838 **
1839 ** Description      This function handles formating a type 2 tag
1840 **
1841 ** Returns          none
1842 **
1843 *******************************************************************************/
rw_t2t_handle_format_tag_rsp(uint8_t * p_data)1844 static void rw_t2t_handle_format_tag_rsp(uint8_t* p_data) {
1845   uint8_t* p;
1846   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1847   tNFC_STATUS status = NFC_STATUS_FAILED;
1848   uint16_t version_no;
1849   const tT2T_INIT_TAG* p_ret;
1850   uint8_t tms;
1851   uint8_t next_block = T2T_FIRST_DATA_BLOCK + 1;
1852   uint16_t addr, locked_area;
1853   bool b_notify = false;
1854 
1855   p = p_t2t->ndef_final_block;
1856   UINT8_TO_BE_STREAM(p, p_t2t->tlv_value[2]);
1857 
1858   switch (p_t2t->substate) {
1859     case RW_T2T_SUBSTATE_WAIT_READ_CC:
1860       /* Start format operation */
1861       status = rw_t2t_format_tag();
1862       break;
1863 
1864     case RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO:
1865 
1866       memcpy(p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
1867       p_t2t->b_read_data = true;
1868       version_no = (uint16_t)p_data[0] << 8 | p_data[1];
1869       p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], true, version_no);
1870       if (p_ret != nullptr) {
1871         /* Valid Version Number */
1872         if (p_ret->b_calc_cc) /* Calculate tag size from Version Information */
1873           tms = rw_t2t_get_tag_size(p_data);
1874 
1875         else
1876           /* Tag size from Look up table */
1877           tms = p_ret->tms;
1878 
1879         /* Set CC with the Tag size from look up table or from calculated value
1880          */
1881         status = rw_t2t_set_cc(tms);
1882       }
1883       break;
1884 
1885     case RW_T2T_SUBSTATE_WAIT_SET_CC:
1886 
1887       version_no = (uint16_t)p_t2t->tag_data[0] << 8 | p_t2t->tag_data[1];
1888       if ((version_no == 0) ||
1889           ((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], true, version_no)) ==
1890            nullptr) ||
1891           (!p_ret->b_multi_version) || (!p_ret->b_calc_cc)) {
1892         /* Currently Formating a non blank tag or a blank tag with manufacturer
1893          * has only one variant of tag. Set Null NDEF TLV and complete Format
1894          * Operation */
1895         next_block = T2T_FIRST_DATA_BLOCK;
1896         p = p_t2t->ndef_final_block;
1897       } else {
1898         addr = (uint16_t)(
1899             ((uint16_t)p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) *
1900                 ((uint16_t)p_t2t->tag_data[4] << 8 | p_t2t->tag_data[5]) +
1901             T2T_STATIC_SIZE);
1902         locked_area = ((uint16_t)p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) *
1903                       ((uint16_t)p_t2t->tag_data[6]);
1904 
1905         status = rw_t2t_set_lock_tlv(addr, p_t2t->tag_data[7], locked_area);
1906         if (status == NFC_STATUS_REJECTED) {
1907           /* Cannot calculate Lock TLV. Set Null NDEF TLV and complete Format
1908            * Operation */
1909           next_block = T2T_FIRST_DATA_BLOCK;
1910           p = p_t2t->ndef_final_block;
1911         } else
1912           break;
1913       }
1914       FALLTHROUGH_INTENDED;
1915 
1916     case RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV:
1917 
1918       /* Prepare NULL NDEF TLV, TERMINATOR_TLV */
1919       UINT8_TO_BE_STREAM(p, TAG_NDEF_TLV);
1920       UINT8_TO_BE_STREAM(p, 0);
1921 
1922       if (((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != nullptr) &&
1923           (!p_ret->b_otp)) {
1924         UINT8_TO_BE_STREAM(p, TAG_TERMINATOR_TLV);
1925       } else
1926         UINT8_TO_BE_STREAM(p, 0);
1927 
1928       p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF;
1929       /* send WRITE-E8 command */
1930       status = rw_t2t_write(next_block, p_t2t->ndef_final_block);
1931       if (status == NFC_STATUS_OK) p_t2t->b_read_data = false;
1932       break;
1933 
1934     case RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF:
1935       /* Tag Formated successfully */
1936       status = NFC_STATUS_OK;
1937       b_notify = true;
1938       break;
1939 
1940     default:
1941       break;
1942   }
1943 
1944   if (status != NFC_STATUS_OK || b_notify) {
1945     /* Notify upper layer the result of Format op */
1946     tRW_DATA evt;
1947     evt.status = status;
1948     rw_t2t_handle_op_complete();
1949     (*rw_cb.p_cback)(RW_T2T_FORMAT_CPLT_EVT, &evt);
1950   }
1951 }
1952 
1953 /*******************************************************************************
1954 **
1955 ** Function         rw_t2t_update_attributes
1956 **
1957 ** Description      This function will update attribute for the current segment
1958 **                  based on lock and reserved bytes
1959 **
1960 ** Returns          None
1961 **
1962 *******************************************************************************/
rw_t2t_update_attributes(void)1963 static void rw_t2t_update_attributes(void) {
1964   uint8_t count = 0;
1965   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1966   uint16_t lower_offset;
1967   uint16_t upper_offset;
1968   uint16_t offset;
1969   uint16_t offset_in_seg;
1970   uint16_t block_boundary;
1971   uint8_t num_internal_bytes;
1972   uint8_t num_bytes;
1973 
1974   /* Prepare attr for the current segment */
1975   memset(p_t2t->attr, 0, RW_T2T_SEGMENT_SIZE * sizeof(uint8_t));
1976 
1977   /* calculate offset where the current segment starts in the tag */
1978   lower_offset = p_t2t->segment * RW_T2T_SEGMENT_BYTES;
1979   /* calculate offset where the current segment ends in the tag */
1980   upper_offset = (p_t2t->segment + 1) * RW_T2T_SEGMENT_BYTES;
1981 
1982   /* check offset of lock bytes in the tag and update p_t2t->attr
1983    * for every lock byte that is present in the current segment */
1984   count = 0;
1985   while (count < p_t2t->num_lockbytes) {
1986     offset = p_t2t->lock_tlv[p_t2t->lockbyte[count].tlv_index].offset +
1987              p_t2t->lockbyte[count].byte_index;
1988     if (offset >= lower_offset && offset < upper_offset) {
1989       /* Calculate offset in the current segment as p_t2t->attr is prepared for
1990        * one segment only */
1991       offset_in_seg = offset % RW_T2T_SEGMENT_BYTES;
1992       /* Every bit in p_t2t->attr indicates one byte of the tag is either a
1993        * lock/reserved byte or not
1994        * So, each array element in p_t2t->attr covers two blocks in the tag as
1995        * T2 block size is 4 and array element size is 8
1996        * Set the corresponding bit in attr to indicate - reserved byte */
1997       p_t2t->attr[offset_in_seg / TAG_BITS_PER_BYTE] |=
1998           rw_t2t_mask_bits[offset_in_seg % TAG_BITS_PER_BYTE];
1999     }
2000     count++;
2001   }
2002 
2003   block_boundary = (offset + 1) % T2T_BLOCK_LEN;
2004   if (block_boundary) {
2005     /* End of DynLock_Area is not aligned to a block boundary. The bytes that
2006      * are not part of the area within the same block are Internal Bytes (see
2007      * [T2T-TS] section 4.7).
2008      * According to REQ 4.4.1.5, either write them to 00h or to their existing
2009      * values. However according to the NDEF Write procedure, REQ 7.5.5.5,
2010      * symbol 5, the Reader SHALL not write to the DynLock_Area and the
2011      * Rsvd_Area(s), as indicated by the Lock Control TLV or the Memory
2012      * Control TLVs, if any.
2013      * Choice is made to consider the bytes within the same block as the
2014      * DynLock_Area last bytes as lock bytes i.e. they will not be written
2015      * and therefore previously read (steps anyhow not expected by NFC Forum
2016      * Test Specifications).
2017      */
2018     num_internal_bytes = T2T_BLOCK_LEN - block_boundary;
2019     count = 1;
2020 
2021     while (count <= num_internal_bytes) {
2022       offset++;
2023       if (offset >= lower_offset && offset < upper_offset) {
2024         /* Calculate offset in the current segment as p_t2t->attr is prepared
2025          * for one segment only */
2026         offset_in_seg = offset % RW_T2T_SEGMENT_BYTES;
2027         /* Every bit in p_t2t->attr indicates one byte of the tag is either a
2028          * lock/reserved/internal byte or not
2029          * So, each array element in p_t2t->attr covers two blocks in the tag as
2030          * T2 block size is 4 and array element size is 8
2031          * Set the corresponding bit in attr to indicate - reserved byte */
2032         p_t2t->attr[offset_in_seg / TAG_BITS_PER_BYTE] |=
2033             rw_t2t_mask_bits[offset_in_seg % TAG_BITS_PER_BYTE];
2034       }
2035       count++;
2036     }
2037   }
2038   /* Search reserved bytes identified by all memory tlvs present in the tag */
2039   count = 0;
2040   while (count < p_t2t->num_mem_tlvs) {
2041     /* check the offset of reserved bytes in the tag and update  p_t2t->attr
2042      * for every  reserved byte that is present in the current segment */
2043     num_bytes = 0;
2044     while (num_bytes < p_t2t->mem_tlv[count].num_bytes) {
2045       offset = p_t2t->mem_tlv[count].offset + num_bytes;
2046       if (offset >= lower_offset && offset < upper_offset) {
2047         /* Let offset represents offset in the current segment as p_t2t->attr is
2048          * prepared for one segment only */
2049         offset %= RW_T2T_SEGMENT_BYTES;
2050         /* Every bit in p_t2t->attr indicates one byte of the tag is either a
2051          * lock/reserved byte or not
2052          * So, each array element in p_t2t->attr covers two blocks in the tag as
2053          * T2 block size is 4 and array element size is 8
2054          * Set the corresponding bit in attr to indicate - reserved byte */
2055         p_t2t->attr[offset / TAG_BITS_PER_BYTE] |=
2056             rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
2057       }
2058       num_bytes++;
2059     }
2060     count++;
2061   }
2062 }
2063 
2064 /*******************************************************************************
2065 **
2066 ** Function         rw_t2t_get_lock_bits_for_segment
2067 **
2068 ** Description      This function returns the offset of lock bits associated for
2069 **                  the specified segment
2070 **
2071 ** Parameters:      segment: The segment number to which lock bits are
2072 **                           associated
2073 **                  p_start_byte: The offset of lock byte that contains the
2074 **                                first lock bit for the segment
2075 **                  p_start_bit:  The offset of the lock bit in the lock byte
2076 **
2077 **                  p_end_byte:   The offset of the last bit associcated to the
2078 **                                segment
2079 **
2080 ** Returns          Total number of lock bits assigned to the specified segment
2081 **
2082 *******************************************************************************/
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)2083 static uint8_t rw_t2t_get_lock_bits_for_segment(uint8_t segment,
2084                                                 uint8_t* p_start_byte,
2085                                                 uint8_t* p_start_bit,
2086                                                 uint8_t* p_end_byte) {
2087   uint8_t total_bits = 0;
2088   uint16_t byte_count = 0;
2089   uint16_t lower_offset, upper_offset;
2090   uint8_t num_dynamic_locks = 0;
2091   uint8_t bit_count = 0;
2092   uint16_t bytes_locked_per_bit;
2093   uint8_t num_bits;
2094   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2095   bool b_all_bits_are_locks = true;
2096   uint16_t tag_size;
2097   uint8_t xx;
2098 
2099   tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
2100              (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_SIZE) + p_t2t->num_lockbytes;
2101 
2102   for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
2103     tag_size += p_t2t->mem_tlv[xx].num_bytes;
2104 
2105   lower_offset = segment * RW_T2T_SEGMENT_BYTES;
2106   if (segment == 0) {
2107     lower_offset += T2T_STATIC_SIZE;
2108   }
2109   upper_offset = (segment + 1) * RW_T2T_SEGMENT_BYTES;
2110 
2111   byte_count = T2T_STATIC_SIZE;
2112   if (tag_size < upper_offset) {
2113     upper_offset = tag_size;
2114   }
2115 
2116   *p_start_byte = num_dynamic_locks;
2117   *p_start_bit = 0;
2118 
2119   while ((byte_count <= lower_offset) &&
2120          (num_dynamic_locks < p_t2t->num_lockbytes)) {
2121     bytes_locked_per_bit =
2122         p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2123             .bytes_locked_per_bit;
2124     /* Number of bits in the current lock byte */
2125     b_all_bits_are_locks =
2126         ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) *
2127              TAG_BITS_PER_BYTE <=
2128          p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2129              .num_bits);
2130     num_bits =
2131         b_all_bits_are_locks
2132             ? TAG_BITS_PER_BYTE
2133             : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2134                       .num_bits %
2135                   TAG_BITS_PER_BYTE;
2136 
2137     if (((bytes_locked_per_bit * num_bits) + byte_count) <= lower_offset) {
2138       /* Skip this lock byte as it covers different segment */
2139       byte_count += bytes_locked_per_bit * num_bits;
2140       num_dynamic_locks++;
2141     } else {
2142       bit_count = 0;
2143       while (bit_count < num_bits) {
2144         byte_count += bytes_locked_per_bit;
2145         if (byte_count > lower_offset) {
2146           /* First lock bit that is used to lock this segment */
2147           *p_start_byte = num_dynamic_locks;
2148           *p_end_byte = num_dynamic_locks;
2149           *p_start_bit = bit_count;
2150           bit_count++;
2151           total_bits = 1;
2152           break;
2153         }
2154         bit_count++;
2155       }
2156     }
2157   }
2158   if (num_dynamic_locks == p_t2t->num_lockbytes) {
2159     return 0;
2160   }
2161   while ((byte_count < upper_offset) &&
2162          (num_dynamic_locks < p_t2t->num_lockbytes)) {
2163     bytes_locked_per_bit =
2164         p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2165             .bytes_locked_per_bit;
2166     /* Number of bits in the current lock byte */
2167     b_all_bits_are_locks =
2168         ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) *
2169              TAG_BITS_PER_BYTE <=
2170          p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2171              .num_bits);
2172     num_bits =
2173         b_all_bits_are_locks
2174             ? TAG_BITS_PER_BYTE
2175             : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2176                       .num_bits %
2177                   TAG_BITS_PER_BYTE;
2178 
2179     if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count <
2180         upper_offset) {
2181       /* Collect all lock bits that covers the current segment */
2182       byte_count += bytes_locked_per_bit * (num_bits - bit_count);
2183       total_bits += num_bits - bit_count;
2184       bit_count = 0;
2185       *p_end_byte = num_dynamic_locks;
2186       num_dynamic_locks++;
2187     } else {
2188       /* The last lock byte that covers the current segment */
2189       bit_count = 0;
2190       while (bit_count < num_bits) {
2191         /* The last lock bit that is used to lock this segment */
2192         byte_count += bytes_locked_per_bit;
2193         if (byte_count >= upper_offset) {
2194           *p_end_byte = num_dynamic_locks;
2195           total_bits += (bit_count + 1);
2196           break;
2197         }
2198         bit_count++;
2199       }
2200     }
2201   }
2202   return total_bits;
2203 }
2204 
2205 /*******************************************************************************
2206 **
2207 ** Function         rw_t2t_update_lock_attributes
2208 **
2209 ** Description      This function will check if the tag index passed as
2210 **                  argument is a locked byte and return TRUE or FALSE
2211 **
2212 ** Parameters:      index, the index of the byte in the tag
2213 **
2214 **
2215 ** Returns          TRUE, if the specified index in the tag is a locked or
2216 **                        reserved or otp byte
2217 **                  FALSE, otherwise
2218 **
2219 *******************************************************************************/
rw_t2t_update_lock_attributes(void)2220 static void rw_t2t_update_lock_attributes(void) {
2221   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2222   uint8_t xx = 0;
2223   uint8_t num_static_lock_bytes = 0;
2224   uint8_t num_dyn_lock_bytes = 0;
2225   uint8_t bits_covered = 0;
2226   uint16_t bytes_covered = 0;
2227   uint8_t block_count = 0;
2228   bool b_all_bits_are_locks = true;
2229   uint16_t bytes_locked_per_lock_bit;
2230   uint8_t start_lock_byte;
2231   uint8_t start_lock_bit;
2232   uint8_t end_lock_byte;
2233   uint8_t num_lock_bits;
2234   uint8_t total_bits;
2235 
2236   /* Prepare lock_attr for the current segment */
2237   memset(p_t2t->lock_attr, 0, RW_T2T_SEGMENT_SIZE * sizeof(uint8_t));
2238 
2239   block_count = 0;
2240   if (p_t2t->segment == 0) {
2241     /* Update lock_attributes based on static lock bytes */
2242     xx = 0;
2243     num_static_lock_bytes = 0;
2244     block_count = 0;
2245     num_lock_bits =
2246         TAG_BITS_PER_BYTE - 1; /* the inner while loop increases xx by 2. need
2247                                   (-1) to avoid coverity overrun error */
2248 
2249     while (num_static_lock_bytes < T2T_NUM_STATIC_LOCK_BYTES) {
2250       /* Update lock attribute based on 2 static locks */
2251       while (xx < num_lock_bits) {
2252         p_t2t->lock_attr[block_count] = 0x00;
2253 
2254         if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] &
2255             rw_t2t_mask_bits[xx++]) {
2256           /* If the bit is set then 1 block is locked */
2257           p_t2t->lock_attr[block_count] = 0x0F;
2258         }
2259 
2260         if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] &
2261             rw_t2t_mask_bits[xx++]) {
2262           /* If the bit is set then 1 block is locked */
2263           p_t2t->lock_attr[block_count] |= 0xF0;
2264         }
2265         block_count++;
2266       }
2267       num_static_lock_bytes++;
2268       xx = 0;
2269     }
2270     /* UID is always locked, irrespective of the lock value */
2271     p_t2t->lock_attr[0x00] = 0xFF;
2272   }
2273 
2274   /* Get lock bits applicable for the current segment */
2275   total_bits = rw_t2t_get_lock_bits_for_segment(
2276       p_t2t->segment, &start_lock_byte, &start_lock_bit, &end_lock_byte);
2277   if (total_bits != 0) {
2278     /* update lock_attributes based on current segment using dynamic lock bytes
2279      */
2280     xx = start_lock_bit;
2281     num_dyn_lock_bytes = start_lock_byte;
2282     bits_covered = 0;
2283     bytes_covered = 0;
2284     num_lock_bits = TAG_BITS_PER_BYTE;
2285     p_t2t->lock_attr[block_count] = 0;
2286 
2287     while (num_dyn_lock_bytes <= end_lock_byte) {
2288       bytes_locked_per_lock_bit =
2289           p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
2290               .bytes_locked_per_bit;
2291       /* Find number of bits in the byte are lock bits */
2292       b_all_bits_are_locks =
2293           ((p_t2t->lockbyte[num_dyn_lock_bytes].byte_index + 1) *
2294                TAG_BITS_PER_BYTE <=
2295            p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
2296                .num_bits);
2297       num_lock_bits =
2298           b_all_bits_are_locks
2299               ? TAG_BITS_PER_BYTE
2300               : p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
2301                         .num_bits %
2302                     TAG_BITS_PER_BYTE;
2303 
2304       while (xx < num_lock_bits) {
2305         bytes_covered = 0;
2306         while (bytes_covered < bytes_locked_per_lock_bit) {
2307           if (p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte &
2308               rw_t2t_mask_bits[xx]) {
2309             /* If the bit is set then it is locked */
2310             if (block_count < RW_T2T_SEGMENT_SIZE)
2311               p_t2t->lock_attr[block_count] |= 0x01 << bits_covered;
2312           }
2313           bytes_covered++;
2314           bits_covered++;
2315           if (bits_covered == TAG_BITS_PER_BYTE) {
2316             /* Move to next 8 bytes */
2317             bits_covered = 0;
2318             block_count++;
2319             /* Assume unlocked before updating using locks */
2320             if (block_count < RW_T2T_SEGMENT_SIZE)
2321               p_t2t->lock_attr[block_count] = 0;
2322           }
2323         }
2324         xx++;
2325       }
2326       num_dyn_lock_bytes++;
2327       xx = 0;
2328     }
2329   }
2330 }
2331 
2332 /*******************************************************************************
2333 **
2334 ** Function         rw_t2t_is_lock_res_byte
2335 **
2336 ** Description      This function will check if the tag index passed as
2337 **                  argument is a lock or reserved or otp byte and return
2338 **                  TRUE or FALSE
2339 **
2340 ** Parameters:      index, the index of the byte in the tag
2341 **
2342 **
2343 ** Returns          TRUE, if the specified index in the tag is a locked or
2344 **                        reserved or otp byte
2345 **                  FALSE, otherwise
2346 **
2347 *******************************************************************************/
rw_t2t_is_lock_res_byte(uint16_t index)2348 static bool rw_t2t_is_lock_res_byte(uint16_t index) {
2349   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2350 
2351   p_t2t->segment = (uint8_t)(index / RW_T2T_SEGMENT_BYTES);
2352 
2353   if (p_t2t->attr_seg != p_t2t->segment) {
2354     /* Update attributes for the current segment */
2355     rw_t2t_update_attributes();
2356     p_t2t->attr_seg = p_t2t->segment;
2357   }
2358 
2359   index = index % RW_T2T_SEGMENT_BYTES;
2360   /* Every bit in p_t2t->attr indicates one specific byte of the tag is either a
2361    * lock/reserved byte or not
2362    * So, each array element in p_t2t->attr covers two blocks in the tag as T2
2363    * block size is 4 and array element size is 8
2364    * Find the block and offset for the index (passed as argument) and Check if
2365    * the offset bit in the
2366    * p_t2t->attr[block/2] is set or not. If the bit is set then it is a
2367    * lock/reserved byte, otherwise not */
2368 
2369   return ((p_t2t->attr[index / 8] & rw_t2t_mask_bits[index % 8]) == 0) ? false
2370                                                                        : true;
2371 }
2372 
2373 /*******************************************************************************
2374 **
2375 ** Function         rw_t2t_is_read_only_byte
2376 **
2377 ** Description      This function will check if the tag index passed as
2378 **                  argument is a locked and return
2379 **                  TRUE or FALSE
2380 **
2381 ** Parameters:      index, the index of the byte in the tag
2382 **
2383 **
2384 ** Returns          TRUE, if the specified index in the tag is a locked or
2385 **                        reserved or otp byte
2386 **                  FALSE, otherwise
2387 **
2388 *******************************************************************************/
rw_t2t_is_read_only_byte(uint16_t index)2389 static bool rw_t2t_is_read_only_byte(uint16_t index) {
2390   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2391 
2392   p_t2t->segment = (uint8_t)(index / RW_T2T_SEGMENT_BYTES);
2393 
2394   if (p_t2t->lock_attr_seg != p_t2t->segment) {
2395     /* Update lock attributes for the current segment */
2396     rw_t2t_update_lock_attributes();
2397     p_t2t->lock_attr_seg = p_t2t->segment;
2398   }
2399 
2400   index = index % RW_T2T_SEGMENT_BYTES;
2401   /* Every bit in p_t2t->lock_attr indicates one specific byte of the tag is a
2402    * read only byte or read write byte
2403    * So, each array element in p_t2t->lock_attr covers two blocks of the tag as
2404    * T2 block size is 4 and array element size is 8
2405    * Find the block and offset for the index (passed as argument) and Check if
2406    * the offset bit in
2407    * p_t2t->lock_attr[block/2] is set or not. If the bit is set then it is a
2408    * read only byte, otherwise read write byte */
2409 
2410   return ((p_t2t->lock_attr[index / 8] & rw_t2t_mask_bits[index % 8]) == 0)
2411              ? false
2412              : true;
2413 }
2414 
2415 /*******************************************************************************
2416 **
2417 ** Function         rw_t2t_set_dynamic_lock_bits
2418 **
2419 ** Description      This function will set dynamic lock bits as part of
2420 **                  configuring tag as read only
2421 **
2422 ** Returns
2423 **                  NFC_STATUS_OK, Command sent to set dynamic lock bits
2424 **                  NFC_STATUS_FAILED: otherwise
2425 **
2426 *******************************************************************************/
rw_t2t_set_dynamic_lock_bits(uint8_t * p_data)2427 tNFC_STATUS rw_t2t_set_dynamic_lock_bits(uint8_t* p_data) {
2428   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2429   uint8_t write_block[T2T_BLOCK_SIZE];
2430   uint16_t offset;
2431   uint16_t next_offset;
2432   uint8_t num_bits;
2433   uint8_t next_num_bits;
2434   tNFC_STATUS status = NFC_STATUS_FAILED;
2435   uint8_t num_locks;
2436   uint8_t lock_count;
2437   bool b_all_bits_are_locks = true;
2438 
2439   num_locks = 0;
2440 
2441   memcpy(write_block, p_data, T2T_BLOCK_SIZE);
2442   while (num_locks < p_t2t->num_lockbytes) {
2443     if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) {
2444       offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
2445                p_t2t->lockbyte[num_locks].byte_index;
2446 
2447       /* Check if all bits are lock bits in the byte */
2448       b_all_bits_are_locks =
2449           ((p_t2t->lockbyte[num_locks].byte_index + 1) * TAG_BITS_PER_BYTE <=
2450            p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits);
2451       num_bits =
2452           b_all_bits_are_locks
2453               ? TAG_BITS_PER_BYTE
2454               : p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits %
2455                     TAG_BITS_PER_BYTE;
2456 
2457       write_block[(uint8_t)(offset % T2T_BLOCK_SIZE)] |=
2458           tags_pow(2, num_bits) - 1;
2459       lock_count = num_locks + 1;
2460 
2461       /* Set all the lock bits in the block using a sing block write command */
2462       while (lock_count < p_t2t->num_lockbytes) {
2463         next_offset =
2464             p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].offset +
2465             p_t2t->lockbyte[lock_count].byte_index;
2466 
2467         /* Check if all bits are lock bits in the byte */
2468         b_all_bits_are_locks =
2469             ((p_t2t->lockbyte[lock_count].byte_index + 1) * TAG_BITS_PER_BYTE <=
2470              p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits);
2471         next_num_bits =
2472             b_all_bits_are_locks
2473                 ? TAG_BITS_PER_BYTE
2474                 : p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index]
2475                           .num_bits %
2476                       TAG_BITS_PER_BYTE;
2477 
2478         if (next_offset / T2T_BLOCK_SIZE == offset / T2T_BLOCK_SIZE) {
2479           write_block[(uint8_t)(next_offset % T2T_BLOCK_SIZE)] |=
2480               tags_pow(2, next_num_bits) - 1;
2481         } else
2482           break;
2483         lock_count++;
2484       }
2485 
2486       p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
2487       /* send WRITE command to set dynamic lock bits */
2488       status = rw_t2t_write((uint16_t)(offset / T2T_BLOCK_SIZE), write_block);
2489       if (status == NFC_STATUS_OK) {
2490         while (lock_count > num_locks) {
2491           /* Set update initiated flag to indicate a write command is sent to
2492            * set dynamic lock bits of the block */
2493           p_t2t->lockbyte[lock_count - 1].lock_status =
2494               RW_T2T_LOCK_UPDATE_INITIATED;
2495           lock_count--;
2496         }
2497       } else
2498         status = NFC_STATUS_FAILED;
2499 
2500       break;
2501 
2502     } else {
2503       status = NFC_STATUS_CONTINUE;
2504     }
2505     num_locks++;
2506   }
2507 
2508   return status;
2509 }
2510 
2511 /*******************************************************************************
2512 **
2513 ** Function         rw_t2t_set_lock_tlv
2514 **
2515 ** Description      This function will set lock control tlv on the blank
2516 **                  activated type 2 tag based on values read from version block
2517 **
2518 ** Parameters:      TAG data memory size
2519 **
2520 ** Returns
2521 **                  NFC_STATUS_OK, Command sent to set Lock TLV
2522 **                  NFC_STATUS_FAILED: otherwise
2523 **
2524 *******************************************************************************/
rw_t2t_set_lock_tlv(uint16_t addr,uint8_t num_dyn_lock_bits,uint16_t locked_area_size)2525 tNFC_STATUS rw_t2t_set_lock_tlv(uint16_t addr, uint8_t num_dyn_lock_bits,
2526                                 uint16_t locked_area_size) {
2527   tNFC_STATUS status = NFC_STATUS_FAILED;
2528   int8_t PageAddr = 0;
2529   int8_t BytePerPage = 0;
2530   int8_t ByteOffset = 0;
2531   uint8_t a;
2532   uint8_t data_block[T2T_BLOCK_SIZE];
2533   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2534   uint8_t* p;
2535   uint8_t xx;
2536 
2537   for (xx = 15; xx > 0; xx--) {
2538     a = (uint8_t)(addr / xx);
2539     a += (addr % xx) ? 1 : 0;
2540 
2541     BytePerPage = (int8_t)tags_log2(a);
2542     ByteOffset = (int8_t)(addr - xx * tags_pow(2, BytePerPage));
2543 
2544     if (ByteOffset < 16) {
2545       PageAddr = xx;
2546       break;
2547     }
2548   }
2549 
2550   if ((ByteOffset < 16) && (BytePerPage < 16) && (PageAddr < 16)) {
2551     memset(data_block, 0, T2T_BLOCK_SIZE);
2552     p = data_block;
2553     UINT8_TO_BE_STREAM(p, T2T_TLV_TYPE_LOCK_CTRL);
2554     UINT8_TO_BE_STREAM(p, T2T_TLEN_LOCK_CTRL_TLV);
2555     UINT8_TO_BE_STREAM(p, (PageAddr << 4 | ByteOffset));
2556     UINT8_TO_BE_STREAM(p, num_dyn_lock_bits);
2557 
2558     p_t2t->tlv_value[0] = PageAddr << 4 | ByteOffset;
2559     p_t2t->tlv_value[1] = num_dyn_lock_bits;
2560     p_t2t->tlv_value[2] =
2561         (uint8_t)(BytePerPage << 4 | tags_log2(locked_area_size));
2562 
2563     p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV;
2564 
2565     /* send WRITE-E8 command */
2566     status = rw_t2t_write(T2T_FIRST_DATA_BLOCK, data_block);
2567     if (status == NFC_STATUS_OK) {
2568       p_t2t->b_read_data = false;
2569     } else
2570       p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2571   } else
2572     status = NFC_STATUS_REJECTED;
2573 
2574   return status;
2575 }
2576 
2577 /*******************************************************************************
2578 **
2579 ** Function         rw_t2t_set_cc
2580 **
2581 ** Description      This function will set Capability Container on the activated
2582 **                  type 2 tag with default values of CC0, CC1, CC4 and
2583 **                  specified CC3 value
2584 **
2585 ** Parameters:      CC3 value of the tag
2586 **
2587 ** Returns
2588 **                  NFC_STATUS_OK, Command sent to set CC
2589 **                  NFC_STATUS_FAILED: otherwise
2590 **
2591 *******************************************************************************/
rw_t2t_set_cc(uint8_t tms)2592 tNFC_STATUS rw_t2t_set_cc(uint8_t tms) {
2593   uint8_t cc_block[T2T_BLOCK_SIZE];
2594   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2595   tNFC_STATUS status = NFC_STATUS_FAILED;
2596   uint8_t* p;
2597 
2598   memset(cc_block, 0, T2T_BLOCK_SIZE);
2599   memset(p_t2t->ndef_final_block, 0, T2T_BLOCK_SIZE);
2600   p = cc_block;
2601 
2602   /* Prepare Capability Container */
2603   UINT8_TO_BE_STREAM(p, T2T_CC0_NMN);
2604   UINT8_TO_BE_STREAM(p, T2T_CC1_VNO);
2605   UINT8_TO_BE_STREAM(p, tms);
2606   UINT8_TO_BE_STREAM(p, T2T_CC3_RWA_RW);
2607 
2608   p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC;
2609 
2610   /* send WRITE-E8 command */
2611   status = rw_t2t_write(T2T_CC_BLOCK, cc_block);
2612   if (status == NFC_STATUS_OK) {
2613     p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2614     p_t2t->b_read_hdr = false;
2615   } else
2616     p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2617 
2618   return status;
2619 }
2620 
2621 /*******************************************************************************
2622 **
2623 ** Function         rw_t2t_format_tag
2624 **
2625 ** Description      This function will format tag based on Manufacturer ID
2626 **
2627 ** Returns
2628 **                  NFC_STATUS_OK, Command sent to format Tag
2629 **                  NFC_STATUS_FAILED: otherwise
2630 **
2631 *******************************************************************************/
rw_t2t_format_tag(void)2632 tNFC_STATUS rw_t2t_format_tag(void) {
2633   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2634   const tT2T_INIT_TAG* p_ret;
2635   uint8_t tms;
2636   tNFC_STATUS status = NFC_STATUS_FAILED;
2637   bool b_blank_tag = true;
2638 
2639   p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0);
2640   if (p_ret == nullptr) {
2641     LOG(WARNING) << StringPrintf(
2642         "rw_t2t_format_tag - Unknown Manufacturer ID: %u, Cannot Format the "
2643         "tag!",
2644         p_t2t->tag_hdr[0]);
2645     return (NFC_STATUS_FAILED);
2646   }
2647 
2648   if (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != 0) {
2649     /* If OTP tag has valid NDEF Message, cannot format the tag */
2650     if ((p_t2t->ndef_msg_len > 0) && (p_ret->b_otp)) {
2651       LOG(WARNING) << StringPrintf(
2652           "rw_t2t_format_tag - Cannot Format a OTP tag with NDEF Message!");
2653       return (NFC_STATUS_FAILED);
2654     }
2655 
2656     if (((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0) &&
2657          (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)) ||
2658         ((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != 0) &&
2659          (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) &&
2660          (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) &&
2661          (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO))) {
2662       LOG(WARNING) << StringPrintf(
2663           "rw_t2t_format_tag - Tag not blank to Format!");
2664       return (NFC_STATUS_FAILED);
2665     } else {
2666       tms = p_t2t->tag_hdr[T2T_CC2_TMS_BYTE];
2667       b_blank_tag = false;
2668     }
2669   } else
2670     tms = p_ret->tms;
2671 
2672   memset(p_t2t->tag_data, 0, T2T_READ_DATA_LEN);
2673 
2674   if (!b_blank_tag || !p_ret->b_multi_version) {
2675     status = rw_t2t_set_cc(tms);
2676   } else if (p_ret->version_block != 0) {
2677     /* If Version number is not read, READ it now */
2678     p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
2679 
2680     status = rw_t2t_read(p_ret->version_block);
2681     if (status == NFC_STATUS_OK)
2682       p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2683     else
2684       p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2685   } else {
2686     /* UID block is the version block */
2687     p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2688     p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
2689     rw_t2t_handle_format_tag_rsp(p_t2t->tag_hdr);
2690   }
2691 
2692   return status;
2693 }
2694 
2695 /*******************************************************************************
2696 **
2697 ** Function         rw_t2t_soft_lock_tag
2698 **
2699 ** Description      This function will soft lock the tag after validating CC.
2700 **
2701 ** Returns
2702 **                  NFC_STATUS_OK, Command sent to soft lock the tag
2703 **                  NFC_STATUS_FAILED: otherwise
2704 **
2705 *******************************************************************************/
rw_t2t_soft_lock_tag(void)2706 tNFC_STATUS rw_t2t_soft_lock_tag(void) {
2707   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2708   tNFC_STATUS status = NFC_STATUS_FAILED;
2709   uint8_t write_block[T2T_BLOCK_SIZE];
2710   uint8_t num_locks;
2711 
2712   /* If CC block is read and cc3 is soft locked, reject the command */
2713   if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO) {
2714     LOG(ERROR) << StringPrintf(
2715         "rw_t2t_soft_lock_tag: Error: Type 2 tag is in Read only state, CC3: "
2716         "%u",
2717         p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2718     return (NFC_STATUS_FAILED);
2719   }
2720 
2721   if (p_t2t->b_hard_lock) {
2722     /* Should have performed NDEF Detection on dynamic memory structure tag,
2723      * before permanently converting to Read only
2724      * Even when no lock control tlv is present, default lock bytes should be
2725      * present */
2726 
2727     if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != T2T_CC2_TMS_STATIC) &&
2728         (p_t2t->num_lockbytes == 0)) {
2729       LOG(ERROR) << StringPrintf(
2730           "rw_t2t_soft_lock_tag: Error: Lock TLV not detected! Cannot hard "
2731           "lock the tag");
2732       return (NFC_STATUS_FAILED);
2733     }
2734 
2735     /* On dynamic memory structure tag, reset all lock bytes status to 'Not
2736      * Updated' if not in Updated status */
2737     num_locks = 0;
2738     while (num_locks < p_t2t->num_lockbytes) {
2739       if (p_t2t->lockbyte[num_locks].lock_status != RW_T2T_LOCK_UPDATED)
2740         p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_NOT_UPDATED;
2741       num_locks++;
2742     }
2743   }
2744 
2745   memcpy(write_block, &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], T2T_BLOCK_SIZE);
2746   write_block[(T2T_CC3_RWA_BYTE % T2T_BLOCK_SIZE)] = T2T_CC3_RWA_RO;
2747 
2748   p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC_RO;
2749   /* First Soft lock the tag */
2750   status = rw_t2t_write(T2T_CC_BLOCK, write_block);
2751   if (status == NFC_STATUS_OK) {
2752     p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
2753     p_t2t->b_read_hdr = false;
2754   } else {
2755     p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2756   }
2757   return status;
2758 }
2759 
2760 /*****************************************************************************
2761 **
2762 ** Function         RW_T2tFormatNDef
2763 **
2764 ** Description
2765 **      Format Tag content
2766 **
2767 ** Returns
2768 **      NFC_STATUS_OK, Command sent to format Tag
2769 **      NFC_STATUS_FAILED: otherwise
2770 **
2771 *****************************************************************************/
RW_T2tFormatNDef(void)2772 tNFC_STATUS RW_T2tFormatNDef(void) {
2773   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2774   tNFC_STATUS status = NFC_STATUS_FAILED;
2775 
2776   if (p_t2t->state != RW_T2T_STATE_IDLE) {
2777     LOG(WARNING) << StringPrintf(
2778         "RW_T2tFormatNDef - Tag not initialized/ Busy! State: %u",
2779         p_t2t->state);
2780     return (NFC_STATUS_FAILED);
2781   }
2782 
2783   if (!p_t2t->b_read_hdr) {
2784     /* If UID is not read, READ it now */
2785     p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
2786 
2787     status = rw_t2t_read(0);
2788     if (status == NFC_STATUS_OK)
2789       p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2790     else
2791       p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2792   } else {
2793     status = rw_t2t_format_tag();
2794     if (status != NFC_STATUS_OK) p_t2t->b_read_hdr = false;
2795   }
2796   return status;
2797 }
2798 
2799 /*******************************************************************************
2800 **
2801 ** Function         RW_T2tLocateTlv
2802 **
2803 ** Description      This function is used to perform TLV detection on a Type 2
2804 **                  tag, and retrieve the tag's TLV attribute information.
2805 **
2806 **                  Before using this API, the application must call
2807 **                  RW_SelectTagType to indicate that a Type 2 tag has been
2808 **                  activated.
2809 **
2810 ** Parameters:      tlv_type : TLV to detect
2811 **
2812 ** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error
2813 **                  status.
2814 **
2815 *******************************************************************************/
RW_T2tLocateTlv(uint8_t tlv_type)2816 tNFC_STATUS RW_T2tLocateTlv(uint8_t tlv_type) {
2817   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2818   tNFC_STATUS status;
2819   uint16_t block;
2820 
2821   if (p_t2t->state != RW_T2T_STATE_IDLE) {
2822     LOG(ERROR) << StringPrintf(
2823         "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
2824     return (NFC_STATUS_BUSY);
2825   }
2826 
2827   if ((tlv_type != TAG_LOCK_CTRL_TLV) && (tlv_type != TAG_MEM_CTRL_TLV) &&
2828       (tlv_type != TAG_NDEF_TLV) && (tlv_type != TAG_PROPRIETARY_TLV)) {
2829     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2830         "RW_T2tLocateTlv - Cannot search TLV: 0x%02x", tlv_type);
2831     return (NFC_STATUS_FAILED);
2832   }
2833 
2834   if ((tlv_type == TAG_LOCK_CTRL_TLV) && (p_t2t->b_read_hdr) &&
2835       (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC)) {
2836     p_t2t->b_read_hdr = false;
2837     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2838         "RW_T2tLocateTlv - No Lock tlv in static structure tag, CC[0]: 0x%02x",
2839         p_t2t->tag_hdr[T2T_CC2_TMS_BYTE]);
2840     return (NFC_STATUS_FAILED);
2841   }
2842 
2843   if ((tlv_type == TAG_NDEF_TLV) && (p_t2t->b_read_hdr) &&
2844       (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)) {
2845     p_t2t->b_read_hdr = false;
2846     LOG(WARNING) << StringPrintf(
2847         "RW_T2tLocateTlv - Invalid NDEF Magic Number!, CC[0]: 0x%02x, CC[1]: "
2848         "0x%02x, CC[3]: 0x%02x",
2849         p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE],
2850         p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2851     return (NFC_STATUS_FAILED);
2852   }
2853 
2854   p_t2t->work_offset = 0;
2855   p_t2t->tlv_detect = tlv_type;
2856 
2857   /* Reset control block variables based on type of tlv to detect */
2858   if (tlv_type == TAG_LOCK_CTRL_TLV) {
2859     p_t2t->num_lockbytes = 0;
2860     p_t2t->num_lock_tlvs = 0;
2861   } else if (tlv_type == TAG_MEM_CTRL_TLV) {
2862     p_t2t->num_mem_tlvs = 0;
2863   } else if (tlv_type == TAG_NDEF_TLV) {
2864     p_t2t->ndef_msg_offset = 0;
2865     p_t2t->num_lockbytes = 0;
2866     p_t2t->num_lock_tlvs = 0;
2867     p_t2t->num_mem_tlvs = 0;
2868     p_t2t->ndef_msg_len = 0;
2869     p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED;
2870   } else {
2871     p_t2t->prop_msg_len = 0;
2872   }
2873 
2874   if (!p_t2t->b_read_hdr) {
2875     /* First read CC block */
2876     block = 0;
2877     p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
2878   } else {
2879     /* Read first data block */
2880     block = T2T_FIRST_DATA_BLOCK;
2881     p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
2882   }
2883 
2884   /* Start reading tag, looking for the specified TLV */
2885   status = rw_t2t_read((uint16_t)block);
2886   if (status == NFC_STATUS_OK) {
2887     p_t2t->state = RW_T2T_STATE_DETECT_TLV;
2888   } else {
2889     p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2890   }
2891   return (status);
2892 }
2893 
2894 /*******************************************************************************
2895 **
2896 ** Function         RW_T2tDetectNDef
2897 **
2898 ** Description      This function is used to perform NDEF detection on a Type 2
2899 **                  tag, and retrieve the tag's NDEF attribute information.
2900 **
2901 **                  Before using this API, the application must call
2902 **                  RW_SelectTagType to indicate that a Type 2 tag has been
2903 **                  activated.
2904 **
2905 ** Parameters:      none
2906 **
2907 ** Returns          NCI_STATUS_OK,if detect op started.Otherwise,error status.
2908 **
2909 *******************************************************************************/
RW_T2tDetectNDef(bool skip_dyn_locks)2910 tNFC_STATUS RW_T2tDetectNDef(bool skip_dyn_locks) {
2911   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2912 
2913   p_t2t->skip_dyn_locks = skip_dyn_locks;
2914 
2915   return RW_T2tLocateTlv(TAG_NDEF_TLV);
2916 }
2917 
2918 /*******************************************************************************
2919 **
2920 ** Function         RW_T2tReadNDef
2921 **
2922 ** Description      Retrieve NDEF contents from a Type2 tag.
2923 **
2924 **                  The RW_T2T_NDEF_READ_EVT event is used to notify the
2925 **                  application after reading the NDEF message.
2926 **
2927 **                  Before using this API, the RW_T2tDetectNDef function must
2928 **                  be called to verify that the tag contains NDEF data, and to
2929 **                  retrieve the NDEF attributes.
2930 **
2931 **                  Internally, this command will be separated into multiple
2932 **                  Tag2 Read commands (if necessary) - depending on the NDEF
2933 **                  Msg size
2934 **
2935 ** Parameters:      p_buffer:   The buffer into which to read the NDEF message
2936 **                  buf_len:    The length of the buffer
2937 **
2938 ** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
2939 **
2940 *******************************************************************************/
RW_T2tReadNDef(uint8_t * p_buffer,uint16_t buf_len)2941 tNFC_STATUS RW_T2tReadNDef(uint8_t* p_buffer, uint16_t buf_len) {
2942   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2943   tNFC_STATUS status = NFC_STATUS_OK;
2944   uint16_t block;
2945 
2946   if (p_t2t->state != RW_T2T_STATE_IDLE) {
2947     LOG(ERROR) << StringPrintf(
2948         "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
2949     return (NFC_STATUS_FAILED);
2950   }
2951 
2952   if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) {
2953     LOG(ERROR) << StringPrintf(
2954         "RW_T2tReadNDef - Error: NDEF detection not performed yet");
2955     return (NFC_STATUS_FAILED);
2956   }
2957 
2958   if (buf_len < p_t2t->ndef_msg_len) {
2959     LOG(WARNING) << StringPrintf(
2960         "RW_T2tReadNDef - buffer size: %u  less than NDEF msg sise: %u",
2961         buf_len, p_t2t->ndef_msg_len);
2962     return (NFC_STATUS_FAILED);
2963   }
2964 
2965   if (!p_t2t->ndef_msg_len) {
2966     LOG(WARNING) << StringPrintf(
2967         "RW_T2tReadNDef - NDEF Message length is zero");
2968     return (NFC_STATUS_NOT_INITIALIZED);
2969   }
2970 
2971   p_t2t->p_ndef_buffer = p_buffer;
2972   p_t2t->work_offset = 0;
2973 
2974   block = (uint16_t)(p_t2t->ndef_msg_offset / T2T_BLOCK_LEN);
2975   block -= block % T2T_READ_BLOCKS;
2976 
2977   p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2978 
2979   if ((block == T2T_FIRST_DATA_BLOCK) && (p_t2t->b_read_data)) {
2980     p_t2t->state = RW_T2T_STATE_READ_NDEF;
2981     p_t2t->block_read = T2T_FIRST_DATA_BLOCK;
2982     rw_t2t_handle_ndef_read_rsp(p_t2t->tag_data);
2983   } else {
2984     /* Start reading NDEF Message */
2985     status = rw_t2t_read(block);
2986     if (status == NFC_STATUS_OK) {
2987       p_t2t->state = RW_T2T_STATE_READ_NDEF;
2988     }
2989   }
2990 
2991   return (status);
2992 }
2993 
2994 /*******************************************************************************
2995 **
2996 ** Function         RW_T2tWriteNDef
2997 **
2998 ** Description      Write NDEF contents to a Type2 tag.
2999 **
3000 **                  Before using this API, the RW_T2tDetectNDef
3001 **                  function must be called to verify that the tag contains
3002 **                  NDEF data, and to retrieve the NDEF attributes.
3003 **
3004 **                  The RW_T2T_NDEF_WRITE_EVT callback event will be used to
3005 **                  notify the application of the response.
3006 **
3007 **                  Internally, this command will be separated into multiple
3008 **                  Tag2 Write commands (if necessary) - depending on the NDEF
3009 **                  Msg size
3010 **
3011 ** Parameters:      msg_len:    The length of the buffer
3012 **                  p_msg:      The NDEF message to write
3013 **
3014 ** Returns          NCI_STATUS_OK,if write was started. Otherwise, error status
3015 **
3016 *******************************************************************************/
RW_T2tWriteNDef(uint16_t msg_len,uint8_t * p_msg)3017 tNFC_STATUS RW_T2tWriteNDef(uint16_t msg_len, uint8_t* p_msg) {
3018   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
3019   uint16_t block;
3020   const tT2T_INIT_TAG* p_ret;
3021 
3022   tNFC_STATUS status = NFC_STATUS_OK;
3023 
3024   if (p_t2t->state != RW_T2T_STATE_IDLE) {
3025     LOG(ERROR) << StringPrintf(
3026         "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
3027     return (NFC_STATUS_FAILED);
3028   }
3029 
3030   if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) {
3031     LOG(ERROR) << StringPrintf(
3032         "RW_T2tWriteNDef - Error: NDEF detection not performed!");
3033     return (NFC_STATUS_FAILED);
3034   }
3035 
3036   if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) {
3037     LOG(ERROR) << StringPrintf(
3038         "RW_T2tWriteNDef - Write access not granted - CC3: %u",
3039         p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
3040     return (NFC_STATUS_REFUSED);
3041   }
3042 
3043   /* Check if there is enough memory on the tag */
3044   if (msg_len > p_t2t->max_ndef_msg_len) {
3045     LOG(ERROR) << StringPrintf(
3046         "RW_T2tWriteNDef - Cannot write NDEF of size greater than %u bytes",
3047         p_t2t->max_ndef_msg_len);
3048     return (NFC_STATUS_FAILED);
3049   }
3050 
3051   /* If OTP tag and tag has valid NDEF Message, stop writting new NDEF Message
3052    * as it may corrupt the tag */
3053   if ((p_t2t->ndef_msg_len > 0) &&
3054       ((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != nullptr) &&
3055       (p_ret->b_otp)) {
3056     LOG(WARNING) << StringPrintf(
3057         "RW_T2tWriteNDef - Cannot Overwrite NDEF Message on a OTP tag!");
3058     return (NFC_STATUS_FAILED);
3059   }
3060   p_t2t->p_new_ndef_buffer = p_msg;
3061   p_t2t->new_ndef_msg_len = msg_len;
3062   p_t2t->work_offset = 0;
3063 
3064   p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK;
3065   /* Read first NDEF Block before updating NDEF */
3066 
3067   block = (uint16_t)(p_t2t->ndef_header_offset / T2T_BLOCK_LEN);
3068 
3069   if ((block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS)) &&
3070       (p_t2t->b_read_data)) {
3071     p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
3072     p_t2t->block_read = block;
3073     rw_t2t_handle_ndef_write_rsp(
3074         &p_t2t->tag_data[(block - T2T_FIRST_DATA_BLOCK) * T2T_BLOCK_LEN]);
3075   } else {
3076     status = rw_t2t_read(block);
3077     if (status == NFC_STATUS_OK)
3078       p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
3079     else
3080       p_t2t->substate = RW_T2T_SUBSTATE_NONE;
3081   }
3082 
3083   return status;
3084 }
3085 
3086 /*******************************************************************************
3087 **
3088 ** Function         RW_T2tSetTagReadOnly
3089 **
3090 ** Description      This function can be called to set T2 tag as read only.
3091 **
3092 ** Parameters:      b_hard_lock:   To indicate hard lock the tag or not
3093 **
3094 ** Returns          NCI_STATUS_OK, if setting tag as read only was started.
3095 **                  Otherwise, error status.
3096 **
3097 *******************************************************************************/
RW_T2tSetTagReadOnly(bool b_hard_lock)3098 tNFC_STATUS RW_T2tSetTagReadOnly(bool b_hard_lock) {
3099   tNFC_STATUS status = NFC_STATUS_FAILED;
3100   tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
3101 
3102   if (p_t2t->state != RW_T2T_STATE_IDLE) {
3103     LOG(ERROR) << StringPrintf(
3104         "RW_T2tSetTagReadOnly: Error: Type 2 tag not activated or Busy - "
3105         "State: %u",
3106         p_t2t->state);
3107     return (NFC_STATUS_FAILED);
3108   }
3109 
3110   p_t2t->b_hard_lock = b_hard_lock;
3111 
3112   if (!p_t2t->b_read_hdr) {
3113     /* Read CC block before configuring tag as Read only */
3114     p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
3115     status = rw_t2t_read((uint16_t)0);
3116     if (status == NFC_STATUS_OK) {
3117       p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
3118     } else
3119       p_t2t->substate = RW_T2T_SUBSTATE_NONE;
3120   } else {
3121     status = rw_t2t_soft_lock_tag();
3122     if (status != NFC_STATUS_OK) p_t2t->b_read_hdr = false;
3123   }
3124 
3125   return status;
3126 }
3127 
3128 #endif /* (RW_NDEF_INCLUDED == TRUE) */
3129