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