rw_t2t_ndef.c revision c11a054fc2855196292b062a843321121b591cc0
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 2 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 static functions */ 39static void rw_t2t_handle_cc_read_rsp (void); 40static void rw_t2t_handle_lock_read_rsp (UINT8 *p_data); 41static void rw_t2t_handle_tlv_detect_rsp (UINT8 *p_data); 42static void rw_t2t_handle_ndef_read_rsp (UINT8 *p_data); 43static void rw_t2t_handle_ndef_write_rsp (UINT8 *p_data); 44static void rw_t2t_handle_format_tag_rsp (UINT8 *p_data); 45static void rw_t2t_handle_config_tag_readonly (UINT8 *p_data); 46static UINT8 rw_t2t_get_tag_size (UINT8 *p_data); 47static void rw_t2t_extract_default_locks_info (void); 48static void rw_t2t_update_cb (UINT16 block, UINT8 *p_write_block, BOOLEAN b_update_len); 49static UINT8 rw_t2t_get_ndef_flags (void); 50static UINT16 rw_t2t_get_ndef_max_size (void); 51static tNFC_STATUS rw_t2t_read_locks (void); 52static tNFC_STATUS rw_t2t_read_ndef_last_block (void); 53static void rw_t2t_update_attributes (void); 54static void rw_t2t_update_lock_attributes (void); 55static BOOLEAN rw_t2t_is_lock_res_byte (UINT16 index); 56static BOOLEAN rw_t2t_is_read_only_byte (UINT16 index); 57static tNFC_STATUS rw_t2t_write_ndef_first_block (UINT16 msg_len, BOOLEAN b_update_len); 58static tNFC_STATUS rw_t2t_write_ndef_next_block (UINT16 block, UINT16 msg_len, BOOLEAN b_update_len); 59static tNFC_STATUS rw_t2t_read_ndef_next_block (UINT16 block); 60static tNFC_STATUS rw_t2t_add_terminator_tlv (void); 61static BOOLEAN rw_t2t_is_read_before_write_block (UINT16 block, UINT16 *p_block_to_read); 62static tNFC_STATUS rw_t2t_set_cc (UINT8 tms); 63static tNFC_STATUS rw_t2t_set_lock_tlv (UINT16 addr, UINT8 num_dyn_lock_bits, UINT16 locked_area_size); 64static tNFC_STATUS rw_t2t_format_tag (void); 65static tNFC_STATUS rw_t2t_soft_lock_tag (void); 66static tNFC_STATUS rw_t2t_set_dynamic_lock_bits (UINT8 *p_data); 67static void rw_t2t_ntf_tlv_detect_complete (tNFC_STATUS status); 68 69const UINT8 rw_t2t_mask_bits[8] = 70{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 71 72/******************************************************************************* 73** 74** Function rw_t2t_handle_rsp 75** 76** Description This function handles response to command sent during 77** NDEF and other tlv operation 78** 79** Returns None 80** 81*******************************************************************************/ 82void rw_t2t_handle_rsp (UINT8 *p_data) 83{ 84 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 85 86 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) 87 { 88 p_t2t->b_read_hdr = TRUE; 89 memcpy (p_t2t->tag_hdr, p_data, T2T_READ_DATA_LEN); 90 91 /* On Ultralight - C tag, if CC is corrupt, correct it */ 92 if ( (p_t2t->tag_hdr[0] == TAG_MIFARE_MID) 93 &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] >= T2T_INVALID_CC_TMS_VAL0) 94 &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] <= T2T_INVALID_CC_TMS_VAL1) ) 95 { 96 p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] = T2T_CC2_TMS_MULC; 97 } 98 } 99 100 switch (p_t2t->state) 101 { 102 case RW_T2T_STATE_DETECT_TLV: 103 if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV) 104 { 105 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) 106 { 107 rw_t2t_handle_cc_read_rsp (); 108 } 109 else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) 110 { 111 rw_t2t_handle_lock_read_rsp (p_data); 112 } 113 else 114 { 115 rw_t2t_handle_tlv_detect_rsp (p_data); 116 } 117 } 118 else if (p_t2t->tlv_detect == TAG_NDEF_TLV) 119 { 120 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) 121 { 122 if (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] == T2T_CC0_NMN) 123 { 124 rw_t2t_handle_cc_read_rsp (); 125 } 126 else 127 { 128 RW_TRACE_WARNING3 ("NDEF Detection failed!, CC[0]: 0x%02x, CC[1]: 0x%02x, CC[3]: 0x%02x", p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE], p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]); 129 rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED); 130 } 131 } 132 else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) 133 { 134 rw_t2t_handle_lock_read_rsp (p_data); 135 } 136 else 137 { 138 rw_t2t_handle_tlv_detect_rsp (p_data); 139 } 140 } 141 else 142 { 143 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) 144 { 145 rw_t2t_handle_cc_read_rsp (); 146 } 147 else 148 { 149 rw_t2t_handle_tlv_detect_rsp (p_data); 150 } 151 } 152 break; 153 154 case RW_T2T_STATE_SET_TAG_RO: 155 rw_t2t_handle_config_tag_readonly (p_data); 156 break; 157 158 case RW_T2T_STATE_FORMAT_TAG: 159 rw_t2t_handle_format_tag_rsp (p_data); 160 break; 161 162 case RW_T2T_STATE_READ_NDEF: 163 rw_t2t_handle_ndef_read_rsp (p_data); 164 break; 165 166 case RW_T2T_STATE_WRITE_NDEF: 167 rw_t2t_handle_ndef_write_rsp (p_data); 168 break; 169 } 170} 171 172/******************************************************************************* 173** 174** Function rw_t2t_info_to_event 175** 176** Description This function returns RW event code based on the current state 177** 178** Returns RW event code 179** 180*******************************************************************************/ 181tRW_EVENT rw_t2t_info_to_event (const tT2T_CMD_RSP_INFO *p_info) 182{ 183 tRW_EVENT rw_event; 184 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 185 186 switch (p_t2t->state) 187 { 188 case RW_T2T_STATE_DETECT_TLV: 189 if (p_t2t->tlv_detect == TAG_NDEF_TLV) 190 rw_event = RW_T2T_NDEF_DETECT_EVT; 191 else 192 rw_event = RW_T2T_TLV_DETECT_EVT; 193 194 break; 195 196 case RW_T2T_STATE_READ_NDEF: 197 rw_event = RW_T2T_NDEF_READ_EVT; 198 break; 199 200 case RW_T2T_STATE_WRITE_NDEF: 201 rw_event = RW_T2T_NDEF_WRITE_EVT; 202 break; 203 204 case RW_T2T_STATE_SET_TAG_RO: 205 rw_event = RW_T2T_SET_TAG_RO_EVT; 206 break; 207 208 case RW_T2T_STATE_CHECK_PRESENCE: 209 rw_event = RW_T2T_PRESENCE_CHECK_EVT; 210 break; 211 212 case RW_T2T_STATE_FORMAT_TAG: 213 rw_event = RW_T2T_FORMAT_CPLT_EVT; 214 break; 215 216 default: 217 rw_event = t2t_info_to_evt (p_info); 218 break; 219 } 220 return rw_event; 221} 222 223/******************************************************************************* 224** 225** Function rw_t2t_handle_cc_read_rsp 226** 227** Description Handle read cc bytes 228** 229** Returns none 230** 231*******************************************************************************/ 232static void rw_t2t_handle_cc_read_rsp (void) 233{ 234 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 235 236 if ( ( (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) 237 &&(p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RO) ) 238 || 239 ( (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) 240 &&(p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) 241 &&(p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO) ) ) 242 { 243 /* Invalid Version number or RWA byte */ 244 rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED); 245 return; 246 } 247 248 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT; 249 250 if (rw_t2t_read ((UINT16) T2T_FIRST_DATA_BLOCK) != NFC_STATUS_OK) 251 { 252 rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED); 253 } 254} 255 256/******************************************************************************* 257** 258** Function rw_t2t_ntf_tlv_detect_complete 259** 260** Description Notify TLV detection complete to upper layer 261** 262** Returns none 263** 264*******************************************************************************/ 265static void rw_t2t_ntf_tlv_detect_complete (tNFC_STATUS status) 266{ 267 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 268 tRW_DETECT_NDEF_DATA ndef_data = {0}; 269 tRW_DETECT_TLV_DATA tlv_data; 270 tRW_T2T_DETECT evt_data; 271 UINT8 xx; 272 273 if (p_t2t->tlv_detect == TAG_NDEF_TLV) 274 { 275 /* Notify upper layer the result of NDEF detect op */ 276 ndef_data.status = status; 277 ndef_data.protocol = NFC_PROTOCOL_T2T; 278 ndef_data.flags = rw_t2t_get_ndef_flags (); 279 ndef_data.cur_size = p_t2t->ndef_msg_len; 280 281 if (status == NFC_STATUS_OK) 282 ndef_data.flags |= RW_NDEF_FL_FORMATED; 283 284 if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] == T2T_CC3_RWA_RW) 285 ndef_data.max_size = (UINT32) rw_t2t_get_ndef_max_size (); 286 else 287 ndef_data.max_size = ndef_data.cur_size; 288 289 if (ndef_data.max_size < ndef_data.cur_size) 290 { 291 ndef_data.flags |= RW_NDEF_FL_READ_ONLY; 292 ndef_data.max_size = ndef_data.cur_size; 293 } 294 295 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) 296 { 297 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE; 298 if (status == NFC_STATUS_OK) 299 ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE; 300 } 301 302 rw_t2t_handle_op_complete (); 303 (*rw_cb.p_cback) (RW_T2T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data); 304 } 305 else if (p_t2t->tlv_detect == TAG_PROPRIETARY_TLV) 306 { 307 evt_data.msg_len = p_t2t->prop_msg_len; 308 evt_data.status = status; 309 rw_t2t_handle_op_complete (); 310 (*rw_cb.p_cback) (RW_T2T_TLV_DETECT_EVT, (tRW_DATA *) &evt_data); 311 } 312 else 313 { 314 /* Notify upper layer the result of Lock/Mem TLV detect op */ 315 tlv_data.protocol = NFC_PROTOCOL_T2T; 316 if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV) 317 { 318 tlv_data.num_bytes = p_t2t->num_lockbytes; 319 } 320 else 321 { 322 tlv_data.num_bytes = 0; 323 for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++) 324 { 325 tlv_data.num_bytes += p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes; 326 } 327 } 328 tlv_data.status = status; 329 rw_t2t_handle_op_complete (); 330 (*rw_cb.p_cback) (RW_T2T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data); 331 } 332 333} 334 335/******************************************************************************* 336** 337** Function rw_t2t_handle_lock_read_rsp 338** 339** Description Handle response to reading lock bytes 340** 341** Returns none 342** 343*******************************************************************************/ 344static void rw_t2t_handle_lock_read_rsp (UINT8 *p_data) 345{ 346 UINT8 updated_lock_byte; 347 UINT8 num_locks; 348 UINT8 offset = 0; 349 UINT16 lock_offset; 350 UINT16 base_lock_offset = 0; 351 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 352 UINT16 block; 353 354 /* Prepare NDEF/TLV attributes (based on current op) for sending response to upper layer */ 355 356 num_locks = 0; 357 updated_lock_byte = 0; 358 359 /* Extract all lock bytes present in the read 16 bytes 360 * but atleast one lock byte (base lock) should be present in the read 16 bytes */ 361 362 while (num_locks < p_t2t->num_lockbytes) 363 { 364 if (p_t2t->lockbyte[num_locks].b_lock_read == FALSE) 365 { 366 lock_offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index; 367 if (updated_lock_byte == 0) 368 { 369 /* The offset of the first lock byte present in the 16 bytes read using READ command */ 370 base_lock_offset = lock_offset; 371 /* Block number used to read may not be the block where lock offset is present */ 372 offset = (UINT8) (lock_offset - (p_t2t->block_read * T2T_BLOCK_SIZE)); 373 /* Update the lock byte value in the control block */ 374 p_t2t->lockbyte[num_locks].lock_byte = p_data[offset]; 375 p_t2t->lockbyte[num_locks].b_lock_read = TRUE; 376 updated_lock_byte++; 377 } 378 else if (lock_offset > base_lock_offset) 379 { 380 /* Atleast one lock byte will get updated in the control block */ 381 if ((lock_offset - base_lock_offset + offset) < T2T_READ_DATA_LEN) 382 { 383 /* And this lock byte is also present in the read data */ 384 p_t2t->lockbyte[num_locks].lock_byte = p_data[lock_offset - base_lock_offset + offset]; 385 p_t2t->lockbyte[num_locks].b_lock_read = TRUE; 386 updated_lock_byte++; 387 } 388 else 389 { 390 /* This lock byte is not present in the read data */ 391 block = (UINT16) (lock_offset / T2T_BLOCK_LEN); 392 block -= block % T2T_READ_BLOCKS; 393 /* send READ command to read this lock byte */ 394 if (NFC_STATUS_OK != rw_t2t_read ((UINT16) block)) 395 { 396 /* Unable to send Read command, notify failure status to upper layer */ 397 rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED); 398 } 399 break; 400 } 401 } 402 else 403 { 404 /* This Lock byte is not present in the read 16 bytes 405 * send READ command to read the lock byte */ 406 if (NFC_STATUS_OK != rw_t2t_read ((UINT16) (lock_offset / T2T_BLOCK_LEN))) 407 { 408 /* Unable to send Read command, notify failure status to upper layer */ 409 rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED); 410 } 411 break; 412 } 413 } 414 num_locks++; 415 } 416 if (num_locks == p_t2t->num_lockbytes) 417 { 418 /* All locks are read, notify upper layer */ 419 rw_t2t_update_lock_attributes (); 420 rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_OK); 421 } 422} 423 424/******************************************************************************* 425** 426** Function rw_t2t_handle_tlv_detect_rsp 427** 428** Description Handle TLV detection. 429** 430** Returns none 431** 432*******************************************************************************/ 433static void rw_t2t_handle_tlv_detect_rsp (UINT8 *p_data) 434{ 435 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 436 UINT16 offset; 437 UINT16 len = 0; 438 BOOLEAN failed = FALSE; 439 BOOLEAN found = FALSE; 440 tRW_EVENT event; 441 UINT8 index; 442 UINT8 count = 0; 443 UINT8 xx; 444 tNFC_STATUS status; 445 tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info; 446 UINT8 tlvtype = p_t2t->tlv_detect; 447 448 if (p_t2t->work_offset == 0) 449 { 450 /* Skip UID,Static Lock block,CC*/ 451 p_t2t->work_offset = T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN; 452 p_t2t->b_read_data = TRUE; 453 memcpy (p_t2t->tag_data, p_data, T2T_READ_DATA_LEN); 454 } 455 456 p_t2t->segment = 0; 457 458 for (offset = 0; offset < T2T_READ_DATA_LEN && !failed && !found;) 459 { 460 if (rw_t2t_is_lock_res_byte ((UINT16) (p_t2t->work_offset + offset)) == TRUE) 461 { 462 /* Skip locks, reserved bytes while searching for TLV */ 463 offset++; 464 continue; 465 } 466 switch (p_t2t->substate) 467 { 468 case RW_T2T_SUBSTATE_WAIT_TLV_DETECT: 469 /* Search for the tlv */ 470 p_t2t->found_tlv = p_data[offset++]; 471 switch (p_t2t->found_tlv) 472 { 473 case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */ 474 break; 475 476 case TAG_NDEF_TLV: 477 if (tlvtype == TAG_NDEF_TLV) 478 { 479 /* NDEF Detected, now collect NDEF Attributes including NDEF Length */ 480 index = (offset % T2T_BLOCK_SIZE); 481 /* Backup ndef first block */ 482 memcpy (p_t2t->ndef_first_block,&p_data[offset-index],index); 483 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN; 484 } 485 else if (tlvtype == TAG_PROPRIETARY_TLV) 486 { 487 /* Proprietary TLV can exist after NDEF Tlv so we continue searching */ 488 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN; 489 } 490 else if ( ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0)) 491 ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0)) ) 492 { 493 /* Lock / Memory control tlv cannot exist after NDEF TLV 494 * So when NDEF is found, we stop searching for Lock and Memory control tlv */ 495 found = TRUE; 496 } 497 else 498 { 499 /* While searching for Lock / Memory control tlv, if NDEF TLV is found 500 * first then our search for Lock /Memory control tlv failed and we stop here */ 501 failed = TRUE; 502 } 503 break; 504 505 case TAG_LOCK_CTRL_TLV: 506 case TAG_MEM_CTRL_TLV: 507 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0; 508 break; 509 510 case TAG_PROPRIETARY_TLV: 511 if (tlvtype == TAG_PROPRIETARY_TLV) 512 { 513 index = (offset % T2T_BLOCK_SIZE); 514 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN; 515 } 516 else 517 { 518 /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we continue searching, skiping proprietary tlv */ 519 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN; 520 } 521 break; 522 523 case TAG_TERMINATOR_TLV: /* Last TLV block in the data area. Must be no NDEF nessage */ 524 if ( ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0)) 525 ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0)) ) 526 { 527 /* No more Lock/Memory TLV control tlv in the tag, so stop searching */ 528 found = TRUE; 529 } 530 else 531 { 532 /* NDEF/Lock/Memory/Proprietary TLV cannot exist after Terminator Tlv */ 533 failed = TRUE; 534 } 535 break; 536 default: 537 failed = TRUE; 538 } 539 break; 540 541 case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN: 542 len = p_data[offset]; 543 switch (p_t2t->found_tlv) 544 { 545 case TAG_NDEF_TLV: 546 p_t2t->ndef_header_offset = offset + p_t2t->work_offset; 547 if (len == TAG_LONG_NDEF_LEN_FIELD_BYTE0) 548 { 549 /* The next two bytes constitute length bytes */ 550 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0; 551 } 552 else 553 { 554 /* one byte length field */ 555 p_t2t->ndef_msg_len = len; 556 p_t2t->bytes_count = p_t2t->ndef_msg_len; 557 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE; 558 } 559 break; 560 561 case TAG_PROPRIETARY_TLV: 562 if (len == T2T_LONG_NDEF_LEN_FIELD_BYTE0) 563 { 564 /* The next two bytes constitute length bytes */ 565 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0; 566 } 567 else 568 { 569 /* one byte length field */ 570 p_t2t->prop_msg_len = len; 571 p_t2t->bytes_count = p_t2t->prop_msg_len; 572 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE; 573 } 574 break; 575 } 576 offset++; 577 break; 578 579 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0: 580 switch (p_t2t->found_tlv) 581 { 582 case TAG_LOCK_CTRL_TLV: 583 case TAG_MEM_CTRL_TLV: 584 585 len = p_data[offset]; 586 if (len == TAG_DEFAULT_TLV_LEN) 587 { 588 /* Valid Lock control TLV */ 589 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE; 590 p_t2t->bytes_count = TAG_DEFAULT_TLV_LEN; 591 } 592 else if ( ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0)) 593 ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0)) ) 594 { 595 /* Stop searching for Lock/ Memory control tlv */ 596 found = TRUE; 597 } 598 else 599 { 600 failed = TRUE; 601 } 602 break; 603 604 case TAG_NDEF_TLV: 605 case TAG_PROPRIETARY_TLV: 606 /* The first length byte */ 607 p_t2t->bytes_count = (UINT8) p_data[offset]; 608 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1; 609 break; 610 } 611 offset++; 612 break; 613 614 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1: 615 /* Prepare NDEF Message length */ 616 p_t2t->bytes_count = (p_t2t->bytes_count << 8) + p_data[offset]; 617 if (p_t2t->found_tlv == TAG_NDEF_TLV) 618 { 619 p_t2t->ndef_msg_len = p_t2t->bytes_count; 620 } 621 else if (p_t2t->found_tlv == TAG_PROPRIETARY_TLV) 622 { 623 p_t2t->prop_msg_len = p_t2t->bytes_count; 624 } 625 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE; 626 offset++; 627 break; 628 629 case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE: 630 switch (p_t2t->found_tlv) 631 { 632 case TAG_NDEF_TLV: 633 if ( (p_t2t->bytes_count == p_t2t->ndef_msg_len) 634 &&(tlvtype == TAG_NDEF_TLV) ) 635 { 636 /* The first byte offset after length field */ 637 p_t2t->ndef_msg_offset = offset + p_t2t->work_offset; 638 } 639 /* Reduce number of NDEF bytes remaining to pass over NDEF TLV */ 640 if (p_t2t->bytes_count > 0) 641 p_t2t->bytes_count--; 642 643 if (tlvtype == TAG_NDEF_TLV) 644 { 645 found = TRUE; 646 p_t2t->ndef_status = T2T_NDEF_DETECTED; 647 } 648 else if (p_t2t->bytes_count == 0) 649 { 650 /* Next byte could be a different TLV */ 651 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT; 652 } 653 break; 654 655 case TAG_LOCK_CTRL_TLV: 656 p_t2t->bytes_count--; 657 if ( (tlvtype == TAG_LOCK_CTRL_TLV) 658 ||(tlvtype == TAG_NDEF_TLV) ) 659 { 660 /* Collect Lock TLV */ 661 p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset]; 662 if (p_t2t->bytes_count == 0) 663 { 664 /* Lock TLV is collected and buffered in tlv_value, now decode it */ 665 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset = (p_t2t->tlv_value[0] >> 4) & 0x0F; 666 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset *= (UINT8) tags_pow (2, p_t2t->tlv_value[2] & 0x0F); 667 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset += p_t2t->tlv_value[0] & 0x0F; 668 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit = (UINT8) tags_pow (2, ((p_t2t->tlv_value[2] & 0xF0) >> 4)); 669 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = p_t2t->tlv_value[1]; 670 count = p_t2t->tlv_value[1] / 8 + ((p_t2t->tlv_value[1]%8 != 0)? 1:0); 671 672 /* Extract lockbytes info addressed by this Lock TLV */ 673 xx = 0; 674 while (xx < count) 675 { 676 p_t2t->lockbyte[p_t2t->num_lockbytes].tlv_index = p_t2t->num_lock_tlvs; 677 p_t2t->lockbyte[p_t2t->num_lockbytes].byte_index = xx; 678 p_t2t->lockbyte[p_t2t->num_lockbytes].b_lock_read = FALSE; 679 xx++; 680 p_t2t->num_lockbytes++; 681 } 682 p_t2t->num_lock_tlvs++; 683 rw_t2t_update_attributes (); 684 /* Next byte could be a different TLV */ 685 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT; 686 } 687 } 688 else 689 { 690 /* If not looking for lock/ndef tlv, just skip this Lock TLV */ 691 if (p_t2t->bytes_count == 0) 692 { 693 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT; 694 } 695 } 696 break; 697 698 case TAG_MEM_CTRL_TLV: 699 p_t2t->bytes_count--; 700 if ( (tlvtype == TAG_MEM_CTRL_TLV) 701 ||(tlvtype == TAG_NDEF_TLV) ) 702 { 703 p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset]; 704 if (p_t2t->bytes_count == 0) 705 { 706 if (p_t2t->num_mem_tlvs >= RW_T2T_MAX_MEM_TLVS) 707 { 708 RW_TRACE_ERROR0 ("rw_t2t_handle_tlv_detect_rsp - Maximum buffer allocated for Memory tlv has reached"); 709 failed = TRUE; 710 } 711 else 712 { 713 /* Extract memory control tlv */ 714 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset = (p_t2t->tlv_value[0] >> 4) & 0x0F; 715 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset *= (UINT8) tags_pow (2, p_t2t->tlv_value[2] & 0x0F); 716 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset += p_t2t->tlv_value[0] & 0x0F; 717 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes = p_t2t->tlv_value[1]; 718 p_t2t->num_mem_tlvs++; 719 rw_t2t_update_attributes (); 720 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT; 721 } 722 } 723 } 724 else 725 { 726 if (p_t2t->bytes_count == 0) 727 { 728 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT; 729 } 730 } 731 break; 732 733 case TAG_PROPRIETARY_TLV: 734 p_t2t->bytes_count--; 735 if (tlvtype == TAG_PROPRIETARY_TLV) 736 { 737 found = TRUE; 738 p_t2t->prop_msg_len = len; 739 } 740 else 741 { 742 if (p_t2t->bytes_count == 0) 743 { 744 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT; 745 } 746 } 747 break; 748 } 749 offset++; 750 break; 751 } 752 } 753 754 755 p_t2t->work_offset += T2T_READ_DATA_LEN; 756 757 event = rw_t2t_info_to_event (p_cmd_rsp_info); 758 759 /* If not found and not failed, read next block and search tlv */ 760 if (!found && !failed) 761 { 762 763 if (p_t2t->work_offset >= (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR)) 764 { 765 if ( ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0)) 766 ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0)) ) 767 { 768 found = TRUE; 769 } 770 else 771 { 772 failed = TRUE; 773 } 774 } 775 else 776 { 777 if (rw_t2t_read ((UINT16) ((p_t2t->work_offset / T2T_BLOCK_LEN) + T2T_FIRST_DATA_BLOCK)) != NFC_STATUS_OK) 778 failed = TRUE; 779 } 780 } 781 782 if (failed || found) 783 { 784 if (tlvtype == TAG_LOCK_CTRL_TLV) 785 { 786 /* Incase no Lock control tlv is present then look for default dynamic lock bytes */ 787 rw_t2t_extract_default_locks_info (); 788 789 /* Send command to read the dynamic lock bytes */ 790 status = rw_t2t_read_locks (); 791 792 if (status != NFC_STATUS_CONTINUE) 793 { 794 /* If unable to read a lock/all locks read, notify upper layer */ 795 rw_t2t_update_lock_attributes (); 796 rw_t2t_ntf_tlv_detect_complete (status); 797 } 798 } 799 else if (tlvtype == TAG_NDEF_TLV) 800 { 801 rw_t2t_extract_default_locks_info (); 802 803 if (failed) 804 { 805 rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED); 806 } 807 else 808 { 809 /* NDEF present,Send command to read the dynamic lock bytes */ 810 status = rw_t2t_read_locks (); 811 if (status != NFC_STATUS_CONTINUE) 812 { 813 /* If unable to read a lock/all locks read, notify upper layer */ 814 rw_t2t_update_lock_attributes (); 815 rw_t2t_ntf_tlv_detect_complete (status); 816 } 817 } 818 } 819 else 820 { 821 /* Notify Memory/ Proprietary tlv detect result */ 822 status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK; 823 rw_t2t_ntf_tlv_detect_complete (status); 824 } 825 } 826} 827 828/******************************************************************************* 829** 830** Function rw_t2t_read_locks 831** 832** Description This function will send command to read next unread locks 833** 834** Returns NFC_STATUS_OK, if all locks are read successfully 835** NFC_STATUS_FAILED, if reading locks failed 836** NFC_STATUS_CONTINUE, if reading locks is in progress 837** 838*******************************************************************************/ 839tNFC_STATUS rw_t2t_read_locks (void) 840{ 841 UINT8 num_locks = 0; 842 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 843 tNFC_STATUS status = NFC_STATUS_CONTINUE; 844 UINT16 offset; 845 UINT16 block; 846 847 if ( (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) 848 ||((p_t2t->tag_hdr[0] == TAG_MIFARE_MID) && (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_MULC)) 849 ||((p_t2t->tag_hdr[0] == TAG_MIFARE_MID) && (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_MUL)) ) 850 851 { 852 /* Skip reading dynamic lock bytes if CC is set as Read only or on MUL/MUL-C tag */ 853 while (num_locks < p_t2t->num_lockbytes) 854 { 855 p_t2t->lockbyte[num_locks].lock_byte = 0x00; 856 p_t2t->lockbyte[num_locks].b_lock_read = TRUE; 857 num_locks++; 858 } 859 } 860 861 while (num_locks < p_t2t->num_lockbytes) 862 { 863 if (p_t2t->lockbyte[num_locks].b_lock_read == FALSE) 864 { 865 /* Send Read command to read the first un read locks */ 866 offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index; 867 868 /* Read 16 bytes where this lock byte is present */ 869 block = (UINT16) (offset / T2T_BLOCK_LEN); 870 block -= block % T2T_READ_BLOCKS; 871 872 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_LOCKS; 873 /* send READ8 command */ 874 if ((status = rw_t2t_read ((UINT16) block)) == NFC_STATUS_OK) 875 { 876 /* Reading Locks */ 877 status = NFC_STATUS_CONTINUE; 878 } 879 else 880 { 881 status = NFC_STATUS_FAILED; 882 } 883 break; 884 } 885 num_locks++; 886 } 887 if (num_locks == p_t2t->num_lockbytes) 888 { 889 /* All locks are read */ 890 status = NFC_STATUS_OK; 891 } 892 893 return status; 894} 895 896/******************************************************************************* 897** 898** Function rw_t2t_extract_default_locks_info 899** 900** Description This function will prepare lockbytes information for default 901** locks present in the tag in the absence of lock control tlv. 902** Adding a virtual lock control tlv for these lock bytes for 903** easier manipulation. 904** 905** Returns None 906** 907*******************************************************************************/ 908void rw_t2t_extract_default_locks_info (void) 909{ 910 UINT8 num_dynamic_lock_bits; 911 UINT8 num_dynamic_lock_bytes; 912 UINT8 xx; 913 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 914 const tT2T_INIT_TAG *p_ret; 915 UINT8 bytes_locked_per_lock_bit = T2T_DEFAULT_LOCK_BLPB; 916 917 918 if ( (p_t2t->num_lock_tlvs == 0) 919 &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] > T2T_CC2_TMS_STATIC) ) 920 { 921 /* No Lock control tlv is detected. Indicates lock bytes are present in default location */ 922 /* Add a virtual Lock tlv to map this default lock location */ 923 if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL) 924 bytes_locked_per_lock_bit = p_ret->default_lock_blpb; 925 926 num_dynamic_lock_bits = ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) - (T2T_STATIC_SIZE - T2T_HEADER_SIZE)) / bytes_locked_per_lock_bit; 927 num_dynamic_lock_bytes = num_dynamic_lock_bits / 8; 928 num_dynamic_lock_bytes += (num_dynamic_lock_bits % 8 == 0) ? 0:1; 929 930 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN); 931 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit = bytes_locked_per_lock_bit; 932 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = num_dynamic_lock_bits; 933 934 /* Based on tag data size the number of locks present in the default location changes */ 935 for (xx = 0; xx < num_dynamic_lock_bytes; xx++) 936 { 937 p_t2t->lockbyte[xx].tlv_index = p_t2t->num_lock_tlvs; 938 p_t2t->lockbyte[xx].byte_index = xx; 939 p_t2t->lockbyte[xx].b_lock_read = FALSE; 940 } 941 p_t2t->num_lockbytes = num_dynamic_lock_bytes; 942 p_t2t->num_lock_tlvs = 1; 943 } 944} 945 946/******************************************************************************* 947** 948** Function rw_t2t_read_ndef_last_block 949** 950** Description This function will locate and read the last ndef block. 951** The last ndef block refers to the tag block where last byte 952** of new ndef message will reside. Also this function will 953** locate the offset of Terminator TLV based on the size of 954** new NDEF Message 955** 956** Returns NCI_STATUS_OK,if able to locate last ndef block & read started 957** Otherwise, error status. 958** 959*******************************************************************************/ 960tNFC_STATUS rw_t2t_read_ndef_last_block (void) 961{ 962 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 963 UINT16 header_len = (p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN) ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN; 964 UINT16 num_ndef_bytes; 965 UINT16 total_ndef_bytes; 966 UINT16 last_ndef_byte_offset; 967 UINT16 terminator_tlv_byte_index; 968 tNFC_STATUS status; 969 UINT16 block; 970 971 972 total_ndef_bytes = header_len + p_t2t->new_ndef_msg_len; 973 num_ndef_bytes = 0; 974 last_ndef_byte_offset = p_t2t->ndef_header_offset; 975 976 /* Locate NDEF final block based on the size of new NDEF Message */ 977 while (num_ndef_bytes < total_ndef_bytes) 978 { 979 if (rw_t2t_is_lock_res_byte ((UINT16) (last_ndef_byte_offset)) == FALSE) 980 num_ndef_bytes++; 981 982 last_ndef_byte_offset++; 983 } 984 p_t2t->ndef_last_block_num = (UINT16) ((last_ndef_byte_offset - 1) / T2T_BLOCK_SIZE); 985 block = p_t2t->ndef_last_block_num; 986 987 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK; 988 /* Read NDEF last block before updating */ 989 if ((status = rw_t2t_read (block))== NFC_STATUS_OK) 990 { 991 if ((p_t2t->new_ndef_msg_len + 1) <= p_t2t->max_ndef_msg_len) 992 { 993 /* Locate Terminator TLV Block */ 994 total_ndef_bytes++; 995 terminator_tlv_byte_index = last_ndef_byte_offset; 996 997 while (num_ndef_bytes < total_ndef_bytes) 998 { 999 if (rw_t2t_is_lock_res_byte ((UINT16) terminator_tlv_byte_index) == FALSE) 1000 num_ndef_bytes++; 1001 1002 terminator_tlv_byte_index++; 1003 } 1004 1005 p_t2t->terminator_byte_index = terminator_tlv_byte_index - 1; 1006 } 1007 else 1008 { 1009 /* No space for Terminator TLV */ 1010 p_t2t->terminator_byte_index = 0x00; 1011 } 1012 } 1013 return status; 1014} 1015 1016/******************************************************************************* 1017** 1018** Function rw_t2t_read_terminator_tlv_block 1019** 1020** Description This function will read the block where terminator tlv will 1021** be added later 1022** 1023** Returns NCI_STATUS_OK, if read was started. Otherwise, error status. 1024** 1025*******************************************************************************/ 1026tNFC_STATUS rw_t2t_read_terminator_tlv_block (void) 1027{ 1028 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1029 tNFC_STATUS status; 1030 UINT16 block; 1031 1032 /* Send read command to read base block (Block % 4==0) where this block is also read as part of 16 bytes */ 1033 block = p_t2t->terminator_byte_index / T2T_BLOCK_SIZE; 1034 block -= block % T2T_READ_BLOCKS; 1035 1036 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK; 1037 /* Read the block where Terminator TLV may be added later during NDEF Write operation */ 1038 status = rw_t2t_read (block); 1039 return status; 1040} 1041 1042/******************************************************************************* 1043** 1044** Function rw_t2t_read_ndef_next_block 1045** 1046** Description This function will read the tag block passed as argument 1047** 1048** Returns NCI_STATUS_OK, if read was started. Otherwise, error status. 1049** 1050*******************************************************************************/ 1051tNFC_STATUS rw_t2t_read_ndef_next_block (UINT16 block) 1052{ 1053 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1054 tNFC_STATUS status; 1055 1056 /* Send read command to read base block (Block % 4==0) where this block is also read as part of 16 bytes */ 1057 block -= block % T2T_READ_BLOCKS; 1058 1059 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK; 1060 /* Read the block */ 1061 status = rw_t2t_read (block); 1062 1063 return status; 1064} 1065 1066/******************************************************************************* 1067** 1068** Function rw_t2t_is_read_before_write_block 1069** 1070** Description This function will check if the block has to be read before 1071** writting to avoid over writting in to lock/reserved bytes 1072** present in the block. 1073** If no bytes in the block can be overwritten it moves in to 1074** next block and check. Finally it finds a block where part of 1075** ndef bytes can exist and check if the whole block can be 1076** updated or only part of block can be modified. 1077** 1078** Returns TRUE, if the block returned should be read before writting 1079** FALSE, if the block need not be read as it was already 1080** read or during NDEF write we may completely overwrite 1081** the block and there is no reserved or locked bytes in 1082** that block 1083** 1084*******************************************************************************/ 1085static BOOLEAN rw_t2t_is_read_before_write_block (UINT16 block, UINT16 *p_block_to_read) 1086{ 1087 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1088 UINT8 *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE]; 1089 UINT8 count; 1090 UINT8 index; 1091 UINT16 tag_size = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK; 1092 BOOLEAN read_before_write = TRUE; 1093 1094 1095 if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) 1096 { 1097 /* First NDEF block is already read */ 1098 read_before_write = FALSE; 1099 memcpy (p_t2t->ndef_read_block,p_t2t->ndef_first_block,T2T_BLOCK_SIZE); 1100 } 1101 else if (block == p_t2t->ndef_last_block_num) 1102 { 1103 /* Last NDEF block is already read */ 1104 read_before_write = FALSE; 1105 memcpy (p_t2t->ndef_read_block,p_t2t->ndef_last_block,T2T_BLOCK_SIZE); 1106 } 1107 else if (block == p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) 1108 { 1109 /* Terminator tlv block is already read */ 1110 read_before_write = FALSE; 1111 memcpy (p_t2t->ndef_read_block,p_t2t->terminator_tlv_block,T2T_BLOCK_SIZE); 1112 } 1113 else 1114 { 1115 count = 0; 1116 while (block < tag_size) 1117 { 1118 index = 0; 1119 1120 while (index < T2T_BLOCK_SIZE) 1121 { 1122 /* check if it is a reserved or locked byte */ 1123 if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE) 1124 { 1125 count++; 1126 } 1127 index++; 1128 } 1129 if (count == T2T_BLOCK_SIZE) 1130 { 1131 /* All the bytes in the block are free to NDEF write */ 1132 read_before_write = FALSE; 1133 break; 1134 } 1135 else if (count == 0) 1136 { 1137 /* The complete block is not free for NDEF write */ 1138 index = 0; 1139 block++; 1140 } 1141 else 1142 { 1143 /* The block has reseved byte (s) or locked byte (s) or both */ 1144 read_before_write = TRUE; 1145 break; 1146 } 1147 } 1148 } 1149 /* Return the block to read next before NDEF write */ 1150 *p_block_to_read = block; 1151 return read_before_write; 1152} 1153 1154/******************************************************************************* 1155** 1156** Function rw_t2t_write_ndef_first_block 1157** 1158** Description This function will write the first NDEF block with Length 1159** field reset to zero. 1160** Also after writting NDEF this function may be called to 1161** update new NDEF length 1162** 1163** Returns NCI_STATUS_OK, if write was started. Otherwise, error status. 1164** 1165*******************************************************************************/ 1166tNFC_STATUS rw_t2t_write_ndef_first_block (UINT16 msg_len, BOOLEAN b_update_len) 1167{ 1168 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1169 UINT8 new_lengthfield_len; 1170 UINT8 write_block[4]; 1171 UINT8 block; 1172 UINT8 *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE]; 1173 UINT16 total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK; 1174 tNFC_STATUS status; 1175 UINT8 length_field[3]; 1176 UINT8 index; 1177 1178 p_t2t->work_offset = 0; 1179 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN; 1180 if (new_lengthfield_len == 3) 1181 { 1182 /* New NDEF is Long NDEF */ 1183 if (msg_len == 0) 1184 { 1185 /* Clear NDEF length field */ 1186 length_field[0] = 0x00; 1187 length_field[1] = 0x00; 1188 length_field[2] = 0x00; 1189 } 1190 else 1191 { 1192 /* Update NDEF length field with new NDEF Msg len */ 1193 length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0; 1194 length_field[1] = (UINT8) (msg_len >> 8); 1195 length_field[2] = (UINT8) (msg_len); 1196 } 1197 } 1198 else 1199 { 1200 /* New NDEF is Short NDEF */ 1201 length_field[0] = (UINT8) (msg_len); 1202 } 1203 1204 /* updating ndef_first_block with new ndef message */ 1205 memcpy (write_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE); 1206 1207 index = p_t2t->ndef_header_offset % T2T_BLOCK_SIZE; 1208 block = (UINT8) (p_t2t->ndef_header_offset / T2T_BLOCK_SIZE); 1209 1210 while (p_t2t->work_offset == 0 && block < total_blocks) 1211 { 1212 /* update length field */ 1213 while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < p_t2t->new_ndef_msg_len) 1214 { 1215 if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE) 1216 { 1217 write_block[index] = length_field[p_t2t->work_offset]; 1218 p_t2t->work_offset++; 1219 } 1220 index++; 1221 if (p_t2t->work_offset == new_lengthfield_len) 1222 { 1223 break; 1224 } 1225 } 1226 /* If more space in this block then add ndef message */ 1227 while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len)) 1228 { 1229 if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE) 1230 { 1231 write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len]; 1232 p_t2t->work_offset++; 1233 } 1234 index++; 1235 } 1236 if (p_t2t->work_offset == 0) 1237 { 1238 /* If no bytes are written move to next block */ 1239 index = 0; 1240 block++; 1241 if (block == p_t2t->ndef_last_block_num) 1242 { 1243 memcpy (write_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE); 1244 } 1245 } 1246 } 1247 if (p_t2t->work_offset == 0) 1248 { 1249 status = NFC_STATUS_FAILED; 1250 } 1251 else 1252 { 1253 rw_t2t_update_cb (block, write_block, b_update_len); 1254 /* Update the identified block with newly prepared data */ 1255 if ((status = rw_t2t_write (block, write_block)) == NFC_STATUS_OK) 1256 { 1257 p_t2t->b_read_data = FALSE; 1258 } 1259 } 1260 return status; 1261} 1262 1263/******************************************************************************* 1264** 1265** Function rw_t2t_write_ndef_next_block 1266** 1267** Description This function can be called to write an NDEF message block 1268** 1269** Returns NCI_STATUS_OK, if write was started. Otherwise, error status. 1270** 1271*******************************************************************************/ 1272tNFC_STATUS rw_t2t_write_ndef_next_block (UINT16 block, UINT16 msg_len, BOOLEAN b_update_len) 1273{ 1274 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1275 UINT8 new_lengthfield_len; 1276 UINT8 write_block[4]; 1277 UINT8 *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE]; 1278 UINT16 total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK; 1279 UINT16 initial_offset; 1280 UINT8 length_field[3]; 1281 UINT8 index; 1282 tNFC_STATUS status; 1283 1284 /* Write NDEF Message */ 1285 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN; 1286 1287 index = 0; 1288 1289 memcpy (write_block, p_t2t->ndef_read_block, T2T_BLOCK_SIZE); 1290 1291 if (p_t2t->work_offset >= new_lengthfield_len) 1292 { 1293 /* Length field is updated, write ndef message field */ 1294 initial_offset = p_t2t->work_offset; 1295 while (p_t2t->work_offset == initial_offset && block < total_blocks) 1296 { 1297 while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len)) 1298 { 1299 if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE) 1300 { 1301 write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len]; 1302 p_t2t->work_offset++; 1303 } 1304 index++; 1305 } 1306 if (p_t2t->work_offset == initial_offset) 1307 { 1308 index = 0; 1309 block++; 1310 } 1311 } 1312 } 1313 else 1314 { 1315 /* Complete writting Length field and then write ndef message */ 1316 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN; 1317 if (new_lengthfield_len == 3) 1318 { 1319 /* New NDEF is Long NDEF */ 1320 if (msg_len == 0) 1321 { 1322 length_field[0] = 0x00; 1323 length_field[1] = 0x00; 1324 length_field[2] = 0x00; 1325 } 1326 else 1327 { 1328 length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0; 1329 length_field[1] = (UINT8) (msg_len >> 8); 1330 length_field[2] = (UINT8) (msg_len); 1331 } 1332 } 1333 else 1334 { 1335 /* New NDEF is short NDEF */ 1336 length_field[0] = (UINT8) (msg_len); 1337 } 1338 initial_offset = p_t2t->work_offset; 1339 while (p_t2t->work_offset == initial_offset && block < total_blocks) 1340 { 1341 /* Update length field */ 1342 while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < p_t2t->new_ndef_msg_len) 1343 { 1344 if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE) 1345 { 1346 write_block[index] = length_field[p_t2t->work_offset]; 1347 p_t2t->work_offset++; 1348 } 1349 index++; 1350 if (p_t2t->work_offset == new_lengthfield_len) 1351 { 1352 break; 1353 } 1354 } 1355 /* Update ndef message field */ 1356 while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len)) 1357 { 1358 if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE) 1359 { 1360 write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len]; 1361 p_t2t->work_offset++; 1362 } 1363 index++; 1364 } 1365 if (p_t2t->work_offset == initial_offset) 1366 { 1367 index = 0; 1368 block++; 1369 } 1370 } 1371 } 1372 if (p_t2t->work_offset == initial_offset) 1373 { 1374 status = NFC_STATUS_FAILED; 1375 } 1376 else 1377 { 1378 rw_t2t_update_cb (block, write_block, b_update_len); 1379 /* Write the NDEF Block */ 1380 status = rw_t2t_write (block, write_block); 1381 } 1382 1383 return status; 1384} 1385 1386/******************************************************************************* 1387** 1388** Function rw_t2t_update_cb 1389** 1390** Description This function can be called to write an NDEF message block 1391** 1392** Returns NCI_STATUS_OK, if write was started. Otherwise, error status. 1393** 1394*******************************************************************************/ 1395static void rw_t2t_update_cb (UINT16 block, UINT8 *p_write_block, BOOLEAN b_update_len) 1396{ 1397 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1398 UINT8 new_lengthfield_len; 1399 1400 /* Write NDEF Message */ 1401 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN; 1402 1403 if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) 1404 { 1405 /* Update ndef first block if the 'block' points to ndef first block */ 1406 memcpy (p_t2t->ndef_first_block,p_write_block,T2T_BLOCK_SIZE); 1407 } 1408 if (p_t2t->terminator_byte_index/T2T_BLOCK_SIZE == block) 1409 { 1410 /* Update terminator block if the 'block' points to terminator tlv block */ 1411 memcpy (p_t2t->terminator_tlv_block, p_write_block, T2T_BLOCK_LEN); 1412 } 1413 if (b_update_len == FALSE) 1414 { 1415 if (block == p_t2t->ndef_last_block_num) 1416 { 1417 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK; 1418 p_t2t->work_offset = 0; 1419 /* Update ndef final block if the 'block' points to ndef final block */ 1420 memcpy (p_t2t->ndef_last_block,p_write_block,T2T_BLOCK_SIZE); 1421 } 1422 else 1423 { 1424 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK; 1425 } 1426 } 1427 else 1428 { 1429 if (block == p_t2t->ndef_last_block_num) 1430 { 1431 /* Update the backup of Ndef final block TLV block */ 1432 memcpy (p_t2t->ndef_last_block,p_write_block,T2T_BLOCK_SIZE); 1433 } 1434 1435 if (p_t2t->work_offset >= new_lengthfield_len) 1436 { 1437 if (p_t2t->terminator_byte_index != 0) 1438 { 1439 /* Add Terminator TLV as part of NDEF Write operation */ 1440 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK; 1441 } 1442 else 1443 { 1444 /* Skip adding Terminator TLV */ 1445 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT; 1446 } 1447 } 1448 else 1449 { 1450 /* Part of NDEF Message Len should be added in the next block */ 1451 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK; 1452 } 1453 } 1454} 1455 1456/******************************************************************************* 1457** 1458** Function rw_t2t_get_ndef_flags 1459** 1460** Description Prepare NDEF Flags 1461** 1462** Returns NDEF Flag value 1463** 1464*******************************************************************************/ 1465static UINT8 rw_t2t_get_ndef_flags (void) 1466{ 1467 UINT8 flags = 0; 1468 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1469 const tT2T_INIT_TAG *p_ret; 1470 1471 flags |= RW_NDEF_FL_SUPPORTED; 1472 1473 if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC) || (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == 0)) 1474 flags |= RW_NDEF_FL_FORMATABLE; 1475 1476 if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO) 1477 flags |=RW_NDEF_FL_READ_ONLY; 1478 1479 if ( ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL) 1480 &&(p_ret->b_otp) ) 1481 { 1482 /* Set otp flag */ 1483 flags |= RW_NDEF_FL_OTP; 1484 1485 /* Set Read only flag if otp tag already has NDEF Message */ 1486 if (p_t2t->ndef_msg_len) 1487 flags |= RW_NDEF_FL_READ_ONLY; 1488 } 1489 return flags; 1490} 1491 1492/******************************************************************************* 1493** 1494** Function rw_t2t_get_ndef_max_size 1495** 1496** Description Calculate maximum size of NDEF message that can be written 1497** on to the tag 1498** 1499** Returns Maximum size of NDEF Message 1500** 1501*******************************************************************************/ 1502static UINT16 rw_t2t_get_ndef_max_size (void) 1503{ 1504 UINT16 offset; 1505 UINT8 xx; 1506 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1507 UINT16 tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN) + p_t2t->num_lockbytes; 1508 1509 for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++) 1510 tag_size += p_t2t->mem_tlv[xx].num_bytes; 1511 1512 offset = p_t2t->ndef_msg_offset; 1513 p_t2t->max_ndef_msg_len = 0; 1514 1515 if ( (tag_size < T2T_STATIC_SIZE) 1516 ||(tag_size > (T2T_SECTOR_SIZE * T2T_MAX_SECTOR)) 1517 ||((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN) && (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0)) ) 1518 { 1519 /* Tag not formated, assume static tag */ 1520 p_t2t->max_ndef_msg_len = T2T_STATIC_SIZE - T2T_HEADER_SIZE - T2T_TLV_TYPE_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN; 1521 return p_t2t->max_ndef_msg_len; 1522 } 1523 1524 /* Starting from NDEF Message offset find the first locked data byte */ 1525 while (offset < tag_size) 1526 { 1527 if (rw_t2t_is_lock_res_byte ((UINT16) offset) == FALSE) 1528 { 1529 if (rw_t2t_is_read_only_byte ((UINT16) offset) == TRUE) 1530 break; 1531 p_t2t->max_ndef_msg_len++; 1532 } 1533 offset++; 1534 } 1535 /* NDEF Length field length changes based on NDEF size */ 1536 if ( (p_t2t->max_ndef_msg_len >= T2T_LONG_NDEF_LEN_FIELD_BYTE0) 1537 &&((p_t2t->ndef_msg_offset - p_t2t->ndef_header_offset) == T2T_SHORT_NDEF_LEN_FIELD_LEN) ) 1538 { 1539 p_t2t->max_ndef_msg_len -= (p_t2t->max_ndef_msg_len == T2T_LONG_NDEF_LEN_FIELD_BYTE0) ? 1: (T2T_LONG_NDEF_LEN_FIELD_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN); 1540 } 1541 return p_t2t->max_ndef_msg_len; 1542} 1543 1544/******************************************************************************* 1545** 1546** Function rw_t2t_add_terminator_tlv 1547** 1548** Description This function will add terminator TLV after NDEF Message 1549** 1550** Returns NCI_STATUS_OK, if write was started. Otherwise, error status. 1551** 1552*******************************************************************************/ 1553tNFC_STATUS rw_t2t_add_terminator_tlv (void) 1554{ 1555 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1556 tNFC_STATUS status; 1557 UINT16 block; 1558 1559 /* Add Terminator TLV after NDEF Message */ 1560 p_t2t->terminator_tlv_block[p_t2t->terminator_byte_index%T2T_BLOCK_LEN] = TAG_TERMINATOR_TLV; 1561 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT; 1562 1563 block = p_t2t->terminator_byte_index/T2T_BLOCK_LEN; 1564 status = rw_t2t_write (block, p_t2t->terminator_tlv_block); 1565 1566 return status; 1567} 1568 1569/******************************************************************************* 1570** 1571** Function rw_t2t_handle_ndef_read_rsp 1572** 1573** Description This function handles reading an NDEF message. 1574** 1575** Returns none 1576** 1577*******************************************************************************/ 1578static void rw_t2t_handle_ndef_read_rsp (UINT8 *p_data) 1579{ 1580 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1581 tRW_READ_DATA evt_data; 1582 UINT16 len; 1583 UINT16 offset; 1584 BOOLEAN failed = FALSE; 1585 BOOLEAN done = FALSE; 1586 1587 /* On the first read, adjust for any partial block offset */ 1588 offset = 0; 1589 len = T2T_READ_DATA_LEN; 1590 1591 if (p_t2t->work_offset == 0) 1592 { 1593 /* The Ndef Message offset may be present in the read 16 bytes */ 1594 offset = (p_t2t->ndef_msg_offset - (p_t2t->block_read * T2T_BLOCK_SIZE)); 1595 } 1596 1597 /* Skip all reserved and lock bytes */ 1598 while ( (offset < len) 1599 &&(p_t2t->work_offset<p_t2t->ndef_msg_len) ) 1600 1601 { 1602 if (rw_t2t_is_lock_res_byte ((UINT16) (offset + p_t2t->block_read * T2T_BLOCK_LEN)) == FALSE) 1603 { 1604 /* Collect the NDEF Message */ 1605 p_t2t->p_ndef_buffer[p_t2t->work_offset] = p_data[offset]; 1606 p_t2t->work_offset++; 1607 } 1608 offset++; 1609 } 1610 1611 if (p_t2t->work_offset >= p_t2t->ndef_msg_len) 1612 { 1613 done = TRUE; 1614 p_t2t->ndef_status = T2T_NDEF_READ; 1615 } 1616 else 1617 { 1618 /* Read next 4 blocks */ 1619 if (rw_t2t_read ((UINT16) (p_t2t->block_read + T2T_READ_BLOCKS)) != NFC_STATUS_OK) 1620 failed = TRUE; 1621 } 1622 1623 if (failed || done) 1624 { 1625 evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK; 1626 evt_data.p_data = NULL; 1627 rw_t2t_handle_op_complete (); 1628 (*rw_cb.p_cback) (RW_T2T_NDEF_READ_EVT, (tRW_DATA *) &evt_data); 1629 } 1630} 1631 1632/******************************************************************************* 1633** 1634** Function rw_t2t_handle_ndef_write_rsp 1635** 1636** Description Handle response received to reading (or part of) NDEF message. 1637** 1638** Returns none 1639** 1640*******************************************************************************/ 1641static void rw_t2t_handle_ndef_write_rsp (UINT8 *p_data) 1642{ 1643 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1644 tRW_READ_DATA evt_data; 1645 BOOLEAN failed = FALSE; 1646 BOOLEAN done = FALSE; 1647 UINT16 block; 1648 UINT8 offset; 1649 1650 switch (p_t2t->substate) 1651 { 1652 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK: 1653 1654 /* Backup the read NDEF first block */ 1655 memcpy (p_t2t->ndef_first_block, p_data, T2T_BLOCK_LEN); 1656 /* Read ndef final block */ 1657 if (rw_t2t_read_ndef_last_block () != NFC_STATUS_OK) 1658 failed = TRUE; 1659 break; 1660 1661 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK: 1662 1663 offset = (UINT8) (p_t2t->ndef_last_block_num - p_t2t->block_read) * T2T_BLOCK_SIZE; 1664 /* Backup the read NDEF final block */ 1665 memcpy (p_t2t->ndef_last_block, &p_data[offset], T2T_BLOCK_LEN); 1666 if ((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) == p_t2t->ndef_last_block_num) 1667 { 1668 /* If Terminator TLV will reside on the NDEF Final block */ 1669 memcpy (p_t2t->terminator_tlv_block, p_t2t->ndef_last_block, T2T_BLOCK_LEN); 1670 if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!= NFC_STATUS_OK) 1671 failed = TRUE; 1672 } 1673 else if (p_t2t->terminator_byte_index != 0) 1674 { 1675 /* If there is space for Terminator TLV and if it will reside outside NDEF Final block */ 1676 if (rw_t2t_read_terminator_tlv_block ()!= NFC_STATUS_OK) 1677 failed = TRUE; 1678 } 1679 else 1680 { 1681 if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!= NFC_STATUS_OK) 1682 failed = TRUE; 1683 } 1684 break; 1685 1686 case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK: 1687 1688 offset = (UINT8) (((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) - p_t2t->block_read) * T2T_BLOCK_SIZE); 1689 /* Backup the read Terminator TLV block */ 1690 memcpy (p_t2t->terminator_tlv_block, &p_data[offset], T2T_BLOCK_LEN); 1691 1692 /* Write the first block for new NDEF Message */ 1693 if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!= NFC_STATUS_OK) 1694 failed = TRUE; 1695 break; 1696 1697 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK: 1698 1699 offset = (UINT8) (p_t2t->ndef_read_block_num - p_t2t->block_read) * T2T_BLOCK_SIZE; 1700 /* Backup read block */ 1701 memcpy (p_t2t->ndef_read_block, &p_data[offset], T2T_BLOCK_LEN); 1702 1703 /* Update the block with new NDEF Message */ 1704 if (rw_t2t_write_ndef_next_block (p_t2t->ndef_read_block_num, 0x0000, FALSE) != NFC_STATUS_OK) 1705 failed = TRUE; 1706 break; 1707 1708 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK: 1709 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK: 1710 if (rw_t2t_is_read_before_write_block ((UINT16) (p_t2t->block_written + 1), &block) == TRUE) 1711 { 1712 p_t2t->ndef_read_block_num = block; 1713 /* If only part of the block is going to be updated read the block to retain previous data for 1714 unchanged part of the block */ 1715 if (rw_t2t_read_ndef_next_block (block) != NFC_STATUS_OK) 1716 failed = TRUE; 1717 } 1718 else 1719 { 1720 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK) 1721 { 1722 /* Directly write the block with new NDEF contents as whole block is going to be updated */ 1723 if (rw_t2t_write_ndef_next_block (block, p_t2t->new_ndef_msg_len, TRUE)!= NFC_STATUS_OK) 1724 failed = TRUE; 1725 } 1726 else 1727 { 1728 /* Directly write the block with new NDEF contents as whole block is going to be updated */ 1729 if (rw_t2t_write_ndef_next_block (block, 0x0000, FALSE)!= NFC_STATUS_OK) 1730 failed = TRUE; 1731 } 1732 } 1733 break; 1734 1735 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK: 1736 /* Write the next block for new NDEF Message */ 1737 p_t2t->ndef_write_block = p_t2t->ndef_header_offset / T2T_BLOCK_SIZE; 1738 if (rw_t2t_is_read_before_write_block ((UINT16) (p_t2t->ndef_write_block), &block) == TRUE) 1739 { 1740 /* If only part of the block is going to be updated read the block to retain previous data for 1741 part of the block thats not going to be changed */ 1742 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK; 1743 if (rw_t2t_read (block) != NFC_STATUS_OK) 1744 failed = TRUE; 1745 1746 } 1747 else 1748 { 1749 /* Update NDEF Message Length in the Tag */ 1750 if (rw_t2t_write_ndef_first_block (p_t2t->new_ndef_msg_len, TRUE)!= NFC_STATUS_OK) 1751 failed = TRUE; 1752 } 1753 break; 1754 1755 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK: 1756 /* Backup read block */ 1757 memcpy (p_t2t->ndef_read_block, p_data, T2T_BLOCK_LEN); 1758 1759 /* Update the block with new NDEF Message */ 1760 if (rw_t2t_write_ndef_next_block (p_t2t->block_read, p_t2t->new_ndef_msg_len, TRUE) == NFC_STATUS_OK) 1761 p_t2t->ndef_write_block = p_t2t->block_read + 1; 1762 else 1763 failed = TRUE; 1764 1765 break; 1766 1767 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK: 1768 if (rw_t2t_add_terminator_tlv ()!= NFC_STATUS_OK) 1769 failed = TRUE; 1770 break; 1771 1772 case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT: 1773 done = TRUE; 1774 break; 1775 1776 default: 1777 break; 1778 } 1779 1780 if (failed || done) 1781 { 1782 evt_data.p_data = NULL; 1783 /* NDEF WRITE Operation is done, inform up the stack */ 1784 evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK; 1785 if (done) 1786 { 1787 if ( (p_t2t->ndef_msg_len >= 0x00FF) 1788 &&(p_t2t->new_ndef_msg_len < 0x00FF) ) 1789 { 1790 p_t2t->ndef_msg_offset -= 2; 1791 } 1792 else if ( (p_t2t->new_ndef_msg_len >= 0x00FF) 1793 &&(p_t2t->ndef_msg_len < 0x00FF) ) 1794 { 1795 p_t2t->ndef_msg_offset += 2; 1796 } 1797 p_t2t->ndef_msg_len = p_t2t->new_ndef_msg_len; 1798 } 1799 rw_t2t_handle_op_complete (); 1800 (*rw_cb.p_cback) (RW_T2T_NDEF_WRITE_EVT, (tRW_DATA *) &evt_data); 1801 } 1802} 1803 1804/******************************************************************************* 1805** 1806** Function rw_t2t_get_tag_size 1807** 1808** Description This function calculates tag data area size from data read 1809** from block with version number 1810** 1811** Returns TMS of the tag 1812** 1813*******************************************************************************/ 1814static UINT8 rw_t2t_get_tag_size (UINT8 *p_data) 1815{ 1816 UINT16 LchunkSize = 0; 1817 UINT16 Num_LChuncks = 0; 1818 UINT16 tms = 0; 1819 1820 LchunkSize = (UINT16) p_data[2] << 8 | p_data[3]; 1821 Num_LChuncks = (UINT16) p_data[4] << 8 | p_data[5]; 1822 1823 tms = (UINT16) (LchunkSize * Num_LChuncks); 1824 1825 tms += (T2T_STATIC_SIZE - T2T_HEADER_SIZE); 1826 1827 tms /= 0x08; 1828 1829 return (UINT8) tms; 1830} 1831 1832/******************************************************************************* 1833** 1834** Function rw_t2t_handle_config_tag_readonly 1835** 1836** Description This function handles configure type 2 tag as read only 1837** 1838** Returns none 1839** 1840*******************************************************************************/ 1841static void rw_t2t_handle_config_tag_readonly (UINT8 *p_data) 1842{ 1843 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1844 tNFC_STATUS status = NFC_STATUS_FAILED; 1845 BOOLEAN b_notify = FALSE; 1846 UINT8 write_block[T2T_BLOCK_SIZE]; 1847 tRW_DATA evt; 1848 BOOLEAN b_pending = FALSE; 1849 UINT8 read_lock = 0; 1850 UINT8 num_locks = 0; 1851 UINT16 offset; 1852 1853 switch (p_t2t->substate) 1854 { 1855 case RW_T2T_SUBSTATE_WAIT_READ_CC: 1856 1857 /* First soft lock the tag */ 1858 rw_t2t_soft_lock_tag (); 1859 1860 break; 1861 1862 case RW_T2T_SUBSTATE_WAIT_SET_CC_RO: 1863 1864 /* Successfully soft locked! Update Tag header for future reference */ 1865 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] = T2T_CC3_RWA_RO; 1866 if (!p_t2t->b_hard_lock) 1867 { 1868 /* Tag configuration complete */ 1869 status = NFC_STATUS_OK; 1870 b_notify = TRUE; 1871 break; 1872 } 1873 1874 /* Coverity: [FALSE-POSITIVE error] intended fall through */ 1875 /* Missing break statement between cases in switch statement */ 1876 /* fall through */ 1877 case RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS: 1878 1879 num_locks = 0; 1880 1881 while (num_locks < p_t2t->num_lockbytes) 1882 { 1883 if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_UPDATE_INITIATED) 1884 { 1885 /* Update control block as one or more dynamic lock byte (s) are set */ 1886 p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_UPDATED; 1887 } 1888 if (!b_pending && p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) 1889 { 1890 /* One or more dynamic lock bits are not set */ 1891 b_pending = TRUE; 1892 read_lock = num_locks; 1893 } 1894 num_locks++; 1895 } 1896 1897 if (b_pending) 1898 { 1899 /* Read the block where dynamic lock bits are present to avoid writing to NDEF bytes in the same block */ 1900 offset = p_t2t->lock_tlv[p_t2t->lockbyte[read_lock].tlv_index].offset + p_t2t->lockbyte[read_lock].byte_index; 1901 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK; 1902 status = rw_t2t_read ((UINT16) (offset / T2T_BLOCK_LEN)); 1903 } 1904 else 1905 { 1906 /* Now set Static lock bits as no more dynamic lock bits to set */ 1907 1908 /* Copy the internal bytes */ 1909 memcpy (write_block, &p_t2t->tag_hdr[T2T_STATIC_LOCK0 - T2T_INTERNAL_BYTES_LEN], T2T_INTERNAL_BYTES_LEN); 1910 /* Set all Static lock bits */ 1911 write_block [T2T_STATIC_LOCK0 % T2T_BLOCK_SIZE] = 0xFF; 1912 write_block [T2T_STATIC_LOCK1 % T2T_BLOCK_SIZE] = 0xFF; 1913 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS; 1914 status = rw_t2t_write ((T2T_STATIC_LOCK0 / T2T_BLOCK_SIZE), write_block); 1915 } 1916 break; 1917 1918 case RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK: 1919 /* Now set the dynamic lock bits present in the block read now */ 1920 status = rw_t2t_set_dynamic_lock_bits (p_data); 1921 break; 1922 1923 case RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS: 1924 /* Tag configuration complete */ 1925 status = NFC_STATUS_OK; 1926 b_notify = TRUE; 1927 break; 1928 1929 } 1930 1931 if (status != NFC_STATUS_OK || b_notify) 1932 { 1933 /* Notify upper layer the result of Configuring Tag as Read only */ 1934 evt.status = status; 1935 rw_t2t_handle_op_complete (); 1936 (*rw_cb.p_cback) (RW_T2T_SET_TAG_RO_EVT, (tRW_DATA *) &evt); 1937 } 1938} 1939 1940/******************************************************************************* 1941** 1942** Function rw_t2t_handle_format_tag_rsp 1943** 1944** Description This function handles formating a type 2 tag 1945** 1946** Returns none 1947** 1948*******************************************************************************/ 1949static void rw_t2t_handle_format_tag_rsp (UINT8 *p_data) 1950{ 1951 tRW_DATA evt; 1952 UINT8 *p; 1953 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 1954 tNFC_STATUS status = NFC_STATUS_FAILED; 1955 UINT16 version_no; 1956 const tT2T_INIT_TAG *p_ret; 1957 UINT8 tms; 1958 UINT8 next_block = T2T_FIRST_DATA_BLOCK + 1; 1959 UINT16 addr, locked_area; 1960 BOOLEAN b_notify = FALSE; 1961 1962 1963 p = p_t2t->ndef_final_block; 1964 UINT8_TO_BE_STREAM (p, p_t2t->tlv_value[2]); 1965 1966 switch (p_t2t->substate) 1967 { 1968 case RW_T2T_SUBSTATE_WAIT_READ_CC: 1969 /* Start format operation */ 1970 status = rw_t2t_format_tag (); 1971 break; 1972 1973 case RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO: 1974 1975 memcpy (p_t2t->tag_data, p_data, T2T_READ_DATA_LEN); 1976 p_t2t->b_read_data = TRUE; 1977 version_no = (UINT16) p_data[0] << 8 | p_data[1]; 1978 if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], TRUE, version_no)) != NULL) 1979 { 1980 /* Valid Version Number */ 1981 if (p_ret->b_calc_cc) 1982 /* Calculate tag size from Version Information */ 1983 tms = rw_t2t_get_tag_size (p_data); 1984 1985 else 1986 /* Tag size from Look up table */ 1987 tms = p_ret->tms; 1988 1989 /* Set CC with the Tag size from look up table or from calculated value */ 1990 status = rw_t2t_set_cc (tms); 1991 } 1992 break; 1993 1994 case RW_T2T_SUBSTATE_WAIT_SET_CC: 1995 1996 version_no = (UINT16) p_t2t->tag_data[0] << 8 | p_t2t->tag_data[1]; 1997 if ( (version_no == 0) 1998 ||((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], TRUE, version_no)) == NULL) 1999 ||(!p_ret->b_multi_version) 2000 ||(!p_ret->b_calc_cc) ) 2001 { 2002 /* Currently Formating a non blank tag or a blank tag with manufacturer 2003 * has only one variant of tag. Set Null NDEF TLV and complete Format Operation */ 2004 next_block = T2T_FIRST_DATA_BLOCK; 2005 p = p_t2t->ndef_final_block; 2006 } 2007 else 2008 { 2009 addr = (UINT16) (((UINT16) p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) * ((UINT16) p_t2t->tag_data[4] << 8 | p_t2t->tag_data[5]) + T2T_STATIC_SIZE); 2010 locked_area = ((UINT16) p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) * ((UINT16) p_t2t->tag_data[6]); 2011 2012 if ((status = rw_t2t_set_lock_tlv (addr, p_t2t->tag_data[7], locked_area)) == NFC_STATUS_REJECTED) 2013 { 2014 /* Cannot calculate Lock TLV. Set Null NDEF TLV and complete Format Operation */ 2015 next_block = T2T_FIRST_DATA_BLOCK; 2016 p = p_t2t->ndef_final_block; 2017 } 2018 else 2019 break; 2020 } 2021 2022 /* falls through */ 2023 case RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV: 2024 2025 /* Prepare NULL NDEF TLV, TERMINATOR_TLV */ 2026 UINT8_TO_BE_STREAM (p, TAG_NDEF_TLV); 2027 UINT8_TO_BE_STREAM (p, 0); 2028 2029 if ( ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL) 2030 &&(!p_ret->b_otp) ) 2031 { 2032 UINT8_TO_BE_STREAM (p, TAG_TERMINATOR_TLV); 2033 } 2034 else 2035 UINT8_TO_BE_STREAM (p, 0); 2036 2037 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF; 2038 /* send WRITE-E8 command */ 2039 if ((status = rw_t2t_write (next_block, p_t2t->ndef_final_block)) == NFC_STATUS_OK) 2040 p_t2t->b_read_data = FALSE; 2041 break; 2042 2043 case RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF: 2044 /* Tag Formated successfully */ 2045 status = NFC_STATUS_OK; 2046 b_notify = TRUE; 2047 break; 2048 2049 default: 2050 break; 2051 2052 } 2053 2054 if (status != NFC_STATUS_OK || b_notify) 2055 { 2056 /* Notify upper layer the result of Format op */ 2057 evt.status = status; 2058 rw_t2t_handle_op_complete (); 2059 (*rw_cb.p_cback) (RW_T2T_FORMAT_CPLT_EVT, (tRW_DATA *) &evt); 2060 } 2061 2062} 2063 2064/******************************************************************************* 2065** 2066** Function rw_t2t_update_attributes 2067** 2068** Description This function will update attribute for the current segment 2069** based on lock and reserved bytes 2070** 2071** Returns None 2072** 2073*******************************************************************************/ 2074static void rw_t2t_update_attributes (void) 2075{ 2076 UINT8 count = 0; 2077 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2078 UINT16 lower_offset; 2079 UINT16 upper_offset; 2080 UINT16 offset; 2081 UINT8 num_bytes; 2082 2083 /* Prepare attr for the current segment */ 2084 memset (p_t2t->attr, 0, RW_T2T_SEGMENT_SIZE * sizeof (UINT8)); 2085 2086 /* calculate offset where the current segment starts in the tag */ 2087 lower_offset = p_t2t->segment * RW_T2T_SEGMENT_BYTES; 2088 /* calculate offset where the current segment ends in the tag */ 2089 upper_offset = (p_t2t->segment + 1) * RW_T2T_SEGMENT_BYTES; 2090 2091 2092 /* check offset of lock bytes in the tag and update p_t2t->attr 2093 * for every lock byte that is present in the current segment */ 2094 count = 0; 2095 while (count < p_t2t->num_lockbytes) 2096 { 2097 offset = p_t2t->lock_tlv[p_t2t->lockbyte[count].tlv_index].offset + p_t2t->lockbyte[count].byte_index; 2098 if (offset >= lower_offset && offset < upper_offset) 2099 { 2100 /* Calculate offset in the current segment as p_t2t->attr is prepared for one segment only */ 2101 offset %= RW_T2T_SEGMENT_BYTES; 2102 /* Every bit in p_t2t->attr indicates one byte of the tag is either a lock/reserved byte or not 2103 * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8 2104 * Set the corresponding bit in attr to indicate - reserved byte */ 2105 p_t2t->attr[offset / TAG_BITS_PER_BYTE] |= rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE]; 2106 } 2107 count++; 2108 } 2109 2110 2111 /* Search reserved bytes identified by all memory tlvs present in the tag */ 2112 count = 0; 2113 while (count < p_t2t->num_mem_tlvs) 2114 { 2115 /* check the offset of reserved bytes in the tag and update p_t2t->attr 2116 * for every reserved byte that is present in the current segment */ 2117 num_bytes = 0; 2118 while (num_bytes < p_t2t->mem_tlv[count].num_bytes) 2119 { 2120 offset = p_t2t->mem_tlv[count].offset + num_bytes; 2121 if (offset >= lower_offset && offset < upper_offset) 2122 { 2123 /* Let offset represents offset in the current segment as p_t2t->attr is prepared for one segment only */ 2124 offset %= RW_T2T_SEGMENT_BYTES; 2125 /* Every bit in p_t2t->attr indicates one byte of the tag is either a lock/reserved byte or not 2126 * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8 2127 * Set the corresponding bit in attr to indicate - reserved byte */ 2128 p_t2t->attr[offset /TAG_BITS_PER_BYTE] |= rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE]; 2129 } 2130 num_bytes++; 2131 } 2132 count++; 2133 } 2134} 2135 2136/******************************************************************************* 2137** 2138** Function rw_t2t_get_lock_bits_for_segment 2139** 2140** Description This function returns the offset of lock bits associated for 2141** the specified segment 2142** 2143** Parameters: segment: The segment number to which lock bits are associated 2144** p_start_byte: The offset of lock byte that contains the first 2145** lock bit for the segment 2146** p_start_bit: The offset of the lock bit in the lock byte 2147** 2148** p_end_byte: The offset of the last bit associcated to the 2149** segment 2150** 2151** Returns Total number of lock bits assigned to the specified segment 2152** 2153*******************************************************************************/ 2154static UINT8 rw_t2t_get_lock_bits_for_segment (UINT8 segment, UINT8 *p_start_byte, UINT8 *p_start_bit, UINT8 *p_end_byte) 2155{ 2156 UINT8 total_bits = 0; 2157 UINT16 byte_count = 0; 2158 UINT16 lower_offset, upper_offset; 2159 UINT8 num_dynamic_locks = 0; 2160 UINT8 bit_count = 0; 2161 UINT8 bytes_locked_per_bit; 2162 UINT8 num_bits; 2163 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2164 BOOLEAN b_all_bits_are_locks = TRUE; 2165 UINT16 tag_size; 2166 UINT8 xx; 2167 2168 tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_SIZE) + p_t2t->num_lockbytes; 2169 2170 for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++) 2171 tag_size += p_t2t->mem_tlv[xx].num_bytes; 2172 2173 lower_offset = segment * RW_T2T_SEGMENT_BYTES; 2174 if (segment == 0) 2175 { 2176 lower_offset += T2T_STATIC_SIZE; 2177 } 2178 upper_offset = (segment + 1) * RW_T2T_SEGMENT_BYTES; 2179 2180 byte_count = T2T_STATIC_SIZE; 2181 if (tag_size < upper_offset) 2182 { 2183 upper_offset = tag_size; 2184 } 2185 2186 *p_start_byte = num_dynamic_locks; 2187 *p_start_bit = 0; 2188 2189 while ( (byte_count <= lower_offset) 2190 &&(num_dynamic_locks < p_t2t->num_lockbytes) ) 2191 { 2192 bytes_locked_per_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit; 2193 /* Number of bits in the current lock byte */ 2194 b_all_bits_are_locks = ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits); 2195 num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE; 2196 2197 if (((bytes_locked_per_bit * num_bits) + byte_count) <= lower_offset) 2198 { 2199 /* Skip this lock byte as it covers different segment */ 2200 byte_count += bytes_locked_per_bit * num_bits; 2201 num_dynamic_locks++; 2202 } 2203 else 2204 { 2205 bit_count = 0; 2206 while (bit_count < num_bits) 2207 { 2208 byte_count += bytes_locked_per_bit; 2209 if (byte_count > lower_offset) 2210 { 2211 /* First lock bit that is used to lock this segment */ 2212 *p_start_byte = num_dynamic_locks; 2213 *p_end_byte = num_dynamic_locks; 2214 *p_start_bit = bit_count; 2215 bit_count++; 2216 total_bits = 1; 2217 break; 2218 } 2219 bit_count++; 2220 } 2221 } 2222 } 2223 if (num_dynamic_locks == p_t2t->num_lockbytes) 2224 { 2225 return 0; 2226 } 2227 while ( (byte_count < upper_offset) 2228 &&(num_dynamic_locks < p_t2t->num_lockbytes) ) 2229 { 2230 bytes_locked_per_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit; 2231 /* Number of bits in the current lock byte */ 2232 b_all_bits_are_locks = ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits); 2233 num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE; 2234 2235 if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count < upper_offset) 2236 { 2237 /* Collect all lock bits that covers the current segment */ 2238 byte_count += bytes_locked_per_bit * (num_bits - bit_count); 2239 total_bits += num_bits - bit_count; 2240 bit_count = 0; 2241 *p_end_byte = num_dynamic_locks; 2242 num_dynamic_locks++; 2243 } 2244 else 2245 { 2246 /* The last lock byte that covers the current segment */ 2247 bit_count = 0; 2248 while (bit_count < num_bits) 2249 { 2250 /* The last lock bit that is used to lock this segment */ 2251 byte_count += bytes_locked_per_bit; 2252 if (byte_count >= upper_offset) 2253 { 2254 *p_end_byte = num_dynamic_locks; 2255 total_bits += (bit_count + 1); 2256 break; 2257 } 2258 bit_count++; 2259 } 2260 } 2261 } 2262 return total_bits; 2263} 2264 2265/******************************************************************************* 2266** 2267** Function rw_t2t_update_lock_attributes 2268** 2269** Description This function will check if the tag index passed as 2270** argument is a locked byte and return TRUE or FALSE 2271** 2272** Parameters: index, the index of the byte in the tag 2273** 2274** 2275** Returns TRUE, if the specified index in the tag is a locked or 2276** reserved or otp byte 2277** FALSE, otherwise 2278** 2279*******************************************************************************/ 2280static void rw_t2t_update_lock_attributes (void) 2281{ 2282 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2283 UINT8 xx = 0; 2284 UINT8 num_static_lock_bytes = 0; 2285 UINT8 num_dyn_lock_bytes = 0; 2286 UINT8 bits_covered = 0; 2287 UINT8 bytes_covered = 0; 2288 UINT8 block_count = 0; 2289 BOOLEAN b_all_bits_are_locks = TRUE; 2290 UINT8 bytes_locked_per_lock_bit; 2291 UINT8 start_lock_byte; 2292 UINT8 start_lock_bit; 2293 UINT8 end_lock_byte; 2294 UINT8 num_lock_bits; 2295 UINT8 total_bits; 2296 2297 2298 /* Prepare lock_attr for the current segment */ 2299 memset (p_t2t->lock_attr, 0, RW_T2T_SEGMENT_SIZE * sizeof (UINT8)); 2300 2301 block_count = 0; 2302 if (p_t2t->segment == 0) 2303 { 2304 /* Update lock_attributes based on static lock bytes */ 2305 xx = 0; 2306 num_static_lock_bytes = 0; 2307 block_count = 0; 2308 num_lock_bits = TAG_BITS_PER_BYTE; 2309 2310 while (num_static_lock_bytes < T2T_NUM_STATIC_LOCK_BYTES) 2311 { 2312 /* Update lock attribute based on 2 static locks */ 2313 while (xx < num_lock_bits) 2314 { 2315 p_t2t->lock_attr[block_count] = 0x00; 2316 2317 if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] & rw_t2t_mask_bits[xx++]) 2318 { 2319 /* If the bit is set then 1 block is locked */ 2320 p_t2t->lock_attr[block_count] = 0x0F; 2321 } 2322 2323 if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] & rw_t2t_mask_bits[xx++]) 2324 { 2325 /* If the bit is set then 1 block is locked */ 2326 p_t2t->lock_attr[block_count] |= 0xF0; 2327 } 2328 block_count++; 2329 } 2330 num_static_lock_bytes++; 2331 xx = 0; 2332 } 2333 /* UID is always locked, irrespective of the lock value */ 2334 p_t2t->lock_attr[0x00] = 0xFF; 2335 } 2336 2337 /* Get lock bits applicable for the current segment */ 2338 if ((total_bits = rw_t2t_get_lock_bits_for_segment (p_t2t->segment,&start_lock_byte, &start_lock_bit, &end_lock_byte)) != 0) 2339 { 2340 /* update lock_attributes based on current segment using dynamic lock bytes */ 2341 xx = start_lock_bit; 2342 num_dyn_lock_bytes = start_lock_byte; 2343 bits_covered = 0; 2344 bytes_covered = 0; 2345 num_lock_bits = TAG_BITS_PER_BYTE; 2346 p_t2t->lock_attr[block_count] = 0; 2347 2348 while (num_dyn_lock_bytes <= end_lock_byte) 2349 { 2350 bytes_locked_per_lock_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].bytes_locked_per_bit; 2351 /* Find number of bits in the byte are lock bits */ 2352 b_all_bits_are_locks = ((p_t2t->lockbyte[num_dyn_lock_bytes].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].num_bits); 2353 num_lock_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].num_bits % TAG_BITS_PER_BYTE; 2354 2355 while (xx < num_lock_bits) 2356 { 2357 bytes_covered = 0; 2358 while (bytes_covered < bytes_locked_per_lock_bit) 2359 { 2360 if (p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte & rw_t2t_mask_bits[xx]) 2361 { 2362 /* If the bit is set then it is locked */ 2363 p_t2t->lock_attr[block_count] |= 0x01 << bits_covered; 2364 } 2365 bytes_covered++; 2366 bits_covered++; 2367 if (bits_covered == TAG_BITS_PER_BYTE) 2368 { 2369 /* Move to next 8 bytes */ 2370 bits_covered = 0; 2371 block_count++; 2372 /* Assume unlocked before updating using locks */ 2373 if (block_count < RW_T2T_SEGMENT_SIZE) 2374 p_t2t->lock_attr[block_count] = 0; 2375 } 2376 } 2377 xx++; 2378 } 2379 num_dyn_lock_bytes++; 2380 xx = 0; 2381 } 2382 } 2383} 2384 2385/******************************************************************************* 2386** 2387** Function rw_t2t_is_lock_res_byte 2388** 2389** Description This function will check if the tag index passed as 2390** argument is a lock or reserved or otp byte and return 2391** TRUE or FALSE 2392** 2393** Parameters: index, the index of the byte in the tag 2394** 2395** 2396** Returns TRUE, if the specified index in the tag is a locked or 2397** reserved or otp byte 2398** FALSE, otherwise 2399** 2400*******************************************************************************/ 2401static BOOLEAN rw_t2t_is_lock_res_byte (UINT16 index) 2402{ 2403 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2404 2405 p_t2t->segment = (UINT8) (index / RW_T2T_SEGMENT_BYTES); 2406 2407 if (p_t2t->attr_seg != p_t2t->segment) 2408 { 2409 /* Update attributes for the current segment */ 2410 rw_t2t_update_attributes (); 2411 p_t2t->attr_seg = p_t2t->segment; 2412 } 2413 2414 index = index % RW_T2T_SEGMENT_BYTES; 2415 /* Every bit in p_t2t->attr indicates one specific byte of the tag is either a lock/reserved byte or not 2416 * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8 2417 * Find the block and offset for the index (passed as argument) and Check if the offset bit in the 2418 * p_t2t->attr[block/2] is set or not. If the bit is set then it is a lock/reserved byte, otherwise not */ 2419 2420 return ((p_t2t->attr[index /8] & rw_t2t_mask_bits[index % 8]) == 0) ? FALSE:TRUE; 2421} 2422 2423/******************************************************************************* 2424** 2425** Function rw_t2t_is_read_only_byte 2426** 2427** Description This function will check if the tag index passed as 2428** argument is a locked and return 2429** TRUE or FALSE 2430** 2431** Parameters: index, the index of the byte in the tag 2432** 2433** 2434** Returns TRUE, if the specified index in the tag is a locked or 2435** reserved or otp byte 2436** FALSE, otherwise 2437** 2438*******************************************************************************/ 2439static BOOLEAN rw_t2t_is_read_only_byte (UINT16 index) 2440{ 2441 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2442 2443 p_t2t->segment = (UINT8) (index / RW_T2T_SEGMENT_BYTES); 2444 2445 if (p_t2t->lock_attr_seg != p_t2t->segment) 2446 { 2447 /* Update lock attributes for the current segment */ 2448 rw_t2t_update_lock_attributes (); 2449 p_t2t->lock_attr_seg = p_t2t->segment; 2450 } 2451 2452 index = index % RW_T2T_SEGMENT_BYTES; 2453 /* Every bit in p_t2t->lock_attr indicates one specific byte of the tag is a read only byte or read write byte 2454 * So, each array element in p_t2t->lock_attr covers two blocks of the tag as T2 block size is 4 and array element size is 8 2455 * Find the block and offset for the index (passed as argument) and Check if the offset bit in 2456 * p_t2t->lock_attr[block/2] is set or not. If the bit is set then it is a read only byte, otherwise read write byte */ 2457 2458 return ((p_t2t->lock_attr[index /8] & rw_t2t_mask_bits[index % 8]) == 0) ? FALSE:TRUE; 2459} 2460 2461/******************************************************************************* 2462** 2463** Function rw_t2t_set_dynamic_lock_bits 2464** 2465** Description This function will set dynamic lock bits as part of 2466** configuring tag as read only 2467** 2468** Returns 2469** NFC_STATUS_OK, Command sent to set dynamic lock bits 2470** NFC_STATUS_FAILED: otherwise 2471** 2472*******************************************************************************/ 2473tNFC_STATUS rw_t2t_set_dynamic_lock_bits (UINT8 *p_data) 2474{ 2475 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2476 UINT8 write_block[T2T_BLOCK_SIZE]; 2477 UINT16 offset; 2478 UINT16 next_offset; 2479 UINT8 num_bits; 2480 UINT8 next_num_bits; 2481 tNFC_STATUS status = NFC_STATUS_FAILED; 2482 UINT8 num_locks; 2483 UINT8 lock_count; 2484 BOOLEAN b_all_bits_are_locks = TRUE; 2485 2486 num_locks = 0; 2487 2488 memcpy (write_block, p_data, T2T_BLOCK_SIZE); 2489 while (num_locks < p_t2t->num_lockbytes) 2490 { 2491 if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) 2492 { 2493 offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index; 2494 2495 /* Check if all bits are lock bits in the byte */ 2496 b_all_bits_are_locks = ((p_t2t->lockbyte[num_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits); 2497 num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE; 2498 2499 write_block[(UINT8) (offset%T2T_BLOCK_SIZE)] |= tags_pow (2,num_bits) - 1; 2500 lock_count = num_locks + 1; 2501 2502 /* Set all the lock bits in the block using a sing block write command */ 2503 while (lock_count < p_t2t->num_lockbytes) 2504 { 2505 next_offset = p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].offset + p_t2t->lockbyte[lock_count].byte_index; 2506 2507 /* Check if all bits are lock bits in the byte */ 2508 b_all_bits_are_locks = ((p_t2t->lockbyte[lock_count].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits); 2509 next_num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits % TAG_BITS_PER_BYTE; 2510 2511 if (next_offset / T2T_BLOCK_SIZE == offset / T2T_BLOCK_SIZE) 2512 { 2513 write_block[(UINT8) (next_offset % T2T_BLOCK_SIZE)] |= tags_pow (2, next_num_bits) - 1; 2514 } 2515 else 2516 break; 2517 lock_count ++; 2518 } 2519 2520 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS; 2521 /* send WRITE command to set dynamic lock bits */ 2522 if ((status = rw_t2t_write ((UINT16) (offset / T2T_BLOCK_SIZE), write_block)) == NFC_STATUS_OK) 2523 { 2524 while (lock_count > num_locks) 2525 { 2526 /* Set update initiated flag to indicate a write command is sent to set dynamic lock bits of the block */ 2527 p_t2t->lockbyte[lock_count - 1].lock_status = RW_T2T_LOCK_UPDATE_INITIATED; 2528 lock_count --; 2529 } 2530 } 2531 else 2532 status = NFC_STATUS_FAILED; 2533 2534 break; 2535 2536 } 2537 num_locks++; 2538 } 2539 2540 return status; 2541} 2542 2543/******************************************************************************* 2544** 2545** Function rw_t2t_set_lock_tlv 2546** 2547** Description This function will set lock control tlv on the blank 2548** activated type 2 tag based on values read from version block 2549** 2550** Parameters: TAG data memory size 2551** 2552** Returns 2553** NFC_STATUS_OK, Command sent to set Lock TLV 2554** NFC_STATUS_FAILED: otherwise 2555** 2556*******************************************************************************/ 2557tNFC_STATUS rw_t2t_set_lock_tlv (UINT16 addr, UINT8 num_dyn_lock_bits, UINT16 locked_area_size) 2558{ 2559 tNFC_STATUS status = NFC_STATUS_FAILED; 2560 INT8 PageAddr = 0; 2561 INT8 BytePerPage = 0; 2562 INT8 ByteOffset = 0; 2563 UINT8 a; 2564 UINT8 data_block[T2T_BLOCK_SIZE]; 2565 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2566 UINT8 *p; 2567 UINT8 xx; 2568 2569 for (xx = 15; xx >0; xx--) 2570 { 2571 a = (UINT8) (addr / xx); 2572 a += (addr % xx) ? 1:0; 2573 2574 BytePerPage = (INT8) tags_log2 (a); 2575 ByteOffset = (INT8) (addr - xx * tags_pow (2, BytePerPage)); 2576 2577 if (ByteOffset < 16) 2578 { 2579 PageAddr = xx; 2580 break; 2581 } 2582 } 2583 2584 if ((ByteOffset < 16) && (BytePerPage < 16) && (PageAddr < 16)) 2585 { 2586 memset (data_block, 0, T2T_BLOCK_SIZE); 2587 p = data_block; 2588 UINT8_TO_BE_STREAM (p, T2T_TLV_TYPE_LOCK_CTRL); 2589 UINT8_TO_BE_STREAM (p, T2T_TLEN_LOCK_CTRL_TLV); 2590 UINT8_TO_BE_STREAM (p, (PageAddr << 4 | ByteOffset)); 2591 UINT8_TO_BE_STREAM (p, num_dyn_lock_bits); 2592 2593 p_t2t->tlv_value[0] = PageAddr << 4 | ByteOffset; 2594 p_t2t->tlv_value[1] = num_dyn_lock_bits; 2595 p_t2t->tlv_value[2] = (UINT8) (BytePerPage << 4 | tags_log2 (locked_area_size)); 2596 2597 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV; 2598 2599 /* send WRITE-E8 command */ 2600 if ((status = rw_t2t_write (T2T_FIRST_DATA_BLOCK, data_block)) == NFC_STATUS_OK) 2601 { 2602 p_t2t->b_read_data = FALSE; 2603 } 2604 else 2605 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 2606 } 2607 else 2608 status = NFC_STATUS_REJECTED; 2609 2610 return status; 2611} 2612 2613/******************************************************************************* 2614** 2615** Function rw_t2t_set_cc 2616** 2617** Description This function will set Capability Container on the activated 2618** type 2 tag with default values of CC0, CC1, CC4 and specified 2619** CC3 value 2620** 2621** Parameters: CC3 value of the tag 2622** 2623** Returns 2624** NFC_STATUS_OK, Command sent to set CC 2625** NFC_STATUS_FAILED: otherwise 2626** 2627*******************************************************************************/ 2628tNFC_STATUS rw_t2t_set_cc (UINT8 tms) 2629{ 2630 UINT8 cc_block[T2T_BLOCK_SIZE]; 2631 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2632 tNFC_STATUS status = NFC_STATUS_FAILED; 2633 UINT8 *p; 2634 2635 memset (cc_block, 0, T2T_BLOCK_SIZE); 2636 memset (p_t2t->ndef_final_block, 0, T2T_BLOCK_SIZE); 2637 p = cc_block; 2638 2639 /* Prepare Capability Container */ 2640 UINT8_TO_BE_STREAM (p, T2T_CC0_NMN); 2641 UINT8_TO_BE_STREAM (p, T2T_CC1_VNO); 2642 UINT8_TO_BE_STREAM (p, tms); 2643 UINT8_TO_BE_STREAM (p, T2T_CC3_RWA_RW); 2644 2645 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC; 2646 2647 /* send WRITE-E8 command */ 2648 if ((status = rw_t2t_write (T2T_CC_BLOCK, cc_block)) == NFC_STATUS_OK) 2649 { 2650 p_t2t->state = RW_T2T_STATE_FORMAT_TAG; 2651 p_t2t->b_read_hdr = FALSE; 2652 } 2653 else 2654 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 2655 2656 return status; 2657} 2658 2659/******************************************************************************* 2660** 2661** Function rw_t2t_format_tag 2662** 2663** Description This function will format tag based on Manufacturer ID 2664** 2665** Returns 2666** NFC_STATUS_OK, Command sent to format Tag 2667** NFC_STATUS_FAILED: otherwise 2668** 2669*******************************************************************************/ 2670tNFC_STATUS rw_t2t_format_tag (void) 2671{ 2672 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2673 const tT2T_INIT_TAG *p_ret; 2674 UINT8 tms; 2675 tNFC_STATUS status = NFC_STATUS_FAILED; 2676 BOOLEAN b_blank_tag = TRUE; 2677 2678 if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) == NULL) 2679 { 2680 RW_TRACE_WARNING1 ("rw_t2t_format_tag - Unknown Manufacturer ID: %u, Cannot Format the tag!", p_t2t->tag_hdr[0]); 2681 return (NFC_STATUS_REJECTED); 2682 } 2683 2684 if (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != 0) 2685 { 2686 /* If OTP tag has valid NDEF Message, cannot format the tag */ 2687 if ( (p_t2t->ndef_msg_len > 0) 2688 &&(p_ret->b_otp) ) 2689 { 2690 RW_TRACE_WARNING0 ("rw_t2t_format_tag - Cannot Format a OTP tag with NDEF Message!"); 2691 return (NFC_STATUS_FAILED); 2692 } 2693 2694 if ( ((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0) && (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)) 2695 ||((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != 0) && (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) && (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) && (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO)) ) 2696 { 2697 RW_TRACE_WARNING0 ("rw_t2t_format_tag - Tag not blank to Format!"); 2698 return (NFC_STATUS_FAILED); 2699 } 2700 else 2701 { 2702 tms = p_t2t->tag_hdr[T2T_CC2_TMS_BYTE]; 2703 b_blank_tag = FALSE; 2704 } 2705 } 2706 else 2707 tms = p_ret->tms; 2708 2709 memset (p_t2t->tag_data, 0, T2T_READ_DATA_LEN); 2710 2711 if (!b_blank_tag || !p_ret->b_multi_version) 2712 { 2713 status = rw_t2t_set_cc (tms); 2714 } 2715 else if (p_ret->version_block != 0) 2716 { 2717 /* If Version number is not read, READ it now */ 2718 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO; 2719 2720 if ((status = rw_t2t_read (p_ret->version_block)) == NFC_STATUS_OK) 2721 p_t2t->state = RW_T2T_STATE_FORMAT_TAG; 2722 else 2723 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 2724 } 2725 else 2726 { 2727 /* UID block is the version block */ 2728 p_t2t->state = RW_T2T_STATE_FORMAT_TAG; 2729 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO; 2730 rw_t2t_handle_format_tag_rsp (p_t2t->tag_hdr); 2731 } 2732 2733 return status; 2734} 2735 2736/******************************************************************************* 2737** 2738** Function rw_t2t_soft_lock_tag 2739** 2740** Description This function will soft lock the tag after validating CC. 2741** 2742** Returns 2743** NFC_STATUS_OK, Command sent to soft lock the tag 2744** NFC_STATUS_FAILED: otherwise 2745** 2746*******************************************************************************/ 2747tNFC_STATUS rw_t2t_soft_lock_tag (void) 2748{ 2749 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2750 tNFC_STATUS status = NFC_STATUS_FAILED; 2751 UINT8 write_block[T2T_BLOCK_SIZE]; 2752 UINT8 num_locks; 2753 2754 /* If CC block is read and cc3 is soft locked, reject the command */ 2755 if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO) 2756 { 2757 RW_TRACE_ERROR1 ("rw_t2t_soft_lock_tag: Error: Type 2 tag is in Read only state, CC3: %u", p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]); 2758 return (NFC_STATUS_FAILED); 2759 } 2760 2761 if (p_t2t->b_hard_lock) 2762 { 2763 /* Should have performed NDEF Detection on dynamic memory structure tag, before permanently converting to Read only 2764 * Even when no lock control tlv is present, default lock bytes should be present */ 2765 2766 if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != T2T_CC2_TMS_STATIC) && (p_t2t->num_lockbytes == 0)) 2767 { 2768 RW_TRACE_ERROR0 ("rw_t2t_soft_lock_tag: Error: Lock TLV not detected! Cannot hard lock the tag"); 2769 return (NFC_STATUS_FAILED); 2770 } 2771 2772 /* On dynamic memory structure tag, reset all lock bytes status to 'Not Updated' if not in Updated status */ 2773 num_locks = 0; 2774 while (num_locks < p_t2t->num_lockbytes) 2775 { 2776 if (p_t2t->lockbyte[num_locks].lock_status != RW_T2T_LOCK_UPDATED) 2777 p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_NOT_UPDATED; 2778 num_locks++; 2779 } 2780 } 2781 2782 memcpy (write_block, &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], T2T_BLOCK_SIZE); 2783 write_block[(T2T_CC3_RWA_BYTE % T2T_BLOCK_SIZE)] = T2T_CC3_RWA_RO; 2784 2785 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC_RO; 2786 /* First Soft lock the tag */ 2787 if ((status = rw_t2t_write (T2T_CC_BLOCK, write_block)) == NFC_STATUS_OK) 2788 { 2789 p_t2t->state = RW_T2T_STATE_SET_TAG_RO; 2790 p_t2t->b_read_hdr = FALSE; 2791 } 2792 else 2793 { 2794 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 2795 } 2796 return status; 2797} 2798 2799/***************************************************************************** 2800** 2801** Function RW_T2tFormatNDef 2802** 2803** Description 2804** Format Tag content 2805** 2806** Returns 2807** NFC_STATUS_OK, Command sent to format Tag 2808** NFC_STATUS_FAILED: otherwise 2809** 2810*****************************************************************************/ 2811tNFC_STATUS RW_T2tFormatNDef (void) 2812{ 2813 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2814 tNFC_STATUS status = NFC_STATUS_FAILED; 2815 2816 if (p_t2t->state != RW_T2T_STATE_IDLE) 2817 { 2818 RW_TRACE_WARNING1 ("RW_T2tFormatNDef - Tag not initialized/ Busy! State: %u", p_t2t->state); 2819 return (NFC_STATUS_FAILED); 2820 } 2821 2822 if (!p_t2t->b_read_hdr) 2823 { 2824 /* If UID is not read, READ it now */ 2825 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC; 2826 2827 if ((status = rw_t2t_read (0)) == NFC_STATUS_OK) 2828 p_t2t->state = RW_T2T_STATE_FORMAT_TAG; 2829 else 2830 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 2831 } 2832 else 2833 status = rw_t2t_format_tag (); 2834 2835 return status; 2836} 2837 2838/******************************************************************************* 2839** 2840** Function RW_T2tLocateTlv 2841** 2842** Description This function is used to perform TLV detection on a Type 2 2843** tag, and retrieve the tag's TLV attribute information. 2844** 2845** Before using this API, the application must call 2846** RW_SelectTagType to indicate that a Type 2 tag has been 2847** activated. 2848** 2849** Parameters: tlv_type : TLV to detect 2850** 2851** Returns NCI_STATUS_OK, if detection was started. Otherwise, error status. 2852** 2853*******************************************************************************/ 2854tNFC_STATUS RW_T2tLocateTlv (UINT8 tlv_type) 2855{ 2856 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2857 tNFC_STATUS status; 2858 UINT16 block; 2859 2860 if (p_t2t->state != RW_T2T_STATE_IDLE) 2861 { 2862 RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 2863 return (NFC_STATUS_BUSY); 2864 } 2865 2866 if ((tlv_type != TAG_LOCK_CTRL_TLV) && (tlv_type != TAG_MEM_CTRL_TLV) && (tlv_type != TAG_NDEF_TLV) && (tlv_type != TAG_PROPRIETARY_TLV)) 2867 { 2868 RW_TRACE_API1 ("RW_T2tLocateTlv - Cannot search TLV: 0x%02x", tlv_type); 2869 return (NFC_STATUS_FAILED); 2870 } 2871 2872 if ( (tlv_type == TAG_LOCK_CTRL_TLV) 2873 &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC) ) 2874 { 2875 RW_TRACE_API1 ("RW_T2tLocateTlv - No Lock tlv in static structure tag, CC[0]: 0x%02x", p_t2t->tag_hdr[T2T_CC2_TMS_BYTE]); 2876 return (NFC_STATUS_FAILED); 2877 } 2878 2879 if ( (tlv_type == TAG_NDEF_TLV) 2880 &&(p_t2t->b_read_hdr) 2881 &&(p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN) ) 2882 { 2883 RW_TRACE_WARNING3 ("RW_T2tLocateTlv - Invalid NDEF Magic Number!, CC[0]: 0x%02x, CC[1]: 0x%02x, CC[3]: 0x%02x", p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE], p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]); 2884 return (NFC_STATUS_FAILED); 2885 } 2886 2887 p_t2t->work_offset = 0; 2888 p_t2t->tlv_detect = tlv_type; 2889 2890 /* Reset control block variables based on type of tlv to detect */ 2891 if (tlv_type == TAG_LOCK_CTRL_TLV) 2892 { 2893 p_t2t->num_lockbytes = 0; 2894 p_t2t->num_lock_tlvs = 0; 2895 } 2896 else if (tlv_type == TAG_MEM_CTRL_TLV) 2897 { 2898 p_t2t->num_mem_tlvs = 0; 2899 } 2900 else if (tlv_type == TAG_NDEF_TLV) 2901 { 2902 p_t2t->ndef_msg_offset = 0; 2903 p_t2t->num_lockbytes = 0; 2904 p_t2t->num_lock_tlvs = 0; 2905 p_t2t->num_mem_tlvs = 0; 2906 p_t2t->ndef_msg_len = 0; 2907 p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED; 2908 } 2909 else 2910 { 2911 p_t2t->prop_msg_len = 0; 2912 } 2913 2914 if (!p_t2t->b_read_hdr) 2915 { 2916 /* First read CC block */ 2917 block = 0; 2918 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC; 2919 } 2920 else 2921 { 2922 /* Read first data block */ 2923 block = T2T_FIRST_DATA_BLOCK; 2924 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT; 2925 } 2926 2927 /* Start reading tag, looking for the specified TLV */ 2928 if ((status = rw_t2t_read ((UINT16) block)) == NFC_STATUS_OK) 2929 { 2930 p_t2t->state = RW_T2T_STATE_DETECT_TLV; 2931 } 2932 else 2933 { 2934 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 2935 } 2936 return (status); 2937} 2938 2939/******************************************************************************* 2940** 2941** Function RW_T2tDetectNDef 2942** 2943** Description This function is used to perform NDEF detection on a Type 2 2944** tag, and retrieve the tag's NDEF attribute information. 2945** 2946** Before using this API, the application must call 2947** RW_SelectTagType to indicate that a Type 2 tag has been 2948** activated. 2949** 2950** Parameters: none 2951** 2952** Returns NCI_STATUS_OK,if detect op started.Otherwise,error status. 2953** 2954*******************************************************************************/ 2955tNFC_STATUS RW_T2tDetectNDef (void) 2956{ 2957 return RW_T2tLocateTlv (TAG_NDEF_TLV); 2958} 2959 2960/******************************************************************************* 2961** 2962** Function RW_T2tReadNDef 2963** 2964** Description Retrieve NDEF contents from a Type2 tag. 2965** 2966** The RW_T2T_NDEF_READ_EVT event is used to notify the 2967** application after reading the NDEF message. 2968** 2969** Before using this API, the RW_T2tDetectNDef function must 2970** be called to verify that the tag contains NDEF data, and to 2971** retrieve the NDEF attributes. 2972** 2973** Internally, this command will be separated into multiple Tag2 2974** Read commands (if necessary) - depending on the NDEF Msg size 2975** 2976** Parameters: p_buffer: The buffer into which to read the NDEF message 2977** buf_len: The length of the buffer 2978** 2979** Returns NCI_STATUS_OK, if read was started. Otherwise, error status. 2980** 2981*******************************************************************************/ 2982tNFC_STATUS RW_T2tReadNDef (UINT8 *p_buffer, UINT16 buf_len) 2983{ 2984 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 2985 tNFC_STATUS status = NFC_STATUS_OK; 2986 UINT16 block; 2987 2988 if (p_t2t->state != RW_T2T_STATE_IDLE) 2989 { 2990 RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 2991 return (NFC_STATUS_FAILED); 2992 } 2993 2994 if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) 2995 { 2996 RW_TRACE_ERROR0 ("RW_T2tReadNDef - Error: NDEF detection not performed yet"); 2997 return (NFC_STATUS_FAILED); 2998 } 2999 3000 if (buf_len < p_t2t->ndef_msg_len) 3001 { 3002 RW_TRACE_WARNING2 ("RW_T2tReadNDef - buffer size: %u less than NDEF msg sise: %u", buf_len, p_t2t->ndef_msg_len); 3003 return (NFC_STATUS_FAILED); 3004 } 3005 3006 if (!p_t2t->ndef_msg_len) 3007 { 3008 RW_TRACE_WARNING1 ("RW_T2tReadNDef - NDEF Message length is zero ", p_t2t->ndef_msg_len); 3009 return (NFC_STATUS_NOT_INITIALIZED); 3010 } 3011 3012 p_t2t->p_ndef_buffer = p_buffer; 3013 p_t2t->work_offset = 0; 3014 3015 block = (UINT16) (p_t2t->ndef_msg_offset / T2T_BLOCK_LEN); 3016 block -= block % T2T_READ_BLOCKS; 3017 3018 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 3019 3020 if ( (block == T2T_FIRST_DATA_BLOCK) 3021 &&(p_t2t->b_read_data) ) 3022 { 3023 p_t2t->state = RW_T2T_STATE_READ_NDEF; 3024 p_t2t->block_read = T2T_FIRST_DATA_BLOCK; 3025 rw_t2t_handle_ndef_read_rsp (p_t2t->tag_data); 3026 } 3027 else 3028 { 3029 /* Start reading NDEF Message */ 3030 if ((status = rw_t2t_read (block)) == NFC_STATUS_OK) 3031 { 3032 p_t2t->state = RW_T2T_STATE_READ_NDEF; 3033 } 3034 } 3035 3036 return (status); 3037} 3038 3039/******************************************************************************* 3040** 3041** Function RW_T2tWriteNDef 3042** 3043** Description Write NDEF contents to a Type2 tag. 3044** 3045** Before using this API, the RW_T2tDetectNDef 3046** function must be called to verify that the tag contains 3047** NDEF data, and to retrieve the NDEF attributes. 3048** 3049** The RW_T2T_NDEF_WRITE_EVT callback event will be used to 3050** notify the application of the response. 3051** 3052** Internally, this command will be separated into multiple Tag2 3053** Write commands (if necessary) - depending on the NDEF Msg size 3054** 3055** Parameters: msg_len: The length of the buffer 3056** p_msg: The NDEF message to write 3057** 3058** Returns NCI_STATUS_OK,if write was started. Otherwise, error status 3059** 3060*******************************************************************************/ 3061tNFC_STATUS RW_T2tWriteNDef (UINT16 msg_len, UINT8 *p_msg) 3062{ 3063 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 3064 UINT16 block; 3065 const tT2T_INIT_TAG *p_ret; 3066 3067 tNFC_STATUS status = NFC_STATUS_OK; 3068 3069 if (p_t2t->state != RW_T2T_STATE_IDLE) 3070 { 3071 RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 3072 return (NFC_STATUS_FAILED); 3073 } 3074 3075 if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) 3076 { 3077 RW_TRACE_ERROR1 ("RW_T2tWriteNDef - Write access not granted - CC3: %u", p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]); 3078 return (NFC_STATUS_REFUSED); 3079 } 3080 3081 if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) 3082 { 3083 RW_TRACE_ERROR0 ("RW_T2tWriteNDef - Error: NDEF detection not performed!"); 3084 return (NFC_STATUS_FAILED); 3085 } 3086 3087 /* Check if there is enough memory on the tag */ 3088 if (msg_len > p_t2t->max_ndef_msg_len) 3089 { 3090 RW_TRACE_ERROR1 ("RW_T2tWriteNDef - Cannot write NDEF of size greater than %u bytes", p_t2t->max_ndef_msg_len); 3091 return (NFC_STATUS_FAILED); 3092 } 3093 3094 /* If OTP tag and tag has valid NDEF Message, stop writting new NDEF Message as it may corrupt the tag */ 3095 if ( (p_t2t->ndef_msg_len > 0) 3096 &&((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL) 3097 &&(p_ret->b_otp) ) 3098 { 3099 RW_TRACE_WARNING0 ("RW_T2tWriteNDef - Cannot Overwrite NDEF Message on a OTP tag!"); 3100 return (NFC_STATUS_FAILED); 3101 } 3102 p_t2t->p_new_ndef_buffer = p_msg; 3103 p_t2t->new_ndef_msg_len = msg_len; 3104 p_t2t->work_offset = 0; 3105 3106 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK; 3107 /* Read first NDEF Block before updating NDEF */ 3108 3109 block = (UINT16) (p_t2t->ndef_header_offset / T2T_BLOCK_LEN); 3110 3111 if ( (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS)) 3112 &&(p_t2t->b_read_data) ) 3113 { 3114 p_t2t->state = RW_T2T_STATE_WRITE_NDEF; 3115 p_t2t->block_read = block; 3116 rw_t2t_handle_ndef_write_rsp (&p_t2t->tag_data[(block - T2T_FIRST_DATA_BLOCK) * T2T_BLOCK_LEN]); 3117 } 3118 else 3119 { 3120 if ((status = rw_t2t_read (block)) == NFC_STATUS_OK) 3121 p_t2t->state = RW_T2T_STATE_WRITE_NDEF; 3122 else 3123 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 3124 } 3125 3126 return status; 3127} 3128 3129/******************************************************************************* 3130** 3131** Function RW_T2tSetTagReadOnly 3132** 3133** Description This function can be called to set T2 tag as read only. 3134** 3135** Parameters: b_hard_lock: To indicate hard lock the tag or not 3136** 3137** Returns NCI_STATUS_OK, if setting tag as read only was started. 3138** Otherwise, error status. 3139** 3140*******************************************************************************/ 3141tNFC_STATUS RW_T2tSetTagReadOnly (BOOLEAN b_hard_lock) 3142{ 3143 tNFC_STATUS status = NFC_STATUS_FAILED; 3144 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 3145 3146 if (p_t2t->state != RW_T2T_STATE_IDLE) 3147 { 3148 RW_TRACE_ERROR1 ("RW_T2tSetTagReadOnly: Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 3149 return (NFC_STATUS_FAILED); 3150 } 3151 3152 p_t2t->b_hard_lock = b_hard_lock; 3153 3154 if (!p_t2t->b_read_hdr) 3155 { 3156 /* Read CC block before configuring tag as Read only */ 3157 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC; 3158 if ((status = rw_t2t_read ((UINT16) 0)) == NFC_STATUS_OK) 3159 { 3160 p_t2t->state = RW_T2T_STATE_SET_TAG_RO; 3161 } 3162 else 3163 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 3164 } 3165 else 3166 status = rw_t2t_soft_lock_tag (); 3167 3168 return status; 3169} 3170 3171#endif /* (defined ((RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) */ 3172 3173#endif /* (NFC_INCLUDED == TRUE) */ 3174