rw_t1t_ndef.c revision 5c65c3a0f42e174e47fecd4e569606003217ff4e
1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/****************************************************************************** 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Copyright (C) 2010-2013 Broadcom Corporation 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Licensed under the Apache License, Version 2.0 (the "License"); 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * you may not use this file except in compliance with the License. 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * You may obtain a copy of the License at: 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * http://www.apache.org/licenses/LICENSE-2.0 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Unless required by applicable law or agreed to in writing, software 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * distributed under the License is distributed on an "AS IS" BASIS, 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * See the License for the specific language governing permissions and 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * limitations under the License. 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ******************************************************************************/ 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/****************************************************************************** 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * This file contains the implementation for Type 1 tag NDEF operation in 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Reader/Writer mode. 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ******************************************************************************/ 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <string.h> 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "nfc_target.h" 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if (NFC_INCLUDED == TRUE) 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "nfc_api.h" 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "nci_hmsgs.h" 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "rw_api.h" 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "rw_int.h" 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "nfc_int.h" 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "gki.h" 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/* Local Functions */ 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic tNFC_STATUS rw_t1t_handle_rall_rsp (BOOLEAN *p_notify,UINT8 *p_data); 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data); 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data); 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic tNFC_STATUS rw_t1t_handle_read_rsp (BOOLEAN *p_callback, UINT8 *p_data); 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data); 45static tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data); 46static tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data); 47static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp (void); 48static tNFC_STATUS rw_t1t_ndef_write_first_block (void); 49static tNFC_STATUS rw_t1t_next_ndef_write_block (void); 50static tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len); 51static tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block); 52static UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len); 53static UINT8 rw_t1t_get_ndef_flags (void); 54static UINT16 rw_t1t_get_ndef_max_size (void); 55static BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index); 56static BOOLEAN rw_t1t_is_read_only_byte (UINT16 index); 57static UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte); 58static void rw_t1t_update_attributes (void); 59static void rw_t1t_update_lock_attributes (void); 60static void rw_t1t_extract_lock_bytes (UINT8 *p_data); 61static void rw_t1t_update_tag_state (void); 62 63const UINT8 rw_t1t_mask_bits[8] = 64{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 65 66/******************************************************************************* 67** 68** Function rw_t1t_handle_rsp 69** 70** Description This function handles the response received for all commands 71** sent to tag 72** 73** Returns event to be sent to application 74** 75*******************************************************************************/ 76tRW_EVENT rw_t1t_handle_rsp (const tT1T_CMD_RSP_INFO * p_info, BOOLEAN *p_notify, UINT8 *p_data, tNFC_STATUS *p_status) 77{ 78 tRW_EVENT rw_event; 79 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 80 UINT8 adds; 81 82 if( (p_t1t->state == RW_T1T_STATE_READ) 83 ||(p_t1t->state == RW_T1T_STATE_WRITE) ) 84 { 85 return t1t_info_to_evt (p_info); 86 } 87 88 rw_event = rw_t1t_info_to_event (p_info); 89 90 if (p_info->opcode == T1T_CMD_RALL) 91 { 92 *p_status = rw_t1t_handle_rall_rsp (p_notify,p_data); 93 } 94 else if (p_info->opcode == T1T_CMD_RSEG) 95 { 96 adds = *p_data; 97 if (adds == 0) 98 { 99 p_t1t->b_rseg = TRUE; 100 rw_t1t_update_tag_state (); 101 rw_t1t_update_attributes (); 102 rw_t1t_update_lock_attributes (); 103 memcpy (p_t1t->mem, (UINT8 *) (p_data + T1T_ADD_LEN), T1T_SEGMENT_SIZE); 104 } 105 *p_status = rw_t1t_handle_dyn_read_rsp (p_notify,p_data); 106 } 107 else if (p_info->opcode == T1T_CMD_READ8) 108 { 109 *p_status = rw_t1t_handle_dyn_read_rsp (p_notify,p_data); 110 } 111 else 112 { 113 *p_status = rw_t1t_handle_write_rsp (p_notify,p_data); 114 } 115 return rw_event; 116} 117 118/******************************************************************************* 119** 120** Function rw_t1t_info_to_event 121** 122** Description This function returns RW event code based on the current state 123** 124** Returns RW event code 125** 126*******************************************************************************/ 127tRW_EVENT rw_t1t_info_to_event (const tT1T_CMD_RSP_INFO * p_info) 128{ 129 tRW_EVENT rw_event; 130 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 131 132 switch (p_t1t->state) 133 { 134 case RW_T1T_STATE_TLV_DETECT: 135 if (p_t1t->tlv_detect == TAG_NDEF_TLV) 136 rw_event = RW_T1T_NDEF_DETECT_EVT; 137 else 138 rw_event = RW_T1T_TLV_DETECT_EVT; 139 break; 140 141 case RW_T1T_STATE_READ_NDEF: 142 rw_event = RW_T1T_NDEF_READ_EVT; 143 break; 144 145 case RW_T1T_STATE_WRITE_NDEF: 146 rw_event = RW_T1T_NDEF_WRITE_EVT; 147 break; 148 149 case RW_T1T_STATE_SET_TAG_RO: 150 rw_event = RW_T1T_SET_TAG_RO_EVT; 151 break; 152 153 case RW_T1T_STATE_CHECK_PRESENCE: 154 rw_event = RW_T1T_PRESENCE_CHECK_EVT; 155 break; 156 157 case RW_T1T_STATE_FORMAT_TAG: 158 rw_event = RW_T1T_FORMAT_CPLT_EVT; 159 break; 160 161 default: 162 rw_event = t1t_info_to_evt (p_info); 163 break; 164 } 165 return rw_event; 166} 167 168/******************************************************************************* 169** 170** Function rw_t1t_extract_lock_bytes 171** 172** Description This function will extract lock bytes if any present in the 173** response data 174** 175** Parameters p_data: Data bytes in the response of RSEG/READ8/RALL command 176** 177** Returns None 178** 179*******************************************************************************/ 180void rw_t1t_extract_lock_bytes (UINT8 *p_data) 181{ 182 UINT16 end; 183 UINT16 start; 184 UINT8 num_locks; 185 UINT16 lock_offset = 0; 186 UINT16 offset; 187 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 188 tT1T_CMD_RSP_INFO *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info; 189 190 num_locks = 0; 191 /* Based on the Command used to read Tag, calculate the offset of the tag read */ 192 if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG) 193 { 194 start = p_t1t->segment * T1T_SEGMENT_SIZE; 195 end = start + T1T_SEGMENT_SIZE; 196 } 197 else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8) 198 { 199 start = p_t1t->block_read * T1T_BLOCK_SIZE; 200 end = start + T1T_BLOCK_SIZE; 201 } 202 else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL) 203 { 204 start = 0; 205 end = T1T_STATIC_SIZE; 206 } 207 else 208 return; 209 210 /* Collect lock bytes that are present in the part of the data read from Tag */ 211 while (num_locks < p_t1t->num_lockbytes) 212 { 213 if (p_t1t->lockbyte[num_locks].b_lock_read == FALSE) 214 { 215 /* Get the exact offset of the dynamic lock byte in the tag */ 216 offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index; 217 if ( (offset < end) 218 &&(offset >= start) ) 219 220 { 221 /* This dynamic lock byte is in the response */ 222 if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG) 223 { 224 lock_offset = (offset % T1T_SEGMENT_SIZE); 225 } 226 else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8) 227 { 228 lock_offset = (offset % T1T_BLOCK_SIZE); 229 } 230 else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL) 231 { 232 lock_offset = offset; 233 } 234 235 p_t1t->lockbyte[num_locks].lock_byte = p_data[lock_offset]; 236 p_t1t->lockbyte[num_locks].b_lock_read = TRUE; 237 } 238 else 239 break; 240 } 241 num_locks++; 242 } 243} 244 245/******************************************************************************* 246** 247** Function rw_t1t_update_tag_attributes 248** 249** Description This function will update tag attributes based on cc, ndef 250** message length 251** 252** Returns None 253** 254*******************************************************************************/ 255void rw_t1t_update_tag_state (void) 256{ 257 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 258 259 /* Set Tag state based on CC value and NDEF Message length */ 260 if ( ((p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN) || (p_t1t->mem[T1T_CC_NMN_BYTE] == 0)) 261 &&((p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_VNO) || (p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_LEGACY_VNO)) 262 &&((p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW) || (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO)) ) 263 { 264 /* Valid CC value, so Tag is initialized */ 265 if (p_t1t->ndef_msg_len > 0) 266 { 267 if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO) 268 { 269 /* NDEF Message presence, CC indication sets Tag as READ ONLY */ 270 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_ONLY; 271 } 272 else if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW) 273 { 274 /* NDEF Message presence, CC indication sets Tag as READ WRITE */ 275 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE; 276 } 277 } 278 else 279 { 280 /* If NDEF is not yet detected then Tag remains in Initialized state 281 * after NDEF Detection the Tag state may be updated */ 282 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED; 283 } 284 } 285 else 286 { 287 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_UNKNOWN; 288 } 289} 290 291/******************************************************************************* 292** 293** Function rw_t1t_read_locks 294** 295** Description This function will send command to read next unread locks 296** 297** Returns NFC_STATUS_OK, if all locks are read successfully 298** NFC_STATUS_FAILED, if reading locks failed 299** NFC_STATUS_CONTINUE, if reading locks is in progress 300** 301*******************************************************************************/ 302tNFC_STATUS rw_t1t_read_locks (void) 303{ 304 UINT8 num_locks = 0; 305 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 306 tNFC_STATUS status = NFC_STATUS_CONTINUE; 307 UINT16 offset; 308 309 while (num_locks < p_t1t->num_lockbytes) 310 { 311 if (p_t1t->lockbyte[num_locks].b_lock_read == FALSE) 312 { 313 offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index; 314 if (offset < T1T_STATIC_SIZE) 315 { 316 p_t1t->lockbyte[num_locks].lock_byte = p_t1t->mem[offset]; 317 p_t1t->lockbyte[num_locks].b_lock_read = TRUE; 318 } 319 else if (offset < (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE) 320 { 321 /* send READ8 command */ 322 p_t1t->block_read = (UINT8) (offset/T1T_BLOCK_SIZE); 323 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK) 324 { 325 /* Reading Locks */ 326 status = NFC_STATUS_CONTINUE; 327 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_LOCKS; 328 } 329 break; 330 } 331 else 332 { 333 /* Read locks failed */ 334 status = NFC_STATUS_FAILED; 335 break; 336 } 337 } 338 num_locks++; 339 } 340 if (num_locks == p_t1t->num_lockbytes) 341 { 342 /* All locks are read */ 343 status = NFC_STATUS_OK; 344 } 345 346 return status; 347} 348 349/******************************************************************************* 350** 351** Function rw_t1t_handle_write_rsp 352** 353** Description This function handles response received for WRITE_E8, 354** WRITE_NE8, WRITE_E, WRITE_NE commands 355** 356** Returns status of the current NDEF/TLV Operation 357** 358*******************************************************************************/ 359static tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data) 360{ 361 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 362 tNFC_STATUS status = NFC_STATUS_OK; 363 UINT8 num_locks; 364 UINT8 lock_count; 365 UINT8 value; 366 UINT8 addr; 367 UINT8 write_block[T1T_BLOCK_SIZE]; 368 UINT16 offset; 369 UINT16 next_offset; 370 UINT8 num_bits; 371 UINT8 next_num_bits; 372 373 *p_notify = FALSE; 374 375 switch (p_t1t->state) 376 { 377 case RW_T1T_STATE_WRITE: 378 *p_notify = TRUE; 379 break; 380 381 case RW_T1T_STATE_FORMAT_TAG: 382 if (p_t1t->substate == RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF) 383 { 384 if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) 385 *p_notify = TRUE; 386 else 387 { 388 if (p_t1t->work_offset < (T1T_BLOCK_SIZE - 1)) 389 { 390 p_t1t->work_offset++; 391 /* send WRITE-E command */ 392 RW_T1T_BLD_ADD ((addr), 1, (UINT8) p_t1t->work_offset); 393 394 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[(UINT8) p_t1t->work_offset])) != NFC_STATUS_OK) 395 *p_notify = TRUE; 396 } 397 else 398 *p_notify = TRUE; 399 } 400 401 } 402 else 403 { 404 /* send WRITE-E8 command */ 405 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 2, p_t1t->ndef_final_block)) != NFC_STATUS_OK) 406 *p_notify = TRUE; 407 else 408 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF; 409 } 410 break; 411 412 case RW_T1T_STATE_SET_TAG_RO: 413 switch (p_t1t->substate) 414 { 415 case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO: 416 417 if (!p_t1t->b_hard_lock) 418 { 419 status = NFC_STATUS_OK; 420 *p_notify = TRUE; 421 break; 422 } 423 424 if ((p_t1t->hr[0] & 0x0F) != 1) 425 { 426 memset (write_block,0,T1T_BLOCK_SIZE); 427 write_block[0] = 0xFF; 428 write_block[1] = 0xFF; 429 430 /* send WRITE-NE8 command */ 431 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, T1T_LOCK_BLOCK, write_block)) != NFC_STATUS_OK) 432 *p_notify = TRUE; 433 else 434 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS; 435 } 436 else 437 { 438 /* send WRITE-NE command */ 439 RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (0)); 440 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK) 441 *p_notify = TRUE; 442 else 443 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS; 444 } 445 break; 446 447 case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS: 448 449 /* send WRITE-NE command */ 450 RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (1)); 451 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK) 452 *p_notify = TRUE; 453 else 454 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS; 455 456 break; 457 458 case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS: 459 num_locks = 0; 460 while (num_locks < p_t1t->num_lockbytes) 461 { 462 if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_UPDATE_INITIATED) 463 { 464 p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATED; 465 } 466 num_locks++; 467 } 468 469 num_locks = 0; 470 while (num_locks < p_t1t->num_lockbytes) 471 { 472 if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_NOT_UPDATED) 473 { 474 offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index; 475 num_bits = ((p_t1t->lockbyte[num_locks].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits % 8; 476 477 if ((p_t1t->hr[0] & 0x0F) != 1) 478 { 479 memset (write_block,0,T1T_BLOCK_SIZE); 480 481 write_block[(UINT8) (offset%T1T_BLOCK_SIZE)] |= tags_pow (2,num_bits) - 1; 482 lock_count = num_locks + 1; 483 while (lock_count < p_t1t->num_lockbytes) 484 { 485 next_offset = p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].offset + p_t1t->lockbyte[lock_count].byte_index; 486 next_num_bits = ((p_t1t->lockbyte[lock_count].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits % 8; 487 488 if (next_offset/T1T_BLOCK_SIZE == offset/T1T_BLOCK_SIZE) 489 { 490 write_block[(UINT8) (next_offset%T1T_BLOCK_SIZE)] |= tags_pow (2,next_num_bits) - 1; 491 } 492 else 493 break; 494 lock_count ++; 495 } 496 497 /* send WRITE-NE8 command */ 498 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, (UINT8) (offset/T1T_BLOCK_SIZE), write_block)) == NFC_STATUS_OK) 499 { 500 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS; 501 while (lock_count > num_locks) 502 { 503 p_t1t->lockbyte[lock_count - 1].lock_status = RW_T1T_LOCK_UPDATE_INITIATED; 504 lock_count --; 505 } 506 } 507 else 508 *p_notify = TRUE; 509 } 510 else 511 { 512 /* send WRITE-NE command */ 513 RW_T1T_BLD_ADD ((addr), ((UINT8) (offset/T1T_BLOCK_SIZE)), ((UINT8) (offset%T1T_BLOCK_SIZE))); 514 value = (UINT8) (tags_pow (2,num_bits) - 1); 515 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, value)) == NFC_STATUS_OK) 516 { 517 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS; 518 p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATE_INITIATED; 519 } 520 else 521 *p_notify = TRUE; 522 } 523 break; 524 } 525 num_locks++; 526 } 527 if (num_locks == p_t1t->num_lockbytes) 528 { 529 rw_t1t_update_lock_attributes (); 530 status = NFC_STATUS_OK; 531 *p_notify = TRUE; 532 } 533 break; 534 } 535 break; 536 537 case RW_T1T_STATE_WRITE_NDEF: 538 switch (p_t1t->substate) 539 { 540 case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF: 541 p_t1t->ndef_msg_len = p_t1t->new_ndef_msg_len; 542 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE; 543 *p_notify = TRUE; 544 break; 545 546 case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED: 547 status = rw_t1t_handle_ndef_write_rsp (p_data); 548 if (status == NFC_STATUS_OK) 549 { 550 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF; 551 } 552 else if (status == NFC_STATUS_FAILED) 553 { 554 /* Send Negative response to upper layer */ 555 *p_notify = TRUE; 556 } 557 break; 558 559 case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE: 560 status = rw_t1t_handle_ndef_write_rsp (p_data); 561 562 if (status == NFC_STATUS_FAILED) 563 { 564 /* Send Negative response to upper layer */ 565 *p_notify = TRUE; 566 } 567 else if (status == NFC_STATUS_OK) 568 { 569 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED; 570 } 571 break; 572 573 case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF: 574 status = rw_t1t_handle_ndef_write_rsp (p_data); 575 if (status == NFC_STATUS_FAILED) 576 { 577 /* Send Negative response to upper layer */ 578 *p_notify = TRUE; 579 } 580 else if (status == NFC_STATUS_CONTINUE) 581 { 582 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_WRITE; 583 } 584 else 585 { 586 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED; 587 } 588 break; 589 } 590 break; 591 } 592 return status; 593} 594 595/******************************************************************************* 596** 597** Function rw_t1t_handle_read_rsp 598** 599** Description This function handle the data bytes excluding ADD(S)/ADD8 field 600** received as part of RSEG, RALL, READ8 command response 601** 602** Returns status of the current NDEF/TLV Operation 603** 604*******************************************************************************/ 605tNFC_STATUS rw_t1t_handle_read_rsp (BOOLEAN *p_notify, UINT8 *p_data) 606{ 607 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 608 tNFC_STATUS status = NFC_STATUS_OK; 609 tRW_DETECT_NDEF_DATA ndef_data; 610 tRW_DETECT_TLV_DATA tlv_data; 611 UINT8 count; 612 tRW_READ_DATA evt_data; 613 614 *p_notify = FALSE; 615 /* Handle the response based on the current state */ 616 switch (p_t1t->state) 617 { 618 case RW_T1T_STATE_READ: 619 *p_notify = TRUE; 620 break; 621 622 case RW_T1T_STATE_READ_NDEF: 623 status = rw_t1t_handle_ndef_rall_rsp (); 624 if (status != NFC_STATUS_CONTINUE) 625 { 626 evt_data.status = status; 627 evt_data.p_data = NULL; 628 rw_t1t_handle_op_complete (); 629 (*rw_cb.p_cback) (RW_T1T_NDEF_READ_EVT, (tRW_DATA *) &evt_data); 630 } 631 break; 632 633 case RW_T1T_STATE_TLV_DETECT: 634 switch (p_t1t->substate) 635 { 636 case RW_T1T_SUBSTATE_WAIT_READ_LOCKS: 637 status = rw_t1t_read_locks (); 638 if (status != NFC_STATUS_CONTINUE) 639 { 640 rw_t1t_update_lock_attributes (); 641 /* Send positive response to upper layer */ 642 if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) 643 { 644 tlv_data.protocol = NFC_PROTOCOL_T1T; 645 tlv_data.num_bytes = p_t1t->num_lockbytes; 646 tlv_data.status = status; 647 rw_t1t_handle_op_complete (); 648 (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data); 649 } 650 else if (p_t1t->tlv_detect == TAG_NDEF_TLV) 651 { 652 ndef_data.protocol = NFC_PROTOCOL_T1T; 653 ndef_data.flags = rw_t1t_get_ndef_flags (); 654 ndef_data.flags |= RW_NDEF_FL_FORMATED; 655 ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size (); 656 ndef_data.cur_size = p_t1t->ndef_msg_len; 657 658 if (ndef_data.max_size < ndef_data.cur_size) 659 { 660 ndef_data.flags |= RW_NDEF_FL_READ_ONLY; 661 ndef_data.max_size = ndef_data.cur_size; 662 } 663 664 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) 665 { 666 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE; 667 if (status == NFC_STATUS_OK) 668 ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE; 669 } 670 ndef_data.status = status; 671 rw_t1t_handle_op_complete (); 672 (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data); 673 } 674 } 675 break; 676 677 case RW_T1T_SUBSTATE_NONE: 678 if (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) 679 { 680 tlv_data.status = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem); 681 tlv_data.protocol = NFC_PROTOCOL_T1T; 682 tlv_data.num_bytes = 0; 683 count = 0; 684 while (count < p_t1t->num_mem_tlvs) 685 { 686 tlv_data.num_bytes += p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes; 687 count++; 688 } 689 rw_t1t_handle_op_complete (); 690 /* Send response to upper layer */ 691 (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data); 692 } 693 else if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) 694 { 695 tlv_data.status = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem); 696 tlv_data.protocol = NFC_PROTOCOL_T1T; 697 tlv_data.num_bytes = p_t1t->num_lockbytes; 698 699 if (tlv_data.status == NFC_STATUS_FAILED) 700 { 701 rw_t1t_handle_op_complete (); 702 703 /* Send Negative response to upper layer */ 704 (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *)&tlv_data); 705 } 706 else 707 { 708 rw_t1t_extract_lock_bytes (p_data); 709 status = rw_t1t_read_locks (); 710 if (status != NFC_STATUS_CONTINUE) 711 { 712 /* Send positive response to upper layer */ 713 tlv_data.status = status; 714 rw_t1t_handle_op_complete (); 715 716 (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data); 717 } 718 } 719 } 720 else if (p_t1t->tlv_detect == TAG_NDEF_TLV) 721 { 722 ndef_data.protocol = NFC_PROTOCOL_T1T; 723 ndef_data.flags = rw_t1t_get_ndef_flags (); 724 725 if (p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN) 726 { 727 ndef_data.status = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem); 728 729 ndef_data.cur_size = p_t1t->ndef_msg_len; 730 if (ndef_data.status == NFC_STATUS_FAILED) 731 { 732 ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size (); 733 if (ndef_data.max_size < ndef_data.cur_size) 734 { 735 ndef_data.flags |= RW_NDEF_FL_READ_ONLY; 736 ndef_data.max_size = ndef_data.cur_size; 737 } 738 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) 739 { 740 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE; 741 } 742 /* Send Negative response to upper layer */ 743 rw_t1t_handle_op_complete (); 744 745 (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data); 746 } 747 else 748 { 749 ndef_data.flags |= RW_NDEF_FL_FORMATED; 750 rw_t1t_extract_lock_bytes (p_data); 751 status = rw_t1t_read_locks (); 752 if (status != NFC_STATUS_CONTINUE) 753 { 754 ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size (); 755 if (ndef_data.max_size < ndef_data.cur_size) 756 { 757 ndef_data.flags |= RW_NDEF_FL_READ_ONLY; 758 ndef_data.max_size = ndef_data.cur_size; 759 } 760 761 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) 762 { 763 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE; 764 if (status == NFC_STATUS_OK) 765 ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE; 766 } 767 /* Send positive response to upper layer */ 768 ndef_data.status = status; 769 rw_t1t_handle_op_complete (); 770 771 (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data); 772 } 773 } 774 } 775 else 776 { 777 /* Send Negative response to upper layer */ 778 ndef_data.status = NFC_STATUS_FAILED; 779 ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size (); 780 ndef_data.cur_size = p_t1t->ndef_msg_len; 781 if (ndef_data.max_size < ndef_data.cur_size) 782 { 783 ndef_data.flags |= RW_NDEF_FL_READ_ONLY; 784 ndef_data.max_size = ndef_data.cur_size; 785 } 786 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) 787 { 788 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE; 789 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE; 790 } 791 rw_t1t_handle_op_complete (); 792 793 (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data); 794 } 795 } 796 break; 797 } 798 break; 799 } 800 return status; 801} 802 803/******************************************************************************* 804** 805** Function rw_t1t_handle_dyn_read_rsp 806** 807** Description This function handles response received for READ8, RSEG 808** commands based on the current state 809** 810** Returns status of the current NDEF/TLV Operation 811** 812*******************************************************************************/ 813static tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data) 814{ 815 tNFC_STATUS status = NFC_STATUS_OK; 816 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 817 818 *p_notify = FALSE; 819 820 p_data += T1T_ADD_LEN; 821 822 rw_t1t_extract_lock_bytes (p_data); 823 824 if (p_t1t->state == RW_T1T_STATE_READ_NDEF) 825 { 826 status = rw_t1t_handle_ndef_read_rsp (p_data); 827 if ( (status == NFC_STATUS_FAILED) 828 ||(status == NFC_STATUS_OK) ) 829 { 830 /* Send response to upper layer */ 831 *p_notify = TRUE; 832 } 833 } 834 else if (p_t1t->state == RW_T1T_STATE_WRITE_NDEF) 835 { 836 status = rw_t1t_handle_ndef_write_rsp (p_data); 837 if (status == NFC_STATUS_FAILED) 838 { 839 /* Send response to upper layer */ 840 *p_notify = TRUE; 841 } 842 else if (status == NFC_STATUS_CONTINUE) 843 { 844 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF; 845 } 846 } 847 else 848 { 849 status = rw_t1t_handle_read_rsp (p_notify, p_data); 850 } 851 return status; 852} 853 854/***************************************************************************** 855** 856** Function rw_t1t_handle_rall_rsp 857** 858** Description Handle response to RALL - Collect CC, set Tag state 859** 860** Returns None 861** 862*****************************************************************************/ 863static tNFC_STATUS rw_t1t_handle_rall_rsp (BOOLEAN *p_notify,UINT8 *p_data) 864{ 865 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 866 867 p_data += T1T_HR_LEN; /* skip HR */ 868 memcpy (p_t1t->mem, (UINT8 *) p_data, T1T_STATIC_SIZE); 869 p_t1t->segment = 0; 870 rw_t1t_extract_lock_bytes (p_data); 871 872 p_data += T1T_UID_LEN + T1T_RES_BYTE_LEN; /* skip Block 0, UID and Reserved byte */ 873 874 RW_TRACE_DEBUG0 ("rw_t1t_handle_rall_rsp ()"); 875 876 rw_t1t_update_tag_state (); 877 rw_t1t_update_attributes (); 878 rw_t1t_update_lock_attributes (); 879 p_t1t->b_update = TRUE; 880 return (rw_t1t_handle_read_rsp (p_notify, p_t1t->mem)); 881} 882 883/******************************************************************************* 884** 885** Function rw_t1t_handle_tlv_detect_rsp 886** 887** Description Handle response to the last command sent while 888** detecting tlv 889** 890** Returns NFC_STATUS_OK, if tlv detect is complete & success 891** NFC_STATUS_FAILED,if tlv detect failed 892** 893*******************************************************************************/ 894static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data) 895{ 896 UINT16 offset; 897 UINT16 len; 898 UINT8 xx; 899 UINT8 *p_readbytes; 900 UINT8 index; 901 UINT8 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT; 902 UINT8 found_tlv = TAG_NULL_TLV; 903 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 904 BOOLEAN failed = FALSE; 905 BOOLEAN found = FALSE; 906 UINT8 count = 0; 907 tNFC_STATUS status = NFC_STATUS_FAILED; 908 UINT8 start_offset = T1T_UID_LEN + T1T_CC_LEN + T1T_RES_BYTE_LEN; 909 UINT8 end_offset = T1T_STATIC_SIZE - (2*T1T_BLOCK_SIZE); 910 UINT8 bytes_read = T1T_STATIC_SIZE; 911 UINT8 tlv_value[T1T_DEFAULT_TLV_LEN]; 912 UINT16 bytes_count = 0; 913 914 p_readbytes = p_data; 915 916 for (offset = start_offset; offset < end_offset && !failed && !found;) 917 { 918 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == TRUE) 919 { 920 offset++; 921 continue; 922 } 923 switch (tlv_detect_state) 924 { 925 case RW_T1T_SUBSTATE_WAIT_TLV_DETECT: 926 /* Search for the tag */ 927 found_tlv = p_readbytes[offset++]; 928 switch (found_tlv) 929 { 930 case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */ 931 break; 932 933 case TAG_NDEF_TLV: 934 if (p_t1t->tlv_detect == TAG_NDEF_TLV) 935 { 936 index = (offset % T1T_BLOCK_SIZE); 937 /* Backup ndef first block */ 938 memcpy (&p_t1t->ndef_first_block[0],&p_readbytes[offset-index],index); 939 memcpy (&p_t1t->ndef_first_block[index],&p_readbytes[offset],T1T_BLOCK_SIZE - index); 940 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN; 941 } 942 else if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV) 943 { 944 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN; 945 } 946 else if ( ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0)) 947 ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0)) ) 948 { 949 found = TRUE; 950 } 951 else 952 { 953 failed = TRUE; 954 } 955 break; 956 957 case TAG_LOCK_CTRL_TLV: 958 case TAG_MEM_CTRL_TLV: 959 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0; 960 break; 961 962 case TAG_PROPRIETARY_TLV: 963 if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV) 964 { 965 index = (offset % T1T_BLOCK_SIZE); 966 /* Backup ndef first block */ 967 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN; 968 } 969 else 970 { 971 /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we continue searching, skiping proprietary tlv */ 972 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN; 973 } 974 break; 975 976 case TAG_TERMINATOR_TLV: /* Last TLV block in the data area. Must be no NDEF nessage */ 977 if ( ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0)) 978 ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0)) ) 979 { 980 found = TRUE; 981 } 982 else 983 { 984 failed = TRUE; 985 } 986 break; 987 default: 988 failed = TRUE; 989 } 990 break; 991 992 case RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN: 993 len = p_readbytes[offset]; 994 switch (found_tlv) 995 { 996 case TAG_NDEF_TLV: 997 p_t1t->ndef_header_offset = offset + p_t1t->work_offset; 998 if (len == T1T_LONG_NDEF_LEN_FIELD_BYTE0) 999 { 1000 /* The next two bytes constitute length bytes */ 1001 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0; 1002 } 1003 else 1004 { 1005 /* one byte length field */ 1006 p_t1t->ndef_msg_len = len; 1007 bytes_count = p_t1t->ndef_msg_len; 1008 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE; 1009 } 1010 break; 1011 1012 case TAG_PROPRIETARY_TLV: 1013 if (len == 0xFF) 1014 { 1015 /* The next two bytes constitute length bytes */ 1016 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0; 1017 } 1018 else 1019 { 1020 /* one byte length field */ 1021 bytes_count = len; 1022 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE; 1023 } 1024 break; 1025 } 1026 offset++; 1027 break; 1028 1029 case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0: 1030 switch (found_tlv) 1031 { 1032 case TAG_LOCK_CTRL_TLV: 1033 case TAG_MEM_CTRL_TLV: 1034 1035 len = p_readbytes[offset]; 1036 if (len == T1T_DEFAULT_TLV_LEN) 1037 { 1038 /* Valid Lock control TLV */ 1039 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE; 1040 bytes_count = T1T_DEFAULT_TLV_LEN; 1041 } 1042 else if ( ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0)) 1043 ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0)) ) 1044 { 1045 found = TRUE; 1046 } 1047 else 1048 { 1049 failed = TRUE; 1050 } 1051 break; 1052 1053 case TAG_NDEF_TLV: 1054 case TAG_PROPRIETARY_TLV: 1055 /* The first length byte */ 1056 bytes_count = (UINT8) p_readbytes[offset]; 1057 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1; 1058 break; 1059 } 1060 offset++; 1061 break; 1062 1063 case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1: 1064 bytes_count = (bytes_count << 8) + p_readbytes[offset]; 1065 if (found_tlv == TAG_NDEF_TLV) 1066 { 1067 p_t1t->ndef_msg_len = bytes_count; 1068 } 1069 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE; 1070 offset++; 1071 break; 1072 1073 case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE: 1074 switch (found_tlv) 1075 { 1076 case TAG_NDEF_TLV: 1077 if ((bytes_count == p_t1t->ndef_msg_len) && (p_t1t->tlv_detect == TAG_NDEF_TLV)) 1078 { 1079 /* The first byte offset after length field */ 1080 p_t1t->ndef_msg_offset = offset + p_t1t->work_offset; 1081 } 1082 if (bytes_count > 0) 1083 bytes_count--; 1084 1085 if (p_t1t->tlv_detect == TAG_NDEF_TLV) 1086 { 1087 if (p_t1t->ndef_msg_len > 0) 1088 { 1089 rw_t1t_update_tag_state (); 1090 } 1091 else 1092 { 1093 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED_NDEF; 1094 } 1095 found = TRUE; 1096 } 1097 else if (bytes_count == 0) 1098 { 1099 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT; 1100 } 1101 break; 1102 1103 case TAG_LOCK_CTRL_TLV: 1104 bytes_count--; 1105 if ( (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) 1106 ||(p_t1t->tlv_detect == TAG_NDEF_TLV) ) 1107 { 1108 tlv_value[2 - bytes_count] = p_readbytes[offset]; 1109 if (bytes_count == 0) 1110 { 1111 if (p_t1t->num_lock_tlvs < RW_T1T_MAX_LOCK_TLVS) 1112 { 1113 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset = (tlv_value[0] >> 4) & 0x0F; 1114 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F); 1115 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset += tlv_value[0] & 0x0F; 1116 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].bytes_locked_per_bit = (UINT8) tags_pow (2, ((tlv_value[2] & 0xF0) >> 4)); 1117 p_t1t->lock_tlv[p_t1t->num_lock_tlvs].num_bits = tlv_value[1]; 1118 count = tlv_value[1] / 8 + ((tlv_value[1] % 8 != 0)? 1:0); 1119 xx = 0; 1120 while (xx < count) 1121 { 1122 if (p_t1t->num_lockbytes < RW_T1T_MAX_LOCK_BYTES) 1123 { 1124 p_t1t->lockbyte[p_t1t->num_lockbytes].tlv_index = p_t1t->num_lock_tlvs; 1125 p_t1t->lockbyte[p_t1t->num_lockbytes].byte_index = xx; 1126 p_t1t->lockbyte[p_t1t->num_lockbytes].b_lock_read = FALSE; 1127 p_t1t->num_lockbytes++; 1128 } 1129 else 1130 RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock bytes=0x%02X", RW_T1T_MAX_LOCK_BYTES); 1131 xx++; 1132 } 1133 p_t1t->num_lock_tlvs++; 1134 rw_t1t_update_attributes (); 1135 } 1136 else 1137 RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock tlvs=0x%02X", RW_T1T_MAX_LOCK_TLVS); 1138 1139 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT; 1140 } 1141 } 1142 else 1143 { 1144 if (bytes_count == 0) 1145 { 1146 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT; 1147 } 1148 } 1149 break; 1150 1151 case TAG_MEM_CTRL_TLV: 1152 bytes_count--; 1153 if ( (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) 1154 ||(p_t1t->tlv_detect == TAG_NDEF_TLV) ) 1155 { 1156 tlv_value[2 - bytes_count] = p_readbytes[offset]; 1157 if (bytes_count == 0) 1158 { 1159 if (p_t1t->num_mem_tlvs >= RW_T1T_MAX_MEM_TLVS) 1160 { 1161 RW_TRACE_ERROR0 ("rw_t1t_handle_tlv_detect_rsp - Maximum buffer allocated for Memory tlv has reached"); 1162 failed = TRUE; 1163 } 1164 else 1165 { 1166 /* Extract dynamic reserved bytes */ 1167 p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset = (tlv_value[0] >> 4) & 0x0F; 1168 p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F); 1169 p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset += tlv_value[0] & 0x0F; 1170 p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes = tlv_value[1]; 1171 p_t1t->num_mem_tlvs++; 1172 rw_t1t_update_attributes (); 1173 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT; 1174 } 1175 } 1176 } 1177 else 1178 { 1179 if (bytes_count == 0) 1180 { 1181 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT; 1182 } 1183 } 1184 break; 1185 1186 case TAG_PROPRIETARY_TLV: 1187 bytes_count--; 1188 if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV) 1189 found = TRUE; 1190 else 1191 { 1192 if (bytes_count == 0) 1193 { 1194 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT; 1195 } 1196 } 1197 break; 1198 } 1199 offset++; 1200 break; 1201 } 1202 } 1203 1204 p_t1t->work_offset += bytes_read; 1205 1206 /* NDEF/Lock/Mem TLV to be found in segment 0, if not assume detection failed */ 1207 if (!found && !failed) 1208 { 1209 if ( ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0)) 1210 ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0)) ) 1211 { 1212 found = TRUE; 1213 } 1214 else 1215 { 1216 if (p_t1t->tlv_detect == TAG_NDEF_TLV) 1217 { 1218 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED; 1219 } 1220 failed = TRUE; 1221 } 1222 } 1223 1224 1225 status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK; 1226 return status; 1227} 1228 1229/******************************************************************************* 1230** 1231** Function rw_t1t_handle_ndef_rall_rsp 1232** 1233** Description Handle response to RALL command sent while reading an 1234** NDEF message 1235** 1236** Returns NFC_STATUS_CONTINUE, if NDEF read operation is not complete 1237** NFC_STATUS_OK, if NDEF read is successfull 1238** NFC_STATUS_FAILED,if NDEF read failed 1239** 1240*******************************************************************************/ 1241static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp (void) 1242{ 1243 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1244 tNFC_STATUS status = NFC_STATUS_CONTINUE; 1245 UINT8 count; 1246 UINT8 adds; 1247 1248 count = (UINT8) p_t1t->ndef_msg_offset; 1249 p_t1t->work_offset = 0; 1250 p_t1t->segment = 0; 1251 1252 while (count < T1T_STATIC_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len) 1253 { 1254 if (rw_t1t_is_lock_reserved_otp_byte (count) == FALSE) 1255 { 1256 p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_t1t->mem[count]; 1257 p_t1t->work_offset++; 1258 } 1259 count++; 1260 } 1261 if (p_t1t->work_offset != p_t1t->ndef_msg_len) 1262 { 1263 if ((p_t1t->hr[0] & 0x0F) != 1) 1264 { 1265 if (p_t1t->work_offset == 0) 1266 return NFC_STATUS_FAILED; 1267 1268 else 1269 { 1270 p_t1t->block_read = T1T_STATIC_BLOCKS + 1; 1271 p_t1t->segment++; 1272 } 1273 if (p_t1t->ndef_msg_len - p_t1t->work_offset <= 8) 1274 { 1275 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK) 1276 { 1277 p_t1t->tlv_detect = TAG_NDEF_TLV; 1278 p_t1t->state = RW_T1T_STATE_READ_NDEF; 1279 status = NFC_STATUS_CONTINUE; 1280 } 1281 } 1282 else 1283 { 1284 /* send RSEG command */ 1285 RW_T1T_BLD_ADDS ((adds), (p_t1t->segment)); 1286 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK) 1287 { 1288 p_t1t->state = RW_T1T_STATE_READ_NDEF; 1289 status = NFC_STATUS_CONTINUE; 1290 } 1291 } 1292 } 1293 else 1294 { 1295 RW_TRACE_ERROR1 ("RW_T1tReadNDef - Invalid NDEF len: %u or NDEF corrupted", p_t1t->ndef_msg_len); 1296 status = NFC_STATUS_FAILED; 1297 } 1298 } 1299 else 1300 { 1301 status = NFC_STATUS_OK; 1302 } 1303 return status; 1304} 1305 1306/******************************************************************************* 1307** 1308** Function rw_t1t_handle_ndef_read_rsp 1309** 1310** Description Handle response to commands sent while reading an 1311** NDEF message 1312** 1313** Returns NFC_STATUS_CONTINUE, if tlv read is not yet complete 1314** NFC_STATUS_OK, if tlv read is complete & success 1315** NFC_STATUS_FAILED,if tlv read failed 1316** 1317*******************************************************************************/ 1318static tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data) 1319{ 1320 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE; 1321 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1322 UINT8 index; 1323 UINT8 adds; 1324 tT1T_CMD_RSP_INFO *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info; 1325 1326 /* The Response received could be for Read8 or Read Segment command */ 1327 switch(p_cmd_rsp_info->opcode) 1328 { 1329 case T1T_CMD_READ8: 1330 if (p_t1t->work_offset == 0) 1331 { 1332 index = p_t1t->ndef_msg_offset % T1T_BLOCK_SIZE; 1333 } 1334 else 1335 { 1336 index = 0; 1337 } 1338 p_t1t->segment = (p_t1t->block_read * T1T_BLOCK_SIZE)/T1T_SEGMENT_SIZE; 1339 while (index < T1T_BLOCK_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len) 1340 { 1341 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((p_t1t->block_read * T1T_BLOCK_SIZE) + index)) == FALSE) 1342 { 1343 p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index]; 1344 p_t1t->work_offset++; 1345 } 1346 index++; 1347 } 1348 break; 1349 1350 case T1T_CMD_RSEG: 1351 if (p_t1t->work_offset == 0) 1352 { 1353 index = p_t1t->ndef_msg_offset % T1T_SEGMENT_SIZE; 1354 } 1355 else 1356 { 1357 index = 0; 1358 } 1359 p_t1t->block_read = ((p_t1t->segment + 1) * T1T_BLOCKS_PER_SEGMENT) - 1; 1360 1361 while (index < T1T_SEGMENT_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len) 1362 { 1363 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (index)) == FALSE) 1364 { 1365 p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index]; 1366 p_t1t->work_offset++; 1367 } 1368 index++; 1369 } 1370 break; 1371 1372 default: 1373 break; 1374 } 1375 if (p_t1t->work_offset < p_t1t->ndef_msg_len) 1376 { 1377 if ((p_t1t->hr[0] & 0x0F) != 1) 1378 { 1379 if ((p_t1t->ndef_msg_len - p_t1t->work_offset) <= T1T_BLOCK_SIZE) 1380 { 1381 p_t1t->block_read++; 1382 if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, (UINT8) (p_t1t->block_read), NULL)) == NFC_STATUS_OK) 1383 { 1384 ndef_status = NFC_STATUS_CONTINUE; 1385 } 1386 } 1387 else 1388 { 1389 p_t1t->segment++; 1390 /* send RSEG command */ 1391 RW_T1T_BLD_ADDS ((adds), (p_t1t->segment)); 1392 if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK) 1393 { 1394 ndef_status = NFC_STATUS_CONTINUE; 1395 } 1396 } 1397 } 1398 } 1399 else 1400 { 1401 ndef_status = NFC_STATUS_OK; 1402 } 1403 return ndef_status; 1404} 1405 1406/******************************************************************************* 1407** 1408** Function rw_t1t_next_ndef_write_block 1409** 1410** Description This function prepare and writes ndef blocks 1411** 1412** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete 1413** NFC_STATUS_OK, if tlv write is complete & success 1414** NFC_STATUS_FAILED,if tlv write failed 1415** 1416*******************************************************************************/ 1417static tNFC_STATUS rw_t1t_next_ndef_write_block (void) 1418{ 1419 BOOLEAN b_block_write_cmd = FALSE; 1420 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1421 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE; 1422 UINT8 write_block[8]; 1423 UINT8 block; 1424 UINT8 index; 1425 UINT8 new_lengthfield_len; 1426 UINT8 length_field[3]; 1427 UINT16 initial_offset; 1428 UINT8 count; 1429 /* Write NDEF Message */ 1430 new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1; 1431 1432 /* Identify the command to use for NDEF write operation */ 1433 if ((p_t1t->hr[0] & 0x0F) != 1) 1434 { 1435 /* Dynamic memory structure */ 1436 b_block_write_cmd = FALSE; 1437 block = p_t1t->ndef_block_written + 1; 1438 p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE; 1439 1440 count = 0; 1441 while (block <= p_t1t->mem[T1T_CC_TMS_BYTE]) 1442 { 1443 index = 0; 1444 if (block == p_t1t->num_ndef_finalblock) 1445 { 1446 /* T1T_CMD_WRITE_E8 Command */ 1447 b_block_write_cmd = TRUE; 1448 break; 1449 } 1450 while (index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + new_lengthfield_len)) 1451 { 1452 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + index)) == FALSE) 1453 { 1454 count++; 1455 } 1456 index++; 1457 } 1458 if (count == T1T_BLOCK_SIZE) 1459 { 1460 /* T1T_CMD_WRITE_E8 Command */ 1461 b_block_write_cmd = TRUE; 1462 break; 1463 } 1464 else if (count == 0) 1465 { 1466 index = 0; 1467 block++; 1468 if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE) 1469 { 1470 p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE; 1471 } 1472 } 1473 else 1474 { 1475 /* T1T_CMD_WRITE_E Command */ 1476 b_block_write_cmd = FALSE; 1477 break; 1478 } 1479 } 1480 } 1481 else 1482 { 1483 /* Static memory structure */ 1484 block = p_t1t->ndef_block_written; 1485 b_block_write_cmd = FALSE; 1486 } 1487 1488 new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1; 1489 if (new_lengthfield_len == 3) 1490 { 1491 length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0; 1492 length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8); 1493 length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len); 1494 } 1495 else 1496 { 1497 length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len); 1498 } 1499 1500 if (b_block_write_cmd) 1501 { 1502 /* Dynamic memory structure */ 1503 index = 0; 1504 p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE; 1505 1506 initial_offset = p_t1t->work_offset; 1507 block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, FALSE, block, new_lengthfield_len); 1508 if (p_t1t->work_offset == initial_offset) 1509 { 1510 ndef_status = NFC_STATUS_FAILED; 1511 } 1512 else 1513 { 1514 /* Send WRITE_E8 command */ 1515 ndef_status = rw_t1t_send_ndef_block (write_block, block); 1516 } 1517 } 1518 else 1519 { 1520 /* Static memory structure */ 1521 if (p_t1t->write_byte + 1 >= T1T_BLOCK_SIZE) 1522 { 1523 index = 0; 1524 block++; 1525 } 1526 else 1527 { 1528 index = p_t1t->write_byte + 1; 1529 } 1530 initial_offset = p_t1t->work_offset; 1531 block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len); 1532 if (p_t1t->work_offset == initial_offset) 1533 { 1534 ndef_status = NFC_STATUS_FAILED; 1535 } 1536 else 1537 { 1538 /* send WRITE-E command */ 1539 ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len); 1540 } 1541 } 1542 return ndef_status; 1543 1544} 1545 1546/******************************************************************************* 1547** 1548** Function rw_t1t_ndef_write_first_block 1549** 1550** Description This function writes ndef first block 1551** 1552** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete 1553** NFC_STATUS_OK, if tlv write is complete & success 1554** NFC_STATUS_FAILED,if tlv write failed 1555** 1556*******************************************************************************/ 1557static tNFC_STATUS rw_t1t_ndef_write_first_block (void) 1558{ 1559 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE; 1560 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1561 UINT8 block; 1562 UINT8 index; 1563 UINT8 new_lengthfield_len; 1564 UINT8 length_field[3]; 1565 UINT8 write_block[8]; 1566 1567 /* handle positive response to invalidating existing NDEF Message */ 1568 p_t1t->work_offset = 0; 1569 new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1; 1570 if (new_lengthfield_len == 3) 1571 { 1572 length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0; 1573 length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8); 1574 length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len); 1575 } 1576 else 1577 { 1578 length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len); 1579 } 1580 /* updating ndef_first_block with new ndef message */ 1581 memcpy(write_block,p_t1t->ndef_first_block,T1T_BLOCK_SIZE); 1582 index = p_t1t->ndef_header_offset % T1T_BLOCK_SIZE; 1583 block = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE); 1584 p_t1t->segment = (UINT8) (p_t1t->ndef_header_offset/T1T_SEGMENT_SIZE); 1585 1586 if ((p_t1t->hr[0] & 0x0F) != 1) 1587 { 1588 /* Dynamic Memory structure */ 1589 block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, FALSE, block, new_lengthfield_len); 1590 1591 if (p_t1t->work_offset == 0) 1592 { 1593 ndef_status = NFC_STATUS_FAILED; 1594 } 1595 else 1596 { 1597 /* Send WRITE-E8 command based on the prepared write_block */ 1598 ndef_status = rw_t1t_send_ndef_block (write_block, block); 1599 } 1600 } 1601 else 1602 { 1603 /* Static Memory structure */ 1604 block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len); 1605 if (p_t1t->work_offset == 0) 1606 { 1607 ndef_status = NFC_STATUS_FAILED; 1608 } 1609 else 1610 { 1611 /* send WRITE-E command */ 1612 ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len); 1613 } 1614 } 1615 1616 return ndef_status; 1617} 1618 1619/******************************************************************************* 1620** 1621** Function rw_t1t_send_ndef_byte 1622** 1623** Description Sends ndef message or length field byte and update 1624** status 1625** 1626** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete 1627** NFC_STATUS_OK, if tlv write is complete & success 1628** NFC_STATUS_FAILED,if tlv write failed 1629** 1630*******************************************************************************/ 1631static tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len) 1632{ 1633 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE; 1634 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1635 UINT8 addr; 1636 1637 /* send WRITE-E command */ 1638 RW_T1T_BLD_ADD ((addr), (block), (index)); 1639 if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, data)) 1640 { 1641 p_t1t->write_byte = index; 1642 p_t1t->ndef_block_written = block; 1643 if (p_t1t->work_offset == p_t1t->new_ndef_msg_len + msg_len) 1644 { 1645 ndef_status = NFC_STATUS_OK; 1646 } 1647 else 1648 { 1649 ndef_status = NFC_STATUS_CONTINUE; 1650 } 1651 } 1652 else 1653 { 1654 ndef_status = NFC_STATUS_FAILED; 1655 } 1656 return ndef_status; 1657} 1658 1659/******************************************************************************* 1660** 1661** Function rw_t1t_prepare_ndef_bytes 1662** 1663** Description prepares ndef block to write 1664** 1665** Returns block number where to write 1666** 1667*******************************************************************************/ 1668static UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len) 1669{ 1670 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1671 UINT8 first_block = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE); 1672 UINT16 initial_offset = p_t1t->work_offset; 1673 1674 while (p_t1t->work_offset == initial_offset && block <= p_t1t->mem[T1T_CC_TMS_BYTE]) 1675 { 1676 if ( (block == p_t1t->num_ndef_finalblock) 1677 &&(block != first_block) ) 1678 { 1679 memcpy (p_data,p_t1t->ndef_final_block,T1T_BLOCK_SIZE); 1680 } 1681 /* Update length field */ 1682 while ( (*p_index < T1T_BLOCK_SIZE) 1683 &&(p_t1t->work_offset < lengthfield_len) ) 1684 { 1685 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE) 1686 { 1687 p_data[*p_index] = p_length_field[p_t1t->work_offset]; 1688 p_t1t->work_offset++; 1689 if (b_one_byte) 1690 return block; 1691 } 1692 (*p_index)++; 1693 if (p_t1t->work_offset == lengthfield_len) 1694 { 1695 break; 1696 } 1697 } 1698 /* Update ndef message field */ 1699 while (*p_index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + lengthfield_len)) 1700 { 1701 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE) 1702 { 1703 p_data[*p_index] = p_t1t->p_ndef_buffer[p_t1t->work_offset - lengthfield_len]; 1704 p_t1t->work_offset++; 1705 if (b_one_byte) 1706 return block; 1707 } 1708 (*p_index)++; 1709 } 1710 if (p_t1t->work_offset == initial_offset) 1711 { 1712 *p_index = 0; 1713 block++; 1714 if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE) 1715 { 1716 p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE; 1717 } 1718 } 1719 } 1720 return block; 1721} 1722 1723/******************************************************************************* 1724** 1725** Function rw_t1t_send_ndef_block 1726** 1727** Description Sends ndef block and update status 1728** 1729** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete 1730** NFC_STATUS_OK, if tlv write is complete & success 1731** NFC_STATUS_FAILED,if tlv write failed 1732** 1733*******************************************************************************/ 1734static tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block) 1735{ 1736 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1737 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE; 1738 1739 if (NFC_STATUS_OK == rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, block, p_data)) 1740 { 1741 p_t1t->ndef_block_written = block; 1742 if (p_t1t->ndef_block_written == p_t1t->num_ndef_finalblock) 1743 { 1744 ndef_status = NFC_STATUS_OK; 1745 } 1746 else 1747 { 1748 ndef_status = NFC_STATUS_CONTINUE; 1749 } 1750 } 1751 else 1752 { 1753 ndef_status = NFC_STATUS_FAILED; 1754 } 1755 return ndef_status; 1756} 1757 1758/******************************************************************************* 1759** 1760** Function rw_t1t_get_ndef_flags 1761** 1762** Description Prepare NDEF Flags 1763** 1764** Returns NDEF Flag value 1765** 1766*******************************************************************************/ 1767static UINT8 rw_t1t_get_ndef_flags (void) 1768{ 1769 UINT8 flags = 0; 1770 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1771 1772 if ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED) 1773 flags |= RW_NDEF_FL_SUPPORTED; 1774 1775 if (t1t_tag_init_data (p_t1t->hr[0]) != NULL) 1776 flags |= RW_NDEF_FL_FORMATABLE; 1777 1778 if ((p_t1t->mem[T1T_CC_RWA_BYTE] & 0x0F) == T1T_CC_RWA_RO) 1779 flags |=RW_NDEF_FL_READ_ONLY; 1780 1781 return flags; 1782} 1783 1784/******************************************************************************* 1785** 1786** Function rw_t1t_get_ndef_max_size 1787** 1788** Description Calculate maximum size of NDEF message that can be written 1789** on to the tag 1790** 1791** Returns Maximum size of NDEF Message 1792** 1793*******************************************************************************/ 1794static UINT16 rw_t1t_get_ndef_max_size (void) 1795{ 1796 UINT16 offset; 1797 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1798 UINT16 tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] +1)* T1T_BLOCK_SIZE; 1799 const tT1T_INIT_TAG *p_ret; 1800 UINT8 init_segment = p_t1t->segment; 1801 1802 p_t1t->max_ndef_msg_len = 0; 1803 offset = p_t1t->ndef_msg_offset; 1804 p_t1t->segment = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE); 1805 1806 if ( (tag_size < T1T_STATIC_SIZE) 1807 ||(tag_size > (T1T_SEGMENT_SIZE * T1T_MAX_SEGMENTS)) 1808 ||((p_t1t->mem[T1T_CC_NMN_BYTE] != T1T_CC_NMN) && (p_t1t->mem[T1T_CC_NMN_BYTE] != 0)) ) 1809 { 1810 /* Tag not formated, determine maximum NDEF size from HR */ 1811 if ( ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED) 1812 &&((p_ret = t1t_tag_init_data (p_t1t->hr[0])) != NULL) ) 1813 { 1814 p_t1t->max_ndef_msg_len = ((p_ret->tms +1)* T1T_BLOCK_SIZE) - T1T_OTP_LOCK_RES_BYTES - T1T_UID_LEN - T1T_ADD_LEN - T1T_CC_LEN - T1T_TLV_TYPE_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN; 1815 if (p_ret->b_dynamic) 1816 { 1817 p_t1t->max_ndef_msg_len -= (T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN + T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN); 1818 p_t1t->max_ndef_msg_len -= T1T_DYNAMIC_LOCK_BYTES; 1819 } 1820 offset = tag_size; 1821 } 1822 else 1823 { 1824 p_t1t->segment = init_segment; 1825 return p_t1t->max_ndef_msg_len; 1826 } 1827 } 1828 1829 /* Starting from NDEF Message offset find the first locked data byte */ 1830 while (offset < tag_size) 1831 { 1832 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == FALSE) 1833 { 1834 if (rw_t1t_is_read_only_byte ((UINT16) offset) == TRUE) 1835 break; 1836 p_t1t->max_ndef_msg_len++; 1837 } 1838 offset++; 1839 if (offset % T1T_SEGMENT_SIZE == 0) 1840 { 1841 p_t1t->segment = (UINT8) (offset / T1T_SEGMENT_SIZE); 1842 } 1843 } 1844 /* NDEF Length field length changes based on NDEF size */ 1845 if ( (p_t1t->max_ndef_msg_len >= T1T_LONG_NDEF_LEN_FIELD_BYTE0) 1846 &&((p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset) == T1T_SHORT_NDEF_LEN_FIELD_LEN) ) 1847 { 1848 p_t1t->max_ndef_msg_len -= (p_t1t->max_ndef_msg_len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)? 1 : (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN); 1849 } 1850 1851 p_t1t->segment = init_segment; 1852 return p_t1t->max_ndef_msg_len; 1853} 1854 1855/******************************************************************************* 1856** 1857** Function rw_t1t_handle_ndef_write_rsp 1858** 1859** Description Handle response to commands sent while writing an 1860** NDEF message 1861** 1862** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete 1863** NFC_STATUS_OK, if tlv write is complete & success 1864** NFC_STATUS_FAILED,if tlv write failed 1865** 1866*******************************************************************************/ 1867static tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data) 1868{ 1869 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1870 tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE; 1871 UINT8 addr; 1872 1873 switch (p_t1t->substate) 1874 { 1875 case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK: 1876 /* Backup ndef_final_block */ 1877 memcpy (p_t1t->ndef_final_block, p_data, T1T_BLOCK_SIZE); 1878 /* Invalidate existing NDEF Message */ 1879 RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET)); 1880 if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0)) 1881 { 1882 ndef_status = NFC_STATUS_CONTINUE; 1883 p_t1t->state = RW_T1T_STATE_WRITE_NDEF; 1884 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF; 1885 } 1886 else 1887 { 1888 ndef_status = NFC_STATUS_FAILED; 1889 } 1890 break; 1891 1892 case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF: 1893 ndef_status = rw_t1t_ndef_write_first_block (); 1894 break; 1895 1896 case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE: 1897 ndef_status = rw_t1t_next_ndef_write_block (); 1898 break; 1899 1900 case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED: 1901 /* Validate new NDEF Message */ 1902 RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET)); 1903 if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, T1T_CC_NMN)) 1904 { 1905 ndef_status = NFC_STATUS_OK; 1906 } 1907 else 1908 { 1909 ndef_status = NFC_STATUS_FAILED; 1910 } 1911 break; 1912 default: 1913 break; 1914 } 1915 1916 return ndef_status; 1917} 1918 1919/******************************************************************************* 1920** 1921** Function rw_t1t_update_attributes 1922** 1923** Description This function will prepare attributes for the current 1924** segment. Every bit in the attribute refers to one byte of 1925** tag content.The bit corresponding to a tag byte will be set 1926** to '1' when the Tag byte is read only,otherwise will be set 1927** to '0' 1928** 1929** Returns None 1930** 1931*******************************************************************************/ 1932static void rw_t1t_update_attributes (void) 1933{ 1934 UINT8 count = 0; 1935 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 1936 UINT16 lower_offset; 1937 UINT16 upper_offset; 1938 UINT8 num_bytes; 1939 UINT16 offset; 1940 UINT8 bits_per_byte = 8; 1941 1942 count = 0; 1943 while (count < T1T_BLOCKS_PER_SEGMENT) 1944 { 1945 p_t1t->attr[count] = 0x00; 1946 count++; 1947 } 1948 1949 lower_offset = p_t1t->segment * T1T_SEGMENT_SIZE; 1950 upper_offset = (p_t1t->segment + 1)* T1T_SEGMENT_SIZE; 1951 1952 if (p_t1t->segment == 0) 1953 { 1954 /* UID/Lock/Reserved/OTP bytes */ 1955 p_t1t->attr[0x00] = 0xFF; /* Uid bytes */ 1956 p_t1t->attr[0x0D] = 0xFF; /* Reserved bytes */ 1957 p_t1t->attr[0x0E] = 0xFF; /* lock/otp bytes */ 1958 p_t1t->attr[0x0F] = 0xFF; /* lock/otp bytes */ 1959 } 1960 1961 /* update attr based on lock control and mem control tlvs */ 1962 count = 0; 1963 while (count < p_t1t->num_lockbytes) 1964 { 1965 offset = p_t1t->lock_tlv[p_t1t->lockbyte[count].tlv_index].offset + p_t1t->lockbyte[count].byte_index; 1966 if (offset >= lower_offset && offset < upper_offset) 1967 { 1968 /* Set the corresponding bit in attr to indicate - lock byte */ 1969 p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte]; 1970 } 1971 count++; 1972 } 1973 count = 0; 1974 while (count < p_t1t->num_mem_tlvs) 1975 { 1976 num_bytes = 0; 1977 while (num_bytes < p_t1t->mem_tlv[count].num_bytes) 1978 { 1979 offset = p_t1t->mem_tlv[count].offset + num_bytes; 1980 if (offset >= lower_offset && offset < upper_offset) 1981 { 1982 /* Set the corresponding bit in attr to indicate - reserved byte */ 1983 p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte]; 1984 } 1985 num_bytes++; 1986 } 1987 count++; 1988 } 1989} 1990 1991/******************************************************************************* 1992** 1993** Function rw_t1t_get_lock_bits_for_segment 1994** 1995** Description This function will identify the index of the dynamic lock 1996** byte that covers the current segment 1997** 1998** Parameters: segment, segment number 1999** p_start_byte, pointer to hold the first lock byte index 2000** p_start_bit, pointer to hold the first lock bit index 2001** p_end_byte, pointer to hold the last lock byte index 2002** 2003** Returns Total lock bits that covers the specified segment 2004** 2005*******************************************************************************/ 2006static UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte) 2007{ 2008 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 2009 UINT16 byte_count = T1T_SEGMENT_SIZE; 2010 UINT8 total_bits = 0; 2011 UINT8 num_dynamic_locks = 0; 2012 UINT8 bit_count = 0; 2013 UINT16 tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] +1) * T1T_BLOCK_SIZE; 2014 UINT16 lower_offset; 2015 UINT16 upper_offset; 2016 BOOLEAN b_all_bits_are_locks = TRUE; 2017 UINT8 bytes_locked_per_bit; 2018 UINT8 num_bits; 2019 2020 upper_offset = (segment + 1) * T1T_SEGMENT_SIZE; 2021 2022 if (upper_offset > tag_size) 2023 upper_offset = tag_size; 2024 2025 lower_offset = segment * T1T_SEGMENT_SIZE; 2026 *p_start_byte = num_dynamic_locks; 2027 *p_start_bit = 0; 2028 2029 while ( (byte_count <= lower_offset) 2030 &&(num_dynamic_locks < p_t1t->num_lockbytes) ) 2031 { 2032 bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit; 2033 /* Number of bits in the current lock byte */ 2034 b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits); 2035 num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE; 2036 2037 /* Skip lock bits that covers all previous segments */ 2038 if (bytes_locked_per_bit * num_bits + byte_count <= lower_offset) 2039 { 2040 byte_count += bytes_locked_per_bit * num_bits; 2041 num_dynamic_locks++; 2042 } 2043 else 2044 { 2045 /* The first lock bit that covers this segment is present in this segment */ 2046 bit_count = 0; 2047 while (bit_count < num_bits) 2048 { 2049 byte_count += bytes_locked_per_bit; 2050 if (byte_count > lower_offset) 2051 { 2052 *p_start_byte = num_dynamic_locks; 2053 *p_end_byte = num_dynamic_locks; 2054 *p_start_bit = bit_count; 2055 bit_count++; 2056 total_bits = 1; 2057 break; 2058 } 2059 bit_count++; 2060 } 2061 } 2062 } 2063 if (num_dynamic_locks == p_t1t->num_lockbytes) 2064 { 2065 return 0; 2066 } 2067 while ( (byte_count < upper_offset) 2068 &&(num_dynamic_locks < p_t1t->num_lockbytes) ) 2069 { 2070 bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit; 2071 2072 /* Number of bits in the current lock byte */ 2073 b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits); 2074 num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE; 2075 2076 /* Collect all lock bits that covers the current segment */ 2077 if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count < upper_offset) 2078 { 2079 byte_count += bytes_locked_per_bit * (num_bits - bit_count); 2080 total_bits += num_bits - bit_count; 2081 bit_count = 0; 2082 *p_end_byte = num_dynamic_locks; 2083 num_dynamic_locks++; 2084 } 2085 else 2086 { 2087 /* The last lock byte that covers the current segment */ 2088 bit_count = 0; 2089 while (bit_count < num_bits) 2090 { 2091 byte_count += bytes_locked_per_bit; 2092 if (byte_count >= upper_offset) 2093 { 2094 *p_end_byte = num_dynamic_locks; 2095 total_bits += (bit_count + 1); 2096 break; 2097 } 2098 bit_count++; 2099 } 2100 } 2101 } 2102 return total_bits; 2103} 2104 2105/******************************************************************************* 2106** 2107** Function rw_t1t_update_lock_attributes 2108** 2109** Description This function will check if the tag index passed as 2110** argument is a locked byte and return 2111** TRUE or FALSE 2112** 2113** Parameters: index, the index of the byte in the tag 2114** 2115** 2116** Returns TRUE, if the specified index in the tag is a locked or 2117** reserved or otp byte 2118** FALSE, otherwise 2119** 2120*******************************************************************************/ 2121static void rw_t1t_update_lock_attributes (void) 2122{ 2123 UINT8 xx = 0; 2124 UINT8 bytes_locked_per_lock_bit; 2125 UINT8 num_static_lock_bytes = 0; 2126 UINT8 num_dynamic_lock_bytes = 0; 2127 UINT8 bits_covered = 0; 2128 UINT8 bytes_covered = 0; 2129 UINT8 block_count = 0; 2130 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 2131 UINT8 start_lock_byte; 2132 UINT8 start_lock_bit; 2133 UINT8 end_lock_byte; 2134 UINT8 num_lock_bits; 2135 UINT8 total_bits; 2136 2137 2138 block_count = 0; 2139 while (block_count < T1T_BLOCKS_PER_SEGMENT) 2140 { 2141 p_t1t->lock_attr[block_count] = 0x00; 2142 block_count++; 2143 } 2144 2145 /* update lock_attr based on static lock bytes */ 2146 if (p_t1t->segment == 0) 2147 { 2148 xx = 0; 2149 num_static_lock_bytes = 0; 2150 block_count = 0; 2151 num_lock_bits = 8; 2152 2153 while (num_static_lock_bytes < T1T_NUM_STATIC_LOCK_BYTES) 2154 { 2155 /* Update lock attribute based on 2 static locks */ 2156 while (xx < num_lock_bits) 2157 { 2158 p_t1t->lock_attr[block_count] = 0x00; 2159 2160 if (p_t1t->mem[T1T_LOCK_0_OFFSET + num_static_lock_bytes] & rw_t1t_mask_bits[xx++]) 2161 { 2162 /* If the bit is set then 1 block is locked */ 2163 p_t1t->lock_attr[block_count] = 0xFF; 2164 } 2165 2166 block_count++; 2167 } 2168 num_static_lock_bytes++; 2169 xx = 0; 2170 } 2171 /* Locked bytes */ 2172 p_t1t->lock_attr[0x00] = 0xFF; 2173 p_t1t->lock_attr[0x0D] = 0xFF; 2174 } 2175 else 2176 { 2177 /* update lock_attr based on segment and using dynamic lock bytes */ 2178 if ((total_bits = rw_t1t_get_lock_bits_for_segment (p_t1t->segment,&start_lock_byte, &start_lock_bit,&end_lock_byte)) != 0) 2179 { 2180 xx = start_lock_bit; 2181 num_dynamic_lock_bytes = start_lock_byte; 2182 bits_covered = 0; 2183 bytes_covered = 0; 2184 block_count = 0; 2185 num_lock_bits = 8; 2186 2187 p_t1t->lock_attr[block_count] = 0; 2188 2189 while (num_dynamic_lock_bytes <= end_lock_byte) 2190 { 2191 bytes_locked_per_lock_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_lock_bytes].tlv_index].bytes_locked_per_bit; 2192 if (num_dynamic_lock_bytes == end_lock_byte) 2193 { 2194 num_lock_bits = (total_bits % 8 == 0)? 8:total_bits % 8; 2195 } 2196 while (xx < num_lock_bits) 2197 { 2198 bytes_covered = 0; 2199 while (bytes_covered < bytes_locked_per_lock_bit) 2200 { 2201 /* Set/clear lock_attr byte bits based on whether a particular lock bit is set or not 2202 * each bit in lock_attr represents one byte in Tag read only attribute */ 2203 if (p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte & rw_t1t_mask_bits[xx]) 2204 { 2205 p_t1t->lock_attr[block_count] |= 0x01 << bits_covered; 2206 } 2207 bytes_covered++; 2208 bits_covered++; 2209 if (bits_covered == 8) 2210 { 2211 bits_covered = 0; 2212 block_count++; 2213 if (block_count < T1T_BLOCKS_PER_SEGMENT) 2214 p_t1t->lock_attr[block_count] = 0; 2215 } 2216 } 2217 xx++; 2218 } 2219 num_dynamic_lock_bytes++; 2220 xx = 0; 2221 } 2222 } 2223 } 2224} 2225 2226/******************************************************************************* 2227** 2228** Function rw_t1t_is_lock_reserved_otp_byte 2229** 2230** Description This function will check if the tag index passed as 2231** argument is a lock or reserved or otp byte 2232** 2233** Parameters: index, the index of the byte in the tag's current segment 2234** 2235** 2236** Returns TRUE, if the specified index in the tag is a locked or 2237** reserved or otp byte 2238** FALSE, otherwise 2239** 2240*******************************************************************************/ 2241static BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index) 2242{ 2243 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 2244 2245 if (p_t1t->attr_seg != p_t1t->segment) 2246 { 2247 /* Update p_t1t->attr to reflect the current segment */ 2248 rw_t1t_update_attributes (); 2249 p_t1t->attr_seg = p_t1t->segment; 2250 } 2251 index = index % T1T_SEGMENT_SIZE; 2252 2253 /* Every bit in p_t1t->attr indicates one specific byte of the tag is either a lock/reserved/otp byte or not 2254 * So, each array element in p_t1t->attr covers one block in the tag as T1 block size and array element size is 8 2255 * Find the block and offset for the index (passed as argument) and Check if the offset bit in the 2256 * p_t1t->attr[block] is set or not. If the bit is set then it is a lock/reserved/otp byte, otherwise not */ 2257 2258 return ((p_t1t->attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE; 2259} 2260 2261/******************************************************************************* 2262** 2263** Function rw_t1t_is_read_only_byte 2264** 2265** Description This function will check if the tag index passed as 2266** argument is a read only byte 2267** 2268** Parameters: index, the index of the byte in the tag's current segment 2269** 2270** 2271** Returns TRUE, if the specified index in the tag is a locked or 2272** reserved or otp byte 2273** FALSE, otherwise 2274** 2275*******************************************************************************/ 2276static BOOLEAN rw_t1t_is_read_only_byte (UINT16 index) 2277{ 2278 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 2279 2280 if (p_t1t->lock_attr_seg != p_t1t->segment) 2281 { 2282 /* Update p_t1t->lock_attr to reflect the current segment */ 2283 rw_t1t_update_lock_attributes (); 2284 p_t1t->lock_attr_seg = p_t1t->segment; 2285 } 2286 2287 index = index % T1T_SEGMENT_SIZE; 2288 /* Every bit in p_t1t->lock_attr indicates one specific byte of the tag is a read only byte or read write byte 2289 * So, each array element in p_t1t->lock_attr covers one block in the tag as T1 block size and array element size is 8 2290 * Find the block and offset for the index (passed as argument) and Check if the offset bit in the 2291 * p_t1t->lock_attr[block] is set or not. If the bit is set then it is a read only byte, otherwise read write byte */ 2292 2293 return ((p_t1t->lock_attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE; 2294} 2295 2296/***************************************************************************** 2297** 2298** Function RW_T1tFormatNDef 2299** 2300** Description 2301** Format Tag content 2302** 2303** Returns 2304** NFC_STATUS_OK, Command sent to format Tag 2305** NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag 2306** NFC_STATUS_FAILED: other error 2307** 2308*****************************************************************************/ 2309tNFC_STATUS RW_T1tFormatNDef (void) 2310{ 2311 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 2312 tNFC_STATUS status = NFC_STATUS_FAILED; 2313 const tT1T_INIT_TAG *p_ret; 2314 UINT8 addr; 2315 UINT8 *p; 2316 2317 if (p_t1t->state != RW_T1T_STATE_IDLE) 2318 { 2319 RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Tag not initialized/ Busy! State: %u", p_t1t->state); 2320 return (NFC_STATUS_FAILED); 2321 } 2322 2323 if ((p_t1t->hr[0] & 0xF0) != T1T_NDEF_SUPPORTED) 2324 { 2325 RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Cannot format tag as NDEF not supported. HR0: %u", p_t1t->hr[0]); 2326 return (NFC_STATUS_REJECTED); 2327 } 2328 2329 if ((p_ret = t1t_tag_init_data (p_t1t->hr[0])) == NULL) 2330 { 2331 RW_TRACE_WARNING2 ("RW_T1tFormatNDef - Invalid HR - HR0: %u, HR1: %u", p_t1t->hr[0], p_t1t->hr[1]); 2332 return (NFC_STATUS_REJECTED); 2333 } 2334 2335 memset (p_t1t->ndef_first_block, 0, T1T_BLOCK_SIZE); 2336 memset (p_t1t->ndef_final_block, 0, T1T_BLOCK_SIZE); 2337 p = p_t1t->ndef_first_block; 2338 2339 /* Prepare Capability Container */ 2340 UINT8_TO_BE_STREAM (p, T1T_CC_NMN); 2341 UINT8_TO_BE_STREAM (p, T1T_CC_VNO); 2342 UINT8_TO_BE_STREAM (p, p_ret->tms); 2343 UINT8_TO_BE_STREAM (p, T1T_CC_RWA_RW); 2344 if (p_ret->b_dynamic) 2345 { 2346 /* Prepare Lock and Memory TLV */ 2347 UINT8_TO_BE_STREAM (p, TAG_LOCK_CTRL_TLV); 2348 UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN); 2349 UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[0]); 2350 UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[1]); 2351 p = p_t1t->ndef_final_block; 2352 UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[2]); 2353 UINT8_TO_BE_STREAM (p, TAG_MEM_CTRL_TLV); 2354 UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN); 2355 UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[0]); 2356 UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[1]); 2357 UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[2]); 2358 } 2359 /* Prepare NULL NDEF TLV */ 2360 UINT8_TO_BE_STREAM (p, TAG_NDEF_TLV); 2361 UINT8_TO_BE_STREAM (p, 0); 2362 2363 if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) 2364 { 2365 /* send WRITE-E8 command */ 2366 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 1, p_t1t->ndef_first_block)) == NFC_STATUS_OK) 2367 { 2368 p_t1t->state = RW_T1T_STATE_FORMAT_TAG; 2369 p_t1t->b_update = FALSE; 2370 p_t1t->b_rseg = FALSE; 2371 if (p_ret->b_dynamic) 2372 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC; 2373 else 2374 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF; 2375 } 2376 } 2377 else 2378 { 2379 /* send WRITE-E command */ 2380 RW_T1T_BLD_ADD ((addr), 1, 0); 2381 2382 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[0])) == NFC_STATUS_OK) 2383 { 2384 p_t1t->work_offset = 0; 2385 p_t1t->state = RW_T1T_STATE_FORMAT_TAG; 2386 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF; 2387 p_t1t->b_update = FALSE; 2388 p_t1t->b_rseg = FALSE; 2389 } 2390 } 2391 2392 return status; 2393} 2394 2395/******************************************************************************* 2396** 2397** Function RW_T1tLocateTlv 2398** 2399** Description This function is called to find the start of the given TLV 2400** 2401** Parameters: tlv_type, Type of TLV to find 2402** 2403** Returns NCI_STATUS_OK, if detection was started. Otherwise, error status. 2404** 2405*******************************************************************************/ 2406tNFC_STATUS RW_T1tLocateTlv (UINT8 tlv_type) 2407{ 2408 tNFC_STATUS status = NFC_STATUS_FAILED; 2409 tRW_T1T_CB *p_t1t= &rw_cb.tcb.t1t; 2410 UINT8 adds; 2411 2412 if (p_t1t->state != RW_T1T_STATE_IDLE) 2413 { 2414 RW_TRACE_WARNING1 ("RW_T1tLocateTlv - Busy - State: %u", p_t1t->state); 2415 return (NFC_STATUS_FAILED); 2416 } 2417 p_t1t->tlv_detect = tlv_type; 2418 2419 if( (p_t1t->tlv_detect == TAG_NDEF_TLV) 2420 &&(((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED) ) 2421 { 2422 RW_TRACE_ERROR0 ("RW_T1tLocateTlv - Error: NDEF not supported by the tag"); 2423 return (NFC_STATUS_REFUSED); 2424 } 2425 2426 if ( (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) 2427 ||(p_t1t->tlv_detect == TAG_NDEF_TLV) ) 2428 { 2429 p_t1t->num_mem_tlvs = 0; 2430 } 2431 2432 if ( (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) 2433 ||(p_t1t->tlv_detect == TAG_NDEF_TLV) ) 2434 { 2435 p_t1t->num_lockbytes = 0; 2436 p_t1t->num_lock_tlvs = 0; 2437 } 2438 2439 /* Start reading memory, looking for the TLV */ 2440 p_t1t->segment = 0; 2441 if ((p_t1t->hr[0] & 0x0F) != 1) 2442 { 2443 /* send RSEG command */ 2444 RW_T1T_BLD_ADDS ((adds), (p_t1t->segment)); 2445 status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL); 2446 } 2447 else 2448 { 2449 status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0); 2450 } 2451 if (status == NFC_STATUS_OK) 2452 { 2453 p_t1t->tlv_detect = tlv_type; 2454 p_t1t->work_offset = 0; 2455 p_t1t->state = RW_T1T_STATE_TLV_DETECT; 2456 p_t1t->substate = RW_T1T_SUBSTATE_NONE; 2457 } 2458 2459 return status; 2460} 2461 2462/***************************************************************************** 2463** 2464** Function RW_T1tDetectNDef 2465** 2466** Description 2467** This function is used to perform NDEF detection on a Type 1 tag, and 2468** retrieve the tag's NDEF attribute information (block 0). 2469** 2470** Before using this API, the application must call RW_SelectTagType to 2471** indicate that a Type 1 tag has been activated. 2472** 2473** Returns 2474** NFC_STATUS_OK: ndef detection procedure started 2475** NFC_STATUS_WRONG_PROTOCOL: type 1 tag not activated 2476** NFC_STATUS_BUSY: another command is already in progress 2477** NFC_STATUS_FAILED: other error 2478** 2479*****************************************************************************/ 2480tNFC_STATUS RW_T1tDetectNDef (void) 2481{ 2482 return RW_T1tLocateTlv (TAG_NDEF_TLV); 2483} 2484 2485/******************************************************************************* 2486** 2487** Function RW_T1tReadNDef 2488** 2489** Description This function can be called to read the NDEF message on the tag. 2490** 2491** Parameters: p_buffer: The buffer into which to read the NDEF message 2492** buf_len: The length of the buffer 2493** 2494** Returns NCI_STATUS_OK, if read was started. Otherwise, error status. 2495** 2496*******************************************************************************/ 2497tNFC_STATUS RW_T1tReadNDef (UINT8 *p_buffer, UINT16 buf_len) 2498{ 2499 tNFC_STATUS status = NFC_STATUS_FAILED; 2500 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 2501 BOOLEAN b_notify; 2502 UINT8 adds; 2503 const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rall = t1t_cmd_to_rsp_info (T1T_CMD_RALL); 2504 const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rseg = t1t_cmd_to_rsp_info (T1T_CMD_RSEG); 2505 2506 2507 2508 if (p_t1t->state != RW_T1T_STATE_IDLE) 2509 { 2510 RW_TRACE_WARNING1 ("RW_T1tReadNDef - Busy - State: %u", p_t1t->state); 2511 return (NFC_STATUS_FAILED); 2512 } 2513 2514 /* Check HR0 if NDEF supported by the tag */ 2515 if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED) 2516 { 2517 RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF not supported by the tag"); 2518 return (NFC_STATUS_REFUSED); 2519 } 2520 2521 if (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF) 2522 { 2523 RW_TRACE_WARNING1 ("RW_T1tReadNDef - NDEF Message length is zero, NDEF Length : %u ", p_t1t->ndef_msg_len); 2524 return (NFC_STATUS_NOT_INITIALIZED); 2525 } 2526 2527 if ( (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE) 2528 &&(p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_ONLY) ) 2529 { 2530 RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF detection not performed yet/ Tag is in Initialized state"); 2531 return (NFC_STATUS_FAILED); 2532 } 2533 2534 if (buf_len < p_t1t->ndef_msg_len) 2535 { 2536 RW_TRACE_WARNING2 ("RW_T1tReadNDef - buffer size: %u less than NDEF msg sise: %u", buf_len, p_t1t->ndef_msg_len); 2537 return (NFC_STATUS_FAILED); 2538 } 2539 p_t1t->p_ndef_buffer = p_buffer; 2540 2541 if (p_t1t->b_rseg == TRUE) 2542 { 2543 /* If already got response to RSEG 0 */ 2544 p_t1t->state = RW_T1T_STATE_READ_NDEF; 2545 p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *)p_cmd_rsp_info_rseg; 2546 2547 rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem); 2548 status = NFC_STATUS_OK; 2549 } 2550 else if (p_t1t->b_update == TRUE) 2551 { 2552 /* If already got response to RALL */ 2553 p_t1t->state = RW_T1T_STATE_READ_NDEF; 2554 p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info_rall; 2555 2556 rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem); 2557 status = NFC_STATUS_OK; 2558 2559 } 2560 else 2561 { 2562 p_t1t->segment = 0; 2563 p_t1t->work_offset = 0; 2564 if ((p_t1t->hr[0] & 0x0F) != 1) 2565 { 2566 /* send RSEG command */ 2567 RW_T1T_BLD_ADDS ((adds), (p_t1t->segment)); 2568 status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL); 2569 } 2570 else 2571 { 2572 status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0); 2573 } 2574 if (status == NFC_STATUS_OK) 2575 p_t1t->state = RW_T1T_STATE_READ_NDEF; 2576 2577 } 2578 2579 return status; 2580} 2581 2582/******************************************************************************* 2583** 2584** Function RW_T1tWriteNDef 2585** 2586** Description This function can be called to write an NDEF message to the tag. 2587** 2588** Parameters: msg_len: The length of the buffer 2589** p_msg: The NDEF message to write 2590** 2591** Returns NCI_STATUS_OK, if write was started. Otherwise, error status. 2592** 2593*******************************************************************************/ 2594tNFC_STATUS RW_T1tWriteNDef (UINT16 msg_len, UINT8 *p_msg) 2595{ 2596 tNFC_STATUS status = NFC_STATUS_FAILED; 2597 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 2598 UINT16 num_ndef_bytes; 2599 UINT16 offset; 2600 UINT8 addr; 2601 UINT8 init_lengthfield_len; 2602 UINT8 new_lengthfield_len; 2603 UINT16 init_ndef_msg_offset; 2604 2605 if (p_t1t->state != RW_T1T_STATE_IDLE) 2606 { 2607 RW_TRACE_WARNING1 ("RW_T1tWriteNDef - Busy - State: %u", p_t1t->state); 2608 return (NFC_STATUS_FAILED); 2609 } 2610 2611 /* Check HR0 if NDEF supported by the tag */ 2612 if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED) 2613 { 2614 RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Error: NDEF not supported by the tag"); 2615 return (NFC_STATUS_REFUSED); 2616 } 2617 2618 if ( (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE) 2619 &&(p_t1t->tag_attribute != RW_T1_TAG_ATTRB_INITIALIZED_NDEF) ) 2620 { 2621 RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Tag cannot update NDEF"); 2622 return (NFC_STATUS_REFUSED); 2623 } 2624 2625 if (msg_len > p_t1t->max_ndef_msg_len) 2626 { 2627 RW_TRACE_ERROR1 ("RW_T1tWriteNDef - Cannot write NDEF of size greater than %u bytes", p_t1t->max_ndef_msg_len); 2628 return (NFC_STATUS_REFUSED); 2629 } 2630 2631 p_t1t->p_ndef_buffer = p_msg; 2632 p_t1t->new_ndef_msg_len = msg_len; 2633 new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1; 2634 init_lengthfield_len = (UINT8) (p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset); 2635 init_ndef_msg_offset = p_t1t->ndef_msg_offset; 2636 2637 /* ndef_msg_offset should reflect the new ndef message offset */ 2638 if (init_lengthfield_len > new_lengthfield_len) 2639 { 2640 p_t1t->ndef_msg_offset = init_ndef_msg_offset - (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN); 2641 } 2642 else if (init_lengthfield_len < new_lengthfield_len) 2643 { 2644 p_t1t->ndef_msg_offset = init_ndef_msg_offset + (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN); 2645 } 2646 2647 num_ndef_bytes = 0; 2648 offset = p_t1t->ndef_msg_offset; 2649 p_t1t->segment = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE); 2650 2651 /* Locate NDEF final block based on the size of new NDEF Message */ 2652 while (num_ndef_bytes < p_t1t->new_ndef_msg_len) 2653 { 2654 if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) offset) == FALSE) 2655 num_ndef_bytes++; 2656 2657 offset++; 2658 if (offset % T1T_SEGMENT_SIZE == 0) 2659 { 2660 p_t1t->segment = (UINT8) (offset / T1T_SEGMENT_SIZE); 2661 } 2662 } 2663 2664 p_t1t->b_update = FALSE; 2665 p_t1t->b_rseg = FALSE; 2666 2667 if ((p_t1t->hr[0] & 0x0F) != 1) 2668 { 2669 /* Dynamic data structure */ 2670 p_t1t->block_read = (UINT8) ((offset - 1)/T1T_BLOCK_SIZE); 2671 /* Read NDEF final block before updating */ 2672 if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK) 2673 { 2674 p_t1t->num_ndef_finalblock = p_t1t->block_read; 2675 p_t1t->state = RW_T1T_STATE_WRITE_NDEF; 2676 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK; 2677 } 2678 } 2679 else 2680 { 2681 /* NDEF detected and Static memory structure so send WRITE-E command */ 2682 RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET)); 2683 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0)) == NFC_STATUS_OK) 2684 { 2685 p_t1t->state = RW_T1T_STATE_WRITE_NDEF; 2686 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF; 2687 } 2688 2689 } 2690 2691 if (status != NFC_STATUS_OK) 2692 { 2693 /* if status failed, reset ndef_msg_offset to initial message */ 2694 p_t1t->ndef_msg_offset = init_ndef_msg_offset; 2695 } 2696 return status; 2697} 2698 2699/******************************************************************************* 2700** 2701** Function RW_T1tSetTagReadOnly 2702** 2703** Description This function can be called to set t1 tag as read only. 2704** 2705** Parameters: None 2706** 2707** Returns NCI_STATUS_OK, if setting tag as read only was started. 2708** Otherwise, error status. 2709** 2710*******************************************************************************/ 2711tNFC_STATUS RW_T1tSetTagReadOnly (BOOLEAN b_hard_lock) 2712{ 2713 tNFC_STATUS status = NFC_STATUS_FAILED; 2714 tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; 2715 UINT8 addr; 2716 UINT8 num_locks; 2717 2718 if (p_t1t->state != RW_T1T_STATE_IDLE) 2719 { 2720 RW_TRACE_WARNING1 ("RW_T1tSetTagReadOnly - Busy - State: %u", p_t1t->state); 2721 return (NFC_STATUS_BUSY); 2722 } 2723 2724 p_t1t->b_hard_lock = b_hard_lock; 2725 2726 if ( (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_WRITE) 2727 ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED) 2728 ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF) ) 2729 { 2730 /* send WRITE-NE command */ 2731 RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_RWA_OFFSET)); 2732 if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0x0F)) == NFC_STATUS_OK) 2733 { 2734 p_t1t->b_update = FALSE; 2735 p_t1t->b_rseg = FALSE; 2736 2737 if (p_t1t->b_hard_lock) 2738 { 2739 num_locks = 0; 2740 while (num_locks < p_t1t->num_lockbytes) 2741 { 2742 p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_NOT_UPDATED; 2743 num_locks++; 2744 } 2745 } 2746 p_t1t->state = RW_T1T_STATE_SET_TAG_RO; 2747 p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO; 2748 } 2749 } 2750 2751 return status; 2752} 2753 2754#if (BT_TRACE_VERBOSE == TRUE) 2755/******************************************************************************* 2756** 2757** Function rw_t1t_get_sub_state_name 2758** 2759** Description This function returns the sub_state name. 2760** 2761** NOTE conditionally compiled to save memory. 2762** 2763** Returns pointer to the name 2764** 2765*******************************************************************************/ 2766static char *rw_t1t_get_sub_state_name (UINT8 sub_state) 2767{ 2768 switch (sub_state) 2769 { 2770 case RW_T1T_SUBSTATE_NONE: 2771 return ("NONE"); 2772 case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE: 2773 return ("EXTRACT_TLV_VALUE"); 2774 case RW_T1T_SUBSTATE_WAIT_READ_LOCKS: 2775 return ("READING_LOCKS"); 2776 case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK: 2777 return ("READ_NDEF_FINAL_BLOCK"); 2778 case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF: 2779 return ("INVALIDATING_NDEF"); 2780 case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE: 2781 return ("WRITE_NDEF_TLV_MESSAGE"); 2782 case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED: 2783 return ("WAITING_RSP_FOR_LAST_NDEF_WRITE"); 2784 case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF: 2785 return ("VALIDATING_NDEF"); 2786 case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO: 2787 return ("SET_RWA_RO"); 2788 case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS: 2789 return ("SET_STATIC_LOCK_BITS"); 2790 case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS: 2791 return ("SET_DYNAMIC_LOCK_BITS"); 2792 2793 default: 2794 return ("???? UNKNOWN SUBSTATE"); 2795 } 2796} 2797#endif /* (BT_TRACE_VERBOSE == TRUE) */ 2798 2799#endif /* (defined ((RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) */ 2800 2801#endif /* (NFC_INCLUDED == TRUE) */ 2802