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