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