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