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