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 1 tag NDEF operation in
22 *  Reader/Writer mode.
23 *
24 ******************************************************************************/
25#include <string>
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 Functions */
44static tNFC_STATUS rw_t1t_handle_rall_rsp(bool* p_notify, uint8_t* p_data);
45static tNFC_STATUS rw_t1t_handle_dyn_read_rsp(bool* p_notify, uint8_t* p_data);
46static tNFC_STATUS rw_t1t_handle_write_rsp(bool* p_notify, uint8_t* p_data);
47static tNFC_STATUS rw_t1t_handle_read_rsp(bool* p_callback, uint8_t* p_data);
48static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp(uint8_t* p_data);
49static tNFC_STATUS rw_t1t_handle_ndef_read_rsp(uint8_t* p_data);
50static tNFC_STATUS rw_t1t_handle_ndef_write_rsp(uint8_t* p_data);
51static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp(void);
52static tNFC_STATUS rw_t1t_ndef_write_first_block(void);
53static tNFC_STATUS rw_t1t_next_ndef_write_block(void);
54static tNFC_STATUS rw_t1t_send_ndef_byte(uint8_t data, uint8_t block,
55                                         uint8_t index, uint8_t msg_len);
56static tNFC_STATUS rw_t1t_send_ndef_block(uint8_t* p_data, uint8_t block);
57static uint8_t rw_t1t_prepare_ndef_bytes(uint8_t* p_data,
58                                         uint8_t* p_length_field,
59                                         uint8_t* p_index, bool b_one_byte,
60                                         uint8_t block,
61                                         uint8_t lengthfield_len);
62static uint8_t rw_t1t_get_ndef_flags(void);
63static uint16_t rw_t1t_get_ndef_max_size(void);
64static bool rw_t1t_is_lock_reserved_otp_byte(uint16_t index);
65static bool rw_t1t_is_read_only_byte(uint16_t index);
66static uint8_t rw_t1t_get_lock_bits_for_segment(uint8_t segment,
67                                                uint8_t* p_start_byte,
68                                                uint8_t* p_start_bit,
69                                                uint8_t* p_end_byte);
70static void rw_t1t_update_attributes(void);
71static void rw_t1t_update_lock_attributes(void);
72static void rw_t1t_extract_lock_bytes(uint8_t* p_data);
73static void rw_t1t_update_tag_state(void);
74
75const uint8_t rw_t1t_mask_bits[8] = {0x01, 0x02, 0x04, 0x08,
76                                     0x10, 0x20, 0x40, 0x80};
77
78/*******************************************************************************
79**
80** Function         rw_t1t_handle_rsp
81**
82** Description      This function handles the response received for all commands
83**                  sent to tag
84**
85** Returns          event to be sent to application
86**
87*******************************************************************************/
88tRW_EVENT rw_t1t_handle_rsp(const tT1T_CMD_RSP_INFO* p_info, bool* p_notify,
89                            uint8_t* p_data, tNFC_STATUS* p_status) {
90  tRW_EVENT rw_event;
91  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
92  uint8_t adds;
93
94  if ((p_t1t->state == RW_T1T_STATE_READ) ||
95      (p_t1t->state == RW_T1T_STATE_WRITE)) {
96    return t1t_info_to_evt(p_info);
97  }
98
99  rw_event = rw_t1t_info_to_event(p_info);
100
101  if (p_info->opcode == T1T_CMD_RALL) {
102    *p_status = rw_t1t_handle_rall_rsp(p_notify, p_data);
103  } else if (p_info->opcode == T1T_CMD_RSEG) {
104    adds = *p_data;
105    if (adds == 0) {
106      p_t1t->b_rseg = true;
107      rw_t1t_update_tag_state();
108      rw_t1t_update_attributes();
109      rw_t1t_update_lock_attributes();
110      memcpy(p_t1t->mem, (uint8_t*)(p_data + T1T_ADD_LEN), T1T_SEGMENT_SIZE);
111    }
112    *p_status = rw_t1t_handle_dyn_read_rsp(p_notify, p_data);
113  } else if (p_info->opcode == T1T_CMD_READ8) {
114    *p_status = rw_t1t_handle_dyn_read_rsp(p_notify, p_data);
115  } else {
116    *p_status = rw_t1t_handle_write_rsp(p_notify, p_data);
117  }
118  return rw_event;
119}
120
121/*******************************************************************************
122**
123** Function         rw_t1t_info_to_event
124**
125** Description      This function returns RW event code based on the current
126**                  state
127**
128** Returns          RW event code
129**
130*******************************************************************************/
131tRW_EVENT rw_t1t_info_to_event(const tT1T_CMD_RSP_INFO* p_info) {
132  tRW_EVENT rw_event;
133  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
134
135  switch (p_t1t->state) {
136    case RW_T1T_STATE_TLV_DETECT:
137      if (p_t1t->tlv_detect == TAG_NDEF_TLV)
138        rw_event = RW_T1T_NDEF_DETECT_EVT;
139      else
140        rw_event = RW_T1T_TLV_DETECT_EVT;
141      break;
142
143    case RW_T1T_STATE_READ_NDEF:
144      rw_event = RW_T1T_NDEF_READ_EVT;
145      break;
146
147    case RW_T1T_STATE_WRITE_NDEF:
148      rw_event = RW_T1T_NDEF_WRITE_EVT;
149      break;
150
151    case RW_T1T_STATE_SET_TAG_RO:
152      rw_event = RW_T1T_SET_TAG_RO_EVT;
153      break;
154
155    case RW_T1T_STATE_CHECK_PRESENCE:
156      rw_event = RW_T1T_PRESENCE_CHECK_EVT;
157      break;
158
159    case RW_T1T_STATE_FORMAT_TAG:
160      rw_event = RW_T1T_FORMAT_CPLT_EVT;
161      break;
162
163    default:
164      rw_event = t1t_info_to_evt(p_info);
165      break;
166  }
167  return rw_event;
168}
169
170/*******************************************************************************
171**
172** Function         rw_t1t_extract_lock_bytes
173**
174** Description      This function will extract lock bytes if any present in the
175**                  response data
176**
177** Parameters       p_data: Data bytes in the response of RSEG/READ8/RALL
178**                          command
179**
180** Returns          None
181**
182*******************************************************************************/
183void rw_t1t_extract_lock_bytes(uint8_t* p_data) {
184  uint16_t end;
185  uint16_t start;
186  uint8_t num_locks;
187  uint16_t lock_offset = 0;
188  uint16_t offset;
189  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
190  tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
191      (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
192
193  num_locks = 0;
194  /* Based on the Command used to read Tag, calculate the offset of the tag read
195   */
196  if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG) {
197    start = p_t1t->segment * T1T_SEGMENT_SIZE;
198    end = start + T1T_SEGMENT_SIZE;
199  } else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8) {
200    start = p_t1t->block_read * T1T_BLOCK_SIZE;
201    end = start + T1T_BLOCK_SIZE;
202  } else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL) {
203    start = 0;
204    end = T1T_STATIC_SIZE;
205  } else
206    return;
207
208  /* Collect lock bytes that are present in the part of the data read from Tag
209   */
210  while (num_locks < p_t1t->num_lockbytes) {
211    if (p_t1t->lockbyte[num_locks].b_lock_read == false) {
212      /* Get the exact offset of the dynamic lock byte in the tag */
213      offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset +
214               p_t1t->lockbyte[num_locks].byte_index;
215      if ((offset < end) && (offset >= start))
216
217      {
218        /* This dynamic lock byte is in the response */
219        if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG) {
220          lock_offset = (offset % T1T_SEGMENT_SIZE);
221        } else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8) {
222          lock_offset = (offset % T1T_BLOCK_SIZE);
223        } else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL) {
224          lock_offset = offset;
225        }
226
227        p_t1t->lockbyte[num_locks].lock_byte = p_data[lock_offset];
228        p_t1t->lockbyte[num_locks].b_lock_read = true;
229      } else
230        break;
231    }
232    num_locks++;
233  }
234}
235
236/*******************************************************************************
237**
238** Function         rw_t1t_update_tag_attributes
239**
240** Description      This function will update tag attributes based on cc, ndef
241**                  message length
242**
243** Returns          None
244**
245*******************************************************************************/
246void rw_t1t_update_tag_state(void) {
247  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
248
249  /* Set Tag state based on CC value and NDEF Message length */
250  if (((p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN) ||
251       (p_t1t->mem[T1T_CC_NMN_BYTE] == 0)) &&
252      ((p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_VNO) ||
253       (p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_LEGACY_VNO)) &&
254      ((p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW) ||
255       (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO))) {
256    /* Valid CC value, so Tag is initialized */
257    if (p_t1t->ndef_msg_len > 0) {
258      if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO) {
259        /* NDEF Message presence, CC indication sets Tag as READ ONLY  */
260        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_ONLY;
261      } else if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW) {
262        /* NDEF Message presence, CC indication sets Tag as READ WRITE */
263        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
264      }
265    } else {
266      /* If NDEF is not yet detected then Tag remains in Initialized state
267      *  after NDEF Detection the Tag state may be updated */
268      p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
269    }
270  } else {
271    p_t1t->tag_attribute = RW_T1_TAG_ATTRB_UNKNOWN;
272  }
273}
274
275/*******************************************************************************
276**
277** Function         rw_t1t_read_locks
278**
279** Description      This function will send command to read next unread locks
280**
281** Returns          NFC_STATUS_OK, if all locks are read successfully
282**                  NFC_STATUS_FAILED, if reading locks failed
283**                  NFC_STATUS_CONTINUE, if reading locks is in progress
284**
285*******************************************************************************/
286tNFC_STATUS rw_t1t_read_locks(void) {
287  uint8_t num_locks = 0;
288  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
289  tNFC_STATUS status = NFC_STATUS_CONTINUE;
290  uint16_t offset;
291
292  while (num_locks < p_t1t->num_lockbytes) {
293    if (p_t1t->lockbyte[num_locks].b_lock_read == false) {
294      offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset +
295               p_t1t->lockbyte[num_locks].byte_index;
296      if (offset < T1T_STATIC_SIZE) {
297        p_t1t->lockbyte[num_locks].lock_byte = p_t1t->mem[offset];
298        p_t1t->lockbyte[num_locks].b_lock_read = true;
299      } else if (offset < (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE) {
300        /* send READ8 command */
301        p_t1t->block_read = (uint8_t)(offset / T1T_BLOCK_SIZE);
302        status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8, p_t1t->block_read, NULL);
303        if (status == NFC_STATUS_OK) {
304          /* Reading Locks */
305          status = NFC_STATUS_CONTINUE;
306          p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_LOCKS;
307        }
308        break;
309      } else {
310        /* Read locks failed */
311        status = NFC_STATUS_FAILED;
312        break;
313      }
314    }
315    num_locks++;
316  }
317  if (num_locks == p_t1t->num_lockbytes) {
318    /* All locks are read */
319    status = NFC_STATUS_OK;
320  }
321
322  return status;
323}
324
325/*******************************************************************************
326**
327** Function         rw_t1t_handle_write_rsp
328**
329** Description      This function handles response received for WRITE_E8,
330**                  WRITE_NE8, WRITE_E, WRITE_NE commands
331**
332** Returns          status of the current NDEF/TLV Operation
333**
334*******************************************************************************/
335static tNFC_STATUS rw_t1t_handle_write_rsp(bool* p_notify, uint8_t* p_data) {
336  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
337  tNFC_STATUS status = NFC_STATUS_OK;
338  uint8_t num_locks;
339  uint8_t lock_count;
340  uint8_t value;
341  uint8_t addr;
342  uint8_t write_block[T1T_BLOCK_SIZE];
343  uint16_t offset;
344  uint16_t next_offset;
345  uint8_t num_bits;
346  uint8_t next_num_bits;
347
348  *p_notify = false;
349
350  switch (p_t1t->state) {
351    case RW_T1T_STATE_WRITE:
352      *p_notify = true;
353      break;
354
355    case RW_T1T_STATE_FORMAT_TAG:
356      if (p_t1t->substate == RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF) {
357        if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
358            rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
359          *p_notify = true;
360        else {
361          if (p_t1t->work_offset < (T1T_BLOCK_SIZE - 1)) {
362            p_t1t->work_offset++;
363            /* send WRITE-E command */
364            RW_T1T_BLD_ADD((addr), 1, (uint8_t)p_t1t->work_offset);
365
366            status = rw_t1t_send_static_cmd(
367                T1T_CMD_WRITE_E, addr,
368                p_t1t->ndef_first_block[(uint8_t)p_t1t->work_offset]);
369            if (status != NFC_STATUS_OK) *p_notify = true;
370          } else
371            *p_notify = true;
372        }
373
374      } else {
375        /* send WRITE-E8 command */
376        status =
377            rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_E8, 2, p_t1t->ndef_final_block);
378        if (status != NFC_STATUS_OK)
379          *p_notify = true;
380        else
381          p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
382      }
383      break;
384
385    case RW_T1T_STATE_SET_TAG_RO:
386      switch (p_t1t->substate) {
387        case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
388
389          if (!p_t1t->b_hard_lock) {
390            status = NFC_STATUS_OK;
391            *p_notify = true;
392            break;
393          }
394
395          if ((p_t1t->hr[0] & 0x0F) != 1) {
396            memset(write_block, 0, T1T_BLOCK_SIZE);
397            write_block[0] = 0xFF;
398            write_block[1] = 0xFF;
399
400            /* send WRITE-NE8 command */
401            status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_NE8, T1T_LOCK_BLOCK,
402                                         write_block);
403            if (status != NFC_STATUS_OK)
404              *p_notify = true;
405            else
406              p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
407          } else {
408            /* send WRITE-NE command */
409            RW_T1T_BLD_ADD((addr), (T1T_LOCK_BLOCK), (0));
410            status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, 0xFF);
411            if (status != NFC_STATUS_OK)
412              *p_notify = true;
413            else
414              p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
415          }
416          break;
417
418        case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
419
420          /* send WRITE-NE command */
421          RW_T1T_BLD_ADD((addr), (T1T_LOCK_BLOCK), (1));
422          status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, 0xFF);
423          if (status != NFC_STATUS_OK)
424            *p_notify = true;
425          else
426            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
427
428          break;
429
430        case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
431          num_locks = 0;
432          while (num_locks < p_t1t->num_lockbytes) {
433            if (p_t1t->lockbyte[num_locks].lock_status ==
434                RW_T1T_LOCK_UPDATE_INITIATED) {
435              p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATED;
436            }
437            num_locks++;
438          }
439
440          num_locks = 0;
441          while (num_locks < p_t1t->num_lockbytes) {
442            if (p_t1t->lockbyte[num_locks].lock_status ==
443                RW_T1T_LOCK_NOT_UPDATED) {
444              offset =
445                  p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset +
446                  p_t1t->lockbyte[num_locks].byte_index;
447              num_bits =
448                  ((p_t1t->lockbyte[num_locks].byte_index + 1) * 8 <=
449                   p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index]
450                       .num_bits)
451                      ? 8
452                      : p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index]
453                                .num_bits %
454                            8;
455
456              if ((p_t1t->hr[0] & 0x0F) != 1) {
457                memset(write_block, 0, T1T_BLOCK_SIZE);
458
459                write_block[(uint8_t)(offset % T1T_BLOCK_SIZE)] |=
460                    tags_pow(2, num_bits) - 1;
461                lock_count = num_locks + 1;
462                while (lock_count < p_t1t->num_lockbytes) {
463                  next_offset =
464                      p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index]
465                          .offset +
466                      p_t1t->lockbyte[lock_count].byte_index;
467                  next_num_bits =
468                      ((p_t1t->lockbyte[lock_count].byte_index + 1) * 8 <=
469                       p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index]
470                           .num_bits)
471                          ? 8
472                          : p_t1t->lock_tlv[p_t1t->lockbyte[lock_count]
473                                                .tlv_index]
474                                    .num_bits %
475                                8;
476
477                  if (next_offset / T1T_BLOCK_SIZE == offset / T1T_BLOCK_SIZE) {
478                    write_block[(uint8_t)(next_offset % T1T_BLOCK_SIZE)] |=
479                        tags_pow(2, next_num_bits) - 1;
480                  } else
481                    break;
482                  lock_count++;
483                }
484
485                /* send WRITE-NE8 command */
486                status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_NE8,
487                                             (uint8_t)(offset / T1T_BLOCK_SIZE),
488                                             write_block);
489                if (status == NFC_STATUS_OK) {
490                  p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
491                  while (lock_count > num_locks) {
492                    p_t1t->lockbyte[lock_count - 1].lock_status =
493                        RW_T1T_LOCK_UPDATE_INITIATED;
494                    lock_count--;
495                  }
496                } else
497                  *p_notify = true;
498              } else {
499                /* send WRITE-NE command */
500                RW_T1T_BLD_ADD((addr), ((uint8_t)(offset / T1T_BLOCK_SIZE)),
501                               ((uint8_t)(offset % T1T_BLOCK_SIZE)));
502                value = (uint8_t)(tags_pow(2, num_bits) - 1);
503                status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, value);
504                if (status == NFC_STATUS_OK) {
505                  p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
506                  p_t1t->lockbyte[num_locks].lock_status =
507                      RW_T1T_LOCK_UPDATE_INITIATED;
508                } else
509                  *p_notify = true;
510              }
511              break;
512            }
513            num_locks++;
514          }
515          if (num_locks == p_t1t->num_lockbytes) {
516            rw_t1t_update_lock_attributes();
517            status = NFC_STATUS_OK;
518            *p_notify = true;
519          }
520          break;
521      }
522      break;
523
524    case RW_T1T_STATE_WRITE_NDEF:
525      switch (p_t1t->substate) {
526        case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
527          p_t1t->ndef_msg_len = p_t1t->new_ndef_msg_len;
528          p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
529          *p_notify = true;
530          break;
531
532        case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
533          status = rw_t1t_handle_ndef_write_rsp(p_data);
534          if (status == NFC_STATUS_OK) {
535            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF;
536          } else if (status == NFC_STATUS_FAILED) {
537            /* Send Negative response to upper layer */
538            *p_notify = true;
539          }
540          break;
541
542        case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
543          status = rw_t1t_handle_ndef_write_rsp(p_data);
544
545          if (status == NFC_STATUS_FAILED) {
546            /* Send Negative response to upper layer */
547            *p_notify = true;
548          } else if (status == NFC_STATUS_OK) {
549            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
550          }
551          break;
552
553        case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
554          status = rw_t1t_handle_ndef_write_rsp(p_data);
555          if (status == NFC_STATUS_FAILED) {
556            /* Send Negative response to upper layer */
557            *p_notify = true;
558          } else if (status == NFC_STATUS_CONTINUE) {
559            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_WRITE;
560          } else {
561            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
562          }
563          break;
564      }
565      break;
566  }
567  return status;
568}
569
570/*******************************************************************************
571**
572** Function         rw_t1t_handle_read_rsp
573**
574** Description      This function handle the data bytes excluding ADD(S)/ADD8
575**                  field received as part of RSEG, RALL, READ8 command response
576**
577** Returns          status of the current NDEF/TLV Operation
578**
579*******************************************************************************/
580tNFC_STATUS rw_t1t_handle_read_rsp(bool* p_notify, uint8_t* p_data) {
581  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
582  tNFC_STATUS status = NFC_STATUS_OK;
583  tRW_DETECT_NDEF_DATA ndef_data;
584  tRW_DETECT_TLV_DATA tlv_data;
585  uint8_t count;
586
587  *p_notify = false;
588  /* Handle the response based on the current state */
589  switch (p_t1t->state) {
590    case RW_T1T_STATE_READ:
591      *p_notify = true;
592      break;
593
594    case RW_T1T_STATE_READ_NDEF:
595      status = rw_t1t_handle_ndef_rall_rsp();
596      if (status != NFC_STATUS_CONTINUE) {
597        tRW_DATA rw_data;
598        rw_data.data.status = status;
599        rw_data.data.p_data = NULL;
600        rw_t1t_handle_op_complete();
601        (*rw_cb.p_cback)(RW_T1T_NDEF_READ_EVT, &rw_data);
602      }
603      break;
604
605    case RW_T1T_STATE_TLV_DETECT:
606      switch (p_t1t->substate) {
607        case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
608          status = rw_t1t_read_locks();
609          if (status != NFC_STATUS_CONTINUE) {
610            rw_t1t_update_lock_attributes();
611            /* Send positive response to upper layer */
612            if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) {
613              tlv_data.protocol = NFC_PROTOCOL_T1T;
614              tlv_data.num_bytes = p_t1t->num_lockbytes;
615              tlv_data.status = status;
616              rw_t1t_handle_op_complete();
617              tRW_DATA rw_data;
618              rw_data.tlv = tlv_data;
619              (*rw_cb.p_cback)(RW_T1T_TLV_DETECT_EVT, &rw_data);
620            } else if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
621              ndef_data.protocol = NFC_PROTOCOL_T1T;
622              ndef_data.flags = rw_t1t_get_ndef_flags();
623              ndef_data.flags |= RW_NDEF_FL_FORMATED;
624              ndef_data.max_size = (uint32_t)rw_t1t_get_ndef_max_size();
625              ndef_data.cur_size = p_t1t->ndef_msg_len;
626
627              if (ndef_data.max_size < ndef_data.cur_size) {
628                ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
629                ndef_data.max_size = ndef_data.cur_size;
630              }
631
632              if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
633                ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
634                if (status == NFC_STATUS_OK)
635                  ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
636              }
637              ndef_data.status = status;
638              rw_t1t_handle_op_complete();
639              tRW_DATA rw_data;
640              rw_data.ndef = ndef_data;
641              (*rw_cb.p_cback)(RW_T1T_NDEF_DETECT_EVT, &rw_data);
642            }
643          }
644          break;
645
646        case RW_T1T_SUBSTATE_NONE:
647          if (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) {
648            tlv_data.status = rw_t1t_handle_tlv_detect_rsp(p_t1t->mem);
649            tlv_data.protocol = NFC_PROTOCOL_T1T;
650            tlv_data.num_bytes = 0;
651            count = 0;
652            while (count < p_t1t->num_mem_tlvs) {
653              tlv_data.num_bytes +=
654                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes;
655              count++;
656            }
657            rw_t1t_handle_op_complete();
658            /* Send response to upper layer */
659            tRW_DATA rw_data;
660            rw_data.tlv = tlv_data;
661            (*rw_cb.p_cback)(RW_T1T_TLV_DETECT_EVT, &rw_data);
662          } else if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) {
663            tlv_data.status = rw_t1t_handle_tlv_detect_rsp(p_t1t->mem);
664            tlv_data.protocol = NFC_PROTOCOL_T1T;
665            tlv_data.num_bytes = p_t1t->num_lockbytes;
666
667            if (tlv_data.status == NFC_STATUS_FAILED) {
668              rw_t1t_handle_op_complete();
669
670              /* Send Negative response to upper layer */
671              tRW_DATA rw_data;
672              rw_data.tlv = tlv_data;
673              (*rw_cb.p_cback)(RW_T1T_TLV_DETECT_EVT, &rw_data);
674            } else {
675              rw_t1t_extract_lock_bytes(p_data);
676              status = rw_t1t_read_locks();
677              if (status != NFC_STATUS_CONTINUE) {
678                /* Send positive response to upper layer */
679                tlv_data.status = status;
680                rw_t1t_handle_op_complete();
681
682                tRW_DATA rw_data;
683                rw_data.tlv = tlv_data;
684                (*rw_cb.p_cback)(RW_T1T_TLV_DETECT_EVT, &rw_data);
685              }
686            }
687          } else if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
688            ndef_data.protocol = NFC_PROTOCOL_T1T;
689            ndef_data.flags = rw_t1t_get_ndef_flags();
690
691            if (p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN) {
692              ndef_data.status = rw_t1t_handle_tlv_detect_rsp(p_t1t->mem);
693
694              ndef_data.cur_size = p_t1t->ndef_msg_len;
695              if (ndef_data.status == NFC_STATUS_FAILED) {
696                ndef_data.max_size = (uint32_t)rw_t1t_get_ndef_max_size();
697                if (ndef_data.max_size < ndef_data.cur_size) {
698                  ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
699                  ndef_data.max_size = ndef_data.cur_size;
700                }
701                if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
702                  ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
703                }
704                /* Send Negative response to upper layer */
705                rw_t1t_handle_op_complete();
706
707                tRW_DATA rw_data;
708                rw_data.ndef = ndef_data;
709                (*rw_cb.p_cback)(RW_T1T_NDEF_DETECT_EVT, &rw_data);
710              } else {
711                ndef_data.flags |= RW_NDEF_FL_FORMATED;
712                rw_t1t_extract_lock_bytes(p_data);
713                status = rw_t1t_read_locks();
714                if (status != NFC_STATUS_CONTINUE) {
715                  ndef_data.max_size = (uint32_t)rw_t1t_get_ndef_max_size();
716                  if (ndef_data.max_size < ndef_data.cur_size) {
717                    ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
718                    ndef_data.max_size = ndef_data.cur_size;
719                  }
720
721                  if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
722                    ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
723                    if (status == NFC_STATUS_OK)
724                      ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
725                  }
726                  /* Send positive response to upper layer */
727                  ndef_data.status = status;
728                  rw_t1t_handle_op_complete();
729
730                  tRW_DATA rw_data;
731                  rw_data.ndef = ndef_data;
732                  (*rw_cb.p_cback)(RW_T1T_NDEF_DETECT_EVT, &rw_data);
733                }
734              }
735            } else {
736              /* Send Negative response to upper layer */
737              ndef_data.status = NFC_STATUS_FAILED;
738              ndef_data.max_size = (uint32_t)rw_t1t_get_ndef_max_size();
739              ndef_data.cur_size = p_t1t->ndef_msg_len;
740              if (ndef_data.max_size < ndef_data.cur_size) {
741                ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
742                ndef_data.max_size = ndef_data.cur_size;
743              }
744              if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
745                ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
746                ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
747              }
748              rw_t1t_handle_op_complete();
749
750              tRW_DATA rw_data;
751              rw_data.ndef = ndef_data;
752              (*rw_cb.p_cback)(RW_T1T_NDEF_DETECT_EVT, &rw_data);
753            }
754          }
755          break;
756      }
757      break;
758  }
759  return status;
760}
761
762/*******************************************************************************
763**
764** Function         rw_t1t_handle_dyn_read_rsp
765**
766** Description      This function handles response received for READ8, RSEG
767**                  commands based on the current state
768**
769** Returns          status of the current NDEF/TLV Operation
770**
771*******************************************************************************/
772static tNFC_STATUS rw_t1t_handle_dyn_read_rsp(bool* p_notify, uint8_t* p_data) {
773  tNFC_STATUS status = NFC_STATUS_OK;
774  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
775
776  *p_notify = false;
777
778  p_data += T1T_ADD_LEN;
779
780  rw_t1t_extract_lock_bytes(p_data);
781
782  if (p_t1t->state == RW_T1T_STATE_READ_NDEF) {
783    status = rw_t1t_handle_ndef_read_rsp(p_data);
784    if ((status == NFC_STATUS_FAILED) || (status == NFC_STATUS_OK)) {
785      /* Send response to upper layer */
786      *p_notify = true;
787    }
788  } else if (p_t1t->state == RW_T1T_STATE_WRITE_NDEF) {
789    status = rw_t1t_handle_ndef_write_rsp(p_data);
790    if (status == NFC_STATUS_FAILED) {
791      /* Send response to upper layer */
792      *p_notify = true;
793    } else if (status == NFC_STATUS_CONTINUE) {
794      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
795    }
796  } else {
797    status = rw_t1t_handle_read_rsp(p_notify, p_data);
798  }
799  return status;
800}
801
802/*****************************************************************************
803**
804** Function         rw_t1t_handle_rall_rsp
805**
806** Description      Handle response to RALL - Collect CC, set Tag state
807**
808** Returns          None
809**
810*****************************************************************************/
811static tNFC_STATUS rw_t1t_handle_rall_rsp(bool* p_notify, uint8_t* p_data) {
812  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
813
814  p_data += T1T_HR_LEN; /* skip HR */
815  memcpy(p_t1t->mem, (uint8_t*)p_data, T1T_STATIC_SIZE);
816  p_t1t->segment = 0;
817  rw_t1t_extract_lock_bytes(p_data);
818
819  p_data +=
820      T1T_UID_LEN + T1T_RES_BYTE_LEN; /* skip Block 0, UID and Reserved byte */
821
822  DLOG_IF(INFO, nfc_debug_enabled) << __func__;
823
824  rw_t1t_update_tag_state();
825  rw_t1t_update_attributes();
826  rw_t1t_update_lock_attributes();
827  p_t1t->b_update = true;
828  return (rw_t1t_handle_read_rsp(p_notify, p_t1t->mem));
829}
830
831/*******************************************************************************
832**
833** Function         rw_t1t_handle_tlv_detect_rsp
834**
835** Description      Handle response to the last command sent while
836**                  detecting tlv
837**
838** Returns          NFC_STATUS_OK, if tlv detect is complete & success
839**                  NFC_STATUS_FAILED,if tlv detect failed
840**
841*******************************************************************************/
842static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp(uint8_t* p_data) {
843  uint16_t offset;
844  uint16_t len;
845  uint8_t xx;
846  uint8_t* p_readbytes;
847  uint8_t index;
848  uint8_t tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
849  uint8_t found_tlv = TAG_NULL_TLV;
850  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
851  bool failed = false;
852  bool found = false;
853  uint8_t count = 0;
854  tNFC_STATUS status = NFC_STATUS_FAILED;
855  uint8_t start_offset = T1T_UID_LEN + T1T_CC_LEN + T1T_RES_BYTE_LEN;
856  uint8_t end_offset = T1T_STATIC_SIZE - (2 * T1T_BLOCK_SIZE);
857  uint8_t bytes_read = T1T_STATIC_SIZE;
858  uint8_t tlv_value[T1T_DEFAULT_TLV_LEN];
859  uint16_t bytes_count = 0;
860
861  p_readbytes = p_data;
862
863  for (offset = start_offset; offset < end_offset && !failed && !found;) {
864    if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)(offset)) == true) {
865      offset++;
866      continue;
867    }
868    switch (tlv_detect_state) {
869      case RW_T1T_SUBSTATE_WAIT_TLV_DETECT:
870        /* Search for the tag */
871        found_tlv = p_readbytes[offset++];
872        switch (found_tlv) {
873          case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */
874            break;
875
876          case TAG_NDEF_TLV:
877            if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
878              index = (offset % T1T_BLOCK_SIZE);
879              /* Backup ndef first block */
880              memcpy(&p_t1t->ndef_first_block[0], &p_readbytes[offset - index],
881                     index);
882              memcpy(&p_t1t->ndef_first_block[index], &p_readbytes[offset],
883                     T1T_BLOCK_SIZE - index);
884              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
885            } else if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV) {
886              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
887            } else if (((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) &&
888                        (p_t1t->num_lockbytes > 0)) ||
889                       ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) &&
890                        (p_t1t->num_mem_tlvs > 0))) {
891              found = true;
892            } else {
893              failed = true;
894            }
895            break;
896
897          case TAG_LOCK_CTRL_TLV:
898          case TAG_MEM_CTRL_TLV:
899            tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
900            break;
901
902          case TAG_PROPRIETARY_TLV:
903            if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV) {
904              index = (offset % T1T_BLOCK_SIZE);
905              /* Backup ndef first block */
906              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
907            } else {
908              /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we
909               * continue searching, skiping proprietary tlv */
910              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
911            }
912            break;
913
914          case TAG_TERMINATOR_TLV: /* Last TLV block in the data area. Must be
915                                      no NDEF nessage */
916            if (((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) &&
917                 (p_t1t->num_lockbytes > 0)) ||
918                ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) &&
919                 (p_t1t->num_mem_tlvs > 0))) {
920              found = true;
921            } else {
922              failed = true;
923            }
924            break;
925          default:
926            failed = true;
927        }
928        break;
929
930      case RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
931        len = p_readbytes[offset];
932        switch (found_tlv) {
933          case TAG_NDEF_TLV:
934            p_t1t->ndef_header_offset = offset + p_t1t->work_offset;
935            if (len == T1T_LONG_NDEF_LEN_FIELD_BYTE0) {
936              /* The next two bytes constitute length bytes */
937              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
938            } else {
939              /* one byte length field */
940              p_t1t->ndef_msg_len = len;
941              bytes_count = p_t1t->ndef_msg_len;
942              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
943            }
944            break;
945
946          case TAG_PROPRIETARY_TLV:
947            if (len == 0xFF) {
948              /* The next two bytes constitute length bytes */
949              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
950            } else {
951              /* one byte length field */
952              bytes_count = len;
953              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
954            }
955            break;
956        }
957        offset++;
958        break;
959
960      case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0:
961        switch (found_tlv) {
962          case TAG_LOCK_CTRL_TLV:
963          case TAG_MEM_CTRL_TLV:
964
965            len = p_readbytes[offset];
966            if (len == T1T_DEFAULT_TLV_LEN) {
967              /* Valid Lock control TLV */
968              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
969              bytes_count = T1T_DEFAULT_TLV_LEN;
970            } else if (((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) &&
971                        (p_t1t->num_lockbytes > 0)) ||
972                       ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) &&
973                        (p_t1t->num_mem_tlvs > 0))) {
974              found = true;
975            } else {
976              failed = true;
977            }
978            break;
979
980          case TAG_NDEF_TLV:
981          case TAG_PROPRIETARY_TLV:
982            /* The first length byte */
983            bytes_count = (uint8_t)p_readbytes[offset];
984            tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1;
985            break;
986        }
987        offset++;
988        break;
989
990      case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1:
991        bytes_count = (bytes_count << 8) + p_readbytes[offset];
992        if (found_tlv == TAG_NDEF_TLV) {
993          p_t1t->ndef_msg_len = bytes_count;
994        }
995        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
996        offset++;
997        break;
998
999      case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
1000        switch (found_tlv) {
1001          case TAG_NDEF_TLV:
1002            if ((bytes_count == p_t1t->ndef_msg_len) &&
1003                (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
1004              /* The first byte offset after length field */
1005              p_t1t->ndef_msg_offset = offset + p_t1t->work_offset;
1006            }
1007            if (bytes_count > 0) bytes_count--;
1008
1009            if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
1010              if (p_t1t->ndef_msg_len > 0) {
1011                rw_t1t_update_tag_state();
1012              } else {
1013                p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED_NDEF;
1014              }
1015              found = true;
1016            } else if (bytes_count == 0) {
1017              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1018            }
1019            break;
1020
1021          case TAG_LOCK_CTRL_TLV:
1022            bytes_count--;
1023            if ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) ||
1024                (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
1025              tlv_value[2 - bytes_count] = p_readbytes[offset];
1026              if (bytes_count == 0) {
1027                if (p_t1t->num_lock_tlvs < RW_T1T_MAX_LOCK_TLVS) {
1028                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset =
1029                      (tlv_value[0] >> 4) & 0x0F;
1030                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset *=
1031                      (uint8_t)tags_pow(2, tlv_value[2] & 0x0F);
1032                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset +=
1033                      tlv_value[0] & 0x0F;
1034                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].bytes_locked_per_bit =
1035                      (uint8_t)tags_pow(2, ((tlv_value[2] & 0xF0) >> 4));
1036                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].num_bits = tlv_value[1];
1037                  count = tlv_value[1] / 8 + ((tlv_value[1] % 8 != 0) ? 1 : 0);
1038                  xx = 0;
1039                  while (xx < count) {
1040                    if (p_t1t->num_lockbytes < RW_T1T_MAX_LOCK_BYTES) {
1041                      p_t1t->lockbyte[p_t1t->num_lockbytes].tlv_index =
1042                          p_t1t->num_lock_tlvs;
1043                      p_t1t->lockbyte[p_t1t->num_lockbytes].byte_index = xx;
1044                      p_t1t->lockbyte[p_t1t->num_lockbytes].b_lock_read = false;
1045                      p_t1t->num_lockbytes++;
1046                    } else
1047                      LOG(ERROR) << StringPrintf(
1048                          "T1T Buffer overflow error. Max supported lock "
1049                          "bytes=0x%02X",
1050                          RW_T1T_MAX_LOCK_BYTES);
1051                    xx++;
1052                  }
1053                  p_t1t->num_lock_tlvs++;
1054                  rw_t1t_update_attributes();
1055                } else
1056                  LOG(ERROR) << StringPrintf(
1057                      "T1T Buffer overflow error. Max supported lock "
1058                      "tlvs=0x%02X",
1059                      RW_T1T_MAX_LOCK_TLVS);
1060
1061                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1062              }
1063            } else {
1064              if (bytes_count == 0) {
1065                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1066              }
1067            }
1068            break;
1069
1070          case TAG_MEM_CTRL_TLV:
1071            bytes_count--;
1072            if ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) ||
1073                (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
1074              tlv_value[2 - bytes_count] = p_readbytes[offset];
1075              if (bytes_count == 0) {
1076                if (p_t1t->num_mem_tlvs >= RW_T1T_MAX_MEM_TLVS) {
1077                  LOG(ERROR) << StringPrintf(
1078                      "rw_t1t_handle_tlv_detect_rsp - Maximum buffer allocated "
1079                      "for Memory tlv has reached");
1080                  failed = true;
1081                } else {
1082                  /* Extract dynamic reserved bytes */
1083                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset =
1084                      (tlv_value[0] >> 4) & 0x0F;
1085                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset *=
1086                      (uint8_t)tags_pow(2, tlv_value[2] & 0x0F);
1087                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset +=
1088                      tlv_value[0] & 0x0F;
1089                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes = tlv_value[1];
1090                  p_t1t->num_mem_tlvs++;
1091                  rw_t1t_update_attributes();
1092                  tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1093                }
1094              }
1095            } else {
1096              if (bytes_count == 0) {
1097                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1098              }
1099            }
1100            break;
1101
1102          case TAG_PROPRIETARY_TLV:
1103            bytes_count--;
1104            if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
1105              found = true;
1106            else {
1107              if (bytes_count == 0) {
1108                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
1109              }
1110            }
1111            break;
1112        }
1113        offset++;
1114        break;
1115    }
1116  }
1117
1118  p_t1t->work_offset += bytes_read;
1119
1120  /* NDEF/Lock/Mem TLV to be found in segment 0, if not assume detection failed
1121   */
1122  if (!found && !failed) {
1123    if (((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) &&
1124         (p_t1t->num_lockbytes > 0)) ||
1125        ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) &&
1126         (p_t1t->num_mem_tlvs > 0))) {
1127      found = true;
1128    } else {
1129      if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
1130        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
1131      }
1132      failed = true;
1133    }
1134  }
1135
1136  status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1137  return status;
1138}
1139
1140/*******************************************************************************
1141**
1142** Function         rw_t1t_handle_ndef_rall_rsp
1143**
1144** Description      Handle response to RALL command sent while reading an
1145**                  NDEF message
1146**
1147** Returns          NFC_STATUS_CONTINUE, if NDEF read operation is not complete
1148**                  NFC_STATUS_OK, if NDEF read is successfull
1149**                  NFC_STATUS_FAILED,if NDEF read failed
1150**
1151*******************************************************************************/
1152static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp(void) {
1153  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1154  tNFC_STATUS status = NFC_STATUS_CONTINUE;
1155  uint8_t count;
1156  uint8_t adds;
1157
1158  count = (uint8_t)p_t1t->ndef_msg_offset;
1159  p_t1t->work_offset = 0;
1160  p_t1t->segment = 0;
1161
1162  while (count < T1T_STATIC_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len) {
1163    if (rw_t1t_is_lock_reserved_otp_byte(count) == false) {
1164      p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_t1t->mem[count];
1165      p_t1t->work_offset++;
1166    }
1167    count++;
1168  }
1169  if (p_t1t->work_offset != p_t1t->ndef_msg_len) {
1170    if ((p_t1t->hr[0] & 0x0F) != 1) {
1171      if (p_t1t->work_offset == 0)
1172        return NFC_STATUS_FAILED;
1173
1174      else {
1175        p_t1t->block_read = T1T_STATIC_BLOCKS + 1;
1176        p_t1t->segment++;
1177      }
1178      if (p_t1t->ndef_msg_len - p_t1t->work_offset <= 8) {
1179        status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8, p_t1t->block_read, NULL);
1180        if (status == NFC_STATUS_OK) {
1181          p_t1t->tlv_detect = TAG_NDEF_TLV;
1182          p_t1t->state = RW_T1T_STATE_READ_NDEF;
1183          status = NFC_STATUS_CONTINUE;
1184        }
1185      } else {
1186        /* send RSEG command */
1187        RW_T1T_BLD_ADDS((adds), (p_t1t->segment));
1188        status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
1189        if (status == NFC_STATUS_OK) {
1190          p_t1t->state = RW_T1T_STATE_READ_NDEF;
1191          status = NFC_STATUS_CONTINUE;
1192        }
1193      }
1194    } else {
1195      LOG(ERROR) << StringPrintf(
1196          "RW_T1tReadNDef - Invalid NDEF len: %u or NDEF corrupted",
1197          p_t1t->ndef_msg_len);
1198      status = NFC_STATUS_FAILED;
1199    }
1200  } else {
1201    status = NFC_STATUS_OK;
1202  }
1203  return status;
1204}
1205
1206/*******************************************************************************
1207**
1208** Function         rw_t1t_handle_ndef_read_rsp
1209**
1210** Description      Handle response to commands sent while reading an
1211**                  NDEF message
1212**
1213** Returns          NFC_STATUS_CONTINUE, if tlv read is not yet complete
1214**                  NFC_STATUS_OK, if tlv read is complete & success
1215**                  NFC_STATUS_FAILED,if tlv read failed
1216**
1217*******************************************************************************/
1218static tNFC_STATUS rw_t1t_handle_ndef_read_rsp(uint8_t* p_data) {
1219  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1220  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1221  uint8_t index;
1222  uint8_t adds;
1223  tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
1224      (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
1225
1226  /* The Response received could be for Read8 or Read Segment command */
1227  switch (p_cmd_rsp_info->opcode) {
1228    case T1T_CMD_READ8:
1229      if (p_t1t->work_offset == 0) {
1230        index = p_t1t->ndef_msg_offset % T1T_BLOCK_SIZE;
1231      } else {
1232        index = 0;
1233      }
1234      p_t1t->segment = (p_t1t->block_read * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
1235      while (index < T1T_BLOCK_SIZE &&
1236             p_t1t->work_offset < p_t1t->ndef_msg_len) {
1237        if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)(
1238                (p_t1t->block_read * T1T_BLOCK_SIZE) + index)) == false) {
1239          p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index];
1240          p_t1t->work_offset++;
1241        }
1242        index++;
1243      }
1244      break;
1245
1246    case T1T_CMD_RSEG:
1247      if (p_t1t->work_offset == 0) {
1248        index = p_t1t->ndef_msg_offset % T1T_SEGMENT_SIZE;
1249      } else {
1250        index = 0;
1251      }
1252      p_t1t->block_read = ((p_t1t->segment + 1) * T1T_BLOCKS_PER_SEGMENT) - 1;
1253
1254      while (index < T1T_SEGMENT_SIZE &&
1255             p_t1t->work_offset < p_t1t->ndef_msg_len) {
1256        if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)(index)) == false) {
1257          p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index];
1258          p_t1t->work_offset++;
1259        }
1260        index++;
1261      }
1262      break;
1263
1264    default:
1265      break;
1266  }
1267  if (p_t1t->work_offset < p_t1t->ndef_msg_len) {
1268    if ((p_t1t->hr[0] & 0x0F) != 1) {
1269      if ((p_t1t->ndef_msg_len - p_t1t->work_offset) <= T1T_BLOCK_SIZE) {
1270        p_t1t->block_read++;
1271        ndef_status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8,
1272                                          (uint8_t)(p_t1t->block_read), NULL);
1273        if (ndef_status == NFC_STATUS_OK) {
1274          ndef_status = NFC_STATUS_CONTINUE;
1275        }
1276      } else {
1277        p_t1t->segment++;
1278        /* send RSEG command */
1279        RW_T1T_BLD_ADDS((adds), (p_t1t->segment));
1280        ndef_status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
1281        if (ndef_status == NFC_STATUS_OK) {
1282          ndef_status = NFC_STATUS_CONTINUE;
1283        }
1284      }
1285    }
1286  } else {
1287    ndef_status = NFC_STATUS_OK;
1288  }
1289  return ndef_status;
1290}
1291
1292/*******************************************************************************
1293**
1294** Function         rw_t1t_next_ndef_write_block
1295**
1296** Description      This function prepare and writes ndef blocks
1297**
1298** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1299**                  NFC_STATUS_OK, if tlv write is complete & success
1300**                  NFC_STATUS_FAILED,if tlv write failed
1301**
1302*******************************************************************************/
1303static tNFC_STATUS rw_t1t_next_ndef_write_block(void) {
1304  bool b_block_write_cmd = false;
1305  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1306  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1307  uint8_t write_block[8];
1308  uint8_t block;
1309  uint8_t index;
1310  uint8_t new_lengthfield_len;
1311  uint8_t length_field[3];
1312  uint16_t initial_offset;
1313  uint8_t count;
1314  /* Write NDEF Message */
1315  new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3 : 1;
1316
1317  /* Identify the command to use for NDEF write operation */
1318  if ((p_t1t->hr[0] & 0x0F) != 1) {
1319    /* Dynamic memory structure */
1320    b_block_write_cmd = false;
1321    block = p_t1t->ndef_block_written + 1;
1322    p_t1t->segment = (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
1323
1324    count = 0;
1325    while (block <= p_t1t->mem[T1T_CC_TMS_BYTE]) {
1326      index = 0;
1327      if (block == p_t1t->num_ndef_finalblock) {
1328        /* T1T_CMD_WRITE_E8 Command */
1329        b_block_write_cmd = true;
1330        break;
1331      }
1332      while (index < T1T_BLOCK_SIZE &&
1333             p_t1t->work_offset <
1334                 (p_t1t->new_ndef_msg_len + new_lengthfield_len)) {
1335        if (rw_t1t_is_lock_reserved_otp_byte(
1336                (uint16_t)((block * T1T_BLOCK_SIZE) + index)) == false) {
1337          count++;
1338        }
1339        index++;
1340      }
1341      if (count == T1T_BLOCK_SIZE) {
1342        /* T1T_CMD_WRITE_E8 Command */
1343        b_block_write_cmd = true;
1344        break;
1345      } else if (count == 0) {
1346        index = 0;
1347        block++;
1348        if (p_t1t->segment != (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE) {
1349          p_t1t->segment = (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
1350        }
1351      } else {
1352        /* T1T_CMD_WRITE_E Command */
1353        b_block_write_cmd = false;
1354        break;
1355      }
1356    }
1357  } else {
1358    /* Static memory structure */
1359    block = p_t1t->ndef_block_written;
1360    b_block_write_cmd = false;
1361  }
1362
1363  new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3 : 1;
1364  if (new_lengthfield_len == 3) {
1365    length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
1366    length_field[1] = (uint8_t)(p_t1t->new_ndef_msg_len >> 8);
1367    length_field[2] = (uint8_t)(p_t1t->new_ndef_msg_len);
1368  } else {
1369    length_field[0] = (uint8_t)(p_t1t->new_ndef_msg_len);
1370  }
1371
1372  if (b_block_write_cmd) {
1373    /* Dynamic memory structure */
1374    index = 0;
1375    p_t1t->segment = (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
1376
1377    initial_offset = p_t1t->work_offset;
1378    block = rw_t1t_prepare_ndef_bytes(write_block, length_field, &index, false,
1379                                      block, new_lengthfield_len);
1380    if (p_t1t->work_offset == initial_offset) {
1381      ndef_status = NFC_STATUS_FAILED;
1382    } else {
1383      /* Send WRITE_E8 command */
1384      ndef_status = rw_t1t_send_ndef_block(write_block, block);
1385    }
1386  } else {
1387    /* Static memory structure */
1388    if (p_t1t->write_byte + 1 >= T1T_BLOCK_SIZE) {
1389      index = 0;
1390      block++;
1391    } else {
1392      index = p_t1t->write_byte + 1;
1393    }
1394    initial_offset = p_t1t->work_offset;
1395    block = rw_t1t_prepare_ndef_bytes(write_block, length_field, &index, true,
1396                                      block, new_lengthfield_len);
1397    if (p_t1t->work_offset == initial_offset) {
1398      ndef_status = NFC_STATUS_FAILED;
1399    } else {
1400      /* send WRITE-E command */
1401      ndef_status = rw_t1t_send_ndef_byte(write_block[index], block, index,
1402                                          new_lengthfield_len);
1403    }
1404  }
1405  return ndef_status;
1406}
1407
1408/*******************************************************************************
1409**
1410** Function         rw_t1t_ndef_write_first_block
1411**
1412** Description      This function writes ndef first block
1413**
1414** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1415**                  NFC_STATUS_OK, if tlv write is complete & success
1416**                  NFC_STATUS_FAILED,if tlv write failed
1417**
1418*******************************************************************************/
1419static tNFC_STATUS rw_t1t_ndef_write_first_block(void) {
1420  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1421  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1422  uint8_t block;
1423  uint8_t index;
1424  uint8_t new_lengthfield_len;
1425  uint8_t length_field[3];
1426  uint8_t write_block[8];
1427
1428  /* handle positive response to invalidating existing NDEF Message */
1429  p_t1t->work_offset = 0;
1430  new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3 : 1;
1431  if (new_lengthfield_len == 3) {
1432    length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
1433    length_field[1] = (uint8_t)(p_t1t->new_ndef_msg_len >> 8);
1434    length_field[2] = (uint8_t)(p_t1t->new_ndef_msg_len);
1435  } else {
1436    length_field[0] = (uint8_t)(p_t1t->new_ndef_msg_len);
1437  }
1438  /* updating ndef_first_block with new ndef message */
1439  memcpy(write_block, p_t1t->ndef_first_block, T1T_BLOCK_SIZE);
1440  index = p_t1t->ndef_header_offset % T1T_BLOCK_SIZE;
1441  block = (uint8_t)(p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
1442  p_t1t->segment = (uint8_t)(p_t1t->ndef_header_offset / T1T_SEGMENT_SIZE);
1443
1444  if ((p_t1t->hr[0] & 0x0F) != 1) {
1445    /* Dynamic Memory structure */
1446    block = rw_t1t_prepare_ndef_bytes(write_block, length_field, &index, false,
1447                                      block, new_lengthfield_len);
1448
1449    if (p_t1t->work_offset == 0) {
1450      ndef_status = NFC_STATUS_FAILED;
1451    } else {
1452      /* Send WRITE-E8 command based on the prepared write_block */
1453      ndef_status = rw_t1t_send_ndef_block(write_block, block);
1454    }
1455  } else {
1456    /* Static Memory structure */
1457    block = rw_t1t_prepare_ndef_bytes(write_block, length_field, &index, true,
1458                                      block, new_lengthfield_len);
1459    if (p_t1t->work_offset == 0) {
1460      ndef_status = NFC_STATUS_FAILED;
1461    } else {
1462      /* send WRITE-E command */
1463      ndef_status = rw_t1t_send_ndef_byte(write_block[index], block, index,
1464                                          new_lengthfield_len);
1465    }
1466  }
1467
1468  return ndef_status;
1469}
1470
1471/*******************************************************************************
1472**
1473** Function         rw_t1t_send_ndef_byte
1474**
1475** Description      Sends ndef message or length field byte and update
1476**                  status
1477**
1478** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1479**                  NFC_STATUS_OK, if tlv write is complete & success
1480**                  NFC_STATUS_FAILED,if tlv write failed
1481**
1482*******************************************************************************/
1483static tNFC_STATUS rw_t1t_send_ndef_byte(uint8_t data, uint8_t block,
1484                                         uint8_t index, uint8_t msg_len) {
1485  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1486  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1487  uint8_t addr;
1488
1489  /* send WRITE-E command */
1490  RW_T1T_BLD_ADD((addr), (block), (index));
1491  if (NFC_STATUS_OK == rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, data)) {
1492    p_t1t->write_byte = index;
1493    p_t1t->ndef_block_written = block;
1494    if (p_t1t->work_offset == p_t1t->new_ndef_msg_len + msg_len) {
1495      ndef_status = NFC_STATUS_OK;
1496    } else {
1497      ndef_status = NFC_STATUS_CONTINUE;
1498    }
1499  } else {
1500    ndef_status = NFC_STATUS_FAILED;
1501  }
1502  return ndef_status;
1503}
1504
1505/*******************************************************************************
1506**
1507** Function         rw_t1t_prepare_ndef_bytes
1508**
1509** Description      prepares ndef block to write
1510**
1511** Returns          block number where to write
1512**
1513*******************************************************************************/
1514static uint8_t rw_t1t_prepare_ndef_bytes(uint8_t* p_data,
1515                                         uint8_t* p_length_field,
1516                                         uint8_t* p_index, bool b_one_byte,
1517                                         uint8_t block,
1518                                         uint8_t lengthfield_len) {
1519  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1520  uint8_t first_block = (uint8_t)(p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
1521  uint16_t initial_offset = p_t1t->work_offset;
1522
1523  while (p_t1t->work_offset == initial_offset &&
1524         block <= p_t1t->mem[T1T_CC_TMS_BYTE]) {
1525    if ((block == p_t1t->num_ndef_finalblock) && (block != first_block)) {
1526      memcpy(p_data, p_t1t->ndef_final_block, T1T_BLOCK_SIZE);
1527    }
1528    /* Update length field */
1529    while ((*p_index < T1T_BLOCK_SIZE) &&
1530           (p_t1t->work_offset < lengthfield_len)) {
1531      if (rw_t1t_is_lock_reserved_otp_byte(
1532              (uint16_t)((block * T1T_BLOCK_SIZE) + *p_index)) == false) {
1533        p_data[*p_index] = p_length_field[p_t1t->work_offset];
1534        p_t1t->work_offset++;
1535        if (b_one_byte) return block;
1536      }
1537      (*p_index)++;
1538      if (p_t1t->work_offset == lengthfield_len) {
1539        break;
1540      }
1541    }
1542    /* Update ndef message field */
1543    while (*p_index < T1T_BLOCK_SIZE &&
1544           p_t1t->work_offset < (p_t1t->new_ndef_msg_len + lengthfield_len)) {
1545      if (rw_t1t_is_lock_reserved_otp_byte(
1546              (uint16_t)((block * T1T_BLOCK_SIZE) + *p_index)) == false) {
1547        p_data[*p_index] =
1548            p_t1t->p_ndef_buffer[p_t1t->work_offset - lengthfield_len];
1549        p_t1t->work_offset++;
1550        if (b_one_byte) return block;
1551      }
1552      (*p_index)++;
1553    }
1554    if (p_t1t->work_offset == initial_offset) {
1555      *p_index = 0;
1556      block++;
1557      if (p_t1t->segment != (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE) {
1558        p_t1t->segment = (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
1559      }
1560    }
1561  }
1562  return block;
1563}
1564
1565/*******************************************************************************
1566**
1567** Function         rw_t1t_send_ndef_block
1568**
1569** Description      Sends ndef block and update status
1570**
1571** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1572**                  NFC_STATUS_OK, if tlv write is complete & success
1573**                  NFC_STATUS_FAILED,if tlv write failed
1574**
1575*******************************************************************************/
1576static tNFC_STATUS rw_t1t_send_ndef_block(uint8_t* p_data, uint8_t block) {
1577  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1578  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1579
1580  if (NFC_STATUS_OK == rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_E8, block, p_data)) {
1581    p_t1t->ndef_block_written = block;
1582    if (p_t1t->ndef_block_written == p_t1t->num_ndef_finalblock) {
1583      ndef_status = NFC_STATUS_OK;
1584    } else {
1585      ndef_status = NFC_STATUS_CONTINUE;
1586    }
1587  } else {
1588    ndef_status = NFC_STATUS_FAILED;
1589  }
1590  return ndef_status;
1591}
1592
1593/*******************************************************************************
1594**
1595** Function         rw_t1t_get_ndef_flags
1596**
1597** Description      Prepare NDEF Flags
1598**
1599** Returns          NDEF Flag value
1600**
1601*******************************************************************************/
1602static uint8_t rw_t1t_get_ndef_flags(void) {
1603  uint8_t flags = 0;
1604  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1605
1606  if ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
1607    flags |= RW_NDEF_FL_SUPPORTED;
1608
1609  if (t1t_tag_init_data(p_t1t->hr[0]) != NULL) flags |= RW_NDEF_FL_FORMATABLE;
1610
1611  if ((p_t1t->mem[T1T_CC_RWA_BYTE] & 0x0F) == T1T_CC_RWA_RO)
1612    flags |= RW_NDEF_FL_READ_ONLY;
1613
1614  return flags;
1615}
1616
1617/*******************************************************************************
1618**
1619** Function         rw_t1t_get_ndef_max_size
1620**
1621** Description      Calculate maximum size of NDEF message that can be written
1622**                  on to the tag
1623**
1624** Returns          Maximum size of NDEF Message
1625**
1626*******************************************************************************/
1627static uint16_t rw_t1t_get_ndef_max_size(void) {
1628  uint16_t offset;
1629  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1630  uint16_t tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE;
1631  const tT1T_INIT_TAG* p_ret;
1632  uint8_t init_segment = p_t1t->segment;
1633
1634  p_t1t->max_ndef_msg_len = 0;
1635  offset = p_t1t->ndef_msg_offset;
1636  p_t1t->segment = (uint8_t)(p_t1t->ndef_msg_offset / T1T_SEGMENT_SIZE);
1637
1638  if ((tag_size < T1T_STATIC_SIZE) ||
1639      (tag_size > (T1T_SEGMENT_SIZE * T1T_MAX_SEGMENTS)) ||
1640      ((p_t1t->mem[T1T_CC_NMN_BYTE] != T1T_CC_NMN) &&
1641       (p_t1t->mem[T1T_CC_NMN_BYTE] != 0))) {
1642    /* Tag not formated, determine maximum NDEF size from HR */
1643    if (((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED) &&
1644        ((p_ret = t1t_tag_init_data(p_t1t->hr[0])) != NULL)) {
1645      p_t1t->max_ndef_msg_len = ((p_ret->tms + 1) * T1T_BLOCK_SIZE) -
1646                                T1T_OTP_LOCK_RES_BYTES - T1T_UID_LEN -
1647                                T1T_ADD_LEN - T1T_CC_LEN - T1T_TLV_TYPE_LEN -
1648                                T1T_SHORT_NDEF_LEN_FIELD_LEN;
1649      if (p_ret->b_dynamic) {
1650        p_t1t->max_ndef_msg_len -=
1651            (T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN +
1652             T1T_DEFAULT_TLV_LEN + T1T_TLV_TYPE_LEN +
1653             T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN);
1654        p_t1t->max_ndef_msg_len -= T1T_DYNAMIC_LOCK_BYTES;
1655      }
1656      offset = tag_size;
1657    } else {
1658      p_t1t->segment = init_segment;
1659      return p_t1t->max_ndef_msg_len;
1660    }
1661  }
1662
1663  /* Starting from NDEF Message offset find the first locked data byte */
1664  while (offset < tag_size) {
1665    if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)(offset)) == false) {
1666      if (rw_t1t_is_read_only_byte((uint16_t)offset) == true) break;
1667      p_t1t->max_ndef_msg_len++;
1668    }
1669    offset++;
1670    if (offset % T1T_SEGMENT_SIZE == 0) {
1671      p_t1t->segment = (uint8_t)(offset / T1T_SEGMENT_SIZE);
1672    }
1673  }
1674  /* NDEF Length field length changes based on NDEF size */
1675  if ((p_t1t->max_ndef_msg_len >= T1T_LONG_NDEF_LEN_FIELD_BYTE0) &&
1676      ((p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset) ==
1677       T1T_SHORT_NDEF_LEN_FIELD_LEN)) {
1678    p_t1t->max_ndef_msg_len -=
1679        (p_t1t->max_ndef_msg_len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)
1680            ? 1
1681            : (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
1682  }
1683
1684  p_t1t->segment = init_segment;
1685  return p_t1t->max_ndef_msg_len;
1686}
1687
1688/*******************************************************************************
1689**
1690** Function         rw_t1t_handle_ndef_write_rsp
1691**
1692** Description      Handle response to commands sent while writing an
1693**                  NDEF message
1694**
1695** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
1696**                  NFC_STATUS_OK, if tlv write is complete & success
1697**                  NFC_STATUS_FAILED,if tlv write failed
1698**
1699*******************************************************************************/
1700static tNFC_STATUS rw_t1t_handle_ndef_write_rsp(uint8_t* p_data) {
1701  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1702  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
1703  uint8_t addr;
1704
1705  switch (p_t1t->substate) {
1706    case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
1707      /* Backup ndef_final_block */
1708      memcpy(p_t1t->ndef_final_block, p_data, T1T_BLOCK_SIZE);
1709      /* Invalidate existing NDEF Message */
1710      RW_T1T_BLD_ADD((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
1711      if (NFC_STATUS_OK == rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, 0)) {
1712        ndef_status = NFC_STATUS_CONTINUE;
1713        p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
1714        p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
1715      } else {
1716        ndef_status = NFC_STATUS_FAILED;
1717      }
1718      break;
1719
1720    case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
1721      ndef_status = rw_t1t_ndef_write_first_block();
1722      break;
1723
1724    case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
1725      ndef_status = rw_t1t_next_ndef_write_block();
1726      break;
1727
1728    case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
1729      /* Validate new NDEF Message */
1730      RW_T1T_BLD_ADD((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
1731      if (NFC_STATUS_OK ==
1732          rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, T1T_CC_NMN)) {
1733        ndef_status = NFC_STATUS_OK;
1734      } else {
1735        ndef_status = NFC_STATUS_FAILED;
1736      }
1737      break;
1738    default:
1739      break;
1740  }
1741
1742  return ndef_status;
1743}
1744
1745/*******************************************************************************
1746**
1747** Function         rw_t1t_update_attributes
1748**
1749** Description      This function will prepare attributes for the current
1750**                  segment. Every bit in the attribute refers to one byte of
1751**                  tag content.The bit corresponding to a tag byte will be set
1752**                  to '1' when the Tag byte is read only,otherwise will be set
1753**                  to '0'
1754**
1755** Returns          None
1756**
1757*******************************************************************************/
1758static void rw_t1t_update_attributes(void) {
1759  uint8_t count = 0;
1760  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1761  uint16_t lower_offset;
1762  uint16_t upper_offset;
1763  uint8_t num_bytes;
1764  uint16_t offset;
1765  uint8_t bits_per_byte = 8;
1766
1767  count = 0;
1768  while (count < T1T_BLOCKS_PER_SEGMENT) {
1769    p_t1t->attr[count] = 0x00;
1770    count++;
1771  }
1772
1773  lower_offset = p_t1t->segment * T1T_SEGMENT_SIZE;
1774  upper_offset = (p_t1t->segment + 1) * T1T_SEGMENT_SIZE;
1775
1776  if (p_t1t->segment == 0) {
1777    /* UID/Lock/Reserved/OTP bytes */
1778    p_t1t->attr[0x00] = 0xFF; /* Uid bytes */
1779    p_t1t->attr[0x0D] = 0xFF; /* Reserved bytes */
1780    p_t1t->attr[0x0E] = 0xFF; /* lock/otp bytes */
1781    p_t1t->attr[0x0F] = 0xFF; /* lock/otp bytes */
1782  }
1783
1784  /* update attr based on lock control and mem control tlvs */
1785  count = 0;
1786  while (count < p_t1t->num_lockbytes) {
1787    offset = p_t1t->lock_tlv[p_t1t->lockbyte[count].tlv_index].offset +
1788             p_t1t->lockbyte[count].byte_index;
1789    if (offset >= lower_offset && offset < upper_offset) {
1790      /* Set the corresponding bit in attr to indicate - lock byte */
1791      p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |=
1792          rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
1793    }
1794    count++;
1795  }
1796  count = 0;
1797  while (count < p_t1t->num_mem_tlvs) {
1798    num_bytes = 0;
1799    while (num_bytes < p_t1t->mem_tlv[count].num_bytes) {
1800      offset = p_t1t->mem_tlv[count].offset + num_bytes;
1801      if (offset >= lower_offset && offset < upper_offset) {
1802        /* Set the corresponding bit in attr to indicate - reserved byte */
1803        p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |=
1804            rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
1805      }
1806      num_bytes++;
1807    }
1808    count++;
1809  }
1810}
1811
1812/*******************************************************************************
1813**
1814** Function         rw_t1t_get_lock_bits_for_segment
1815**
1816** Description      This function will identify the index of the dynamic lock
1817**                  byte that covers the current segment
1818**
1819** Parameters:      segment, segment number
1820**                  p_start_byte, pointer to hold the first lock byte index
1821**                  p_start_bit, pointer to hold the first lock bit index
1822**                  p_end_byte, pointer to hold the last lock byte index
1823**
1824** Returns          Total lock bits that covers the specified segment
1825**
1826*******************************************************************************/
1827static uint8_t rw_t1t_get_lock_bits_for_segment(uint8_t segment,
1828                                                uint8_t* p_start_byte,
1829                                                uint8_t* p_start_bit,
1830                                                uint8_t* p_end_byte) {
1831  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1832  uint16_t byte_count = T1T_SEGMENT_SIZE;
1833  uint8_t total_bits = 0;
1834  uint8_t num_dynamic_locks = 0;
1835  uint8_t bit_count = 0;
1836  uint16_t tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE;
1837  uint16_t lower_offset;
1838  uint16_t upper_offset;
1839  bool b_all_bits_are_locks = true;
1840  uint8_t bytes_locked_per_bit;
1841  uint8_t num_bits;
1842
1843  upper_offset = (segment + 1) * T1T_SEGMENT_SIZE;
1844
1845  if (upper_offset > tag_size) upper_offset = tag_size;
1846
1847  lower_offset = segment * T1T_SEGMENT_SIZE;
1848  *p_start_byte = num_dynamic_locks;
1849  *p_start_bit = 0;
1850
1851  while ((byte_count <= lower_offset) &&
1852         (num_dynamic_locks < p_t1t->num_lockbytes)) {
1853    bytes_locked_per_bit =
1854        p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
1855            .bytes_locked_per_bit;
1856    /* Number of bits in the current lock byte */
1857    b_all_bits_are_locks =
1858        ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) *
1859             TAG_BITS_PER_BYTE <=
1860         p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
1861             .num_bits);
1862    num_bits =
1863        b_all_bits_are_locks
1864            ? TAG_BITS_PER_BYTE
1865            : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
1866                      .num_bits %
1867                  TAG_BITS_PER_BYTE;
1868
1869    /* Skip lock bits that covers all previous segments */
1870    if (bytes_locked_per_bit * num_bits + byte_count <= lower_offset) {
1871      byte_count += bytes_locked_per_bit * num_bits;
1872      num_dynamic_locks++;
1873    } else {
1874      /* The first lock bit that covers this segment is present in this segment
1875       */
1876      bit_count = 0;
1877      while (bit_count < num_bits) {
1878        byte_count += bytes_locked_per_bit;
1879        if (byte_count > lower_offset) {
1880          *p_start_byte = num_dynamic_locks;
1881          *p_end_byte = num_dynamic_locks;
1882          *p_start_bit = bit_count;
1883          bit_count++;
1884          total_bits = 1;
1885          break;
1886        }
1887        bit_count++;
1888      }
1889    }
1890  }
1891  if (num_dynamic_locks == p_t1t->num_lockbytes) {
1892    return 0;
1893  }
1894  while ((byte_count < upper_offset) &&
1895         (num_dynamic_locks < p_t1t->num_lockbytes)) {
1896    bytes_locked_per_bit =
1897        p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
1898            .bytes_locked_per_bit;
1899
1900    /* Number of bits in the current lock byte */
1901    b_all_bits_are_locks =
1902        ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) *
1903             TAG_BITS_PER_BYTE <=
1904         p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
1905             .num_bits);
1906    num_bits =
1907        b_all_bits_are_locks
1908            ? TAG_BITS_PER_BYTE
1909            : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
1910                      .num_bits %
1911                  TAG_BITS_PER_BYTE;
1912
1913    /* Collect all lock bits that covers the current segment */
1914    if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count <
1915        upper_offset) {
1916      byte_count += bytes_locked_per_bit * (num_bits - bit_count);
1917      total_bits += num_bits - bit_count;
1918      bit_count = 0;
1919      *p_end_byte = num_dynamic_locks;
1920      num_dynamic_locks++;
1921    } else {
1922      /* The last lock byte that covers the current segment */
1923      bit_count = 0;
1924      while (bit_count < num_bits) {
1925        byte_count += bytes_locked_per_bit;
1926        if (byte_count >= upper_offset) {
1927          *p_end_byte = num_dynamic_locks;
1928          total_bits += (bit_count + 1);
1929          break;
1930        }
1931        bit_count++;
1932      }
1933    }
1934  }
1935  return total_bits;
1936}
1937
1938/*******************************************************************************
1939**
1940** Function         rw_t1t_update_lock_attributes
1941**
1942** Description      This function will check if the tag index passed as
1943**                  argument is a locked byte and return
1944**                  TRUE or FALSE
1945**
1946** Parameters:      index, the index of the byte in the tag
1947**
1948**
1949** Returns          TRUE, if the specified index in the tag is a locked or
1950**                        reserved or otp byte
1951**                  FALSE, otherwise
1952**
1953*******************************************************************************/
1954static void rw_t1t_update_lock_attributes(void) {
1955  uint8_t xx = 0;
1956  uint8_t bytes_locked_per_lock_bit;
1957  uint8_t num_static_lock_bytes = 0;
1958  uint8_t num_dynamic_lock_bytes = 0;
1959  uint8_t bits_covered = 0;
1960  uint8_t bytes_covered = 0;
1961  uint8_t block_count = 0;
1962  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
1963  uint8_t start_lock_byte;
1964  uint8_t start_lock_bit;
1965  uint8_t end_lock_byte;
1966  uint8_t num_lock_bits;
1967  uint8_t total_bits;
1968
1969  block_count = 0;
1970  while (block_count < T1T_BLOCKS_PER_SEGMENT) {
1971    p_t1t->lock_attr[block_count] = 0x00;
1972    block_count++;
1973  }
1974
1975  /* update lock_attr based on static lock bytes */
1976  if (p_t1t->segment == 0) {
1977    xx = 0;
1978    num_static_lock_bytes = 0;
1979    block_count = 0;
1980    num_lock_bits = 8;
1981
1982    while (num_static_lock_bytes < T1T_NUM_STATIC_LOCK_BYTES) {
1983      /* Update lock attribute based on 2 static locks */
1984      while (xx < num_lock_bits) {
1985        p_t1t->lock_attr[block_count] = 0x00;
1986
1987        if (p_t1t->mem[T1T_LOCK_0_OFFSET + num_static_lock_bytes] &
1988            rw_t1t_mask_bits[xx++]) {
1989          /* If the bit is set then 1 block is locked */
1990          p_t1t->lock_attr[block_count] = 0xFF;
1991        }
1992
1993        block_count++;
1994      }
1995      num_static_lock_bytes++;
1996      xx = 0;
1997    }
1998    /* Locked bytes */
1999    p_t1t->lock_attr[0x00] = 0xFF;
2000    p_t1t->lock_attr[0x0D] = 0xFF;
2001  } else {
2002    /* update lock_attr based on segment and using dynamic lock bytes */
2003    total_bits = rw_t1t_get_lock_bits_for_segment(
2004        p_t1t->segment, &start_lock_byte, &start_lock_bit, &end_lock_byte);
2005    if (total_bits != 0) {
2006      xx = start_lock_bit;
2007      num_dynamic_lock_bytes = start_lock_byte;
2008      bits_covered = 0;
2009      bytes_covered = 0;
2010      block_count = 0;
2011      num_lock_bits = 8;
2012
2013      p_t1t->lock_attr[block_count] = 0;
2014
2015      while (num_dynamic_lock_bytes <= end_lock_byte) {
2016        bytes_locked_per_lock_bit =
2017            p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_lock_bytes].tlv_index]
2018                .bytes_locked_per_bit;
2019        if (num_dynamic_lock_bytes == end_lock_byte) {
2020          num_lock_bits = (total_bits % 8 == 0) ? 8 : total_bits % 8;
2021        }
2022        while (xx < num_lock_bits) {
2023          bytes_covered = 0;
2024          while (bytes_covered < bytes_locked_per_lock_bit) {
2025            /* Set/clear lock_attr byte bits based on whether a particular lock
2026             * bit is set or not
2027             * each bit in lock_attr represents one byte in Tag read only
2028             * attribute */
2029            if ((p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte &
2030                 rw_t1t_mask_bits[xx]) &&
2031                (block_count < T1T_BLOCKS_PER_SEGMENT)) {
2032              p_t1t->lock_attr[block_count] |= 0x01 << bits_covered;
2033            }
2034            bytes_covered++;
2035            bits_covered++;
2036            if (bits_covered == 8) {
2037              bits_covered = 0;
2038              block_count++;
2039              if (block_count < T1T_BLOCKS_PER_SEGMENT)
2040                p_t1t->lock_attr[block_count] = 0;
2041            }
2042          }
2043          xx++;
2044        }
2045        num_dynamic_lock_bytes++;
2046        xx = 0;
2047      }
2048    }
2049  }
2050}
2051
2052/*******************************************************************************
2053**
2054** Function         rw_t1t_is_lock_reserved_otp_byte
2055**
2056** Description      This function will check if the tag index passed as
2057**                  argument is a lock or reserved or otp byte
2058**
2059** Parameters:      index, the index of the byte in the tag's current segment
2060**
2061**
2062** Returns          TRUE, if the specified index in the tag is a locked or
2063**                        reserved or otp byte
2064**                  FALSE, otherwise
2065**
2066*******************************************************************************/
2067static bool rw_t1t_is_lock_reserved_otp_byte(uint16_t index) {
2068  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
2069
2070  if (p_t1t->attr_seg != p_t1t->segment) {
2071    /* Update p_t1t->attr to reflect the current segment */
2072    rw_t1t_update_attributes();
2073    p_t1t->attr_seg = p_t1t->segment;
2074  }
2075  index = index % T1T_SEGMENT_SIZE;
2076
2077  /* Every bit in p_t1t->attr indicates one specific byte of the tag is either a
2078   * lock/reserved/otp byte or not
2079   * So, each array element in p_t1t->attr covers one block in the tag as T1
2080   * block size and array element size is 8
2081   * Find the block and offset for the index (passed as argument) and Check if
2082   * the offset bit in the
2083   * p_t1t->attr[block] is set or not. If the bit is set then it is a
2084   * lock/reserved/otp byte, otherwise not */
2085
2086  return ((p_t1t->attr[index / 8] & rw_t1t_mask_bits[index % 8]) == 0) ? false
2087                                                                       : true;
2088}
2089
2090/*******************************************************************************
2091**
2092** Function         rw_t1t_is_read_only_byte
2093**
2094** Description      This function will check if the tag index passed as
2095**                  argument is a read only byte
2096**
2097** Parameters:      index, the index of the byte in the tag's current segment
2098**
2099**
2100** Returns          TRUE, if the specified index in the tag is a locked or
2101**                        reserved or otp byte
2102**                  FALSE, otherwise
2103**
2104*******************************************************************************/
2105static bool rw_t1t_is_read_only_byte(uint16_t index) {
2106  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
2107
2108  if (p_t1t->lock_attr_seg != p_t1t->segment) {
2109    /* Update p_t1t->lock_attr to reflect the current segment */
2110    rw_t1t_update_lock_attributes();
2111    p_t1t->lock_attr_seg = p_t1t->segment;
2112  }
2113
2114  index = index % T1T_SEGMENT_SIZE;
2115  /* Every bit in p_t1t->lock_attr indicates one specific byte of the tag is a
2116   * read only byte or read write byte
2117   * So, each array element in p_t1t->lock_attr covers one block in the tag as
2118   * T1 block size and array element size is 8
2119   * Find the block and offset for the index (passed as argument) and Check if
2120   * the offset bit in the
2121   * p_t1t->lock_attr[block] is set or not. If the bit is set then it is a read
2122   * only byte, otherwise read write byte */
2123
2124  return ((p_t1t->lock_attr[index / 8] & rw_t1t_mask_bits[index % 8]) == 0)
2125             ? false
2126             : true;
2127}
2128
2129/*****************************************************************************
2130**
2131** Function         RW_T1tFormatNDef
2132**
2133** Description
2134**      Format Tag content
2135**
2136** Returns
2137**      NFC_STATUS_OK, Command sent to format Tag
2138**      NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag
2139**      NFC_STATUS_FAILED: other error
2140**
2141*****************************************************************************/
2142tNFC_STATUS RW_T1tFormatNDef(void) {
2143  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
2144  tNFC_STATUS status = NFC_STATUS_FAILED;
2145  const tT1T_INIT_TAG* p_ret;
2146  uint8_t addr;
2147  uint8_t* p;
2148
2149  if (p_t1t->state != RW_T1T_STATE_IDLE) {
2150    LOG(WARNING) << StringPrintf(
2151        "RW_T1tFormatNDef - Tag not initialized/ Busy! State: %u",
2152        p_t1t->state);
2153    return (NFC_STATUS_FAILED);
2154  }
2155
2156  if ((p_t1t->hr[0] & 0xF0) != T1T_NDEF_SUPPORTED) {
2157    LOG(WARNING) << StringPrintf(
2158        "RW_T1tFormatNDef - Cannot format tag as NDEF not supported. HR0: %u",
2159        p_t1t->hr[0]);
2160    return (NFC_STATUS_REJECTED);
2161  }
2162
2163  p_ret = t1t_tag_init_data(p_t1t->hr[0]);
2164  if (p_ret == NULL) {
2165    LOG(WARNING) << StringPrintf(
2166        "RW_T1tFormatNDef - Invalid HR - HR0: %u, HR1: %u", p_t1t->hr[0],
2167        p_t1t->hr[1]);
2168    return (NFC_STATUS_REJECTED);
2169  }
2170
2171  memset(p_t1t->ndef_first_block, 0, T1T_BLOCK_SIZE);
2172  memset(p_t1t->ndef_final_block, 0, T1T_BLOCK_SIZE);
2173  p = p_t1t->ndef_first_block;
2174
2175  /* Prepare Capability Container */
2176  UINT8_TO_BE_STREAM(p, T1T_CC_NMN);
2177  UINT8_TO_BE_STREAM(p, T1T_CC_VNO);
2178  UINT8_TO_BE_STREAM(p, p_ret->tms);
2179  UINT8_TO_BE_STREAM(p, T1T_CC_RWA_RW);
2180  if (p_ret->b_dynamic) {
2181    /* Prepare Lock and Memory TLV */
2182    UINT8_TO_BE_STREAM(p, TAG_LOCK_CTRL_TLV);
2183    UINT8_TO_BE_STREAM(p, T1T_DEFAULT_TLV_LEN);
2184    UINT8_TO_BE_STREAM(p, p_ret->lock_tlv[0]);
2185    UINT8_TO_BE_STREAM(p, p_ret->lock_tlv[1]);
2186    p = p_t1t->ndef_final_block;
2187    UINT8_TO_BE_STREAM(p, p_ret->lock_tlv[2]);
2188    UINT8_TO_BE_STREAM(p, TAG_MEM_CTRL_TLV);
2189    UINT8_TO_BE_STREAM(p, T1T_DEFAULT_TLV_LEN);
2190    UINT8_TO_BE_STREAM(p, p_ret->mem_tlv[0]);
2191    UINT8_TO_BE_STREAM(p, p_ret->mem_tlv[1]);
2192    UINT8_TO_BE_STREAM(p, p_ret->mem_tlv[2]);
2193  }
2194  /* Prepare NULL NDEF TLV */
2195  UINT8_TO_BE_STREAM(p, TAG_NDEF_TLV);
2196  UINT8_TO_BE_STREAM(p, 0);
2197
2198  if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
2199      rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
2200    /* send WRITE-E8 command */
2201    status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_E8, 1, p_t1t->ndef_first_block);
2202    if (status == NFC_STATUS_OK) {
2203      p_t1t->state = RW_T1T_STATE_FORMAT_TAG;
2204      p_t1t->b_update = false;
2205      p_t1t->b_rseg = false;
2206      if (p_ret->b_dynamic)
2207        p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC;
2208      else
2209        p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
2210    }
2211  } else {
2212    /* send WRITE-E command */
2213    RW_T1T_BLD_ADD((addr), 1, 0);
2214
2215    status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr,
2216                                    p_t1t->ndef_first_block[0]);
2217    if (status == NFC_STATUS_OK) {
2218      p_t1t->work_offset = 0;
2219      p_t1t->state = RW_T1T_STATE_FORMAT_TAG;
2220      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
2221      p_t1t->b_update = false;
2222      p_t1t->b_rseg = false;
2223    }
2224  }
2225
2226  return status;
2227}
2228
2229/*******************************************************************************
2230**
2231** Function         RW_T1tLocateTlv
2232**
2233** Description      This function is called to find the start of the given TLV
2234**
2235** Parameters:      tlv_type, Type of TLV to find
2236**
2237** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error
2238**                  status.
2239**
2240*******************************************************************************/
2241tNFC_STATUS RW_T1tLocateTlv(uint8_t tlv_type) {
2242  tNFC_STATUS status = NFC_STATUS_FAILED;
2243  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
2244  uint8_t adds;
2245
2246  if (p_t1t->state != RW_T1T_STATE_IDLE) {
2247    LOG(WARNING) << StringPrintf("RW_T1tLocateTlv - Busy - State: %u",
2248                                 p_t1t->state);
2249    return (NFC_STATUS_FAILED);
2250  }
2251  p_t1t->tlv_detect = tlv_type;
2252
2253  if ((p_t1t->tlv_detect == TAG_NDEF_TLV) &&
2254      (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)) {
2255    LOG(ERROR) << StringPrintf(
2256        "RW_T1tLocateTlv - Error: NDEF not supported by the tag");
2257    return (NFC_STATUS_REFUSED);
2258  }
2259
2260  if ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) ||
2261      (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
2262    p_t1t->num_mem_tlvs = 0;
2263  }
2264
2265  if ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) ||
2266      (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
2267    p_t1t->num_lockbytes = 0;
2268    p_t1t->num_lock_tlvs = 0;
2269  }
2270
2271  /* Start reading memory, looking for the TLV */
2272  p_t1t->segment = 0;
2273  if ((p_t1t->hr[0] & 0x0F) != 1) {
2274    /* send RSEG command */
2275    RW_T1T_BLD_ADDS((adds), (p_t1t->segment));
2276    status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
2277  } else {
2278    status = rw_t1t_send_static_cmd(T1T_CMD_RALL, 0, 0);
2279  }
2280  if (status == NFC_STATUS_OK) {
2281    p_t1t->tlv_detect = tlv_type;
2282    p_t1t->work_offset = 0;
2283    p_t1t->state = RW_T1T_STATE_TLV_DETECT;
2284    p_t1t->substate = RW_T1T_SUBSTATE_NONE;
2285  }
2286
2287  return status;
2288}
2289
2290/*****************************************************************************
2291**
2292** Function         RW_T1tDetectNDef
2293**
2294** Description
2295**      This function is used to perform NDEF detection on a Type 1 tag, and
2296**      retrieve the tag's NDEF attribute information (block 0).
2297**
2298**      Before using this API, the application must call RW_SelectTagType to
2299**      indicate that a Type 1 tag has been activated.
2300**
2301** Returns
2302**      NFC_STATUS_OK: ndef detection procedure started
2303**      NFC_STATUS_WRONG_PROTOCOL: type 1 tag not activated
2304**      NFC_STATUS_BUSY: another command is already in progress
2305**      NFC_STATUS_FAILED: other error
2306**
2307*****************************************************************************/
2308tNFC_STATUS RW_T1tDetectNDef(void) { return RW_T1tLocateTlv(TAG_NDEF_TLV); }
2309
2310/*******************************************************************************
2311**
2312** Function         RW_T1tReadNDef
2313**
2314** Description      This function can be called to read the NDEF message on the
2315**                  tag.
2316**
2317** Parameters:      p_buffer:   The buffer into which to read the NDEF message
2318**                  buf_len:    The length of the buffer
2319**
2320** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
2321**
2322*******************************************************************************/
2323tNFC_STATUS RW_T1tReadNDef(uint8_t* p_buffer, uint16_t buf_len) {
2324  tNFC_STATUS status = NFC_STATUS_FAILED;
2325  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
2326  bool b_notify;
2327  uint8_t adds;
2328  const tT1T_CMD_RSP_INFO* p_cmd_rsp_info_rall =
2329      t1t_cmd_to_rsp_info(T1T_CMD_RALL);
2330  const tT1T_CMD_RSP_INFO* p_cmd_rsp_info_rseg =
2331      t1t_cmd_to_rsp_info(T1T_CMD_RSEG);
2332
2333  if (p_t1t->state != RW_T1T_STATE_IDLE) {
2334    LOG(WARNING) << StringPrintf("RW_T1tReadNDef - Busy - State: %u",
2335                                 p_t1t->state);
2336    return (NFC_STATUS_FAILED);
2337  }
2338
2339  /* Check HR0 if NDEF supported by the tag */
2340  if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED) {
2341    LOG(ERROR) << StringPrintf(
2342        "RW_T1tReadNDef - Error: NDEF not supported by the tag");
2343    return (NFC_STATUS_REFUSED);
2344  }
2345
2346  if (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF) {
2347    LOG(WARNING) << StringPrintf(
2348        "RW_T1tReadNDef - NDEF Message length is zero, NDEF Length : %u ",
2349        p_t1t->ndef_msg_len);
2350    return (NFC_STATUS_NOT_INITIALIZED);
2351  }
2352
2353  if ((p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE) &&
2354      (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_ONLY)) {
2355    LOG(ERROR) << StringPrintf(
2356        "RW_T1tReadNDef - Error: NDEF detection not performed yet/ Tag is in "
2357        "Initialized state");
2358    return (NFC_STATUS_FAILED);
2359  }
2360
2361  if (buf_len < p_t1t->ndef_msg_len) {
2362    LOG(WARNING) << StringPrintf(
2363        "RW_T1tReadNDef - buffer size: %u  less than NDEF msg sise: %u",
2364        buf_len, p_t1t->ndef_msg_len);
2365    return (NFC_STATUS_FAILED);
2366  }
2367  p_t1t->p_ndef_buffer = p_buffer;
2368
2369  if (p_t1t->b_rseg == true) {
2370    /* If already got response to RSEG 0 */
2371    p_t1t->state = RW_T1T_STATE_READ_NDEF;
2372    p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO*)p_cmd_rsp_info_rseg;
2373
2374    rw_t1t_handle_read_rsp(&b_notify, p_t1t->mem);
2375    status = NFC_STATUS_OK;
2376  } else if (p_t1t->b_update == true) {
2377    /* If already got response to RALL */
2378    p_t1t->state = RW_T1T_STATE_READ_NDEF;
2379    p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO*)p_cmd_rsp_info_rall;
2380
2381    rw_t1t_handle_read_rsp(&b_notify, p_t1t->mem);
2382    status = NFC_STATUS_OK;
2383
2384  } else {
2385    p_t1t->segment = 0;
2386    p_t1t->work_offset = 0;
2387    if ((p_t1t->hr[0] & 0x0F) != 1) {
2388      /* send RSEG command */
2389      RW_T1T_BLD_ADDS((adds), (p_t1t->segment));
2390      status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
2391    } else {
2392      status = rw_t1t_send_static_cmd(T1T_CMD_RALL, 0, 0);
2393    }
2394    if (status == NFC_STATUS_OK) p_t1t->state = RW_T1T_STATE_READ_NDEF;
2395  }
2396
2397  return status;
2398}
2399
2400/*******************************************************************************
2401**
2402** Function         RW_T1tWriteNDef
2403**
2404** Description      This function can be called to write an NDEF message to the
2405**                  tag.
2406**
2407** Parameters:      msg_len:    The length of the buffer
2408**                  p_msg:      The NDEF message to write
2409**
2410** Returns          NCI_STATUS_OK, if write was started. Otherwise, error
2411**                  status.
2412**
2413*******************************************************************************/
2414tNFC_STATUS RW_T1tWriteNDef(uint16_t msg_len, uint8_t* p_msg) {
2415  tNFC_STATUS status = NFC_STATUS_FAILED;
2416  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
2417  uint16_t num_ndef_bytes;
2418  uint16_t offset;
2419  uint8_t addr;
2420  uint8_t init_lengthfield_len;
2421  uint8_t new_lengthfield_len;
2422  uint16_t init_ndef_msg_offset;
2423
2424  if (p_t1t->state != RW_T1T_STATE_IDLE) {
2425    LOG(WARNING) << StringPrintf("RW_T1tWriteNDef - Busy - State: %u",
2426                                 p_t1t->state);
2427    return (NFC_STATUS_FAILED);
2428  }
2429
2430  /* Check HR0 if NDEF supported by the tag */
2431  if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED) {
2432    LOG(ERROR) << StringPrintf(
2433        "RW_T1tWriteNDef - Error: NDEF not supported by the tag");
2434    return (NFC_STATUS_REFUSED);
2435  }
2436
2437  if ((p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE) &&
2438      (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_INITIALIZED_NDEF)) {
2439    LOG(ERROR) << StringPrintf("RW_T1tWriteNDef - Tag cannot update NDEF");
2440    return (NFC_STATUS_REFUSED);
2441  }
2442
2443  if (msg_len > p_t1t->max_ndef_msg_len) {
2444    LOG(ERROR) << StringPrintf(
2445        "RW_T1tWriteNDef - Cannot write NDEF of size greater than %u bytes",
2446        p_t1t->max_ndef_msg_len);
2447    return (NFC_STATUS_REFUSED);
2448  }
2449
2450  p_t1t->p_ndef_buffer = p_msg;
2451  p_t1t->new_ndef_msg_len = msg_len;
2452  new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3 : 1;
2453  init_lengthfield_len =
2454      (uint8_t)(p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset);
2455  init_ndef_msg_offset = p_t1t->ndef_msg_offset;
2456
2457  /* ndef_msg_offset should reflect the new ndef message offset */
2458  if (init_lengthfield_len > new_lengthfield_len) {
2459    p_t1t->ndef_msg_offset =
2460        init_ndef_msg_offset -
2461        (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
2462  } else if (init_lengthfield_len < new_lengthfield_len) {
2463    p_t1t->ndef_msg_offset =
2464        init_ndef_msg_offset +
2465        (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
2466  }
2467
2468  num_ndef_bytes = 0;
2469  offset = p_t1t->ndef_msg_offset;
2470  p_t1t->segment = (uint8_t)(p_t1t->ndef_msg_offset / T1T_SEGMENT_SIZE);
2471
2472  /* Locate NDEF final block based on the size of new NDEF Message */
2473  while (num_ndef_bytes < p_t1t->new_ndef_msg_len) {
2474    if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)offset) == false)
2475      num_ndef_bytes++;
2476
2477    offset++;
2478    if (offset % T1T_SEGMENT_SIZE == 0) {
2479      p_t1t->segment = (uint8_t)(offset / T1T_SEGMENT_SIZE);
2480    }
2481  }
2482
2483  p_t1t->b_update = false;
2484  p_t1t->b_rseg = false;
2485
2486  if ((p_t1t->hr[0] & 0x0F) != 1) {
2487    /* Dynamic data structure */
2488    p_t1t->block_read = (uint8_t)((offset - 1) / T1T_BLOCK_SIZE);
2489    /* Read NDEF final block before updating */
2490    status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8, p_t1t->block_read, NULL);
2491    if (status == NFC_STATUS_OK) {
2492      p_t1t->num_ndef_finalblock = p_t1t->block_read;
2493      p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
2494      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK;
2495    }
2496  } else {
2497    /* NDEF detected and Static memory structure so send WRITE-E command */
2498    RW_T1T_BLD_ADD((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
2499    status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, 0);
2500    if (status == NFC_STATUS_OK) {
2501      p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
2502      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
2503    }
2504  }
2505
2506  if (status != NFC_STATUS_OK) {
2507    /* if status failed, reset ndef_msg_offset to initial message */
2508    p_t1t->ndef_msg_offset = init_ndef_msg_offset;
2509  }
2510  return status;
2511}
2512
2513/*******************************************************************************
2514**
2515** Function         RW_T1tSetTagReadOnly
2516**
2517** Description      This function can be called to set t1 tag as read only.
2518**
2519** Parameters:      None
2520**
2521** Returns          NCI_STATUS_OK, if setting tag as read only was started.
2522**                  Otherwise, error status.
2523**
2524*******************************************************************************/
2525tNFC_STATUS RW_T1tSetTagReadOnly(bool b_hard_lock) {
2526  tNFC_STATUS status = NFC_STATUS_FAILED;
2527  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
2528  uint8_t addr;
2529  uint8_t num_locks;
2530
2531  if (p_t1t->state != RW_T1T_STATE_IDLE) {
2532    LOG(WARNING) << StringPrintf("RW_T1tSetTagReadOnly - Busy - State: %u",
2533                                 p_t1t->state);
2534    return (NFC_STATUS_BUSY);
2535  }
2536
2537  p_t1t->b_hard_lock = b_hard_lock;
2538
2539  if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_WRITE) ||
2540      (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED) ||
2541      (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF)) {
2542    /* send WRITE-NE command */
2543    RW_T1T_BLD_ADD((addr), (T1T_CC_BLOCK), (T1T_CC_RWA_OFFSET));
2544    status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, 0x0F);
2545    if (status == NFC_STATUS_OK) {
2546      p_t1t->b_update = false;
2547      p_t1t->b_rseg = false;
2548
2549      if (p_t1t->b_hard_lock) {
2550        num_locks = 0;
2551        while (num_locks < p_t1t->num_lockbytes) {
2552          p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_NOT_UPDATED;
2553          num_locks++;
2554        }
2555      }
2556      p_t1t->state = RW_T1T_STATE_SET_TAG_RO;
2557      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO;
2558    }
2559  }
2560
2561  return status;
2562}
2563
2564#endif /* (RW_NDEF_INCLUDED == TRUE) */
2565