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