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