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