rw_t2t.c revision 5c65c3a0f42e174e47fecd4e569606003217ff4e
1/****************************************************************************** 2 * 3 * Copyright (C) 2010-2013 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 20/****************************************************************************** 21 * 22 * This file contains the implementation for Type 2 tag in Reader/Writer 23 * mode. 24 * 25 ******************************************************************************/ 26#include <string.h> 27#include "nfc_target.h" 28#include "bt_types.h" 29 30#if (NFC_INCLUDED == TRUE) 31#include "nfc_api.h" 32#include "nci_hmsgs.h" 33#include "rw_api.h" 34#include "rw_int.h" 35#include "nfc_int.h" 36#include "gki.h" 37 38/* Static local functions */ 39static void rw_t2t_proc_data (UINT8 conn_id, tNFC_CONN_EVT event, BT_HDR *p_pkt); 40static tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat); 41static void rw_t2t_process_error (void); 42static void rw_t2t_process_frame_error (void); 43static void rw_t2t_handle_presence_check_rsp (tNFC_STATUS status); 44static void rw_t2t_resume_op (void); 45 46#if (BT_TRACE_VERBOSE == TRUE) 47static char *rw_t2t_get_state_name (UINT8 state); 48static char *rw_t2t_get_substate_name (UINT8 substate); 49#endif 50 51/******************************************************************************* 52** 53** Function rw_t2t_proc_data 54** 55** Description This function handles data evt received from NFC Controller. 56** 57** Returns none 58** 59*******************************************************************************/ 60static void rw_t2t_proc_data (UINT8 conn_id, tNFC_CONN_EVT event, BT_HDR *p_pkt) 61{ 62 tRW_EVENT rw_event = RW_RAW_FRAME_EVT; 63 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 64 BOOLEAN b_notify = TRUE; 65 BOOLEAN b_release = TRUE; 66 UINT8 *p; 67 tRW_READ_DATA evt_data = {0}; 68 tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info; 69 tRW_DETECT_NDEF_DATA ndef_data; 70#if (BT_TRACE_VERBOSE == TRUE) 71 UINT8 begin_state = p_t2t->state; 72#endif 73 74 if ( (p_t2t->state == RW_T2T_STATE_IDLE) 75 ||(p_cmd_rsp_info == NULL) ) 76 { 77 RW_TRACE_DEBUG2 ("rw_t2t_proc_data - Raw frame event! state: IDLE, conn_id: %u event: %u", 78 conn_id, event); 79 80 evt_data.status = NFC_STATUS_OK; 81 evt_data.p_data = p_pkt; 82 (*rw_cb.p_cback) (RW_T2T_RAW_FRAME_EVT, (tRW_DATA *)&evt_data); 83 return; 84 } 85#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 86 /* Update rx stats */ 87 rw_main_update_rx_stats (p_pkt->len); 88#endif 89 /* Stop timer as response is received */ 90 nfc_stop_quick_timer (&p_t2t->t2_timer); 91 92 RW_TRACE_EVENT2 ("RW RECV [%s]:0x%x RSP", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode); 93 94 if ( (p_pkt->len != p_cmd_rsp_info->rsp_len) 95 &&(p_pkt->len != p_cmd_rsp_info->nack_rsp_len) 96 &&(p_t2t->substate != RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) ) 97 { 98#if (BT_TRACE_VERBOSE == TRUE) 99 RW_TRACE_ERROR1 ("T2T Frame error. state=%s ", rw_t2t_get_state_name (p_t2t->state)); 100#else 101 RW_TRACE_ERROR1 ("T2T Frame error. state=0x%02X command=0x%02X ", p_t2t->state); 102#endif 103 /* Retrasmit the last sent command if retry-count < max retry */ 104 rw_t2t_process_frame_error (); 105 GKI_freebuf (p_pkt); 106 return; 107 } 108 rw_cb.cur_retry = 0; 109 110 /* Assume the data is just the response byte sequence */ 111 p = (UINT8 *) (p_pkt + 1) + p_pkt->offset; 112 113 114 RW_TRACE_EVENT5 ("rw_t2t_proc_data State: %u conn_id: %u event: %u len: %u data[0]: 0x%02x", 115 p_t2t->state, conn_id, event, p_pkt->len, *p); 116 117 evt_data.p_data = NULL; 118 119 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT) 120 { 121 /* The select process happens in two steps */ 122 if ((*p & 0x0f) == T2T_RSP_ACK) 123 { 124 if (rw_t2t_sector_change (p_t2t->select_sector) == NFC_STATUS_OK) 125 b_notify = FALSE; 126 else 127 evt_data.status = NFC_STATUS_FAILED; 128 } 129 else 130 { 131 evt_data.status = NFC_STATUS_FAILED; 132 } 133 } 134 else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) 135 { 136 evt_data.status = NFC_STATUS_FAILED; 137 } 138 else if (p_pkt->len == p_cmd_rsp_info->rsp_len) 139 { 140 /* If the response length indicates positive response or cannot be known from length then assume success */ 141 evt_data.status = NFC_STATUS_OK; 142 143 /* The response data depends on what the current operation was */ 144 switch (p_t2t->state) 145 { 146 case RW_T2T_STATE_CHECK_PRESENCE: 147 b_notify = FALSE; 148 rw_t2t_handle_presence_check_rsp (NFC_STATUS_OK); 149 break; 150 151 case RW_T2T_STATE_READ: 152 evt_data.p_data = p_pkt; 153 b_release = FALSE; 154 if (p_t2t->block_read == 0) 155 { 156 p_t2t->b_read_hdr = TRUE; 157 memcpy (p_t2t->tag_hdr, p, T2T_READ_DATA_LEN); 158 159 /* On Ultralight - C tag, if CC is corrupt, correct it */ 160 if ( (p_t2t->tag_hdr[0] == TAG_MIFARE_MID) 161 &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] >= T2T_INVALID_CC_TMS_VAL0) 162 &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] <= T2T_INVALID_CC_TMS_VAL1) ) 163 { 164 p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] = T2T_CC2_TMS_MULC; 165 } 166 } 167 break; 168 169 case RW_T2T_STATE_WRITE: 170 /* Check positive or negative acknowledgment */ 171 if ((*p & 0x0f) != T2T_RSP_ACK) 172 evt_data.status = NFC_STATUS_FAILED; 173 break; 174 175 default: 176 /* NDEF/other Tlv Operation/Format Tag/Config Tag as Read only 177 * Check if Positive response to previous write command */ 178 if ( (p_cmd_rsp_info->opcode == T2T_CMD_WRITE) 179 &&((*p & 0x0f) != T2T_RSP_ACK) ) 180 evt_data.status = NFC_STATUS_FAILED; 181 else 182 { 183 b_notify = FALSE; 184 rw_t2t_handle_rsp (p); 185 } 186 break; 187 } 188 } 189 else 190 { 191 evt_data.p_data = p_pkt; 192 if (p_t2t->state == RW_T2T_STATE_READ) 193 b_release = FALSE; 194 195 /* Negative response to the command sent */ 196 evt_data.status = NFC_STATUS_FAILED; 197 } 198 199 if (b_notify) 200 { 201 rw_event = rw_t2t_info_to_event (p_cmd_rsp_info); 202 /* Move back to idle state */ 203 rw_t2t_handle_op_complete (); 204 if (rw_event == RW_T2T_NDEF_DETECT_EVT) 205 { 206 ndef_data.status = evt_data.status; 207 ndef_data.protocol = NFC_PROTOCOL_T2T; 208 ndef_data.flags = RW_NDEF_FL_UNKNOWN; 209 ndef_data.max_size = 0; 210 ndef_data.cur_size = 0; 211 (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data); 212 } 213 else 214 (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data); 215 } 216 217 if (b_release) 218 GKI_freebuf (p_pkt); 219#if (BT_TRACE_VERBOSE == TRUE) 220 if (begin_state != p_t2t->state) 221 { 222 RW_TRACE_DEBUG2 ("RW T2T state changed:<%s> -> <%s>", 223 rw_t2t_get_state_name (begin_state), 224 rw_t2t_get_state_name (p_t2t->state)); 225 } 226#endif 227} 228 229/******************************************************************************* 230** 231** Function rw_t2t_conn_cback 232** 233** Description This callback function receives events/data from NFCC. 234** 235** Returns none 236** 237*******************************************************************************/ 238void rw_t2t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) 239{ 240 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 241 tRW_READ_DATA evt_data; 242 243 RW_TRACE_DEBUG2 ("rw_t2t_conn_cback: conn_id=%i, evt=%i", conn_id, event); 244 /* Only handle static conn_id */ 245 if (conn_id != NFC_RF_CONN_ID) 246 { 247 return; 248 } 249 250 switch (event) 251 { 252 case NFC_CONN_CREATE_CEVT: 253 case NFC_CONN_CLOSE_CEVT: 254 break; 255 256 case NFC_DEACTIVATE_CEVT: 257#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 258 /* Display stats */ 259 rw_main_log_stats (); 260#endif 261 /* Stop t2t timer (if started) */ 262 nfc_stop_quick_timer (&p_t2t->t2_timer); 263 264 /* Free cmd buf for retransmissions */ 265 if (p_t2t->p_cur_cmd_buf) 266 { 267 GKI_freebuf (p_t2t->p_cur_cmd_buf); 268 p_t2t->p_cur_cmd_buf = NULL; 269 } 270 /* Free cmd buf used to hold command before sector change */ 271 if (p_t2t->p_sec_cmd_buf) 272 { 273 GKI_freebuf (p_t2t->p_sec_cmd_buf); 274 p_t2t->p_sec_cmd_buf = NULL; 275 } 276 277 p_t2t->state = RW_T2T_STATE_NOT_ACTIVATED; 278 NFC_SetStaticRfCback (NULL); 279 break; 280 281 case NFC_DATA_CEVT: 282 if ( (p_data != NULL) 283 &&(p_data->data.status == NFC_STATUS_OK) ) 284 { 285 rw_t2t_proc_data (conn_id, event, (BT_HDR *) (p_data->data.p_data)); 286 break; 287 } 288 /* Data event with error status...fall through to NFC_ERROR_CEVT case */ 289 290 case NFC_ERROR_CEVT: 291 if ( (p_t2t->state == RW_T2T_STATE_NOT_ACTIVATED) 292 ||(p_t2t->state == RW_T2T_STATE_IDLE) ) 293 { 294#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 295 rw_main_update_trans_error_stats (); 296#endif /* RW_STATS_INCLUDED */ 297 if (event == NFC_ERROR_CEVT) 298 evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data); 299 else if (p_data) 300 evt_data.status = p_data->status; 301 else 302 evt_data.status = NFC_STATUS_FAILED; 303 304 evt_data.p_data = NULL; 305 (*rw_cb.p_cback) (RW_T2T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data); 306 break; 307 } 308 nfc_stop_quick_timer (&p_t2t->t2_timer); 309#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 310 rw_main_update_trans_error_stats (); 311#endif 312 if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE) 313 { 314 rw_t2t_handle_presence_check_rsp (NFC_STATUS_FAILED); 315 } 316 else 317 { 318 rw_t2t_process_error (); 319 } 320 break; 321 322 default: 323 break; 324 325 } 326} 327 328/******************************************************************************* 329** 330** Function rw_t2t_send_cmd 331** 332** Description This function composes a Type 2 Tag command and send it via 333** NCI to NFCC. 334** 335** Returns NFC_STATUS_OK if the command is successfuly sent to NCI 336** otherwise, error status 337** 338*******************************************************************************/ 339tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat) 340{ 341 tNFC_STATUS status = NFC_STATUS_FAILED; 342 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 343 const tT2T_CMD_RSP_INFO *p_cmd_rsp_info = t2t_cmd_to_rsp_info (opcode); 344 BT_HDR *p_data; 345 UINT8 *p; 346 347 if (p_cmd_rsp_info) 348 { 349 /* a valid opcode for RW */ 350 p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID); 351 if (p_data) 352 { 353 p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info; 354 p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 355 p = (UINT8 *) (p_data + 1) + p_data->offset; 356 357 UINT8_TO_STREAM (p, opcode); 358 359 if (p_dat) 360 { 361 ARRAY_TO_STREAM (p, p_dat, (p_cmd_rsp_info->cmd_len - 1)); 362 } 363 364 p_data->len = p_cmd_rsp_info->cmd_len; 365 366 /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */ 367 rw_cb.cur_retry = 0; 368 memcpy (p_t2t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len); 369 370#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 371 /* Update stats */ 372 rw_main_update_tx_stats (p_data->len, FALSE); 373#endif 374 RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode); 375 376 if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK) 377 { 378 nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, 379 (RW_T2T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000); 380 } 381 else 382 { 383#if (BT_TRACE_VERBOSE == TRUE) 384 RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=%s substate=%s ", rw_t2t_get_state_name (p_t2t->state), rw_t2t_get_substate_name (p_t2t->substate)); 385#else 386 RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=0x%02X substate=0x%02X ", p_t2t->state, p_t2t->substate); 387#endif 388 } 389 } 390 else 391 { 392 status = NFC_STATUS_NO_BUFFERS; 393 } 394 } 395 return status; 396} 397 398/******************************************************************************* 399** 400** Function rw_t2t_process_timeout 401** 402** Description handles timeout event 403** 404** Returns none 405** 406*******************************************************************************/ 407void rw_t2t_process_timeout (TIMER_LIST_ENT *p_tle) 408{ 409 tRW_READ_DATA evt_data; 410 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 411 412 if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE) 413 { 414 /* Move back to idle state */ 415 rw_t2t_handle_presence_check_rsp (NFC_STATUS_FAILED); 416 return; 417 } 418 419 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) 420 { 421 p_t2t->sector = p_t2t->select_sector; 422 /* Here timeout is an acknowledgment for successfull sector change */ 423 if (p_t2t->state == RW_T2T_STATE_SELECT_SECTOR) 424 { 425 /* Notify that select sector op is successfull */ 426 rw_t2t_handle_op_complete (); 427 evt_data.status = NFC_STATUS_OK; 428 evt_data.p_data = NULL; 429 (*rw_cb.p_cback) (RW_T2T_SELECT_CPLT_EVT, (tRW_DATA *) &evt_data); 430 } 431 else 432 { 433 /* Resume operation from where we stopped before sector change */ 434 rw_t2t_resume_op (); 435 } 436 } 437 else if (p_t2t->state != RW_T2T_STATE_IDLE) 438 { 439#if (BT_TRACE_VERBOSE == TRUE) 440 RW_TRACE_ERROR1 ("T2T timeout. state=%s ", rw_t2t_get_state_name (p_t2t->state)); 441#else 442 RW_TRACE_ERROR1 ("T2T timeout. state=0x%02X ", p_t2t->state); 443#endif 444 /* Handle timeout error as no response to the command sent */ 445 rw_t2t_process_error (); 446 } 447} 448 449/******************************************************************************* 450** 451** Function rw_t2t_process_frame_error 452** 453** Description handles frame crc error 454** 455** Returns none 456** 457*******************************************************************************/ 458static void rw_t2t_process_frame_error (void) 459{ 460#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 461 /* Update stats */ 462 rw_main_update_crc_error_stats (); 463#endif 464 /* Process the error */ 465 rw_t2t_process_error (); 466} 467 468/******************************************************************************* 469** 470** Function rw_t2t_process_error 471** 472** Description Process error including Timeout, Frame error. This function 473** will retry atleast till RW_MAX_RETRIES before give up and 474** sending negative notification to upper layer 475** 476** Returns none 477** 478*******************************************************************************/ 479static void rw_t2t_process_error (void) 480{ 481 tRW_READ_DATA evt_data; 482 tRW_EVENT rw_event; 483 BT_HDR *p_cmd_buf; 484 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 485 tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info; 486 tRW_DETECT_NDEF_DATA ndef_data; 487 488 RW_TRACE_DEBUG1 ("rw_t2t_process_error () State: %u", p_t2t->state); 489 490 /* Retry sending command if retry-count < max */ 491 if (rw_cb.cur_retry < RW_MAX_RETRIES) 492 { 493 /* retry sending the command */ 494 rw_cb.cur_retry++; 495 496 RW_TRACE_DEBUG2 ("T2T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES); 497 498 /* allocate a new buffer for message */ 499 if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL) 500 { 501 memcpy (p_cmd_buf, p_t2t->p_cur_cmd_buf, sizeof (BT_HDR) + p_t2t->p_cur_cmd_buf->offset + p_t2t->p_cur_cmd_buf->len); 502#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 503 /* Update stats */ 504 rw_main_update_tx_stats (p_cmd_buf->len, TRUE); 505#endif 506 if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) 507 { 508 /* Start timer for waiting for response */ 509 nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, 510 (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); 511 512 return; 513 } 514 } 515 } 516 else 517 { 518 RW_TRACE_DEBUG1 ("T2T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES); 519 } 520 rw_event = rw_t2t_info_to_event (p_cmd_rsp_info); 521#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 522 /* update failure count */ 523 rw_main_update_fail_stats (); 524#endif 525 /* If not activated remain in non activated state, otherwise move to idle state */ 526 if (p_t2t->state != RW_T2T_STATE_NOT_ACTIVATED) 527 rw_t2t_handle_op_complete (); 528 529 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 530 evt_data.status = NFC_STATUS_TIMEOUT; 531 if (rw_event == RW_T2T_NDEF_DETECT_EVT) 532 { 533 ndef_data.status = evt_data.status; 534 ndef_data.protocol = NFC_PROTOCOL_T2T; 535 ndef_data.flags = RW_NDEF_FL_UNKNOWN; 536 ndef_data.max_size = 0; 537 ndef_data.cur_size = 0; 538 (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data); 539 } 540 else 541 { 542 evt_data.p_data = NULL; 543 (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data); 544 } 545} 546 547/***************************************************************************** 548** 549** Function rw_t2t_handle_presence_check_rsp 550** 551** Description Handle response to presence check 552** 553** Returns Nothing 554** 555*****************************************************************************/ 556void rw_t2t_handle_presence_check_rsp (tNFC_STATUS status) 557{ 558 tRW_READ_DATA evt_data; 559 560 /* Notify, Tag is present or not */ 561 evt_data.status = status; 562 rw_t2t_handle_op_complete (); 563 564 (*rw_cb.p_cback) (RW_T2T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data); 565} 566 567/******************************************************************************* 568** 569** Function rw_t2t_resume_op 570** 571** Description This function will continue operation after moving to new 572** sector 573** 574** Returns tNFC_STATUS 575** 576*******************************************************************************/ 577static void rw_t2t_resume_op (void) 578{ 579 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 580 tRW_READ_DATA evt_data; 581 BT_HDR *p_cmd_buf; 582 tRW_EVENT event; 583 const tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info; 584 UINT8 *p; 585 586 /* Move back to the substate where we were before changing sector */ 587 p_t2t->substate = p_t2t->prev_substate; 588 589 p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset; 590 p_cmd_rsp_info = t2t_cmd_to_rsp_info ((UINT8) *p); 591 p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info; 592 593 /* allocate a new buffer for message */ 594 if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL) 595 { 596 memcpy (p_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_cmd_buf->len); 597 memcpy (p_t2t->p_cur_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_cmd_buf->len); 598 599#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 600 /* Update stats */ 601 rw_main_update_tx_stats (p_cmd_buf->len, TRUE); 602#endif 603 if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) 604 { 605 /* Start timer for waiting for response */ 606 nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, 607 (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); 608 } 609 else 610 { 611 /* failure - could not send buffer */ 612 evt_data.p_data = NULL; 613 evt_data.status = NFC_STATUS_FAILED; 614 event = rw_t2t_info_to_event (p_cmd_rsp_info); 615 rw_t2t_handle_op_complete (); 616 (*rw_cb.p_cback) (event, (tRW_DATA *) &evt_data); 617 } 618 } 619} 620 621/******************************************************************************* 622** 623** Function rw_t2t_sector_change 624** 625** Description This function issues Type 2 Tag SECTOR-SELECT command 626** packet 1. 627** 628** Returns tNFC_STATUS 629** 630*******************************************************************************/ 631tNFC_STATUS rw_t2t_sector_change (UINT8 sector) 632{ 633 tNFC_STATUS status; 634 BT_HDR *p_data; 635 UINT8 *p; 636 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 637 638 if ((p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL) 639 { 640 RW_TRACE_ERROR0 ("rw_t2t_sector_change - No buffer"); 641 return (NFC_STATUS_NO_BUFFERS); 642 } 643 644 p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 645 p = (UINT8 *) (p_data + 1) + p_data->offset; 646 647 UINT8_TO_BE_STREAM (p, sector); 648 UINT8_TO_BE_STREAM (p, 0x00); 649 UINT8_TO_BE_STREAM (p, 0x00); 650 UINT8_TO_BE_STREAM (p, 0x00); 651 652 p_data->len = 4; 653 654 if ((status = NFC_SendData (NFC_RF_CONN_ID , p_data)) == NFC_STATUS_OK) 655 { 656 /* Passive rsp command and suppose not to get response to this command */ 657 p_t2t->p_cmd_rsp_info = NULL; 658 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR; 659 660 RW_TRACE_EVENT0 ("rw_t2t_sector_change Sent Second Command"); 661 nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE, 662 (RW_T2T_SEC_SEL_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000); 663 } 664 else 665 { 666 RW_TRACE_ERROR1 ("rw_t2t_sector_change Send failed at rw_t2t_send_cmd, error: %u", status); 667 } 668 669 return status; 670} 671 672/******************************************************************************* 673** 674** Function rw_t2t_read 675** 676** Description This function issues Type 2 Tag READ command for the 677** specified block. If the specified block is in different 678** sector then it first sends command to move to new sector 679** and after the tag moves to new sector it issues the read 680** command for the block. 681** 682** Returns tNFC_STATUS 683** 684*******************************************************************************/ 685tNFC_STATUS rw_t2t_read (UINT16 block) 686{ 687 tNFC_STATUS status; 688 UINT8 *p; 689 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 690 UINT8 sector_byte2[1]; 691 UINT8 read_cmd[1]; 692 693 694 read_cmd[0] = block % T2T_BLOCKS_PER_SECTOR; 695 if (p_t2t->sector != block/T2T_BLOCKS_PER_SECTOR) 696 { 697 sector_byte2[0] = 0xFF; 698 /* First Move to new sector before sending Read command */ 699 if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL,sector_byte2)) == NFC_STATUS_OK) 700 { 701 /* Prepare command that needs to be sent after sector change op is completed */ 702 p_t2t->select_sector = (UINT8) (block/T2T_BLOCKS_PER_SECTOR); 703 p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 704 705 p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset; 706 UINT8_TO_BE_STREAM (p, T2T_CMD_READ); 707 UINT8_TO_BE_STREAM (p, read_cmd[0]); 708 p_t2t->p_sec_cmd_buf->len = 2; 709 p_t2t->block_read = block; 710 711 /* Backup the current substate to move back to this substate after changing sector */ 712 p_t2t->prev_substate = p_t2t->substate; 713 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT; 714 return NFC_STATUS_OK; 715 } 716 return NFC_STATUS_FAILED; 717 } 718 719 /* Send Read command as sector change is not needed */ 720 if ((status = rw_t2t_send_cmd (T2T_CMD_READ, (UINT8 *) read_cmd)) == NFC_STATUS_OK) 721 { 722 p_t2t->block_read = block; 723 RW_TRACE_EVENT1 ("rw_t2t_read Sent Command for Block: %u", block); 724 } 725 726 return status; 727} 728 729/******************************************************************************* 730** 731** Function rw_t2t_write 732** 733** Description This function issues Type 2 Tag WRITE command for the 734** specified block. If the specified block is in different 735** sector then it first sends command to move to new sector 736** and after the tag moves to new sector it issues the write 737** command for the block. 738** 739** Returns tNFC_STATUS 740** 741*******************************************************************************/ 742tNFC_STATUS rw_t2t_write (UINT16 block, UINT8 *p_write_data) 743{ 744 tNFC_STATUS status; 745 UINT8 *p; 746 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 747 UINT8 write_cmd[T2T_WRITE_DATA_LEN + 1]; 748 UINT8 sector_byte2[1]; 749 750 p_t2t->block_written = block; 751 write_cmd[0] = (UINT8) (block%T2T_BLOCKS_PER_SECTOR); 752 memcpy (&write_cmd[1], p_write_data, T2T_WRITE_DATA_LEN); 753 754 if (p_t2t->sector != block/T2T_BLOCKS_PER_SECTOR) 755 { 756 sector_byte2[0] = 0xFF; 757 /* First Move to new sector before sending Write command */ 758 if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL, sector_byte2)) == NFC_STATUS_OK) 759 { 760 /* Prepare command that needs to be sent after sector change op is completed */ 761 p_t2t->select_sector = (UINT8) (block/T2T_BLOCKS_PER_SECTOR); 762 p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 763 p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset; 764 UINT8_TO_BE_STREAM (p, T2T_CMD_WRITE); 765 memcpy (p, write_cmd, T2T_WRITE_DATA_LEN + 1); 766 p_t2t->p_sec_cmd_buf->len = 2 + T2T_WRITE_DATA_LEN; 767 p_t2t->block_written = block; 768 769 /* Backup the current substate to move back to this substate after changing sector */ 770 p_t2t->prev_substate = p_t2t->substate; 771 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT; 772 return NFC_STATUS_OK; 773 } 774 return NFC_STATUS_FAILED; 775 } 776 777 /* Send Write command as sector change is not needed */ 778 if ((status = rw_t2t_send_cmd (T2T_CMD_WRITE, write_cmd)) == NFC_STATUS_OK) 779 { 780 RW_TRACE_EVENT1 ("rw_t2t_write Sent Command for Block: %u", block); 781 } 782 783 return status; 784} 785 786/******************************************************************************* 787** 788** Function rw_t2t_select 789** 790** Description This function selects type 2 tag. 791** 792** Returns Tag selection status 793** 794*******************************************************************************/ 795tNFC_STATUS rw_t2t_select (void) 796{ 797 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 798 799 p_t2t->state = RW_T2T_STATE_IDLE; 800 p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED; 801 802 803 /* Alloc cmd buf for retransmissions */ 804 if (p_t2t->p_cur_cmd_buf == NULL) 805 { 806 if ((p_t2t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL) 807 { 808 RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer for retransmission"); 809 return (NFC_STATUS_FAILED); 810 } 811 } 812 /* Alloc cmd buf for holding a command untill sector changes */ 813 if (p_t2t->p_sec_cmd_buf == NULL) 814 { 815 if ((p_t2t->p_sec_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL) 816 { 817 RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer used during sector change"); 818 return (NFC_STATUS_FAILED); 819 } 820 } 821 822 NFC_SetStaticRfCback (rw_t2t_conn_cback); 823 rw_t2t_handle_op_complete (); 824 825 return NFC_STATUS_OK; 826} 827 828/***************************************************************************** 829** 830** Function rw_t2t_handle_op_complete 831** 832** Description Reset to IDLE state 833** 834** Returns Nothing 835** 836*****************************************************************************/ 837void rw_t2t_handle_op_complete (void) 838{ 839 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 840 841 if ( (p_t2t->state == RW_T2T_STATE_READ_NDEF) 842 ||(p_t2t->state == RW_T2T_STATE_WRITE_NDEF) ) 843 { 844 p_t2t->b_read_data = FALSE; 845 } 846 847 p_t2t->state = RW_T2T_STATE_IDLE; 848 p_t2t->substate = RW_T2T_SUBSTATE_NONE; 849 return; 850} 851 852/***************************************************************************** 853** 854** Function RW_T2tPresenceCheck 855** 856** Description 857** Check if the tag is still in the field. 858** 859** The RW_T2T_PRESENCE_CHECK_EVT w/ status is used to indicate presence 860** or non-presence. 861** 862** Returns 863** NFC_STATUS_OK, if raw data frame sent 864** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 865** NFC_STATUS_FAILED: other error 866** 867*****************************************************************************/ 868tNFC_STATUS RW_T2tPresenceCheck (void) 869{ 870 tNFC_STATUS retval = NFC_STATUS_OK; 871 tRW_DATA evt_data; 872 tRW_CB *p_rw_cb = &rw_cb; 873 UINT8 sector_blk = 0; /* block 0 of current sector */ 874 875 RW_TRACE_API0 ("RW_T2tPresenceCheck"); 876 877 /* If RW_SelectTagType was not called (no conn_callback) return failure */ 878 if (!p_rw_cb->p_cback) 879 { 880 retval = NFC_STATUS_FAILED; 881 } 882 /* If we are not activated, then RW_T2T_PRESENCE_CHECK_EVT status=FAIL */ 883 else if (p_rw_cb->tcb.t2t.state == RW_T2T_STATE_NOT_ACTIVATED) 884 { 885 evt_data.status = NFC_STATUS_FAILED; 886 (*p_rw_cb->p_cback) (RW_T2T_PRESENCE_CHECK_EVT, &evt_data); 887 } 888 /* If command is pending, assume tag is still present */ 889 else if (p_rw_cb->tcb.t2t.state != RW_T2T_STATE_IDLE) 890 { 891 evt_data.status = NFC_STATUS_OK; 892 (*p_rw_cb->p_cback) (RW_T2T_PRESENCE_CHECK_EVT, &evt_data); 893 } 894 else 895 { 896 /* IDLE state: send a READ command to block 0 of the current sector */ 897 if((retval = rw_t2t_send_cmd (T2T_CMD_READ, §or_blk))== NFC_STATUS_OK) 898 { 899 p_rw_cb->tcb.t2t.state = RW_T2T_STATE_CHECK_PRESENCE; 900 } 901 } 902 903 return (retval); 904} 905 906/******************************************************************************* 907** 908** Function RW_T2tRead 909** 910** Description This function issues the Type 2 Tag READ command. When the 911** operation is complete the callback function will be called 912** with a RW_T2T_READ_EVT. 913** 914** Returns tNFC_STATUS 915** 916*******************************************************************************/ 917tNFC_STATUS RW_T2tRead (UINT16 block) 918{ 919 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 920 tNFC_STATUS status; 921 922 if (p_t2t->state != RW_T2T_STATE_IDLE) 923 { 924 RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 925 return (NFC_STATUS_FAILED); 926 } 927 928 if ((status = rw_t2t_read (block)) == NFC_STATUS_OK) 929 { 930 p_t2t->state = RW_T2T_STATE_READ; 931 RW_TRACE_EVENT0 ("RW_T2tRead Sent Read command"); 932 } 933 934 return status; 935 936} 937 938/******************************************************************************* 939** 940** Function RW_T2tWrite 941** 942** Description This function issues the Type 2 Tag WRITE command. When the 943** operation is complete the callback function will be called 944** with a RW_T2T_WRITE_EVT. 945** 946** p_new_bytes points to the array of 4 bytes to be written 947** 948** Returns tNFC_STATUS 949** 950*******************************************************************************/ 951tNFC_STATUS RW_T2tWrite (UINT16 block, UINT8 *p_write_data) 952{ 953 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 954 tNFC_STATUS status; 955 956 if (p_t2t->state != RW_T2T_STATE_IDLE) 957 { 958 RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 959 return (NFC_STATUS_FAILED); 960 } 961 962 if ((status = rw_t2t_write (block, p_write_data)) == NFC_STATUS_OK) 963 { 964 p_t2t->state = RW_T2T_STATE_WRITE; 965 if (block < T2T_FIRST_DATA_BLOCK) 966 p_t2t->b_read_hdr = FALSE; 967 else if (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS)) 968 p_t2t->b_read_data = FALSE; 969 RW_TRACE_EVENT0 ("RW_T2tWrite Sent Write command"); 970 } 971 972 return status; 973} 974 975/******************************************************************************* 976** 977** Function RW_T2tSectorSelect 978** 979** Description This function issues the Type 2 Tag SECTOR-SELECT command 980** packet 1. If a NACK is received as the response, the callback 981** function will be called with a RW_T2T_SECTOR_SELECT_EVT. If 982** an ACK is received as the response, the command packet 2 with 983** the given sector number is sent to the peer device. When the 984** response for packet 2 is received, the callback function will 985** be called with a RW_T2T_SECTOR_SELECT_EVT. 986** 987** A sector is 256 contiguous blocks (1024 bytes). 988** 989** Returns tNFC_STATUS 990** 991*******************************************************************************/ 992tNFC_STATUS RW_T2tSectorSelect (UINT8 sector) 993{ 994 tNFC_STATUS status; 995 tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; 996 UINT8 sector_byte2[1]; 997 998 if (p_t2t->state != RW_T2T_STATE_IDLE) 999 { 1000 RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state); 1001 return (NFC_STATUS_FAILED); 1002 } 1003 1004 if (sector >= T2T_MAX_SECTOR) 1005 { 1006 RW_TRACE_ERROR2 ("RW_T2tSectorSelect - Invalid sector: %u, T2 Max supported sector value: %u", sector, T2T_MAX_SECTOR - 1); 1007 return (NFC_STATUS_FAILED); 1008 } 1009 1010 sector_byte2[0] = 0xFF; 1011 1012 if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL, sector_byte2)) == NFC_STATUS_OK) 1013 { 1014 p_t2t->state = RW_T2T_STATE_SELECT_SECTOR; 1015 p_t2t->select_sector = sector; 1016 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT; 1017 1018 RW_TRACE_EVENT0 ("RW_T2tSectorSelect Sent Sector select first command"); 1019 } 1020 1021 return status; 1022} 1023 1024#if (BT_TRACE_VERBOSE == TRUE) 1025/******************************************************************************* 1026** 1027** Function rw_t2t_get_state_name 1028** 1029** Description This function returns the state name. 1030** 1031** NOTE conditionally compiled to save memory. 1032** 1033** Returns pointer to the name 1034** 1035*******************************************************************************/ 1036static char *rw_t2t_get_state_name (UINT8 state) 1037{ 1038 switch (state) 1039 { 1040 case RW_T2T_STATE_NOT_ACTIVATED: 1041 return ("NOT_ACTIVATED"); 1042 case RW_T2T_STATE_IDLE: 1043 return ("IDLE"); 1044 case RW_T2T_STATE_READ: 1045 return ("APP_READ"); 1046 case RW_T2T_STATE_WRITE: 1047 return ("APP_WRITE"); 1048 case RW_T2T_STATE_SELECT_SECTOR: 1049 return ("SECTOR_SELECT"); 1050 case RW_T2T_STATE_DETECT_TLV: 1051 return ("TLV_DETECT"); 1052 case RW_T2T_STATE_READ_NDEF: 1053 return ("READ_NDEF"); 1054 case RW_T2T_STATE_WRITE_NDEF: 1055 return ("WRITE_NDEF"); 1056 case RW_T2T_STATE_SET_TAG_RO: 1057 return ("SET_TAG_RO"); 1058 case RW_T2T_STATE_CHECK_PRESENCE: 1059 return ("CHECK_PRESENCE"); 1060 default: 1061 return ("???? UNKNOWN STATE"); 1062 } 1063} 1064 1065/******************************************************************************* 1066** 1067** Function rw_t2t_get_substate_name 1068** 1069** Description This function returns the substate name. 1070** 1071** NOTE conditionally compiled to save memory. 1072** 1073** Returns pointer to the name 1074** 1075*******************************************************************************/ 1076static char *rw_t2t_get_substate_name (UINT8 substate) 1077{ 1078 switch (substate) 1079 { 1080 case RW_T2T_SUBSTATE_NONE: 1081 return ("RW_T2T_SUBSTATE_NONE"); 1082 case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT: 1083 return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT"); 1084 case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR: 1085 return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR"); 1086 case RW_T2T_SUBSTATE_WAIT_READ_CC: 1087 return ("RW_T2T_SUBSTATE_WAIT_READ_CC"); 1088 case RW_T2T_SUBSTATE_WAIT_TLV_DETECT: 1089 return ("RW_T2T_SUBSTATE_WAIT_TLV_DETECT"); 1090 case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN: 1091 return ("RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN"); 1092 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0: 1093 return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0"); 1094 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1: 1095 return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1"); 1096 case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE: 1097 return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE"); 1098 case RW_T2T_SUBSTATE_WAIT_READ_LOCKS: 1099 return ("RW_T2T_SUBSTATE_WAIT_READ_LOCKS"); 1100 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK: 1101 return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK"); 1102 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK: 1103 return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK"); 1104 case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK: 1105 return ("RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK"); 1106 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK: 1107 return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK"); 1108 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK: 1109 return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK"); 1110 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK: 1111 return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK"); 1112 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK: 1113 return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK"); 1114 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK: 1115 return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK"); 1116 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK: 1117 return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK"); 1118 case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT: 1119 return ("RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT"); 1120 default: 1121 return ("???? UNKNOWN SUBSTATE"); 1122 } 1123} 1124 1125#endif /* (BT_TRACE_VERBOSE == TRUE) */ 1126 1127#endif /* NFC_INCLUDED == TRUE*/ 1128