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