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