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