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