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