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