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