rw_t3t.c revision e9df6ba5a8fcccf306a80b1670b423be8fe7746a
1/****************************************************************************** 2 * 3 * Copyright (C) 2010-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19/****************************************************************************** 20 * 21 * This file contains the implementation for Type 3 tag in Reader/Writer 22 * mode. 23 * 24 ******************************************************************************/ 25#include <string.h> 26#include "nfc_target.h" 27#include "bt_types.h" 28#include "trace_api.h" 29 30#include "nfc_api.h" 31#include "nfc_int.h" 32#include "nci_hmsgs.h" 33#include "rw_api.h" 34#include "rw_int.h" 35#include "tags_int.h" 36#include "gki.h" 37 38/* Definitions for constructing t3t command messages */ 39#define RW_T3T_FL_PADDING 0x01 /* Padding needed for last NDEF block */ 40#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13) /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are < 256) */ 41#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12) /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are >= 256) */ 42 43/* Definitions for SENSF_RES */ 44#define RW_T3T_SENSF_RES_RD_OFFSET 17 /* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES length) */ 45#define RW_T3T_SENSF_RES_RD_LEN 2 /* Size of RD in SENSF_RES */ 46 47/* Timeout definitions for commands */ 48#define RW_T3T_POLL_CMD_TIMEOUT_TICKS ((RW_T3T_TOUT_RESP*2*QUICK_TIMER_TICKS_PER_SEC) / 1000) 49#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS ((RW_T3T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000) 50#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4) 51 52/* Macro to extract major version from NDEF version byte */ 53#define T3T_GET_MAJOR_VERSION(ver) (ver>>4) 54 55/* Enumeration of API commands */ 56enum 57{ 58 RW_T3T_CMD_DETECT_NDEF, 59 RW_T3T_CMD_CHECK_NDEF, 60 RW_T3T_CMD_UPDATE_NDEF, 61 RW_T3T_CMD_CHECK, 62 RW_T3T_CMD_UPDATE, 63 RW_T3T_CMD_SEND_RAW_FRAME, 64 RW_T3T_CMD_GET_SYSTEM_CODES, 65 RW_T3T_CMD_FORMAT, 66 67 RW_T3T_CMD_MAX 68}; 69 70/* RW_CBACK events corresponding to API comands */ 71const UINT8 rw_t3t_api_res_evt[RW_T3T_CMD_MAX] = 72{ 73 RW_T3T_NDEF_DETECT_EVT, /* RW_T3T_CMD_DETECT_NDEF */ 74 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK_NDEF */ 75 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE_NDEF */ 76 RW_T3T_CHECK_CPLT_EVT, /* RW_T3T_CMD_CHECK */ 77 RW_T3T_UPDATE_CPLT_EVT, /* RW_T3T_CMD_UPDATE */ 78 RW_T3T_RAW_FRAME_EVT, /* RW_T3T_CMD_SEND_RAW_FRAME */ 79 RW_T3T_GET_SYSTEM_CODES_EVT, /* RW_T3T_CMD_GET_SYSTEM_CODES */ 80 RW_T3T_FORMAT_CPLT_EVT /* RW_T3T_CMD_FORMAT */ 81}; 82 83/* States */ 84enum 85{ 86 RW_T3T_STATE_NOT_ACTIVATED, 87 RW_T3T_STATE_IDLE, 88 RW_T3T_STATE_COMMAND_PENDING 89}; 90 91/* Sub-states */ 92enum 93{ 94 /* Sub states for getting system codes */ 95 RW_T3T_GET_SC_SST_POLL_WILDCARD, /* Waiting for wilcard poll response */ 96 RW_T3T_GET_SC_SST_POLL_NDEF, /* Waiting for NDEF poll response */ 97 RW_T3T_GET_SC_SST_REQUEST_SC, /* Waiting for REQUEST_SYSTEM_CODE response */ 98 99 /* Sub states for formatting Felica-Lite */ 100 RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for formatting) */ 101 RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-read to complete */ 102 RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-write to complete */ 103 RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB /* Waiting for NDEF attribute block-write to complete */ 104}; 105 106#if (BT_TRACE_VERBOSE == TRUE) 107static char *rw_t3t_cmd_str (UINT8 cmd_id); 108static char *rw_t3t_state_str (UINT8 state_id); 109#endif 110 111 112/* Local static functions */ 113static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[]); 114static BT_HDR *rw_t3t_get_cmd_buf (void); 115static tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg); 116static void rw_t3t_handle_get_system_codes_cplt (void); 117static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf); 118static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf); 119static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf); 120 121 122/* Default NDEF attribute information block (used when formatting Felica-Lite tags) */ 123#define RW_T3T_DEFAULT_FELICALITE_NBR 4 /* NBr (max block reads per cmd)*/ 124#define RW_T3T_DEFAULT_FELICALITE_NBW 1 /* NBw (max block write per cmd)*/ 125#define RW_T3T_DEFAULT_FELICALITE_NMAXB 13 /* Nmaxb (max size in blocks) */ 126#define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM ((T3T_MSG_NDEF_VERSION + \ 127 RW_T3T_DEFAULT_FELICALITE_NBR + \ 128 RW_T3T_DEFAULT_FELICALITE_NBW + \ 129 (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8) + \ 130 (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF) +\ 131 T3T_MSG_NDEF_WRITEF_OFF + \ 132 T3T_MSG_NDEF_RWFLAG_RW) & 0xFFFF) 133 134const UINT8 rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] = 135{ 136 T3T_MSG_NDEF_VERSION, /* Ver */ 137 RW_T3T_DEFAULT_FELICALITE_NBR, /* NBr (max block reads per cmd)*/ 138 RW_T3T_DEFAULT_FELICALITE_NBW, /* NBw (max block write per cmd)*/ 139 (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8), /* Nmaxb (max size in blocks) */ 140 (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF), /* Nmaxb (max size in blocks) */ 141 0, 0, 0, 0, /* Unused */ 142 T3T_MSG_NDEF_WRITEF_OFF, /* WriteF */ 143 T3T_MSG_NDEF_RWFLAG_RW, /* RW Flag */ 144 0, 0, 0, /* Ln (current size in bytes) */ 145 146 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >> 8), /* checksum (high-byte) */ 147 (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM & 0xFF) /* checksum (low-byte) */ 148 149}; 150 151/***************************************************************************** 152** Type3 TAG COMMANDS 153*****************************************************************************/ 154 155/******************************************************************************* 156** 157** Function rw_t3t_process_error 158** 159** Description Process error (timeout or CRC error) 160** 161** Returns none 162** 163*******************************************************************************/ 164void rw_t3t_process_error (tNFC_STATUS status) 165{ 166 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 167 UINT8 evt; 168 tRW_DATA evt_data; 169 BT_HDR *p_cmd_buf; 170 171 if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING) 172 { 173 if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES) 174 { 175 /* For GetSystemCode: either tag did not respond to requested POLL, or REQUEST_SYSTEM_CODE command */ 176 rw_t3t_handle_get_system_codes_cplt (); 177 return; 178 } 179 /* Retry sending command if retry-count < max */ 180 else if (rw_cb.cur_retry < RW_MAX_RETRIES) 181 { 182 /* retry sending the command */ 183 rw_cb.cur_retry++; 184 185 RW_TRACE_DEBUG2 ("T3T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES); 186 187 /* allocate a new buffer for message */ 188 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 189 { 190 memcpy (p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof (BT_HDR) + p_cb->p_cur_cmd_buf->offset + p_cb->p_cur_cmd_buf->len); 191 192 if (rw_t3t_send_to_lower (p_cmd_buf) == NFC_STATUS_OK) 193 { 194 /* Start timer for waiting for response */ 195 nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, p_cb->cur_tout); 196 return; 197 } 198 else 199 { 200 /* failure - could not send buffer */ 201 GKI_freebuf (p_cmd_buf); 202 } 203 } 204 } 205 else 206 { 207 RW_TRACE_DEBUG1 ("T3T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES); 208 } 209 210#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 211 /* update failure count */ 212 rw_main_update_fail_stats (); 213#endif /* RW_STATS_INCLUDED */ 214 215 p_cb->rw_state = RW_T3T_STATE_IDLE; 216 217 /* Notify app of result (if there was a pending command) */ 218 if (p_cb->cur_cmd < RW_T3T_CMD_MAX) 219 { 220 /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise NFC_STATUS_TIMEOUT */ 221 evt_data.status = status; 222 evt = rw_t3t_api_res_evt[p_cb->cur_cmd]; 223 224 /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */ 225 if (evt == RW_T3T_NDEF_DETECT_EVT) 226 { 227 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN; 228 } 229 230 (*(rw_cb.p_cback)) (evt, &evt_data); 231 } 232 } 233 else 234 { 235 evt_data.status = status; 236 (*(rw_cb.p_cback)) (RW_T3T_INTF_ERROR_EVT, &evt_data); 237 } 238} 239 240/******************************************************************************* 241** 242** Function rw_t3t_start_poll_timer 243** 244** Description Start the timer for T3T POLL Command 245** 246** Returns none 247** 248*******************************************************************************/ 249void rw_t3t_start_poll_timer (tRW_T3T_CB *p_cb) 250{ 251 nfc_start_quick_timer (&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE, RW_T3T_POLL_CMD_TIMEOUT_TICKS); 252} 253 254/******************************************************************************* 255** 256** Function rw_t3t_handle_nci_poll_ntf 257** 258** Description Handle NCI_T3T_POLLING_NTF 259** 260** Returns none 261** 262*******************************************************************************/ 263void rw_t3t_handle_nci_poll_ntf (UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf) 264{ 265 tRW_DATA evt_data; 266 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 267 268 /* stop timer for poll response */ 269 nfc_stop_quick_timer (&p_cb->poll_timer); 270 271 /* Stop t3t timer (if started) */ 272 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) 273 { 274 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP; 275 evt_data.status = nci_status; 276 p_cb->rw_state = RW_T3T_STATE_IDLE; 277 (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data); 278 } 279 else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) 280 { 281 /* Handle POLL ntf in response to get system codes */ 282 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP; 283 rw_t3t_handle_get_sc_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf); 284 } 285 else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) 286 { 287 /* Handle POLL ntf in response to get system codes */ 288 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP; 289 rw_t3t_handle_fmt_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf); 290 } 291 else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) 292 { 293 /* Handle POLL ntf in response to ndef detection */ 294 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP; 295 rw_t3t_handle_ndef_detect_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf); 296 } 297 else 298 { 299 /* Handle POLL ntf in response to RW_T3tPoll */ 300 if ((evt_data.t3t_poll.status = nci_status) == NCI_STATUS_OK) 301 { 302 evt_data.t3t_poll.rc = p_cb->cur_poll_rc; 303 evt_data.t3t_poll.response_num = num_responses; 304 evt_data.t3t_poll.response_bufsize = sensf_res_buf_size; 305 evt_data.t3t_poll.response_buf = p_sensf_res_buf; 306 } 307 308 p_cb->rw_state = RW_T3T_STATE_IDLE; 309 (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, &evt_data); 310 } 311} 312 313 314/******************************************************************************* 315** 316** Function rw_t3t_handle_get_system_codes_cplt 317** 318** Description Notify upper layer of system codes 319** 320** Returns none 321** 322*******************************************************************************/ 323void rw_t3t_handle_get_system_codes_cplt (void) 324{ 325 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 326 tRW_DATA evt_data; 327 UINT8 i; 328 329 evt_data.t3t_sc.status = NFC_STATUS_OK; 330 evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes; 331 evt_data.t3t_sc.p_system_codes = p_cb->system_codes; 332 333 RW_TRACE_DEBUG1 ("rw_t3t_handle_get_system_codes_cplt, number of systems: %i", evt_data.t3t_sc.num_system_codes); 334 for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++) 335 { 336 RW_TRACE_DEBUG2 (" system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]); 337 } 338 339 p_cb->rw_state = RW_T3T_STATE_IDLE; 340 (*(rw_cb.p_cback)) (RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data); 341 342 343} 344 345/******************************************************************************* 346** 347** Function rw_t3t_format_cplt 348** 349** Description Notify upper layer of format complete 350** 351** Returns none 352** 353*******************************************************************************/ 354void rw_t3t_format_cplt (tNFC_STATUS status) 355{ 356 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 357 tRW_DATA evt_data; 358 359 p_cb->rw_state = RW_T3T_STATE_IDLE; 360 361 /* Notify upper layer of format complete */ 362 evt_data.status = status; 363 (*(rw_cb.p_cback)) (RW_T3T_FORMAT_CPLT_EVT, &evt_data); 364} 365 366/******************************************************************************* 367** 368** Function rw_t3t_process_timeout 369** 370** Description Process timeout 371** 372** Returns none 373** 374*******************************************************************************/ 375void rw_t3t_process_timeout (TIMER_LIST_ENT *p_tle) 376{ 377 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 378 tRW_DATA evt_data; 379 380 /* Check which timer timed out */ 381 if (p_tle == &p_cb->timer) 382 { 383 /* UPDATE/CHECK response timeout */ 384#if (BT_TRACE_VERBOSE == TRUE) 385 RW_TRACE_ERROR3 ("T3T timeout. state=%s cur_cmd=0x%02X (%s)", rw_t3t_state_str (rw_cb.tcb.t3t.rw_state), rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str (rw_cb.tcb.t3t.cur_cmd)); 386#else 387 RW_TRACE_ERROR2 ("T3T timeout. state=0x%02X cur_cmd=0x%02X", rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd); 388#endif 389 390 rw_t3t_process_error (NFC_STATUS_TIMEOUT); 391 } 392 else 393 { 394 RW_TRACE_ERROR0 ("T3T POLL timeout."); 395 396 /* POLL response timeout */ 397 if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) 398 { 399 /* POLL timeout for presence check */ 400 p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP; 401 evt_data.status = NFC_STATUS_FAILED; 402 p_cb->rw_state = RW_T3T_STATE_IDLE; 403 (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data); 404 } 405 else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) 406 { 407 /* POLL timeout for getting system codes */ 408 p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP; 409 rw_t3t_handle_get_system_codes_cplt (); 410 } 411 else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) 412 { 413 /* POLL timeout for formatting Felica Lite */ 414 p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP; 415 RW_TRACE_ERROR0 ("Felica-Lite tag not detected"); 416 rw_t3t_format_cplt (NFC_STATUS_FAILED); 417 } 418 else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) 419 { 420 /* POLL timeout for ndef detection */ 421 p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP; 422 rw_t3t_handle_ndef_detect_poll_rsp (p_cb, NFC_STATUS_TIMEOUT, 0, 0, NULL); 423 } 424 else 425 { 426 /* Timeout waiting for response for RW_T3tPoll */ 427 evt_data.t3t_poll.status = NFC_STATUS_FAILED; 428 p_cb->rw_state = RW_T3T_STATE_IDLE; 429 (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, (tRW_DATA *) &evt_data); 430 } 431 } 432} 433 434 435/******************************************************************************* 436** 437** Function rw_t3t_process_frame_error 438** 439** Description Process frame crc error 440** 441** Returns none 442** 443*******************************************************************************/ 444void rw_t3t_process_frame_error (void) 445{ 446#if (BT_TRACE_VERBOSE == TRUE) 447 RW_TRACE_ERROR3 ("T3T frame error. state=%s cur_cmd=0x%02X (%s)", rw_t3t_state_str (rw_cb.tcb.t3t.rw_state), rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str (rw_cb.tcb.t3t.cur_cmd)); 448#else 449 RW_TRACE_ERROR2 ("T3T frame error. state=0x%02X cur_cmd=0x%02X", rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd); 450#endif 451 452#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 453 /* Update stats */ 454 rw_main_update_crc_error_stats (); 455#endif /* RW_STATS_INCLUDED */ 456 457 /* Process the error */ 458 rw_t3t_process_error (NFC_STATUS_MSG_CORRUPTED); 459} 460 461/******************************************************************************* 462** 463** Function rw_t3t_send_to_lower 464** 465** Description Send command to lower layer 466** 467** Returns status of the send 468** 469*******************************************************************************/ 470tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg) 471{ 472 UINT8 *p; 473 474#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 475 BOOLEAN is_retry; 476 /* Update stats */ 477 rw_main_update_tx_stats (p_msg->len, ((rw_cb.cur_retry==0) ? FALSE : TRUE)); 478#endif /* RW_STATS_INCLUDED */ 479 480 /* Set NFC-F SoD field (payload len + 1) */ 481 p_msg->offset -= 1; /* Point to SoD field */ 482 p = (UINT8 *) (p_msg+1) + p_msg->offset; 483 UINT8_TO_STREAM (p, (p_msg->len+1)); 484 p_msg->len += 1; /* Increment len to include SoD */ 485 486#if (BT_TRACE_PROTOCOL == TRUE) 487 DispT3TagMessage (p_msg, FALSE); 488#endif 489 490 return (NFC_SendData (NFC_RF_CONN_ID, p_msg)); 491} 492 493/***************************************************************************** 494** 495** Function rw_t3t_get_cmd_buf 496** 497** Description Get a buffer for sending T3T messages 498** 499** Returns BT_HDR * 500** 501*****************************************************************************/ 502BT_HDR *rw_t3t_get_cmd_buf (void) 503{ 504 BT_HDR *p_cmd_buf; 505 506 if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL) 507 { 508 /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */ 509 p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1; 510 p_cmd_buf->len = 0; 511 } 512 513 return (p_cmd_buf); 514} 515 516/***************************************************************************** 517** 518** Function rw_t3t_send_cmd 519** 520** Description Send command to tag, and start timer for response 521** 522** Returns tNFC_STATUS 523** 524*****************************************************************************/ 525tNFC_STATUS rw_t3t_send_cmd (tRW_T3T_CB *p_cb, UINT8 rw_t3t_cmd, BT_HDR *p_cmd_buf, UINT32 timeout_ms) 526{ 527 tNFC_STATUS retval; 528 529 /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */ 530 rw_cb.cur_retry = 0; 531 memcpy (p_cb->p_cur_cmd_buf, p_cmd_buf, sizeof (BT_HDR) + p_cmd_buf->offset + p_cmd_buf->len); 532 533 p_cb->cur_cmd = rw_t3t_cmd; 534 p_cb->cur_tout = timeout_ms; 535 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING; 536 537 if ((retval = rw_t3t_send_to_lower (p_cmd_buf)) == NFC_STATUS_OK) 538 { 539 /* Start timer for waiting for response */ 540 nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, timeout_ms); 541 } 542 else 543 { 544 /* Error sending */ 545 p_cb->rw_state = RW_T3T_STATE_IDLE; 546 } 547 548 return (retval); 549} 550 551/***************************************************************************** 552** 553** Function rw_t3t_send_update_ndef_attribute_cmd 554** 555** Description Send UPDATE command for Attribute Information 556** 557** Returns tNFC_STATUS 558** 559*****************************************************************************/ 560tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd (tRW_T3T_CB *p_cb, BOOLEAN write_in_progress) 561{ 562 tNFC_STATUS retval = NFC_STATUS_OK; 563 BT_HDR *p_cmd_buf; 564 UINT8 *p_cmd_start, *p; 565 UINT16 checksum, i; 566 UINT8 write_f; 567 UINT32 ln; 568 UINT8 *p_ndef_attr_info_start; 569 570 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 571 { 572 /* Construct T3T message */ 573 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset; 574 575 /* Add UPDATE opcode to message */ 576 UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD); 577 578 /* Add IDm to message */ 579 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN); 580 581 /* Add Service code list */ 582 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */ 583 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */ 584 585 /* Add number of blocks in this UPDATE command */ 586 UINT8_TO_STREAM (p, 1); /* Number of blocks to write in this command */ 587 588 /* Block List element: the NDEF attribute information block (block 0) */ 589 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); 590 UINT8_TO_STREAM (p, 0); 591 592 /* Add payload (Attribute information block) */ 593 p_ndef_attr_info_start = p; /* Save start of a NDEF attribute info block for checksum */ 594 UINT8_TO_STREAM (p, T3T_MSG_NDEF_VERSION); 595 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr); 596 UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw); 597 UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb); 598 UINT32_TO_STREAM (p, 0); 599 600 /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */ 601 if (write_in_progress) 602 { 603 write_f = T3T_MSG_NDEF_WRITEF_ON; 604 ln = p_cb->ndef_attrib.ln; 605 } 606 /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */ 607 else 608 { 609 write_f = T3T_MSG_NDEF_WRITEF_OFF; 610 ln = p_cb->ndef_msg_len; 611 } 612 UINT8_TO_STREAM (p, write_f); 613 UINT8_TO_STREAM (p, p_cb->ndef_attrib.rwflag); 614 UINT8_TO_STREAM (p, (ln>>16) & 0xFF); /* High byte (of 3) of Ln */ 615 UINT8_TO_STREAM (p, (ln>>8) & 0xFF); /* Middle byte (of 3) of Ln */ 616 UINT8_TO_STREAM (p, (ln) & 0xFF); /* Low byte (of 3) of Ln */ 617 618 /* Calculate and append Checksum */ 619 checksum = 0; 620 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) 621 { 622 checksum+=p_ndef_attr_info_start[i]; 623 } 624 UINT16_TO_BE_STREAM (p, checksum); 625 626 627 /* Calculate length of message */ 628 p_cmd_buf->len = (UINT16) (p - p_cmd_start); 629 630 /* Send the T3T message */ 631 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS); 632 } 633 else 634 { 635 retval = NFC_STATUS_NO_BUFFERS; 636 } 637 638 return (retval); 639} 640 641/***************************************************************************** 642** 643** Function rw_t3t_send_next_ndef_update_cmd 644** 645** Description Send next segment of NDEF message to update 646** 647** Returns tNFC_STATUS 648** 649*****************************************************************************/ 650tNFC_STATUS rw_t3t_send_next_ndef_update_cmd (tRW_T3T_CB *p_cb) 651{ 652 tNFC_STATUS retval = NFC_STATUS_OK; 653 UINT16 block_id; 654 UINT16 first_block_to_write; 655 UINT16 ndef_blocks_to_write, ndef_blocks_remaining; 656 UINT32 ndef_bytes_remaining, ndef_padding = 0; 657 UINT8 flags = 0; 658 UINT8 *p_cur_ndef_src_offset; 659 BT_HDR *p_cmd_buf; 660 UINT8 *p_cmd_start, *p; 661 UINT8 blocks_per_update; 662 UINT32 timeout; 663 664 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 665 { 666 /* Construct T3T message */ 667 p = p_cmd_start = (UINT8 *) (p_cmd_buf + 1) + p_cmd_buf->offset; 668 669 /* Calculate number of ndef bytes remaining to write */ 670 ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent; 671 672 /* Calculate number of blocks remaining to write */ 673 ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4); /* ndef blocks remaining (rounded upward) */ 674 675 /* Calculate first NDEF block ID for this UPDATE command */ 676 first_block_to_write = (UINT16) ((p_cb->ndef_msg_bytes_sent >> 4) + 1); 677 678 /* Calculate max number of blocks per write. */ 679 if ((first_block_to_write + RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100) 680 { 681 /* All block-numbers are < 0x100 (i.e. can be specified using one-byte format) */ 682 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT; 683 } 684 else 685 { 686 /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte format) */ 687 blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT; 688 } 689 690 /* Check if blocks_per_update is bigger than what peer allows */ 691 if (blocks_per_update > p_cb->ndef_attrib.nbw) 692 blocks_per_update = p_cb->ndef_attrib.nbw; 693 694 /* Check if remaining blocks can fit into one UPDATE command */ 695 if (ndef_blocks_remaining <= blocks_per_update) 696 { 697 /* remaining blocks can fit into one UPDATE command */ 698 ndef_blocks_to_write = ndef_blocks_remaining; 699 } 700 else 701 { 702 /* Remaining blocks cannot fit into one UPDATE command */ 703 ndef_blocks_to_write = blocks_per_update; 704 } 705 706 707 /* Write to command header for UPDATE */ 708 709 /* Add UPDATE opcode to message */ 710 UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD); 711 712 /* Add IDm to message */ 713 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN); 714 715 /* Add Service code list */ 716 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */ 717 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */ 718 719 720 /* Add number of blocks in this UPDATE command */ 721 UINT8_TO_STREAM (p, ndef_blocks_to_write); /* Number of blocks to write in this command */ 722 timeout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) ndef_blocks_to_write; 723 724 for (block_id = first_block_to_write; block_id < (first_block_to_write + ndef_blocks_to_write); block_id++) 725 { 726 if (block_id<256) 727 { 728 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */ 729 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte0: len=1; access-mode=0; service code list order=0 */ 730 UINT8_TO_STREAM (p, block_id); /* byte1: block number */ 731 } 732 else 733 { 734 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */ 735 UINT8_TO_STREAM (p, 0x00); /* byte0: len=0; access-mode=0; service code list order=0 */ 736 UINT16_TO_STREAM (p, block_id); /* byte1-2: block number in little-endian format */ 737 } 738 739 } 740 741 /* Add NDEF payload */ 742 743 /* If this sending last block of NDEF, check if padding is needed to make payload a multiple of 16 bytes */ 744 if (ndef_blocks_to_write == ndef_blocks_remaining) 745 { 746 ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F; 747 if (ndef_padding) 748 { 749 flags |= RW_T3T_FL_PADDING; 750 ndef_blocks_to_write--; /* handle the last block separately if it needs padding */ 751 } 752 } 753 754 /* Add NDEF payload to the message */ 755 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent]; 756 757 758 ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16)); 759 p_cb->ndef_msg_bytes_sent += ((UINT32) ndef_blocks_to_write * 16); 760 761 if (flags & RW_T3T_FL_PADDING) 762 { 763 /* Add last of the NDEF message */ 764 p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent]; 765 ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (int) (16-ndef_padding)); 766 p_cb->ndef_msg_bytes_sent += (16-ndef_padding); 767 768 /* Add padding */ 769 memset (p, 0, ndef_padding); 770 p+=ndef_padding; 771 } 772 773 /* Calculate length of message */ 774 p_cmd_buf->len = (UINT16) (p - p_cmd_start); 775 776 /* Send the T3T message */ 777 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout); 778 } 779 else 780 { 781 retval = NFC_STATUS_NO_BUFFERS; 782 } 783 784 return (retval); 785} 786 787 788 789/***************************************************************************** 790** 791** Function rw_t3t_send_next_ndef_check_cmd 792** 793** Description Send command for reading next segment of NDEF message 794** 795** Returns tNFC_STATUS 796** 797*****************************************************************************/ 798tNFC_STATUS rw_t3t_send_next_ndef_check_cmd (tRW_T3T_CB *p_cb) 799{ 800 tNFC_STATUS retval = NFC_STATUS_OK; 801 UINT16 block_id; 802 UINT16 ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read; 803 UINT32 ndef_bytes_remaining; 804 BT_HDR *p_cmd_buf; 805 UINT8 *p_cmd_start, *p; 806 807 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 808 { 809 /* Construct T3T message */ 810 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset; 811 812 /* Calculate number of ndef bytes remaining to read */ 813 ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset; 814 815 /* Calculate number of blocks remaining to read */ 816 ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4); /* ndef blocks remaining (rounded upward) */ 817 818 /* Calculate first NDEF block ID */ 819 first_block_to_read = (UINT16) ((p_cb->ndef_rx_offset >> 4) + 1); 820 821 /* Check if remaining blocks can fit into one CHECK command */ 822 if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr) 823 { 824 /* remaining blocks can fit into one CHECK command */ 825 cur_blocks_to_read = ndef_blocks_remaining; 826 p_cb->ndef_rx_readlen = ndef_bytes_remaining; 827 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT; 828 } 829 else 830 { 831 /* Remaining blocks cannot fit into one CHECK command */ 832 cur_blocks_to_read = p_cb->ndef_attrib.nbr; /* Read maximum number of blocks allowed by the peer */ 833 p_cb->ndef_rx_readlen = ((UINT32) p_cb->ndef_attrib.nbr * 16); 834 } 835 836 RW_TRACE_DEBUG3 ("rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i", 837 ndef_bytes_remaining, cur_blocks_to_read, (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)); 838 839 /* Write to command header for UPDATE */ 840 841 /* Add UPDATE opcode to message */ 842 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD); 843 844 /* Add IDm to message */ 845 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN); 846 847 /* Add Service code list */ 848 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */ 849 850 /* Service code (little-endian format) . If NDEF is read-only, then use T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */ 851 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO) 852 { 853 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); 854 } 855 else 856 { 857 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); 858 } 859 860 /* Add number of blocks in this UPDATE command */ 861 UINT8_TO_STREAM (p, cur_blocks_to_read); /* Number of blocks to check in this command */ 862 863 for (block_id = first_block_to_read; block_id < (first_block_to_read + cur_blocks_to_read); block_id++) 864 { 865 if (block_id<256) 866 { 867 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */ 868 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte1: len=0; access-mode=0; service code list order=0 */ 869 UINT8_TO_STREAM (p, block_id); /* byte1: block number */ 870 } 871 else 872 { 873 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */ 874 UINT8_TO_STREAM (p, 0x00); /* byte0: len=1; access-mode=0; service code list order=0 */ 875 UINT16_TO_STREAM (p, block_id); /* byte1-2: block number in little-endian format */ 876 } 877 878 } 879 880 /* Calculate length of message */ 881 p_cmd_buf->len = (UINT16) (p - p_cmd_start); 882 883 /* Send the T3T message */ 884 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) cur_blocks_to_read); 885 } 886 else 887 { 888 retval = NFC_STATUS_NO_BUFFERS; 889 } 890 891 return(retval); 892} 893 894 895/***************************************************************************** 896** 897** Function rw_t3t_message_set_block_list 898** 899** Description Add block list to T3T message 900** 901** Returns Number of bytes added to message 902** 903*****************************************************************************/ 904void rw_t3t_message_set_block_list (tRW_T3T_CB *p_cb, UINT8 **p, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks) 905{ 906 UINT16 i, cur_service_code; 907 UINT8 service_code_idx, num_services = 0; 908 UINT8 *p_msg_num_services; 909 UINT16 service_list[T3T_MSG_SERVICE_LIST_MAX]; 910 911 /* Add CHECK or UPDATE opcode to message */ 912 UINT8_TO_STREAM ((*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD:T3T_MSG_OPC_UPDATE_CMD)); 913 914 /* Add IDm to message */ 915 ARRAY_TO_STREAM ((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN); 916 917 /* Skip over Number of Services field */ 918 p_msg_num_services = (*p); /* pointer to Number of Services offset */ 919 (*p)++; 920 921 /* Count number of different services are specified in the list, and add services to Service Code list */ 922 for (i = 0; i < num_blocks; i++) 923 { 924 cur_service_code = p_t3t_blocks[i].service_code; 925 926 /* Check if current service_code is already in the service_list */ 927 for (service_code_idx=0; service_code_idx<num_services; service_code_idx++) 928 { 929 if (service_list[service_code_idx] == cur_service_code) 930 break; 931 } 932 933 if (service_code_idx == num_services) 934 { 935 /* Service not in the list yet. Add it. */ 936 service_list[service_code_idx] = cur_service_code; 937 num_services++; 938 939 /* Add service code to T3T message */ 940 UINT16_TO_STREAM ((*p), cur_service_code); 941 } 942 } 943 944 /* Add 'Number of Sservices' to the message */ 945 *p_msg_num_services = num_services; 946 947 /* Add 'number of blocks' to the message */ 948 UINT8_TO_STREAM ((*p), num_blocks); 949 950 /* Add block descriptors */ 951 for (i = 0; i < num_blocks; i++) 952 { 953 cur_service_code = p_t3t_blocks[i].service_code; 954 955 /* Check if current service_code is already in the service_list */ 956 for (service_code_idx=0; service_code_idx<num_services; service_code_idx++) 957 { 958 if (service_list[service_code_idx] == cur_service_code) 959 break; 960 } 961 962 /* Add decriptor to T3T message */ 963 if (p_t3t_blocks[i].block_number > 0xFF) 964 { 965 UINT8_TO_STREAM ((*p), service_code_idx); 966 UINT16_TO_STREAM ((*p), p_t3t_blocks[i].block_number); 967 } 968 else 969 { 970 service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT; 971 UINT8_TO_STREAM ((*p), service_code_idx); 972 UINT8_TO_STREAM ((*p), p_t3t_blocks[i].block_number); 973 } 974 } 975} 976 977/***************************************************************************** 978** 979** Function rw_t3t_send_check_cmd 980** 981** Description Send CHECK command 982** 983** Returns tNFC_STATUS 984** 985*****************************************************************************/ 986tNFC_STATUS rw_t3t_send_check_cmd (tRW_T3T_CB *p_cb, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks) 987{ 988 BT_HDR *p_cmd_buf; 989 UINT8 *p, *p_cmd_start; 990 tNFC_STATUS retval = NFC_STATUS_OK; 991 992 p_cb->cur_cmd = RW_T3T_CMD_CHECK; 993 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 994 { 995 /* Construct T3T message */ 996 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset; 997 rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks); 998 999 /* Calculate length of message */ 1000 p_cmd_buf->len = (UINT16) (p - p_cmd_start); 1001 1002 /* Send the T3T message */ 1003 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) num_blocks); 1004 } 1005 else 1006 { 1007 retval = NFC_STATUS_NO_BUFFERS; 1008 } 1009 1010 return(retval); 1011} 1012 1013/***************************************************************************** 1014** 1015** Function rw_t3t_send_update_cmd 1016** 1017** Description Send UPDATE command 1018** 1019** Returns tNFC_STATUS 1020** 1021*****************************************************************************/ 1022tNFC_STATUS rw_t3t_send_update_cmd (tRW_T3T_CB *p_cb, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks, UINT8 *p_data) 1023{ 1024 BT_HDR *p_cmd_buf; 1025 UINT8 *p, *p_cmd_start; 1026 tNFC_STATUS retval = NFC_STATUS_OK; 1027 1028 p_cb->cur_cmd = RW_T3T_CMD_UPDATE; 1029 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 1030 { 1031 /* Construct T3T message */ 1032 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset; 1033 rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks); 1034 1035 /* Add data blocks to the message */ 1036 ARRAY_TO_STREAM (p, p_data, num_blocks*16); 1037 1038 /* Calculate length of message */ 1039 p_cmd_buf->len = (UINT16) (p - p_cmd_start); 1040 1041 /* Send the T3T message */ 1042 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) num_blocks); 1043 } 1044 else 1045 { 1046 retval = NFC_STATUS_NO_BUFFERS; 1047 } 1048 1049 return(retval); 1050} 1051 1052/***************************************************************************** 1053** 1054** Function rw_t3t_send_raw_frame 1055** 1056** Description Send raw frame 1057** 1058** Returns tNFC_STATUS 1059** 1060*****************************************************************************/ 1061tNFC_STATUS rw_t3t_send_raw_frame (tRW_T3T_CB *p_cb, UINT16 len, UINT8 *p_data) 1062{ 1063 BT_HDR *p_cmd_buf; 1064 UINT8 *p; 1065 tNFC_STATUS retval = NFC_STATUS_OK; 1066 1067 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 1068 { 1069 /* Construct T3T message */ 1070 p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset; 1071 1072 /* Add data blocks to the message */ 1073 ARRAY_TO_STREAM (p, p_data, len); 1074 1075 /* Calculate length of message */ 1076 p_cmd_buf->len = len; 1077 1078 /* Send the T3T message */ 1079 retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf, RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS); 1080 } 1081 else 1082 { 1083 retval = NFC_STATUS_NO_BUFFERS; 1084 } 1085 1086 return (retval); 1087} 1088 1089 1090/***************************************************************************** 1091** TAG RESPONSE HANDLERS 1092*****************************************************************************/ 1093 1094 1095/***************************************************************************** 1096** 1097** Function rw_t3t_act_handle_ndef_detect_rsp 1098** 1099** Description Handle response to NDEF detection 1100** 1101** Returns Nothing 1102** 1103*****************************************************************************/ 1104void rw_t3t_act_handle_ndef_detect_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp) 1105{ 1106 UINT8 *p; 1107 UINT32 temp; 1108 UINT8 i; 1109 UINT16 checksum_calc, checksum_rx; 1110 tRW_DETECT_NDEF_DATA evt_data; 1111 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset; 1112 1113 evt_data.status = NFC_STATUS_FAILED; 1114 evt_data.flags = RW_NDEF_FL_UNKNOWN; 1115 1116 /* Check if response code is CHECK resp (for reading NDEF attribute block) */ 1117 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) 1118 { 1119 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]); 1120 evt_data.status = NFC_STATUS_FAILED; 1121 } 1122 /* Validate status code and NFCID2 response from tag */ 1123 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */ 1124 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */ 1125 { 1126 evt_data.status = NFC_STATUS_FAILED; 1127 } 1128 else 1129 { 1130 /* Get checksum from received ndef attribute msg */ 1131 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA+T3T_MSG_NDEF_ATTR_INFO_SIZE]; 1132 BE_STREAM_TO_UINT16 (checksum_rx, p); 1133 1134 /* Calculate checksum - move check for checsum to beginning */ 1135 checksum_calc = 0; 1136 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; 1137 for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) 1138 { 1139 checksum_calc+=p[i]; 1140 } 1141 1142 /* Validate checksum */ 1143 if (checksum_calc != checksum_rx) 1144 { 1145 p_cb->ndef_attrib.status = NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be boolean*/ 1146 1147 RW_TRACE_ERROR0 ("RW_T3tDetectNDEF checksum failed"); 1148 } 1149 else 1150 { 1151 p_cb->ndef_attrib.status = NFC_STATUS_OK; 1152 1153 /* Validate version number */ 1154 STREAM_TO_UINT8 (p_cb->ndef_attrib.version, p); 1155 1156 if (T3T_GET_MAJOR_VERSION (T3T_MSG_NDEF_VERSION) < T3T_GET_MAJOR_VERSION (p_cb->ndef_attrib.version)) 1157 { 1158 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP RQ_T3T_NDA_024 */ 1159 RW_TRACE_ERROR2 ("RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, Remote=0x%02x", T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version); 1160 p_cb->ndef_attrib.status = NFC_STATUS_FAILED; 1161 evt_data.status = NFC_STATUS_BAD_RESP; 1162 } 1163 else 1164 { 1165 /* Remote tag's MajorVer is equal or older than our's. NDEF is compatible with our version. */ 1166 1167 /* Update NDEF info */ 1168 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbr, p); /* NBr: number of blocks that can be read using one Check command */ 1169 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbw, p); /* Nbw: number of blocks that can be written using one Update command */ 1170 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.nmaxb, p); /* Nmaxb: maximum number of blocks available for NDEF data */ 1171 BE_STREAM_TO_UINT32 (temp, p); 1172 STREAM_TO_UINT8 (p_cb->ndef_attrib.writef, p); /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */ 1173 STREAM_TO_UINT8 (p_cb->ndef_attrib.rwflag, p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */ 1174 1175 /* Get length (3-byte, big-endian) */ 1176 STREAM_TO_UINT8 (temp, p); /* Ln: high-byte */ 1177 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.ln, p); /* Ln: lo-word */ 1178 p_cb->ndef_attrib.ln += (temp << 16); 1179 1180 1181 RW_TRACE_DEBUG1 ("Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version); 1182 RW_TRACE_DEBUG6 ("Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, RWFlag=%i, Ln=%i", 1183 p_cb->ndef_attrib.nbr, 1184 p_cb->ndef_attrib.nbw, 1185 p_cb->ndef_attrib.nmaxb, 1186 p_cb->ndef_attrib.writef, 1187 p_cb->ndef_attrib.rwflag, 1188 p_cb->ndef_attrib.ln); 1189 1190 /* Set data for RW_T3T_NDEF_DETECT_EVT */ 1191 evt_data.status = p_cb->ndef_attrib.status; 1192 evt_data.cur_size = p_cb->ndef_attrib.ln; 1193 evt_data.max_size = (UINT32) p_cb->ndef_attrib.nmaxb * 16; 1194 evt_data.protocol = NFC_PROTOCOL_T3T; 1195 evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED); 1196 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO) 1197 evt_data.flags |= RW_NDEF_FL_READ_ONLY; 1198 } 1199 } 1200 } 1201 1202 RW_TRACE_DEBUG1 ("RW_T3tDetectNDEF response: %i", evt_data.status); 1203 1204 p_cb->rw_state = RW_T3T_STATE_IDLE; 1205 1206 /* Notify app of NDEF detection result */ 1207 (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, (tRW_DATA *) &evt_data); 1208 1209 GKI_freebuf (p_msg_rsp); 1210} 1211 1212 1213/***************************************************************************** 1214** 1215** Function rw_t3t_act_handle_check_rsp 1216** 1217** Description Handle response to CHECK command 1218** 1219** Returns Nothing 1220** 1221*****************************************************************************/ 1222void rw_t3t_act_handle_check_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp) 1223{ 1224 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset; 1225 tRW_READ_DATA evt_data; 1226 tNFC_STATUS nfc_status = NFC_STATUS_OK; 1227 1228 /* Validate response from tag */ 1229 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */ 1230 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */ 1231 { 1232 nfc_status = NFC_STATUS_FAILED; 1233 GKI_freebuf (p_msg_rsp); 1234 } 1235 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) 1236 { 1237 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]); 1238 nfc_status = NFC_STATUS_FAILED; 1239 GKI_freebuf (p_msg_rsp); 1240 } 1241 else 1242 { 1243 /* Copy incoming data into buffer */ 1244 p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */ 1245 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA; 1246 evt_data.status = NFC_STATUS_OK; 1247 evt_data.p_data = p_msg_rsp; 1248 (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &evt_data); 1249 } 1250 1251 1252 p_cb->rw_state = RW_T3T_STATE_IDLE; 1253 1254 (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &nfc_status); 1255} 1256 1257/***************************************************************************** 1258** 1259** Function rw_t3t_act_handle_update_rsp 1260** 1261** Description Handle response to UPDATE command 1262** 1263** Returns Nothing 1264** 1265*****************************************************************************/ 1266void rw_t3t_act_handle_update_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp) 1267{ 1268 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset; 1269 tRW_READ_DATA evt_data; 1270 1271 /* Validate response from tag */ 1272 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */ 1273 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */ 1274 { 1275 evt_data.status = NFC_STATUS_FAILED; 1276 } 1277 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) 1278 { 1279 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]); 1280 evt_data.status = NFC_STATUS_FAILED; 1281 } 1282 else 1283 { 1284 /* Copy incoming data into buffer */ 1285 evt_data.status = NFC_STATUS_OK; 1286 } 1287 1288 p_cb->rw_state = RW_T3T_STATE_IDLE; 1289 1290 (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *)&evt_data); 1291 1292 GKI_freebuf (p_msg_rsp); 1293} 1294 1295/***************************************************************************** 1296** 1297** Function rw_t3t_act_handle_raw_senddata_rsp 1298** 1299** Description Handle response to NDEF detection 1300** 1301** Returns Nothing 1302** 1303*****************************************************************************/ 1304void rw_t3t_act_handle_raw_senddata_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp) 1305{ 1306 tRW_READ_DATA evt_data; 1307 1308 /* Copy incoming data into buffer */ 1309 evt_data.status = NFC_STATUS_OK; 1310 evt_data.p_data = p_msg_rsp; 1311 1312 p_cb->rw_state = RW_T3T_STATE_IDLE; 1313 1314 (*(rw_cb.p_cback)) (RW_T3T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data); 1315} 1316 1317/***************************************************************************** 1318** 1319** Function rw_t3t_act_handle_check_ndef_rsp 1320** 1321** Description Handle response to NDEF read segment 1322** 1323** Returns Nothing 1324** 1325*****************************************************************************/ 1326void rw_t3t_act_handle_check_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp) 1327{ 1328 BOOLEAN check_complete = TRUE; 1329 tNFC_STATUS nfc_status = NFC_STATUS_OK; 1330 tRW_READ_DATA read_data; 1331 tRW_DATA evt_data; 1332 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset; 1333 UINT8 rsp_num_bytes_rx; 1334 1335 /* Validate response from tag */ 1336 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */ 1337 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) /* verify response IDm */ 1338 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] != ((p_cb->ndef_rx_readlen+15) >> 4)) ) /* verify length of response */ 1339 { 1340 RW_TRACE_ERROR2 ("Response error: bad status, nfcid2, or invalid len: %i %i", p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS], ((p_cb->ndef_rx_readlen+15)>>4)); 1341 nfc_status = NFC_STATUS_FAILED; 1342 GKI_freebuf (p_msg_rsp); 1343 } 1344 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) 1345 { 1346 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]); 1347 nfc_status = NFC_STATUS_FAILED; 1348 GKI_freebuf (p_msg_rsp); 1349 } 1350 else 1351 { 1352 /* Notify app of NDEF segment received */ 1353 rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] * 16; /* Number of bytes received, according to header */ 1354 p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen; 1355 read_data.status = NFC_STATUS_OK; 1356 p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block data) */ 1357 p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA; 1358 1359 /* Verify that the bytes received is really the amount indicated in the check-response header */ 1360 if (rsp_num_bytes_rx > p_msg_rsp->len) 1361 { 1362 RW_TRACE_ERROR2 ("Response error: CHECK rsp header indicates %i bytes, but only received %i bytes", rsp_num_bytes_rx, p_msg_rsp->len); 1363 nfc_status = NFC_STATUS_FAILED; 1364 GKI_freebuf (p_msg_rsp); 1365 } 1366 else 1367 { 1368 /* If this is the the final block, then set len to reflect only valid bytes (do not include padding to 16-byte boundary) */ 1369 if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) && (p_cb->ndef_attrib.ln & 0x000F)) 1370 { 1371 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F)); 1372 } 1373 1374 p_msg_rsp->len = rsp_num_bytes_rx; 1375 read_data.p_data = p_msg_rsp; 1376 (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &read_data); 1377 1378 /* Send CHECK cmd for next NDEF segment, if needed */ 1379 if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)) 1380 { 1381 if ((nfc_status = rw_t3t_send_next_ndef_check_cmd (p_cb)) == NFC_STATUS_OK) 1382 { 1383 /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet */ 1384 check_complete = FALSE; 1385 } 1386 } 1387 } 1388 } 1389 1390 /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if failure */ 1391 if (check_complete) 1392 { 1393 p_cb->rw_state = RW_T3T_STATE_IDLE; 1394 evt_data.status = nfc_status; 1395 (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &evt_data); 1396 } 1397} 1398 1399 1400/***************************************************************************** 1401** 1402** Function rw_t3t_act_handle_update_ndef_rsp 1403** 1404** Description Handle response to NDEF write segment 1405** 1406** Returns Nothing 1407** 1408*****************************************************************************/ 1409void rw_t3t_act_handle_update_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp) 1410{ 1411 BOOLEAN update_complete = TRUE; 1412 tNFC_STATUS nfc_status = NFC_STATUS_OK; 1413 tRW_DATA evt_data; 1414 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset; 1415 1416 /* Check nfcid2 and status of response */ 1417 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */ 1418 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */ 1419 { 1420 nfc_status = NFC_STATUS_FAILED; 1421 } 1422 /* Validate response opcode */ 1423 else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) 1424 { 1425 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]); 1426 nfc_status = NFC_STATUS_FAILED; 1427 } 1428 /* If this is response to final UPDATE, then update NDEF local size */ 1429 else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) 1430 { 1431 /* If successful, update current NDEF size */ 1432 p_cb->ndef_attrib.ln = p_cb->ndef_msg_len; 1433 } 1434 /* If any more NDEF bytes to update, then send next UPDATE command */ 1435 else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len) 1436 { 1437 /* Send UPDATE command for next segment of NDEF */ 1438 if ((nfc_status = rw_t3t_send_next_ndef_update_cmd (p_cb)) == NFC_STATUS_OK) 1439 { 1440 /* Wait for update response */ 1441 update_complete = FALSE; 1442 } 1443 } 1444 /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information block */ 1445 else 1446 { 1447 p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT; 1448 if ((nfc_status = rw_t3t_send_update_ndef_attribute_cmd (p_cb, FALSE)) == NFC_STATUS_OK) 1449 { 1450 /* Wait for update response */ 1451 update_complete = FALSE; 1452 } 1453 } 1454 1455 /* If update is completed, then notify app */ 1456 if (update_complete) 1457 { 1458 p_cb->rw_state = RW_T3T_STATE_IDLE; 1459 evt_data.status = nfc_status; 1460 (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *) &evt_data); 1461 } 1462 1463 1464 GKI_freebuf (p_msg_rsp); 1465 1466 return; 1467} 1468 1469 1470/***************************************************************************** 1471** 1472** Function rw_t3t_handle_get_sc_poll_rsp 1473** 1474** Description Handle POLL response for getting system codes 1475** 1476** Returns Nothing 1477** 1478*****************************************************************************/ 1479static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf) 1480{ 1481 BT_HDR *p_cmd_buf; 1482 UINT8 *p, *p_cmd_start; 1483 UINT16 sc; 1484 tNFC_STATUS status = NFC_STATUS_FAILED; 1485 1486 /* If waiting for wildcard POLL */ 1487 if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_WILDCARD) 1488 { 1489 /* Get the system code from the response */ 1490 if ( (nci_status == NCI_STATUS_OK) 1491 &&(num_responses > 0) 1492 &&(sensf_res_buf_size >= (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN)) ) 1493 { 1494 p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET]; 1495 BE_STREAM_TO_UINT16 (sc, p); 1496 1497 /* Handle felica lite */ 1498 if (sc == T3T_SYSTEM_CODE_FELICA_LITE) 1499 { 1500 RW_TRACE_DEBUG1 ("FeliCa Lite tag detected (system code %04X)", sc); 1501 /* Store system code */ 1502 p_cb->system_codes[p_cb->num_system_codes++] = sc; 1503 1504 /* Poll for NDEF system code */ 1505 if ((status = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_NDEF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK) 1506 { 1507 p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_NDEF; 1508 p_cb->cur_poll_rc = 0; 1509 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP; 1510 1511 /* start timer for waiting for responses */ 1512 rw_t3t_start_poll_timer (p_cb); 1513 } 1514 } 1515 else 1516 { 1517 /* All other types, send REQUEST_SYSTEM_CODE command */ 1518 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 1519 { 1520 p_cb->rw_substate = RW_T3T_GET_SC_SST_REQUEST_SC; 1521 1522 /* Construct T3T message */ 1523 p_cmd_start = p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset; 1524 UINT8_TO_STREAM (p, T3T_MSG_OPC_REQ_SYSTEMCODE_CMD); 1525 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN); 1526 1527 /* Fill in length field */ 1528 p_cmd_buf->len = (UINT16) (p - p_cmd_start); 1529 1530 /* Send the T3T message */ 1531 status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_GET_SYSTEM_CODES, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS); 1532 } 1533 } 1534 } 1535 1536 /* Error proceeding. Notify upper layer of system codes found so far */ 1537 if (status != NFC_STATUS_OK) 1538 { 1539 rw_t3t_handle_get_system_codes_cplt (); 1540 } 1541 } 1542 /* If waiting for NDEF POLL */ 1543 else if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_NDEF) 1544 { 1545 /* Validate response for NDEF poll */ 1546 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) 1547 { 1548 /* Tag responded for NDEF poll */ 1549 p_cb->system_codes[p_cb->num_system_codes++] = T3T_SYSTEM_CODE_NDEF; 1550 } 1551 rw_t3t_handle_get_system_codes_cplt (); 1552 } 1553} 1554 1555/***************************************************************************** 1556** 1557** Function rw_t3t_handle_ndef_detect_poll_rsp 1558** 1559** Description Handle POLL response for getting system codes 1560** 1561** Returns Nothing 1562** 1563*****************************************************************************/ 1564static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf) 1565{ 1566 BT_HDR *p_cmd_buf; 1567 UINT8 *p, *p_cmd_start; 1568 tRW_DATA evt_data; 1569 1570 /* Validate response for NDEF poll */ 1571 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) 1572 { 1573 /* Tag responded for NDEF poll */ 1574 1575 /* Read NDEF attribute block */ 1576 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 1577 { 1578 /* Construct T3T message */ 1579 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset; 1580 1581 /* Add CHECK opcode to message */ 1582 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD); 1583 1584 /* Add IDm to message */ 1585 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN); 1586 1587 /* Add Service code list */ 1588 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */ 1589 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */ 1590 1591 /* Number of blocks */ 1592 UINT8_TO_STREAM (p, 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */ 1593 1594 /* Block List element: the NDEF attribute information block (block 0) */ 1595 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); 1596 UINT8_TO_STREAM (p, 0); 1597 1598 /* Calculate length of message */ 1599 p_cmd_buf->len = (UINT16) (p - p_cmd_start); 1600 1601 /* Send the T3T message */ 1602 if ((evt_data.status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS)) == NFC_STATUS_OK) 1603 { 1604 /* CHECK command sent. Wait for response */ 1605 return; 1606 } 1607 } 1608 nci_status = NFC_STATUS_FAILED; 1609 } 1610 1611 /* NDEF detection failed */ 1612 p_cb->rw_state = RW_T3T_STATE_IDLE; 1613 evt_data.ndef.status = nci_status; 1614 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN; 1615 (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, &evt_data); 1616} 1617 1618 1619/***************************************************************************** 1620** 1621** Function rw_t3t_act_handle_get_sc_rsp 1622** 1623** Description Handle response for getting system codes 1624** 1625** Returns Nothing 1626** 1627*****************************************************************************/ 1628void rw_t3t_act_handle_get_sc_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp) 1629{ 1630 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset; 1631 UINT8 *p; 1632 UINT16 sc; 1633 UINT8 num_sc, i; 1634 1635 /* Validate response opcode */ 1636 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_REQ_SYSTEMCODE_RSP) 1637 { 1638 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_REQ_SYSTEMCODE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]); 1639 } 1640 else 1641 { 1642 /* Point to number of systems parameter */ 1643 p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMSYS]; 1644 STREAM_TO_UINT8 (num_sc, p); 1645 1646 /* Validate maximum */ 1647 if (num_sc>T3T_MAX_SYSTEM_CODES) 1648 { 1649 RW_TRACE_DEBUG2 ("Tag's number of systems (%i) exceeds NFA max (%i)", num_sc, T3T_MAX_SYSTEM_CODES); 1650 num_sc = T3T_MAX_SYSTEM_CODES; 1651 } 1652 1653 for (i = 0; i < num_sc; i++) 1654 { 1655 BE_STREAM_TO_UINT16 (sc, p); 1656 p_cb->system_codes[p_cb->num_system_codes++] = sc; 1657 } 1658 } 1659 rw_t3t_handle_get_system_codes_cplt (); 1660 1661 GKI_freebuf (p_msg_rsp); 1662} 1663 1664/***************************************************************************** 1665** 1666** Function rw_t3t_update_block 1667** 1668** Description Send UPDATE command for single block (for formatting) 1669** 1670** Returns tNFC_STATUS 1671** 1672*****************************************************************************/ 1673tNFC_STATUS rw_t3t_update_block (tRW_T3T_CB *p_cb, UINT8 block_id, UINT8 *p_block_data) 1674{ 1675 UINT8 *p_dst, *p_cmd_start; 1676 BT_HDR *p_cmd_buf; 1677 tNFC_STATUS status; 1678 1679 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 1680 { 1681 p_dst = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset; 1682 1683 /* Add UPDATE opcode to message */ 1684 UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_UPDATE_CMD); 1685 1686 /* Add IDm to message */ 1687 ARRAY_TO_STREAM (p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN); 1688 1689 /* Add Service code list */ 1690 UINT8_TO_STREAM (p_dst, 1); /* Number of services (only 1 service: NDEF) */ 1691 UINT16_TO_STREAM (p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */ 1692 1693 /* Number of blocks */ 1694 UINT8_TO_STREAM (p_dst, 1); 1695 1696 /* Add Block list element for MC */ 1697 UINT8_TO_STREAM (p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); 1698 UINT8_TO_STREAM (p_dst, block_id); 1699 1700 /* Copy MC data to UPDATE message */ 1701 ARRAY_TO_STREAM (p_dst, p_block_data, T3T_MSG_BLOCKSIZE); 1702 1703 /* Calculate length of message */ 1704 p_cmd_buf->len = (UINT16) (p_dst - p_cmd_start); 1705 1706 /* Send the T3T message */ 1707 status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_FORMAT, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS); 1708 } 1709 else 1710 { 1711 /* Unable to send UPDATE command */ 1712 status = NFC_STATUS_NO_BUFFERS; 1713 } 1714 1715 return (status); 1716} 1717 1718/***************************************************************************** 1719** 1720** Function rw_t3t_handle_fmt_poll_rsp 1721** 1722** Description Handle POLL response for formatting felica-lite 1723** 1724** Returns Nothing 1725** 1726*****************************************************************************/ 1727static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf) 1728{ 1729 BT_HDR *p_cmd_buf; 1730 UINT8 *p, *p_cmd_start; 1731 tRW_DATA evt_data; 1732 1733 evt_data.status = NFC_STATUS_OK; 1734 1735 /* Validate response for poll response */ 1736 if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) 1737 { 1738 /* Tag responded for Felica-Lite poll */ 1739 /* Get MemoryControl block */ 1740 RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block."); 1741 1742 /* Read NDEF attribute block */ 1743 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL) 1744 { 1745 p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK; 1746 1747 /* Construct T3T message */ 1748 p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset; 1749 1750 /* Add CHECK opcode to message */ 1751 UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD); 1752 1753 /* Add IDm to message */ 1754 ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN); 1755 1756 /* Add Service code list */ 1757 UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */ 1758 UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */ 1759 1760 /* Number of blocks */ 1761 UINT8_TO_STREAM (p, 1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */ 1762 1763 /* Block List element: the NDEF attribute information block (block 0) */ 1764 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); 1765 UINT8_TO_STREAM (p, T3T_MSG_FELICALITE_BLOCK_ID_MC); 1766 1767 /* Calculate length of message */ 1768 p_cmd_buf->len = (UINT16) (p - p_cmd_start); 1769 1770 /* Send the T3T message */ 1771 evt_data.status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_FORMAT, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS); 1772 } 1773 else 1774 { 1775 RW_TRACE_ERROR0 ("Unable to allocate buffer to read MC block"); 1776 evt_data.status = NFC_STATUS_NO_BUFFERS; 1777 } 1778 } 1779 else 1780 { 1781 RW_TRACE_ERROR0 ("Felica-Lite tag not detected"); 1782 evt_data.status = NFC_STATUS_FAILED; 1783 } 1784 1785 /* If error, notify upper layer */ 1786 if (evt_data.status != NFC_STATUS_OK) 1787 { 1788 rw_t3t_format_cplt (evt_data.status); 1789 } 1790} 1791 1792/***************************************************************************** 1793** 1794** Function rw_t3t_act_handle_fmt_rsp 1795** 1796** Description Handle response for formatting codes 1797** 1798** Returns Nothing 1799** 1800*****************************************************************************/ 1801void rw_t3t_act_handle_fmt_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp) 1802{ 1803 UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset; 1804 UINT8 *p_mc; 1805 tRW_DATA evt_data; 1806 1807 evt_data.status = NFC_STATUS_OK; 1808 1809 /* Check tags's response for reading MemoryControl block */ 1810 if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK) 1811 { 1812 /* Validate response opcode */ 1813 if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) 1814 { 1815 RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]); 1816 evt_data.status = NFC_STATUS_FAILED; 1817 } 1818 /* Validate status code and NFCID2 response from tag */ 1819 else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */ 1820 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */ 1821 { 1822 evt_data.status = NFC_STATUS_FAILED; 1823 } 1824 else 1825 { 1826 /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */ 1827 p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of CHECK response */ 1828 1829 if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01) 1830 { 1831 /* Tag is not currently enabled for NDEF. Indicate that we need to update the MC block */ 1832 1833 /* Set SYS_OP field to 0x01 (enable NDEF) */ 1834 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01; 1835 1836 /* Construct and send UPDATE message to write MC block */ 1837 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK; 1838 evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc); 1839 } 1840 else 1841 { 1842 /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */ 1843 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB; 1844 evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_default_attrib_info); 1845 } 1846 } 1847 1848 /* If error, notify upper layer */ 1849 if (evt_data.status != NFC_STATUS_OK) 1850 { 1851 rw_t3t_format_cplt (evt_data.status); 1852 } 1853 } 1854 else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK) 1855 { 1856 /* Validate response opcode */ 1857 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) 1858 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) ) 1859 1860 { 1861 RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]); 1862 evt_data.status = NFC_STATUS_FAILED; 1863 } 1864 else 1865 { 1866 /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */ 1867 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB; 1868 evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_default_attrib_info); 1869 } 1870 1871 /* If error, notify upper layer */ 1872 if (evt_data.status != NFC_STATUS_OK) 1873 { 1874 rw_t3t_format_cplt (evt_data.status); 1875 } 1876 } 1877 else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB) 1878 { 1879 /* Validate response opcode */ 1880 if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) 1881 ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) ) 1882 1883 { 1884 RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]); 1885 evt_data.status = NFC_STATUS_FAILED; 1886 } 1887 1888 1889 rw_t3t_format_cplt (evt_data.status); 1890 } 1891 1892 GKI_freebuf (p_msg_rsp); 1893} 1894 1895/******************************************************************************* 1896** 1897** Function rw_t3t_data_cback 1898** 1899** Description This callback function receives the data from NFCC. 1900** 1901** Returns none 1902** 1903*******************************************************************************/ 1904void rw_t3t_data_cback (UINT8 conn_id, BT_HDR *p_msg) 1905{ 1906 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 1907 BOOLEAN free_msg = FALSE; /* if TRUE, free msg buffer before returning */ 1908 UINT8 *p, sod; 1909 1910 /* Stop rsponse timer */ 1911 nfc_stop_quick_timer (&p_cb->timer); 1912 1913#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 1914 /* Update rx stats */ 1915 rw_main_update_rx_stats (p_msg->len); 1916#endif /* RW_STATS_INCLUDED */ 1917 1918 /* Check if we are expecting a response */ 1919 if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING) 1920 { 1921 /* 1922 ** This must be raw frame response 1923 ** send raw frame to app with SoD 1924 */ 1925 rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_msg); 1926 } 1927 /* Sanity check: verify msg len is big enough to contain t3t header */ 1928 else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN) 1929 { 1930 RW_TRACE_ERROR1 ("T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len); 1931 free_msg = TRUE; 1932 1933 rw_t3t_process_frame_error (); 1934 } 1935 else 1936 { 1937 /* Check for RF frame error */ 1938 p = (UINT8 *) (p_msg+1) + p_msg->offset; 1939 sod = p[0]; 1940 if (p[sod] != NCI_STATUS_OK) 1941 { 1942 RW_TRACE_ERROR1 ("T3T: rf frame error (crc status=%i)", p[sod]); 1943 GKI_freebuf (p_msg); 1944 1945 rw_t3t_process_frame_error (); 1946 return; 1947 } 1948 1949#if (BT_TRACE_PROTOCOL == TRUE) 1950 DispT3TagMessage (p_msg, TRUE); 1951#endif 1952 1953 /* Skip over SoD */ 1954 p_msg->offset++; 1955 p_msg->len--; 1956 1957 /* Get response code */ 1958 switch (p_cb->cur_cmd) 1959 { 1960 case RW_T3T_CMD_DETECT_NDEF: 1961 rw_t3t_act_handle_ndef_detect_rsp (p_cb, p_msg); 1962 break; 1963 1964 case RW_T3T_CMD_CHECK_NDEF: 1965 rw_t3t_act_handle_check_ndef_rsp (p_cb, p_msg); 1966 break; 1967 1968 case RW_T3T_CMD_UPDATE_NDEF: 1969 rw_t3t_act_handle_update_ndef_rsp (p_cb, p_msg); 1970 break; 1971 1972 case RW_T3T_CMD_CHECK: 1973 rw_t3t_act_handle_check_rsp (p_cb, p_msg); 1974 break; 1975 1976 case RW_T3T_CMD_UPDATE: 1977 rw_t3t_act_handle_update_rsp (p_cb, p_msg); 1978 break; 1979 1980 case RW_T3T_CMD_SEND_RAW_FRAME: 1981 rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_msg); 1982 break; 1983 1984 case RW_T3T_CMD_GET_SYSTEM_CODES: 1985 rw_t3t_act_handle_get_sc_rsp (p_cb, p_msg); 1986 break; 1987 1988 case RW_T3T_CMD_FORMAT: 1989 rw_t3t_act_handle_fmt_rsp (p_cb, p_msg); 1990 break; 1991 1992 default: 1993 GKI_freebuf (p_msg); 1994 break; 1995 } 1996 } 1997 1998 if (free_msg) 1999 { 2000 GKI_freebuf (p_msg); 2001 } 2002} 2003 2004 2005/******************************************************************************* 2006** 2007** Function rw_t3t_conn_cback 2008** 2009** Description This callback function receives the events/data from NFCC. 2010** 2011** Returns none 2012** 2013*******************************************************************************/ 2014void rw_t3t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) 2015{ 2016 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2017 RW_TRACE_DEBUG2 ("rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event); 2018 2019 /* Only handle NFC_RF_CONN_ID conn_id */ 2020 if (conn_id != NFC_RF_CONN_ID) 2021 { 2022 return; 2023 } 2024 2025 switch (event) 2026 { 2027 case NFC_DEACTIVATE_CEVT: 2028 rw_t3t_unselect (NULL); 2029 break; 2030 2031 case NFC_DATA_CEVT: /* check for status in tNFC_CONN */ 2032 if (p_data->data.status == NFC_STATUS_OK) 2033 { 2034 rw_t3t_data_cback (conn_id, p_data->data.p_data); 2035 break; 2036 } 2037 /* Data event with error status...fall through to NFC_ERROR_CEVT case */ 2038 2039 2040 case NFC_ERROR_CEVT: 2041 nfc_stop_quick_timer (&p_cb->timer); 2042 2043#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 2044 rw_main_update_trans_error_stats (); 2045#endif /* RW_STATS_INCLUDED */ 2046 2047 if (event == NFC_ERROR_CEVT) 2048 rw_t3t_process_error (NFC_STATUS_TIMEOUT); 2049 else 2050 rw_t3t_process_error (p_data->status); 2051 break; 2052 2053 default: 2054 break; 2055 2056 } 2057} 2058 2059 2060/******************************************************************************* 2061** 2062** Function rw_t3t_select 2063** 2064** Description Called by NFC manager when a Type3 tag has been activated 2065** 2066** Returns NFC_STATUS_OK 2067** 2068*******************************************************************************/ 2069tNFC_STATUS rw_t3t_select (UINT8 peer_nfcid2[NCI_RF_F_UID_LEN], UINT8 mrti_check, UINT8 mrti_update) 2070{ 2071 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2072 2073 RW_TRACE_API0 ("rw_t3t_select"); 2074 2075 memcpy (p_cb->peer_nfcid2, peer_nfcid2, NCI_NFCID2_LEN); /* Store tag's NFCID2 */ 2076 p_cb->ndef_attrib.status = NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been performed yet */ 2077 p_cb->rw_state = RW_T3T_STATE_IDLE; 2078 p_cb->flags = 0; 2079 2080 /* Alloc cmd buf for retransmissions */ 2081 if (p_cb->p_cur_cmd_buf == NULL) 2082 { 2083 if ((p_cb->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL) 2084 { 2085 RW_TRACE_ERROR0 ("rw_t3t_select: unable to allocate buffer for retransmission"); 2086 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED; 2087 return (NFC_STATUS_FAILED); 2088 } 2089 } 2090 2091 2092 NFC_SetStaticRfCback (rw_t3t_conn_cback); 2093 2094 return NFC_STATUS_OK; 2095} 2096 2097 2098/******************************************************************************* 2099** 2100** Function rw_t3t_unselect 2101** 2102** Description Called by NFC manager when a Type3 tag has been de-activated 2103** 2104** Returns NFC_STATUS_OK 2105** 2106*******************************************************************************/ 2107static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[]) 2108{ 2109 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2110 2111#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) 2112 /* Display stats */ 2113 rw_main_log_stats (); 2114#endif /* RW_STATS_INCLUDED */ 2115 2116 /* Stop t3t timer (if started) */ 2117 nfc_stop_quick_timer (&p_cb->timer); 2118 2119 /* Free cmd buf for retransmissions */ 2120 if (p_cb->p_cur_cmd_buf) 2121 { 2122 GKI_freebuf (p_cb->p_cur_cmd_buf); 2123 p_cb->p_cur_cmd_buf = NULL; 2124 } 2125 2126 p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED; 2127 NFC_SetStaticRfCback (NULL); 2128 2129 return NFC_STATUS_OK; 2130} 2131 2132 2133#if (BT_TRACE_VERBOSE == TRUE) 2134/******************************************************************************* 2135** 2136** Function rw_t3t_cmd_str 2137** 2138** Description Converts cmd_id to command string for logging 2139** 2140** Returns command string 2141** 2142*******************************************************************************/ 2143static char *rw_t3t_cmd_str (UINT8 cmd_id) 2144{ 2145 switch (cmd_id) 2146 { 2147 case RW_T3T_CMD_DETECT_NDEF: 2148 return "RW_T3T_CMD_DETECT_NDEF"; 2149 2150 case RW_T3T_CMD_CHECK_NDEF: 2151 return "RW_T3T_CMD_CHECK_NDEF"; 2152 2153 case RW_T3T_CMD_UPDATE_NDEF: 2154 return "RW_T3T_CMD_UPDATE_NDEF"; 2155 2156 case RW_T3T_CMD_CHECK: 2157 return "RW_T3T_CMD_CHECK"; 2158 2159 case RW_T3T_CMD_UPDATE: 2160 return "RW_T3T_CMD_UPDATE"; 2161 2162 case RW_T3T_CMD_SEND_RAW_FRAME: 2163 return "RW_T3T_CMD_SEND_RAW_FRAME"; 2164 2165 case RW_T3T_CMD_GET_SYSTEM_CODES: 2166 return "RW_T3T_CMD_GET_SYSTEM_CODES"; 2167 2168 default: 2169 return "Unknown"; 2170 } 2171} 2172 2173 2174/******************************************************************************* 2175** 2176** Function rw_t3t_state_str 2177** 2178** Description Converts state_id to command string for logging 2179** 2180** Returns command string 2181** 2182*******************************************************************************/ 2183static char *rw_t3t_state_str (UINT8 state_id) 2184{ 2185 switch (state_id) 2186 { 2187 case RW_T3T_STATE_NOT_ACTIVATED: 2188 return "RW_T3T_STATE_NOT_ACTIVATED"; 2189 2190 case RW_T3T_STATE_IDLE: 2191 return "RW_T3T_STATE_IDLE"; 2192 2193 case RW_T3T_STATE_COMMAND_PENDING: 2194 return "RW_T3T_STATE_COMMAND_PENDING"; 2195 2196 default: 2197 return "Unknown"; 2198 } 2199} 2200#endif 2201 2202/***************************************************************************** 2203** Type3 Tag API Functions 2204*****************************************************************************/ 2205 2206 2207/***************************************************************************** 2208** 2209** Function RW_T3tDetectNDef 2210** 2211** Description 2212** This function is used to perform NDEF detection on a Type 3 tag, and 2213** retrieve the tag's NDEF attribute information (block 0). 2214** 2215** Before using this API, the application must call RW_SelectTagType to 2216** indicate that a Type 3 tag has been activated, and to provide the 2217** tag's Manufacture ID (IDm) . 2218** 2219** Returns 2220** NFC_STATUS_OK: ndef detection procedure started 2221** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2222** NFC_STATUS_FAILED: other error 2223** 2224*****************************************************************************/ 2225tNFC_STATUS RW_T3tDetectNDef (void) 2226{ 2227 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2228 tNFC_STATUS retval = NFC_STATUS_OK; 2229 2230 RW_TRACE_API0 ("RW_T3tDetectNDef"); 2231 2232 /* Check if we are in valid state to handle this API */ 2233 if (p_cb->rw_state != RW_T3T_STATE_IDLE) 2234 { 2235 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state); 2236 return (NFC_STATUS_FAILED); 2237 } 2238 2239 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_NDEF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK) 2240 { 2241 p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF; 2242 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS; 2243 p_cb->cur_poll_rc = 0; 2244 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING; 2245 p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP; 2246 2247 /* start timer for waiting for responses */ 2248 rw_t3t_start_poll_timer (p_cb); 2249 } 2250 2251 return (retval); 2252} 2253 2254 2255/***************************************************************************** 2256** 2257** Function RW_T3tCheckNDef 2258** 2259** Description 2260** Retrieve NDEF contents from a Type3 tag. 2261** 2262** The RW_T3T_CHECK_EVT event is used to notify the application for each 2263** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used to 2264** notify the application all segments have been received. 2265** 2266** Before using this API, the RW_T3tDetectNDef function must be called to 2267** verify that the tag contains NDEF data, and to retrieve the NDEF 2268** attributes. 2269** 2270** Internally, this command will be separated into multiple Tag 3 Check 2271** commands (if necessary) - depending on the tag's Nbr (max number of 2272** blocks per read) attribute. 2273** 2274** Returns 2275** NFC_STATUS_OK: check command started 2276** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2277** NFC_STATUS_FAILED: other error 2278** 2279*****************************************************************************/ 2280tNFC_STATUS RW_T3tCheckNDef (void) 2281{ 2282 tNFC_STATUS retval = NFC_STATUS_OK; 2283 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2284 2285 RW_TRACE_API0 ("RW_T3tCheckNDef"); 2286 2287 /* Check if we are in valid state to handle this API */ 2288 if (p_cb->rw_state != RW_T3T_STATE_IDLE) 2289 { 2290 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state); 2291 return (NFC_STATUS_FAILED); 2292 } 2293 else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */ 2294 { 2295 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet"); 2296 return (NFC_STATUS_NOT_INITIALIZED); 2297 } 2298 else if (p_cb->ndef_attrib.ln == 0) 2299 { 2300 RW_TRACE_ERROR0 ("Type 3 tag contains empty NDEF message"); 2301 return (NFC_STATUS_FAILED); 2302 } 2303 2304 /* Check number of blocks needed for this update */ 2305 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT; 2306 p_cb->ndef_rx_offset = 0; 2307 retval = rw_t3t_send_next_ndef_check_cmd (p_cb); 2308 2309 return (retval); 2310} 2311 2312/***************************************************************************** 2313** 2314** Function RW_T3tUpdateNDef 2315** 2316** Description 2317** Write NDEF contents to a Type3 tag. 2318** 2319** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the 2320** application of the response. 2321** 2322** Before using this API, the RW_T3tDetectNDef function must be called to 2323** verify that the tag contains NDEF data, and to retrieve the NDEF 2324** attributes. 2325** 2326** Internally, this command will be separated into multiple Tag 3 Update 2327** commands (if necessary) - depending on the tag's Nbw (max number of 2328** blocks per write) attribute. 2329** 2330** Returns 2331** NFC_STATUS_OK: check command started 2332** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2333** NFC_STATUS_REFUSED: tag is read-only 2334** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size 2335** NFC_STATUS_FAILED: other error 2336** 2337*****************************************************************************/ 2338tNFC_STATUS RW_T3tUpdateNDef (UINT32 len, UINT8 *p_data) 2339{ 2340 tNFC_STATUS retval = NFC_STATUS_OK; 2341 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2342 2343 RW_TRACE_API1 ("RW_T3tUpdateNDef (len=%i)", len); 2344 2345 /* Check if we are in valid state to handle this API */ 2346 if (p_cb->rw_state != RW_T3T_STATE_IDLE) 2347 { 2348 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state); 2349 return (NFC_STATUS_FAILED); 2350 } 2351 else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */ 2352 { 2353 RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet"); 2354 return (NFC_STATUS_NOT_INITIALIZED); 2355 } 2356 else if (len > (((UINT32)p_cb->ndef_attrib.nmaxb) * 16)) /* Len exceed's tag's NDEF memory? */ 2357 { 2358 return (NFC_STATUS_BUFFER_FULL); 2359 } 2360 else if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)/* Tag's NDEF memory is read-only? */ 2361 { 2362 return (NFC_STATUS_REFUSED); 2363 } 2364 2365 /* Check number of blocks needed for this update */ 2366 p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT; 2367 p_cb->ndef_msg_bytes_sent = 0; 2368 p_cb->ndef_msg_len = len; 2369 p_cb->ndef_msg = p_data; 2370 2371 /* Send initial UPDATE command for NDEF Attribute Info */ 2372 retval = rw_t3t_send_update_ndef_attribute_cmd (p_cb, TRUE); 2373 2374 return (retval); 2375} 2376 2377/***************************************************************************** 2378** 2379** Function RW_T3tCheck 2380** 2381** Description 2382** Read (non-NDEF) contents from a Type3 tag. 2383** 2384** The RW_READ_EVT event is used to notify the application for each 2385** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to 2386** notify the application all segments have been received. 2387** 2388** Before using this API, the application must call RW_SelectTagType to 2389** indicate that a Type 3 tag has been activated, and to provide the 2390** tag's Manufacture ID (IDm) . 2391** 2392** Returns 2393** NFC_STATUS_OK: check command started 2394** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2395** NFC_STATUS_FAILED: other error 2396** 2397*****************************************************************************/ 2398tNFC_STATUS RW_T3tCheck (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks) 2399{ 2400 tNFC_STATUS retval = NFC_STATUS_OK; 2401 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2402 2403 RW_TRACE_API1 ("RW_T3tCheck (num_blocks = %i)", num_blocks); 2404 2405 /* Check if we are in valid state to handle this API */ 2406 if (p_cb->rw_state != RW_T3T_STATE_IDLE) 2407 { 2408 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state); 2409 return (NFC_STATUS_FAILED); 2410 } 2411 2412 /* Send the CHECK command */ 2413 retval = rw_t3t_send_check_cmd (p_cb, num_blocks, t3t_blocks); 2414 2415 return (retval); 2416} 2417 2418/***************************************************************************** 2419** 2420** Function RW_T3tUpdate 2421** 2422** Description 2423** Write (non-NDEF) contents to a Type3 tag. 2424** 2425** The RW_WRITE_CPLT_EVT event is used to notify the application all 2426** segments have been received. 2427** 2428** Before using this API, the application must call RW_SelectTagType to 2429** indicate that a Type 3 tag has been activated, and to provide the tag's 2430** Manufacture ID (IDm) . 2431** 2432** Returns 2433** NFC_STATUS_OK: check command started 2434** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2435** NFC_STATUS_FAILED: other error 2436** 2437*****************************************************************************/ 2438tNFC_STATUS RW_T3tUpdate (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks, UINT8 *p_data) 2439{ 2440 tNFC_STATUS retval = NFC_STATUS_OK; 2441 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2442 2443 RW_TRACE_API1 ("RW_T3tUpdate (num_blocks = %i)", num_blocks); 2444 2445 /* Check if we are in valid state to handle this API */ 2446 if (p_cb->rw_state != RW_T3T_STATE_IDLE) 2447 { 2448 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state); 2449 return (NFC_STATUS_FAILED); 2450 } 2451 2452 /* Send the UPDATE command */ 2453 retval = rw_t3t_send_update_cmd (p_cb, num_blocks, t3t_blocks, p_data); 2454 2455 return (retval); 2456} 2457 2458/***************************************************************************** 2459** 2460** Function RW_T3tPresenceCheck 2461** 2462** Description 2463** Check if the tag is still in the field. 2464** 2465** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence 2466** or non-presence. 2467** 2468** Returns 2469** NFC_STATUS_OK, if raw data frame sent 2470** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2471** NFC_STATUS_FAILED: other error 2472** 2473*****************************************************************************/ 2474tNFC_STATUS RW_T3tPresenceCheck (void) 2475{ 2476 tNFC_STATUS retval = NFC_STATUS_OK; 2477 tRW_DATA evt_data; 2478 tRW_CB *p_rw_cb = &rw_cb; 2479 2480 RW_TRACE_API0 ("RW_T3tPresenceCheck"); 2481 2482 /* If RW_SelectTagType was not called (no conn_callback) return failure */ 2483 if (!(p_rw_cb->p_cback)) 2484 { 2485 retval = NFC_STATUS_FAILED; 2486 } 2487 /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */ 2488 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED) 2489 { 2490 evt_data.status = NFC_STATUS_FAILED; 2491 (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data); 2492 } 2493 /* If command is pending */ 2494 else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING) 2495 { 2496 /* If already performing presence check, return error */ 2497 if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) 2498 { 2499 RW_TRACE_DEBUG0 ("RW_T3tPresenceCheck already in progress"); 2500 retval = NFC_STATUS_FAILED; 2501 } 2502 /* If busy with any other command, assume that the tag is present */ 2503 else 2504 { 2505 evt_data.status = NFC_STATUS_OK; 2506 (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data); 2507 } 2508 } 2509 else 2510 { 2511 /* IDLE state: send POLL command */ 2512 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK) 2513 { 2514 p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP; 2515 p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING; 2516 p_rw_cb->tcb.t3t.cur_poll_rc = 0; 2517 2518 /* start timer for waiting for responses */ 2519 rw_t3t_start_poll_timer (&p_rw_cb->tcb.t3t); 2520 } 2521 else 2522 { 2523 RW_TRACE_DEBUG1 ("RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = 0x%0x)", retval); 2524 } 2525 } 2526 2527 return (retval); 2528} 2529 2530/***************************************************************************** 2531** 2532** Function RW_T3tPoll 2533** 2534** Description 2535** Send POLL command 2536** 2537** Returns 2538** NFC_STATUS_OK, if raw data frame sent 2539** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2540** NFC_STATUS_FAILED: other error 2541** 2542*****************************************************************************/ 2543tNFC_STATUS RW_T3tPoll (UINT16 system_code, tT3T_POLL_RC rc, UINT8 tsn) 2544{ 2545 tNFC_STATUS retval = NFC_STATUS_OK; 2546 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2547 2548 RW_TRACE_API0 ("RW_T3tPoll"); 2549 2550 /* Check if we are in valid state to handle this API */ 2551 if (p_cb->rw_state != RW_T3T_STATE_IDLE) 2552 { 2553 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state); 2554 return (NFC_STATUS_FAILED); 2555 } 2556 2557 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (system_code, (UINT8) rc, tsn)) == NCI_STATUS_OK) 2558 { 2559 /* start timer for waiting for responses */ 2560 p_cb->cur_poll_rc = rc; 2561 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING; 2562 rw_t3t_start_poll_timer (p_cb); 2563 } 2564 2565 2566 return (retval); 2567} 2568 2569/***************************************************************************** 2570** 2571** Function RW_T3tSendRawFrame 2572** 2573** Description 2574** This function is called to send a raw data frame to the peer device. 2575** When type 3 tag receives response from peer, the callback function 2576** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6]. 2577** 2578** Before using this API, the application must call RW_SelectTagType to 2579** indicate that a Type 3 tag has been activated. 2580** 2581** The raw frame should be a properly formatted Type 3 tag message. 2582** 2583** Returns 2584** NFC_STATUS_OK, if raw data frame sent 2585** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2586** NFC_STATUS_FAILED: other error 2587** 2588*****************************************************************************/ 2589tNFC_STATUS RW_T3tSendRawFrame (UINT16 len, UINT8 *p_data) 2590{ 2591 tNFC_STATUS retval = NFC_STATUS_OK; 2592 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2593 2594 RW_TRACE_API1 ("RW_T3tSendRawFrame (len = %i)", len); 2595 2596 /* Check if we are in valid state to handle this API */ 2597 if (p_cb->rw_state != RW_T3T_STATE_IDLE) 2598 { 2599 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state); 2600 return (NFC_STATUS_FAILED); 2601 } 2602 2603 /* Send the UPDATE command */ 2604 retval = rw_t3t_send_raw_frame (p_cb, len ,p_data); 2605 2606 return (retval); 2607} 2608 2609/***************************************************************************** 2610** 2611** Function RW_T3tGetSystemCodes 2612** 2613** Description 2614** Get systems codes supported by the activated tag: 2615** Poll for wildcard (FFFF): 2616** - If felica-lite code then poll for ndef (12fc) 2617** - Otherwise send RequestSystmCode command to get 2618** system codes. 2619** 2620** Before using this API, the application must call RW_SelectTagType to 2621** indicate that a Type 3 tag has been activated. 2622** 2623** Returns 2624** NFC_STATUS_OK, if raw data frame sent 2625** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2626** NFC_STATUS_FAILED: other error 2627** 2628*****************************************************************************/ 2629tNFC_STATUS RW_T3tGetSystemCodes (void) 2630{ 2631 tNFC_STATUS retval = NFC_STATUS_OK; 2632 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2633 2634 RW_TRACE_API0 ("RW_T3tGetSystemCodes"); 2635 2636 /* Check if we are in valid state to handle this API */ 2637 if (p_cb->rw_state != RW_T3T_STATE_IDLE) 2638 { 2639 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state); 2640 return (NFC_STATUS_FAILED); 2641 } 2642 else 2643 { 2644 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK) 2645 { 2646 p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES; 2647 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS; 2648 p_cb->cur_poll_rc = T3T_POLL_RC_SC; 2649 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING; 2650 p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_WILDCARD; 2651 p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP; 2652 p_cb->num_system_codes = 0; 2653 2654 /* start timer for waiting for responses */ 2655 rw_t3t_start_poll_timer (p_cb); 2656 } 2657 } 2658 2659 2660 2661 return (retval); 2662} 2663 2664/***************************************************************************** 2665** 2666** Function RW_T3tFormatNDef 2667** 2668** Description 2669** Format a type-3 tag for NDEF. 2670** 2671** Only Felica-Lite tags are supported by this API. The 2672** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation. 2673** 2674** Returns 2675** NFC_STATUS_OK: ndef detection procedure started 2676** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation 2677** NFC_STATUS_FAILED: other error 2678** 2679*****************************************************************************/ 2680tNFC_STATUS RW_T3tFormatNDef (void) 2681{ 2682 tNFC_STATUS retval = NFC_STATUS_OK; 2683 tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t; 2684 2685 RW_TRACE_API0 ("RW_T3tFormatNDef"); 2686 2687 /* Check if we are in valid state to handle this API */ 2688 if (p_cb->rw_state != RW_T3T_STATE_IDLE) 2689 { 2690 RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state); 2691 return (NFC_STATUS_FAILED); 2692 } 2693 else 2694 { 2695 /* Poll tag, to see if Felica-Lite system is supported */ 2696 if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK) 2697 { 2698 p_cb->cur_cmd = RW_T3T_CMD_FORMAT; 2699 p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS; 2700 p_cb->cur_poll_rc = T3T_POLL_RC_SC; 2701 p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING; 2702 p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE; 2703 p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP; 2704 2705 /* start timer for waiting for responses */ 2706 rw_t3t_start_poll_timer (p_cb); 2707 } 2708 } 2709 2710 2711 2712 return (retval); 2713} 2714