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