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