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