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