1 /****************************************************************************** 2 * 3 * Copyright (C) 2010-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This file contains the action functions the NFA_RW state machine. 22 * 23 ******************************************************************************/ 24 #include <string.h> 25 #include "nfa_rw_int.h" 26 #include "nfa_dm_int.h" 27 #include "nfa_sys_int.h" 28 #include "nfa_mem_co.h" 29 #include "ndef_utils.h" 30 #include "rw_api.h" 31 32 /* Local static function prototypes */ 33 static tNFC_STATUS nfa_rw_start_ndef_read(void); 34 static tNFC_STATUS nfa_rw_start_ndef_write(void); 35 static tNFC_STATUS nfa_rw_start_ndef_detection(void); 36 static tNFC_STATUS nfa_rw_config_tag_ro(BOOLEAN b_hard_lock); 37 static BOOLEAN nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data); 38 static void nfa_rw_error_cleanup (UINT8 event); 39 40 /******************************************************************************* 41 ** 42 ** Function nfa_rw_free_ndef_rx_buf 43 ** 44 ** Description Free buffer allocated to hold incoming NDEF message 45 ** 46 ** Returns Nothing 47 ** 48 *******************************************************************************/ 49 void nfa_rw_free_ndef_rx_buf(void) 50 { 51 if (nfa_rw_cb.p_ndef_buf) 52 { 53 nfa_mem_co_free(nfa_rw_cb.p_ndef_buf); 54 nfa_rw_cb.p_ndef_buf = NULL; 55 } 56 } 57 58 /******************************************************************************* 59 ** 60 ** Function nfa_rw_store_ndef_rx_buf 61 ** 62 ** Description Store data into NDEF buffer 63 ** 64 ** Returns Nothing 65 ** 66 *******************************************************************************/ 67 static void nfa_rw_store_ndef_rx_buf (tRW_DATA *p_rw_data) 68 { 69 UINT8 *p; 70 71 p = (UINT8 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset; 72 73 /* Save data into buffer */ 74 memcpy(&nfa_rw_cb.p_ndef_buf[nfa_rw_cb.ndef_rd_offset], p, p_rw_data->data.p_data->len); 75 nfa_rw_cb.ndef_rd_offset += p_rw_data->data.p_data->len; 76 77 GKI_freebuf(p_rw_data->data.p_data); 78 p_rw_data->data.p_data = NULL; 79 } 80 81 /******************************************************************************* 82 ** 83 ** Function nfa_rw_send_data_to_upper 84 ** 85 ** Description Send data to upper layer 86 ** 87 ** Returns Nothing 88 ** 89 *******************************************************************************/ 90 static void nfa_rw_send_data_to_upper (tRW_DATA *p_rw_data) 91 { 92 tNFA_CONN_EVT_DATA conn_evt_data; 93 94 if ( (p_rw_data->status == NFC_STATUS_TIMEOUT) 95 ||(p_rw_data->data.p_data == NULL) ) 96 return; 97 98 /* Notify conn cback of NFA_DATA_EVT */ 99 conn_evt_data.data.p_data = (UINT8 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset; 100 conn_evt_data.data.len = p_rw_data->data.p_data->len; 101 102 nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data); 103 104 GKI_freebuf(p_rw_data->data.p_data); 105 p_rw_data->data.p_data = NULL; 106 } 107 108 /******************************************************************************* 109 ** 110 ** Function nfa_rw_error_cleanup 111 ** 112 ** Description Handle failure - signal command complete and notify app 113 ** 114 ** Returns Nothing 115 ** 116 *******************************************************************************/ 117 static void nfa_rw_error_cleanup (UINT8 event) 118 { 119 tNFA_CONN_EVT_DATA conn_evt_data; 120 121 nfa_rw_command_complete(); 122 123 conn_evt_data.status = NFA_STATUS_FAILED; 124 125 nfa_dm_act_conn_cback_notify (event, &conn_evt_data); 126 } 127 128 /******************************************************************************* 129 ** 130 ** Function nfa_rw_check_start_presence_check_timer 131 ** 132 ** Description Start timer for presence check 133 ** 134 ** Returns Nothing 135 ** 136 *******************************************************************************/ 137 static void nfa_rw_check_start_presence_check_timer (void) 138 { 139 #if (defined (NFA_DM_AUTO_PRESENCE_CHECK) && (NFA_DM_AUTO_PRESENCE_CHECK == TRUE)) 140 if (nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) 141 { 142 NFA_TRACE_DEBUG0("Starting presence check timer..."); 143 nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TICK_EVT, NFA_RW_PRESENCE_CHECK_INTERVAL); 144 } 145 #endif /* NFA_DM_AUTO_PRESENCE_CHECK */ 146 } 147 148 /******************************************************************************* 149 ** 150 ** Function nfa_rw_stop_presence_check_timer 151 ** 152 ** Description Stop timer for presence check 153 ** 154 ** Returns Nothing 155 ** 156 *******************************************************************************/ 157 void nfa_rw_stop_presence_check_timer(void) 158 { 159 nfa_sys_stop_timer(&nfa_rw_cb.tle); 160 NFA_TRACE_DEBUG0("Stopped presence check timer (if started)"); 161 } 162 163 /******************************************************************************* 164 ** 165 ** Function nfa_rw_handle_ndef_detect 166 ** 167 ** Description Handler for NDEF detection reader/writer event 168 ** 169 ** Returns Nothing 170 ** 171 *******************************************************************************/ 172 static void nfa_rw_handle_ndef_detect(tRW_EVENT event, tRW_DATA *p_rw_data) 173 { 174 tNFA_CONN_EVT_DATA conn_evt_data; 175 176 NFA_TRACE_DEBUG3("NDEF Detection completed: cur_size=%i, max_size=%i, flags=0x%x", 177 p_rw_data->ndef.cur_size, p_rw_data->ndef.max_size, p_rw_data->ndef.flags); 178 179 /* Check if NDEF detection succeeded */ 180 if (p_rw_data->ndef.status == NFC_STATUS_OK) 181 { 182 /* Set NDEF detection state */ 183 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_TRUE; 184 185 /* Store ndef properties */ 186 conn_evt_data.ndef_detect.status = NFA_STATUS_OK; 187 conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol; 188 conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size; 189 conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size; 190 conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags; 191 192 if (p_rw_data->ndef.flags & RW_NDEF_FL_READ_ONLY) 193 nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY; 194 else 195 nfa_rw_cb.flags &= ~NFA_RW_FL_TAG_IS_READONLY; 196 197 /* Determine what operation triggered the NDEF detection procedure */ 198 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 199 { 200 /* if ndef detection was done as part of ndef-read operation, then perform ndef read now */ 201 if ((conn_evt_data.status = nfa_rw_start_ndef_read()) != NFA_STATUS_OK) 202 { 203 /* Failed to start NDEF Read */ 204 205 /* Command complete - perform cleanup, notify app */ 206 nfa_rw_command_complete(); 207 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 208 } 209 } 210 else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 211 { 212 /* if ndef detection was done as part of ndef-write operation, then perform ndef write now */ 213 if ((conn_evt_data.status = nfa_rw_start_ndef_write()) != NFA_STATUS_OK) 214 { 215 /* Failed to start NDEF Write. */ 216 217 /* Command complete - perform cleanup, notify app */ 218 nfa_rw_command_complete(); 219 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 220 } 221 } 222 else 223 { 224 /* current op was stand-alone NFA_DetectNDef. Command complete - perform cleanup and notify app */ 225 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 226 nfa_rw_command_complete(); 227 228 nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data); 229 } 230 } 231 else 232 { 233 /* NDEF detection failed... */ 234 235 /* Command complete - perform cleanup, notify app */ 236 nfa_rw_command_complete(); 237 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE; 238 239 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 240 { 241 /* if ndef detection was done as part of ndef-read operation, then notify NDEF handlers of failure */ 242 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 243 244 /* Notify app of read status */ 245 conn_evt_data.status = NFC_STATUS_FAILED; 246 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 247 } 248 else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 249 { 250 /* if ndef detection was done as part of ndef-write operation, then notify app of failure */ 251 conn_evt_data.status = NFA_STATUS_FAILED; 252 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 253 } 254 else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF) 255 { 256 conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol; 257 /* current op was stand-alone NFA_DetectNDef. Notify app of failure */ 258 conn_evt_data.ndef_detect.status = NFA_STATUS_FAILED; 259 if (p_rw_data->ndef.status == NFC_STATUS_TIMEOUT) 260 { 261 /* Tag could have moved away */ 262 conn_evt_data.ndef_detect.cur_size = 0; 263 conn_evt_data.ndef_detect.max_size = 0; 264 conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; 265 } 266 else 267 { 268 /* NDEF Detection failed for other reasons */ 269 conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size; 270 conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size; 271 conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags; 272 } 273 nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data); 274 } 275 276 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 277 } 278 } 279 280 /******************************************************************************* 281 ** 282 ** Function nfa_rw_handle_tlv_detect 283 ** 284 ** Description Handler for TLV detection reader/writer event 285 ** 286 ** Returns Nothing 287 ** 288 *******************************************************************************/ 289 static void nfa_rw_handle_tlv_detect(tRW_EVENT event, tRW_DATA *p_rw_data) 290 { 291 tNFA_CONN_EVT_DATA conn_evt_data; 292 293 /* Set TLV detection state */ 294 if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) 295 { 296 if(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) 297 { 298 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE; 299 } 300 else 301 { 302 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE; 303 } 304 } 305 else 306 { 307 if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) 308 { 309 nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE; 310 } 311 else if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) 312 { 313 nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE; 314 } 315 } 316 317 /* Check if TLV detection succeeded */ 318 if (p_rw_data->tlv.status == NFC_STATUS_OK) 319 { 320 NFA_TRACE_DEBUG1("TLV Detection succeeded: num_bytes=%i",p_rw_data->tlv.num_bytes); 321 322 /* Store tlv properties */ 323 conn_evt_data.tlv_detect.status = NFA_STATUS_OK; 324 conn_evt_data.tlv_detect.protocol = p_rw_data->tlv.protocol; 325 conn_evt_data.tlv_detect.num_bytes = p_rw_data->tlv.num_bytes; 326 327 328 /* Determine what operation triggered the TLV detection procedure */ 329 if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) 330 { 331 if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) 332 { 333 /* Failed to set tag read only */ 334 conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED; 335 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 336 } 337 } 338 else 339 { 340 /* current op was stand-alone NFA_DetectTlv. Command complete - perform cleanup and notify app */ 341 nfa_rw_command_complete(); 342 nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data); 343 } 344 } 345 346 /* Handle failures */ 347 if (p_rw_data->tlv.status != NFC_STATUS_OK) 348 { 349 /* Command complete - perform cleanup, notify the app */ 350 nfa_rw_command_complete(); 351 352 conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED; 353 if( (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) 354 ||(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) ) 355 { 356 nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data); 357 } 358 else if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) 359 { 360 if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) 361 { 362 /* Failed to set tag read only */ 363 conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED; 364 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 365 } 366 } 367 } 368 } 369 370 371 /******************************************************************************* 372 ** 373 ** Function nfa_rw_handle_presence_check_rsp 374 ** 375 ** Description Handler RW_T#t_PRESENCE_CHECK_EVT 376 ** 377 ** Returns Nothing 378 ** 379 *******************************************************************************/ 380 void nfa_rw_handle_presence_check_rsp (tNFC_STATUS status) 381 { 382 BT_HDR *p_pending_msg; 383 384 if (status == NFA_STATUS_OK) 385 { 386 /* Clear the BUSY flag and restart the presence-check timer */ 387 nfa_rw_command_complete(); 388 } 389 else 390 { 391 /* If presence check failed just clear the BUSY flag */ 392 nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY; 393 } 394 395 /* Handle presence check due to auto-presence-check */ 396 if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) 397 { 398 nfa_rw_cb.flags &= ~NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY; 399 400 /* If an API was called during auto-presence-check, then handle it now */ 401 if (nfa_rw_cb.p_pending_msg) 402 { 403 /* If NFA_RwPresenceCheck was called during auto-presence-check, notify app of result */ 404 if (nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_PRESENCE_CHECK) 405 { 406 /* Notify app of presence check status */ 407 nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (tNFA_CONN_EVT_DATA *)&status); 408 GKI_freebuf(nfa_rw_cb.p_pending_msg); 409 nfa_rw_cb.p_pending_msg = NULL; 410 } 411 /* For all other APIs called during auto-presence check, perform the command now (if tag is still present) */ 412 else if (status == NFC_STATUS_OK) 413 { 414 NFA_TRACE_DEBUG0("Performing deferred operation after presence check..."); 415 p_pending_msg = (BT_HDR *)nfa_rw_cb.p_pending_msg; 416 nfa_rw_cb.p_pending_msg = NULL; 417 nfa_rw_handle_event(p_pending_msg); 418 } 419 else 420 { 421 /* Tag no longer present. Free command for pending API command */ 422 GKI_freebuf(nfa_rw_cb.p_pending_msg); 423 nfa_rw_cb.p_pending_msg = NULL; 424 } 425 } 426 427 /* Auto-presence check failed. Deactivate */ 428 if (status != NFC_STATUS_OK) 429 { 430 NFA_TRACE_DEBUG0("Auto presence check failed. Deactivating..."); 431 nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY); 432 } 433 } 434 /* Handle presence check due to NFA_RwPresenceCheck API call */ 435 else 436 { 437 /* Notify app of presence check status */ 438 nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (tNFA_CONN_EVT_DATA *)&status); 439 440 /* If in normal mode (not-exclusive RF mode) then deactivate the link if presence check failed */ 441 if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) && (status != NFC_STATUS_OK)) 442 { 443 NFA_TRACE_DEBUG0("Presence check failed. Deactivating..."); 444 nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY); 445 } 446 } 447 } 448 449 /******************************************************************************* 450 ** 451 ** Function nfa_rw_handle_t1t_evt 452 ** 453 ** Description Handler for Type-1 tag reader/writer events 454 ** 455 ** Returns Nothing 456 ** 457 *******************************************************************************/ 458 static void nfa_rw_handle_t1t_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 459 { 460 tNFA_CONN_EVT_DATA conn_evt_data; 461 462 conn_evt_data.status = p_rw_data->data.status; 463 switch (event) 464 { 465 case RW_T1T_RID_EVT: 466 case RW_T1T_RALL_CPLT_EVT: 467 case RW_T1T_READ_CPLT_EVT: 468 case RW_T1T_RSEG_CPLT_EVT: 469 case RW_T1T_READ8_CPLT_EVT: 470 nfa_rw_send_data_to_upper (p_rw_data); 471 472 /* Command complete - perform cleanup, notify the app */ 473 nfa_rw_command_complete(); 474 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 475 break; 476 477 case RW_T1T_WRITE_E_CPLT_EVT: 478 case RW_T1T_WRITE_NE_CPLT_EVT: 479 case RW_T1T_WRITE_E8_CPLT_EVT: 480 case RW_T1T_WRITE_NE8_CPLT_EVT: 481 nfa_rw_send_data_to_upper (p_rw_data); 482 483 /* Command complete - perform cleanup, notify the app */ 484 nfa_rw_command_complete(); 485 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 486 break; 487 488 case RW_T1T_TLV_DETECT_EVT: 489 nfa_rw_handle_tlv_detect(event, p_rw_data); 490 break; 491 492 case RW_T1T_NDEF_DETECT_EVT: 493 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE; 494 nfa_rw_handle_ndef_detect(event, p_rw_data); 495 break; 496 497 case RW_T1T_NDEF_READ_EVT: 498 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE; 499 if (p_rw_data->status == NFC_STATUS_OK) 500 { 501 /* Process the ndef record */ 502 nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 503 } 504 else 505 { 506 /* Notify app of failure */ 507 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 508 { 509 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 510 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 511 } 512 } 513 514 /* Command complete - perform cleanup, notify the app */ 515 nfa_rw_command_complete(); 516 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 517 518 /* Free ndef buffer */ 519 nfa_rw_free_ndef_rx_buf(); 520 break; 521 522 case RW_T1T_NDEF_WRITE_EVT: 523 if (p_rw_data->data.status != NFA_STATUS_OK) 524 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 525 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE; 526 527 528 /* Command complete - perform cleanup, notify the app */ 529 nfa_rw_command_complete(); 530 531 /* Notify app */ 532 conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 533 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 534 { 535 /* Update local cursize of ndef message */ 536 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 537 } 538 539 /* Notify app of ndef write complete status */ 540 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 541 break; 542 543 case RW_T1T_SET_TAG_RO_EVT: 544 /* Command complete - perform cleanup, notify the app */ 545 nfa_rw_command_complete(); 546 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 547 break; 548 549 case RW_T1T_RAW_FRAME_EVT: 550 nfa_rw_send_data_to_upper (p_rw_data); 551 552 /* Command complete - perform cleanup */ 553 nfa_rw_command_complete(); 554 break; 555 556 case RW_T1T_PRESENCE_CHECK_EVT: /* Presence check completed */ 557 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 558 break; 559 560 case RW_T1T_FORMAT_CPLT_EVT: 561 if (p_rw_data->data.status == NFA_STATUS_OK) 562 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 563 564 /* Command complete - perform cleanup, notify the app */ 565 nfa_rw_command_complete(); 566 nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data); 567 break; 568 569 case RW_T1T_INTF_ERROR_EVT: 570 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 571 break; 572 } 573 } 574 575 /******************************************************************************* 576 ** 577 ** Function nfa_rw_handle_t2t_evt 578 ** 579 ** Description Handler for Type-2 tag reader/writer events 580 ** 581 ** Returns Nothing 582 ** 583 *******************************************************************************/ 584 static void nfa_rw_handle_t2t_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 585 { 586 tNFA_CONN_EVT_DATA conn_evt_data; 587 588 conn_evt_data.status = p_rw_data->data.status; 589 switch (event) 590 { 591 case RW_T2T_READ_CPLT_EVT: /* Read completed */ 592 nfa_rw_send_data_to_upper (p_rw_data); 593 /* Command complete - perform cleanup, notify the app */ 594 nfa_rw_command_complete(); 595 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 596 break; 597 598 case RW_T2T_WRITE_CPLT_EVT: /* Write completed */ 599 /* Command complete - perform cleanup, notify the app */ 600 nfa_rw_command_complete(); 601 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 602 break; 603 604 case RW_T2T_SELECT_CPLT_EVT: /* Sector select completed */ 605 /* Command complete - perform cleanup, notify the app */ 606 nfa_rw_command_complete(); 607 nfa_dm_act_conn_cback_notify(NFA_SELECT_CPLT_EVT, &conn_evt_data); 608 break; 609 610 case RW_T2T_NDEF_DETECT_EVT: /* NDEF detection complete */ 611 nfa_rw_handle_ndef_detect(event, p_rw_data); 612 break; 613 614 case RW_T2T_TLV_DETECT_EVT: /* Lock control/Mem/Prop tlv detection complete */ 615 nfa_rw_handle_tlv_detect(event, p_rw_data); 616 break; 617 618 case RW_T2T_NDEF_READ_EVT: /* NDEF read completed */ 619 if (p_rw_data->status == NFC_STATUS_OK) 620 { 621 /* Process the ndef record */ 622 nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 623 } 624 else 625 { 626 /* Notify app of failure */ 627 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 628 { 629 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 630 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 631 } 632 } 633 634 /* Notify app of read status */ 635 conn_evt_data.status = p_rw_data->status; 636 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 637 /* Free ndef buffer */ 638 nfa_rw_free_ndef_rx_buf(); 639 640 /* Command complete - perform cleanup */ 641 nfa_rw_command_complete(); 642 break; 643 644 case RW_T2T_NDEF_WRITE_EVT: /* NDEF write complete */ 645 646 /* Command complete - perform cleanup, notify the app */ 647 nfa_rw_command_complete(); 648 649 /* Notify app */ 650 conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 651 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 652 { 653 /* Update local cursize of ndef message */ 654 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 655 } 656 657 /* Notify app of ndef write complete status */ 658 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 659 660 break; 661 662 case RW_T2T_SET_TAG_RO_EVT: 663 /* Command complete - perform cleanup, notify the app */ 664 nfa_rw_command_complete(); 665 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 666 break; 667 668 case RW_T2T_RAW_FRAME_EVT: 669 nfa_rw_send_data_to_upper (p_rw_data); 670 671 /* Command complete - perform cleanup */ 672 nfa_rw_command_complete(); 673 break; 674 675 case RW_T2T_PRESENCE_CHECK_EVT: /* Presence check completed */ 676 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 677 break; 678 679 case RW_T2T_FORMAT_CPLT_EVT: 680 if (p_rw_data->data.status == NFA_STATUS_OK) 681 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 682 683 /* Command complete - perform cleanup, notify the app */ 684 nfa_rw_command_complete(); 685 nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data); 686 break; 687 688 case RW_T2T_INTF_ERROR_EVT: 689 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 690 break; 691 } 692 } 693 694 /******************************************************************************* 695 ** 696 ** Function nfa_rw_handle_t3t_evt 697 ** 698 ** Description Handler for Type-3 tag reader/writer events 699 ** 700 ** Returns Nothing 701 ** 702 *******************************************************************************/ 703 static void nfa_rw_handle_t3t_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 704 { 705 tNFA_CONN_EVT_DATA conn_evt_data; 706 tNFA_TAG_PARAMS tag_params; 707 708 switch (event) 709 { 710 case RW_T3T_NDEF_DETECT_EVT: /* NDEF detection complete */ 711 nfa_rw_handle_ndef_detect(event, p_rw_data); 712 break; 713 714 case RW_T3T_UPDATE_CPLT_EVT: /* Write completed */ 715 /* Command complete - perform cleanup, notify the app */ 716 nfa_rw_command_complete(); 717 718 /* Notify app */ 719 conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 720 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 721 { 722 /* Update local cursize of ndef message */ 723 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 724 } 725 726 /* Notify app of ndef write complete status */ 727 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 728 729 break; 730 731 case RW_T3T_CHECK_CPLT_EVT: /* Read completed */ 732 if (p_rw_data->status == NFC_STATUS_OK) 733 { 734 /* Process the ndef record */ 735 nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 736 } 737 else 738 { 739 /* Notify app of failure */ 740 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 741 { 742 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 743 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 744 } 745 } 746 747 /* Free ndef buffer */ 748 nfa_rw_free_ndef_rx_buf(); 749 750 /* Command complete - perform cleanup, notify the app */ 751 nfa_rw_command_complete(); 752 conn_evt_data.status = p_rw_data->status; 753 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 754 break; 755 756 case RW_T3T_CHECK_EVT: /* Segment of data received from type 3 tag */ 757 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 758 { 759 nfa_rw_store_ndef_rx_buf (p_rw_data); 760 } 761 else 762 { 763 nfa_rw_send_data_to_upper (p_rw_data); 764 } 765 break; 766 767 case RW_T3T_RAW_FRAME_EVT: /* SendRawFrame response */ 768 nfa_rw_send_data_to_upper (p_rw_data); 769 770 /* Command complete - perform cleanup */ 771 nfa_rw_command_complete(); 772 break; 773 774 case RW_T3T_PRESENCE_CHECK_EVT: /* Presence check completed */ 775 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 776 break; 777 778 case RW_T3T_GET_SYSTEM_CODES_EVT: /* Presence check completed */ 779 /* Command complete - perform cleanup */ 780 nfa_rw_command_complete(); 781 782 /* System codes retrieved - notify app of ACTIVATION */ 783 if (p_rw_data->status == NFC_STATUS_OK) 784 { 785 tag_params.t3t.num_system_codes = p_rw_data->t3t_sc.num_system_codes; 786 tag_params.t3t.p_system_codes = p_rw_data->t3t_sc.p_system_codes; 787 } 788 else 789 { 790 tag_params.t3t.num_system_codes = 0; 791 tag_params.t3t.p_system_codes = NULL; 792 } 793 794 nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params); 795 break; 796 797 case RW_T3T_FORMAT_CPLT_EVT: /* Format completed */ 798 /* Command complete - perform cleanup, notify the app */ 799 nfa_rw_command_complete(); 800 801 /* Notify app */ 802 conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED; 803 804 /* Notify app of ndef write complete status */ 805 nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data); 806 break; 807 808 809 case RW_T3T_INTF_ERROR_EVT: 810 conn_evt_data.status = p_rw_data->status; 811 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 812 break; 813 } 814 815 } 816 817 818 /******************************************************************************* 819 ** 820 ** Function nfa_rw_handle_t4t_evt 821 ** 822 ** Description Handler for Type-4 tag reader/writer events 823 ** 824 ** Returns Nothing 825 ** 826 *******************************************************************************/ 827 static void nfa_rw_handle_t4t_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 828 { 829 tNFA_CONN_EVT_DATA conn_evt_data; 830 831 switch (event) 832 { 833 case RW_T4T_NDEF_DETECT_EVT : /* Result of NDEF detection procedure */ 834 nfa_rw_handle_ndef_detect(event, p_rw_data); 835 break; 836 837 case RW_T4T_NDEF_READ_EVT: /* Segment of data received from type 4 tag */ 838 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 839 { 840 nfa_rw_store_ndef_rx_buf (p_rw_data); 841 } 842 else 843 { 844 nfa_rw_send_data_to_upper (p_rw_data); 845 } 846 break; 847 848 case RW_T4T_NDEF_READ_CPLT_EVT: /* Read operation completed */ 849 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 850 { 851 nfa_rw_store_ndef_rx_buf (p_rw_data); 852 853 /* Process the ndef record */ 854 nfa_dm_ndef_handle_message (NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 855 856 /* Free ndef buffer */ 857 nfa_rw_free_ndef_rx_buf(); 858 } 859 else 860 { 861 nfa_rw_send_data_to_upper (p_rw_data); 862 } 863 864 /* Command complete - perform cleanup, notify the app */ 865 nfa_rw_command_complete(); 866 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 867 conn_evt_data.status = NFC_STATUS_OK; 868 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 869 break; 870 871 case RW_T4T_NDEF_READ_FAIL_EVT: /* Read operation failed */ 872 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 873 { 874 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 875 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 876 877 /* Free ndef buffer */ 878 nfa_rw_free_ndef_rx_buf(); 879 } 880 881 /* Command complete - perform cleanup, notify the app */ 882 nfa_rw_command_complete(); 883 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 884 conn_evt_data.status = NFA_STATUS_FAILED; 885 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 886 break; 887 888 case RW_T4T_NDEF_UPDATE_CPLT_EVT: /* Update operation completed */ 889 case RW_T4T_NDEF_UPDATE_FAIL_EVT: /* Update operation failed */ 890 891 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 892 { 893 /* Update local cursize of ndef message */ 894 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 895 } 896 897 /* Notify app */ 898 if (event == RW_T4T_NDEF_UPDATE_CPLT_EVT) 899 conn_evt_data.status = NFA_STATUS_OK; 900 else 901 conn_evt_data.status = NFA_STATUS_FAILED; 902 903 /* Command complete - perform cleanup, notify the app */ 904 nfa_rw_command_complete(); 905 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 906 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 907 break; 908 909 case RW_T4T_RAW_FRAME_EVT: /* Raw Frame data event */ 910 nfa_rw_send_data_to_upper (p_rw_data); 911 912 /* Command complete - perform cleanup */ 913 nfa_rw_command_complete(); 914 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 915 break; 916 917 case RW_T4T_INTF_ERROR_EVT: /* RF Interface error event */ 918 /* if NDEF operation */ 919 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 920 { 921 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 922 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 923 924 /* Free ndef buffer */ 925 nfa_rw_free_ndef_rx_buf(); 926 } 927 else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 928 { 929 /* Update local cursize of ndef message */ 930 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 931 } 932 933 /* Command complete - perform cleanup, notify app */ 934 nfa_rw_command_complete(); 935 conn_evt_data.status = p_rw_data->status; 936 937 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 938 { 939 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 940 } 941 else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 942 { 943 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 944 } 945 else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF) 946 { 947 conn_evt_data.ndef_detect.cur_size = 0; 948 conn_evt_data.ndef_detect.max_size = 0; 949 conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; 950 nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data); 951 } 952 else 953 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 954 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 955 break; 956 957 958 case RW_T4T_PRESENCE_CHECK_EVT: /* Presence check completed */ 959 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 960 break; 961 962 default: 963 NFA_TRACE_DEBUG1("nfa_rw_handle_t4t_evt(); Unhandled RW event 0x%X", event); 964 break; 965 } 966 } 967 968 /******************************************************************************* 969 ** 970 ** Function nfa_rw_handle_i93_evt 971 ** 972 ** Description Handler for ISO 15693 tag reader/writer events 973 ** 974 ** Returns Nothing 975 ** 976 *******************************************************************************/ 977 static void nfa_rw_handle_i93_evt (tRW_EVENT event, tRW_DATA *p_rw_data) 978 { 979 tNFA_CONN_EVT_DATA conn_evt_data; 980 tNFA_TAG_PARAMS i93_params; 981 982 switch (event) 983 { 984 case RW_I93_NDEF_DETECT_EVT : /* Result of NDEF detection procedure */ 985 nfa_rw_handle_ndef_detect(event, p_rw_data); 986 break; 987 988 case RW_I93_NDEF_READ_EVT: /* Segment of data received from type 4 tag */ 989 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 990 { 991 nfa_rw_store_ndef_rx_buf (p_rw_data); 992 } 993 else 994 { 995 nfa_rw_send_data_to_upper (p_rw_data); 996 } 997 break; 998 999 case RW_I93_NDEF_READ_CPLT_EVT: /* Read operation completed */ 1000 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1001 { 1002 nfa_rw_store_ndef_rx_buf (p_rw_data); 1003 1004 /* Process the ndef record */ 1005 nfa_dm_ndef_handle_message (NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size); 1006 1007 /* Free ndef buffer */ 1008 nfa_rw_free_ndef_rx_buf(); 1009 } 1010 else 1011 { 1012 nfa_rw_send_data_to_upper (p_rw_data); 1013 } 1014 1015 /* Command complete - perform cleanup, notify app */ 1016 nfa_rw_command_complete(); 1017 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1018 conn_evt_data.status = NFC_STATUS_OK; 1019 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1020 break; 1021 1022 case RW_I93_NDEF_READ_FAIL_EVT: /* Read operation failed */ 1023 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1024 { 1025 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 1026 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 1027 1028 /* Free ndef buffer */ 1029 nfa_rw_free_ndef_rx_buf(); 1030 } 1031 1032 /* Command complete - perform cleanup, notify app */ 1033 nfa_rw_command_complete(); 1034 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1035 conn_evt_data.status = NFA_STATUS_FAILED; 1036 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1037 break; 1038 1039 case RW_I93_NDEF_UPDATE_CPLT_EVT: /* Update operation completed */ 1040 case RW_I93_NDEF_UPDATE_FAIL_EVT: /* Update operation failed */ 1041 1042 if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 1043 { 1044 /* Update local cursize of ndef message */ 1045 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 1046 } 1047 1048 /* Command complete - perform cleanup, notify app */ 1049 nfa_rw_command_complete(); 1050 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1051 1052 if (event == RW_I93_NDEF_UPDATE_CPLT_EVT) 1053 conn_evt_data.status = NFA_STATUS_OK; 1054 else 1055 conn_evt_data.status = NFA_STATUS_FAILED; 1056 1057 /* Notify app of ndef write complete status */ 1058 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 1059 break; 1060 1061 case RW_I93_RAW_FRAME_EVT: /* Raw Frame data event */ 1062 nfa_rw_send_data_to_upper (p_rw_data); 1063 1064 /* Command complete - perform cleanup */ 1065 nfa_rw_command_complete(); 1066 break; 1067 1068 case RW_I93_INTF_ERROR_EVT: /* RF Interface error event */ 1069 if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) 1070 { 1071 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 1072 1073 memset (&i93_params, 0x00, sizeof (tNFA_TAG_PARAMS)); 1074 memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN); 1075 1076 /* Command complete - perform cleanup, notify app */ 1077 nfa_rw_command_complete(); 1078 1079 nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params); 1080 } 1081 else 1082 { 1083 /* if NDEF operation */ 1084 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1085 { 1086 /* If current operation is READ_NDEF, then notify ndef handlers of failure */ 1087 nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0); 1088 1089 /* Free ndef buffer */ 1090 nfa_rw_free_ndef_rx_buf(); 1091 } 1092 else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 1093 { 1094 /* Update local cursize of ndef message */ 1095 nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len; 1096 } 1097 1098 /* Command complete - perform cleanup, notify app */ 1099 nfa_rw_command_complete(); 1100 1101 conn_evt_data.status = p_rw_data->status; 1102 1103 if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) 1104 { 1105 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1106 } 1107 else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) 1108 { 1109 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 1110 } 1111 else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF) 1112 { 1113 conn_evt_data.ndef_detect.cur_size = 0; 1114 conn_evt_data.ndef_detect.max_size = 0; 1115 conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; 1116 nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data); 1117 } 1118 else 1119 { 1120 /* this event doesn't have command */ 1121 nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data); 1122 } 1123 } 1124 1125 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1126 break; 1127 1128 1129 case RW_I93_PRESENCE_CHECK_EVT: /* Presence check completed */ 1130 nfa_rw_handle_presence_check_rsp(p_rw_data->status); 1131 break; 1132 1133 case RW_I93_FORMAT_CPLT_EVT: /* Format procedure complete */ 1134 if (p_rw_data->data.status == NFA_STATUS_OK) 1135 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 1136 1137 /* Command complete - perform cleanup, notify app */ 1138 nfa_rw_command_complete(); 1139 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1140 conn_evt_data.status = p_rw_data->status; 1141 nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data); 1142 break; 1143 1144 case RW_I93_SET_TAG_RO_EVT: /* Set read-only procedure complete */ 1145 nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY; 1146 1147 /* Command complete - perform cleanup, notify app */ 1148 nfa_rw_command_complete(); 1149 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1150 conn_evt_data.status = p_rw_data->status; 1151 nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data); 1152 break; 1153 1154 case RW_I93_INVENTORY_EVT: /* Response of Inventory */ 1155 1156 /* Command complete - perform cleanup, notify app */ 1157 nfa_rw_command_complete(); 1158 1159 if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) 1160 { 1161 /* read AFI */ 1162 if (RW_I93ReadSingleBlock ((UINT8)(nfa_rw_cb.i93_afi_location / nfa_rw_cb.i93_block_size)) != NFC_STATUS_OK) 1163 { 1164 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 1165 1166 i93_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE); 1167 i93_params.i93.dsfid = p_rw_data->i93_inventory.dsfid; 1168 i93_params.i93.block_size = nfa_rw_cb.i93_block_size; 1169 i93_params.i93.num_block = nfa_rw_cb.i93_num_block; 1170 memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN); 1171 1172 nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params); 1173 } 1174 else 1175 { 1176 nfa_rw_cb.i93_dsfid = p_rw_data->i93_inventory.dsfid; 1177 break; 1178 } 1179 } 1180 else 1181 { 1182 conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_inventory.status; 1183 conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_INVENTORY; 1184 1185 conn_evt_data.i93_cmd_cplt.params.inventory.dsfid = p_rw_data->i93_inventory.dsfid; 1186 memcpy (conn_evt_data.i93_cmd_cplt.params.inventory.uid, 1187 p_rw_data->i93_inventory.uid, 1188 I93_UID_BYTE_LEN); 1189 1190 nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data); 1191 } 1192 1193 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1194 break; 1195 1196 case RW_I93_DATA_EVT: /* Response of Read, Get Multi Security */ 1197 1198 /* Command complete - perform cleanup, notify app */ 1199 nfa_rw_command_complete(); 1200 1201 conn_evt_data.data.p_data = (UINT8 *)(p_rw_data->i93_data.p_data + 1) + p_rw_data->i93_data.p_data->offset; 1202 1203 if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) 1204 { 1205 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 1206 1207 i93_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE|I93_INFO_FLAG_AFI); 1208 i93_params.i93.afi = *(conn_evt_data.data.p_data + nfa_rw_cb.i93_afi_location % nfa_rw_cb.i93_block_size); 1209 i93_params.i93.dsfid = nfa_rw_cb.i93_dsfid; 1210 i93_params.i93.block_size = nfa_rw_cb.i93_block_size; 1211 i93_params.i93.num_block = nfa_rw_cb.i93_num_block; 1212 memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN); 1213 1214 nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params); 1215 } 1216 else 1217 { 1218 conn_evt_data.data.len = p_rw_data->i93_data.p_data->len; 1219 1220 nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data); 1221 } 1222 1223 GKI_freebuf(p_rw_data->i93_data.p_data); 1224 p_rw_data->i93_data.p_data = NULL; 1225 1226 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1227 break; 1228 1229 case RW_I93_SYS_INFO_EVT: /* Response of System Information */ 1230 1231 /* Command complete - perform cleanup, notify app */ 1232 nfa_rw_command_complete(); 1233 1234 if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) 1235 { 1236 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING; 1237 1238 nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size; 1239 nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block; 1240 1241 i93_params.i93.info_flags = p_rw_data->i93_sys_info.info_flags; 1242 i93_params.i93.dsfid = p_rw_data->i93_sys_info.dsfid; 1243 i93_params.i93.afi = p_rw_data->i93_sys_info.afi; 1244 i93_params.i93.num_block = p_rw_data->i93_sys_info.num_block; 1245 i93_params.i93.block_size = p_rw_data->i93_sys_info.block_size; 1246 i93_params.i93.IC_reference = p_rw_data->i93_sys_info.IC_reference; 1247 memcpy (i93_params.i93.uid, p_rw_data->i93_sys_info.uid, I93_UID_BYTE_LEN); 1248 1249 nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params); 1250 } 1251 else 1252 { 1253 conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_inventory.status; 1254 conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_GET_SYS_INFO; 1255 1256 conn_evt_data.i93_cmd_cplt.params.sys_info.info_flags = p_rw_data->i93_sys_info.info_flags; 1257 memcpy (conn_evt_data.i93_cmd_cplt.params.sys_info.uid, 1258 p_rw_data->i93_sys_info.uid, 1259 I93_UID_BYTE_LEN); 1260 conn_evt_data.i93_cmd_cplt.params.sys_info.dsfid = p_rw_data->i93_sys_info.dsfid; 1261 conn_evt_data.i93_cmd_cplt.params.sys_info.afi = p_rw_data->i93_sys_info.afi; 1262 conn_evt_data.i93_cmd_cplt.params.sys_info.num_block = p_rw_data->i93_sys_info.num_block; 1263 conn_evt_data.i93_cmd_cplt.params.sys_info.block_size = p_rw_data->i93_sys_info.block_size; 1264 conn_evt_data.i93_cmd_cplt.params.sys_info.IC_reference = p_rw_data->i93_sys_info.IC_reference; 1265 1266 /* store tag memory information for writing blocks */ 1267 nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size; 1268 nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block; 1269 1270 nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data); 1271 } 1272 1273 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1274 break; 1275 1276 case RW_I93_CMD_CMPL_EVT: /* Command complete */ 1277 /* Command complete - perform cleanup, notify app */ 1278 nfa_rw_command_complete(); 1279 1280 conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_cmd_cmpl.status; 1281 conn_evt_data.i93_cmd_cplt.sent_command = p_rw_data->i93_cmd_cmpl.command; 1282 1283 if (conn_evt_data.i93_cmd_cplt.status != NFC_STATUS_OK) 1284 conn_evt_data.i93_cmd_cplt.params.error_code = p_rw_data->i93_cmd_cmpl.error_code; 1285 1286 nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data); 1287 1288 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */ 1289 break; 1290 1291 default: 1292 NFA_TRACE_DEBUG1("nfa_rw_handle_i93_evt(); Unhandled RW event 0x%X", event); 1293 break; 1294 } 1295 } 1296 1297 /******************************************************************************* 1298 ** 1299 ** Function nfa_rw_cback 1300 ** 1301 ** Description Callback for reader/writer event notification 1302 ** 1303 ** Returns Nothing 1304 ** 1305 *******************************************************************************/ 1306 static void nfa_rw_cback (tRW_EVENT event, tRW_DATA *p_rw_data) 1307 { 1308 NFA_TRACE_DEBUG1("nfa_rw_cback: event=0x%02x", event); 1309 1310 /* Call appropriate event handler for tag type */ 1311 if (event < RW_T1T_MAX_EVT) 1312 { 1313 /* Handle Type-1 tag events */ 1314 nfa_rw_handle_t1t_evt(event, p_rw_data); 1315 } 1316 else if (event < RW_T2T_MAX_EVT) 1317 { 1318 /* Handle Type-2 tag events */ 1319 nfa_rw_handle_t2t_evt(event, p_rw_data); 1320 } 1321 else if (event < RW_T3T_MAX_EVT) 1322 { 1323 /* Handle Type-3 tag events */ 1324 nfa_rw_handle_t3t_evt(event, p_rw_data); 1325 } 1326 else if (event < RW_T4T_MAX_EVT) 1327 { 1328 /* Handle Type-4 tag events */ 1329 nfa_rw_handle_t4t_evt(event, p_rw_data); 1330 } 1331 else if (event < RW_I93_MAX_EVT) 1332 { 1333 /* Handle ISO 15693 tag events */ 1334 nfa_rw_handle_i93_evt(event, p_rw_data); 1335 } 1336 else 1337 { 1338 NFA_TRACE_ERROR1("nfa_rw_cback: unhandled event=0x%02x", event); 1339 } 1340 } 1341 1342 /******************************************************************************* 1343 ** 1344 ** Function nfa_rw_start_ndef_detection 1345 ** 1346 ** Description Start NDEF detection on activated tag 1347 ** 1348 ** Returns Nothing 1349 ** 1350 *******************************************************************************/ 1351 static tNFC_STATUS nfa_rw_start_ndef_detection(void) 1352 { 1353 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1354 tNFC_STATUS status = NFC_STATUS_FAILED; 1355 1356 switch (protocol) 1357 { 1358 case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */ 1359 status = RW_T1tDetectNDef(); 1360 break; 1361 1362 case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */ 1363 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1364 status = RW_T2tDetectNDef(); 1365 break; 1366 1367 case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */ 1368 status = RW_T3tDetectNDef(); 1369 break; 1370 1371 case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */ 1372 status = RW_T4tDetectNDef(); 1373 break; 1374 1375 case NFC_PROTOCOL_15693: /* ISO 15693 */ 1376 status = RW_I93DetectNDef(); 1377 break; 1378 1379 default: 1380 break; 1381 } 1382 1383 return(status); 1384 } 1385 1386 /******************************************************************************* 1387 ** 1388 ** Function nfa_rw_start_ndef_read 1389 ** 1390 ** Description Start NDEF read on activated tag 1391 ** 1392 ** Returns Nothing 1393 ** 1394 *******************************************************************************/ 1395 static tNFC_STATUS nfa_rw_start_ndef_read(void) 1396 { 1397 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1398 tNFC_STATUS status = NFC_STATUS_FAILED; 1399 tNFA_CONN_EVT_DATA conn_evt_data; 1400 1401 /* Handle zero length NDEF message */ 1402 if (nfa_rw_cb.ndef_cur_size == 0) 1403 { 1404 NFA_TRACE_DEBUG0("NDEF message is zero-length"); 1405 1406 /* Send zero-lengh NDEF message to ndef callback */ 1407 nfa_dm_ndef_handle_message(NFA_STATUS_OK, NULL, 0); 1408 1409 /* Command complete - perform cleanup, notify app */ 1410 nfa_rw_command_complete(); 1411 conn_evt_data.status = NFA_STATUS_OK; 1412 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1413 return NFC_STATUS_OK; 1414 } 1415 1416 /* Allocate buffer for incoming NDEF message (free previous NDEF rx buffer, if needed) */ 1417 nfa_rw_free_ndef_rx_buf (); 1418 if ((nfa_rw_cb.p_ndef_buf = (UINT8 *)nfa_mem_co_alloc(nfa_rw_cb.ndef_cur_size)) == NULL) 1419 { 1420 NFA_TRACE_ERROR1("Unable to allocate a buffer for reading NDEF (size=%i)", nfa_rw_cb.ndef_cur_size); 1421 1422 /* Command complete - perform cleanup, notify app */ 1423 nfa_rw_command_complete(); 1424 conn_evt_data.status = NFA_STATUS_FAILED; 1425 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1426 return NFC_STATUS_FAILED; 1427 } 1428 nfa_rw_cb.ndef_rd_offset = 0; 1429 1430 switch (protocol) 1431 { 1432 case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */ 1433 status = RW_T1tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size); 1434 break; 1435 1436 case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */ 1437 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1438 status = RW_T2tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size); 1439 1440 break; 1441 1442 case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */ 1443 status = RW_T3tCheckNDef(); 1444 break; 1445 1446 case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */ 1447 status = RW_T4tReadNDef(); 1448 break; 1449 1450 case NFC_PROTOCOL_15693: /* ISO 15693 */ 1451 status = RW_I93ReadNDef(); 1452 break; 1453 1454 default: 1455 break; 1456 } 1457 return(status); 1458 } 1459 1460 /******************************************************************************* 1461 ** 1462 ** Function nfa_rw_detect_ndef 1463 ** 1464 ** Description Handler for NFA_RW_API_DETECT_NDEF_EVT 1465 ** 1466 ** Returns TRUE (message buffer to be freed by caller) 1467 ** 1468 *******************************************************************************/ 1469 static BOOLEAN nfa_rw_detect_ndef(tNFA_RW_MSG *p_data) 1470 { 1471 tNFA_CONN_EVT_DATA conn_evt_data; 1472 NFA_TRACE_DEBUG0("nfa_rw_detect_ndef"); 1473 1474 if ((conn_evt_data.ndef_detect.status = nfa_rw_start_ndef_detection()) != NFC_STATUS_OK) 1475 { 1476 /* Command complete - perform cleanup, notify app */ 1477 nfa_rw_command_complete(); 1478 conn_evt_data.ndef_detect.cur_size = 0; 1479 conn_evt_data.ndef_detect.max_size = 0; 1480 conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; 1481 nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data); 1482 } 1483 1484 return TRUE; 1485 } 1486 1487 /******************************************************************************* 1488 ** 1489 ** Function nfa_rw_start_ndef_write 1490 ** 1491 ** Description Start NDEF write on activated tag 1492 ** 1493 ** Returns Nothing 1494 ** 1495 *******************************************************************************/ 1496 static tNFC_STATUS nfa_rw_start_ndef_write(void) 1497 { 1498 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1499 tNFC_STATUS status = NFC_STATUS_FAILED; 1500 1501 if (nfa_rw_cb.flags & NFA_RW_FL_TAG_IS_READONLY) 1502 { 1503 /* error: ndef tag is read-only */ 1504 status = NFC_STATUS_FAILED; 1505 NFA_TRACE_ERROR0("Unable to write NDEF. Tag is read-only") 1506 } 1507 else if (nfa_rw_cb.ndef_max_size < nfa_rw_cb.ndef_wr_len) 1508 { 1509 /* error: ndef tag size is too small */ 1510 status = NFC_STATUS_BUFFER_FULL; 1511 NFA_TRACE_ERROR2("Unable to write NDEF. Tag maxsize=%i, request write size=%i", nfa_rw_cb.ndef_max_size, nfa_rw_cb.ndef_wr_len) 1512 } 1513 else 1514 { 1515 switch (protocol) 1516 { 1517 case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */ 1518 status = RW_T1tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1519 break; 1520 1521 case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */ 1522 1523 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1524 status = RW_T2tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1525 break; 1526 1527 case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */ 1528 status = RW_T3tUpdateNDef(nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1529 break; 1530 1531 case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */ 1532 status = RW_T4tUpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1533 break; 1534 1535 case NFC_PROTOCOL_15693: /* ISO 15693 */ 1536 status = RW_I93UpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf); 1537 break; 1538 1539 default: 1540 break; 1541 } 1542 } 1543 1544 return(status); 1545 } 1546 1547 /******************************************************************************* 1548 ** 1549 ** Function nfa_rw_read_ndef 1550 ** 1551 ** Description Handler for NFA_RW_API_READ_NDEF_EVT 1552 ** 1553 ** Returns TRUE (message buffer to be freed by caller) 1554 ** 1555 *******************************************************************************/ 1556 static BOOLEAN nfa_rw_read_ndef(tNFA_RW_MSG *p_data) 1557 { 1558 tNFA_STATUS status = NFA_STATUS_OK; 1559 tNFA_CONN_EVT_DATA conn_evt_data; 1560 1561 NFA_TRACE_DEBUG0("nfa_rw_read_ndef"); 1562 1563 /* Check if ndef detection has been performed yet */ 1564 if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) 1565 { 1566 /* Perform ndef detection first */ 1567 status = nfa_rw_start_ndef_detection(); 1568 } 1569 else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) 1570 { 1571 /* Tag is not NDEF */ 1572 status = NFA_STATUS_FAILED; 1573 } 1574 else 1575 { 1576 /* Perform the NDEF read operation */ 1577 status = nfa_rw_start_ndef_read(); 1578 } 1579 1580 /* Handle failure */ 1581 if (status != NFA_STATUS_OK) 1582 { 1583 /* Command complete - perform cleanup, notify app */ 1584 nfa_rw_command_complete(); 1585 conn_evt_data.status = status; 1586 nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data); 1587 } 1588 1589 1590 return TRUE; 1591 } 1592 1593 /******************************************************************************* 1594 ** 1595 ** Function nfa_rw_write_ndef 1596 ** 1597 ** Description Handler for NFA_RW_API_WRITE_NDEF_EVT 1598 ** 1599 ** Returns TRUE (message buffer to be freed by caller) 1600 ** 1601 *******************************************************************************/ 1602 static BOOLEAN nfa_rw_write_ndef(tNFA_RW_MSG *p_data) 1603 { 1604 tNDEF_STATUS ndef_status; 1605 tNFA_STATUS write_status = NFA_STATUS_OK; 1606 tNFA_CONN_EVT_DATA conn_evt_data; 1607 NFA_TRACE_DEBUG0("nfa_rw_write_ndef"); 1608 1609 /* Validate NDEF message */ 1610 if ((ndef_status = NDEF_MsgValidate(p_data->op_req.params.write_ndef.p_data, p_data->op_req.params.write_ndef.len, FALSE)) != NDEF_OK) 1611 { 1612 NFA_TRACE_ERROR1("Invalid NDEF message. NDEF_MsgValidate returned %i", ndef_status); 1613 1614 /* Command complete - perform cleanup, notify app */ 1615 nfa_rw_command_complete(); 1616 conn_evt_data.status = NFA_STATUS_FAILED; 1617 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 1618 return TRUE; 1619 } 1620 1621 /* Store pointer to source NDEF */ 1622 nfa_rw_cb.p_ndef_wr_buf = p_data->op_req.params.write_ndef.p_data; 1623 nfa_rw_cb.ndef_wr_len = p_data->op_req.params.write_ndef.len; 1624 1625 /* Check if ndef detection has been performed yet */ 1626 if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) 1627 { 1628 /* Perform ndef detection first */ 1629 write_status = nfa_rw_start_ndef_detection(); 1630 } 1631 else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) 1632 { 1633 /* Tag is not NDEF */ 1634 write_status = NFA_STATUS_FAILED; 1635 } 1636 else 1637 { 1638 /* Perform the NDEF read operation */ 1639 write_status = nfa_rw_start_ndef_write(); 1640 } 1641 1642 /* Handle failure */ 1643 if (write_status != NFA_STATUS_OK) 1644 { 1645 /* Command complete - perform cleanup, notify app */ 1646 nfa_rw_command_complete(); 1647 conn_evt_data.status = write_status; 1648 nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data); 1649 } 1650 1651 return TRUE; 1652 } 1653 1654 /******************************************************************************* 1655 ** 1656 ** Function nfa_rw_presence_check 1657 ** 1658 ** Description Handler for NFA_RW_API_PRESENCE_CHECK 1659 ** 1660 ** Returns Nothing 1661 ** 1662 *******************************************************************************/ 1663 void nfa_rw_presence_check (tNFA_RW_MSG *p_data) 1664 { 1665 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1666 UINT8 sel_res = nfa_rw_cb.pa_sel_res; 1667 tNFC_STATUS status = NFC_STATUS_FAILED; 1668 1669 switch (protocol) 1670 { 1671 case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */ 1672 status = RW_T1tPresenceCheck(); 1673 break; 1674 1675 case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */ 1676 status = RW_T3tPresenceCheck(); 1677 break; 1678 1679 case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */ 1680 status = RW_T4tPresenceCheck(); 1681 break; 1682 1683 case NFC_PROTOCOL_15693: /* ISO 15693 */ 1684 status = RW_I93PresenceCheck(); 1685 break; 1686 1687 case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */ 1688 /* If T2T NFC-Forum, then let RW handle presence check; otherwise fall through */ 1689 if (sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1690 { 1691 status = RW_T2tPresenceCheck(); 1692 break; 1693 } 1694 1695 default: 1696 /* Protocol unsupported by RW module... */ 1697 /* Let DM perform presence check (by putting tag to sleep and then waking it up) */ 1698 status = nfa_dm_disc_presence_check(); 1699 break; 1700 } 1701 1702 /* Handle presence check failure */ 1703 if (status != NFC_STATUS_OK) 1704 nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED); 1705 } 1706 1707 1708 /******************************************************************************* 1709 ** 1710 ** Function nfa_rw_presence_check_tick 1711 ** 1712 ** Description Called on expiration of NFA_RW_PRESENCE_CHECK_INTERVAL 1713 ** Initiate presence check 1714 ** 1715 ** Returns TRUE (caller frees message buffer) 1716 ** 1717 *******************************************************************************/ 1718 BOOLEAN nfa_rw_presence_check_tick(tNFA_RW_MSG *p_data) 1719 { 1720 /* Store the current operation */ 1721 nfa_rw_cb.cur_op = NFA_RW_OP_PRESENCE_CHECK; 1722 nfa_rw_cb.flags |= NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY; 1723 NFA_TRACE_DEBUG0("Auto-presence check starting..."); 1724 1725 /* Perform presence check */ 1726 nfa_rw_presence_check(NULL); 1727 1728 return TRUE; 1729 } 1730 1731 /******************************************************************************* 1732 ** 1733 ** Function nfa_rw_format_tag 1734 ** 1735 ** Description Handler for NFA_RW_API_FORMAT_TAG 1736 ** 1737 ** Returns Nothing 1738 ** 1739 *******************************************************************************/ 1740 static void nfa_rw_format_tag (tNFA_RW_MSG *p_data) 1741 { 1742 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1743 tNFC_STATUS status = NFC_STATUS_FAILED; 1744 1745 if (protocol == NFC_PROTOCOL_T1T) 1746 { 1747 status = RW_T1tFormatNDef(); 1748 } 1749 else if ( (protocol == NFC_PROTOCOL_T2T) 1750 &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) ) 1751 { 1752 status = RW_T2tFormatNDef(); 1753 } 1754 else if (protocol == NFC_PROTOCOL_T3T) 1755 { 1756 status = RW_T3tFormatNDef(); 1757 } 1758 else if (protocol == NFC_PROTOCOL_15693) 1759 { 1760 status = RW_I93FormatNDef(); 1761 } 1762 1763 /* If unable to format NDEF, notify the app */ 1764 if (status != NFC_STATUS_OK) 1765 nfa_rw_error_cleanup (NFA_FORMAT_CPLT_EVT); 1766 } 1767 1768 /******************************************************************************* 1769 ** 1770 ** Function nfa_rw_detect_tlv 1771 ** 1772 ** Description Handler for NFA_RW_API_DETECT_NDEF_EVT 1773 ** 1774 ** Returns TRUE (message buffer to be freed by caller) 1775 ** 1776 *******************************************************************************/ 1777 static BOOLEAN nfa_rw_detect_tlv (tNFA_RW_MSG *p_data, UINT8 tlv) 1778 { 1779 NFA_TRACE_DEBUG0("nfa_rw_detect_tlv"); 1780 1781 switch (nfa_rw_cb.protocol) 1782 { 1783 case NFC_PROTOCOL_T1T: 1784 if (RW_T1tLocateTlv(tlv) != NFC_STATUS_OK) 1785 nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT); 1786 break; 1787 1788 case NFC_PROTOCOL_T2T: 1789 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1790 { 1791 if (RW_T2tLocateTlv(tlv) != NFC_STATUS_OK) 1792 nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT); 1793 } 1794 break; 1795 1796 default: 1797 break; 1798 } 1799 1800 return TRUE; 1801 } 1802 1803 /******************************************************************************* 1804 ** 1805 ** Function nfa_rw_config_tag_ro 1806 ** 1807 ** Description Handler for NFA_RW_OP_SET_TAG_RO 1808 ** 1809 ** Returns TRUE (message buffer to be freed by caller) 1810 ** 1811 *******************************************************************************/ 1812 static tNFC_STATUS nfa_rw_config_tag_ro (BOOLEAN b_hard_lock) 1813 { 1814 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol; 1815 tNFC_STATUS status = NFC_STATUS_FAILED; 1816 1817 NFA_TRACE_DEBUG0("nfa_rw_config_tag_ro"); 1818 1819 switch (protocol) 1820 { 1821 case NFC_PROTOCOL_T1T: 1822 if( (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) 1823 ||(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE) ) 1824 { 1825 status = RW_T1tLocateTlv(TAG_LOCK_CTRL_TLV); 1826 } 1827 else if ( (status = RW_T1tSetTagReadOnly(b_hard_lock)) != NFC_STATUS_OK) 1828 { 1829 nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT); 1830 } 1831 else 1832 { 1833 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 1834 } 1835 break; 1836 1837 case NFC_PROTOCOL_T2T: 1838 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 1839 { 1840 if ( (status = RW_T2tSetTagReadOnly(b_hard_lock)) != NFC_STATUS_OK) 1841 { 1842 nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT); 1843 } 1844 else 1845 { 1846 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 1847 } 1848 } 1849 break; 1850 1851 case NFC_PROTOCOL_15693: 1852 if ( (status = RW_I93SetTagReadOnly()) != NFC_STATUS_OK) 1853 nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT); 1854 break; 1855 1856 default: 1857 /* NOTE: type type-3 and type-4 protocol does not define transition to read-only */ 1858 break; 1859 1860 } 1861 return (status); 1862 } 1863 1864 /******************************************************************************* 1865 ** 1866 ** Function nfa_rw_t1t_rid 1867 ** 1868 ** Description Handler for T1T_RID API 1869 ** 1870 ** Returns TRUE (message buffer to be freed by caller) 1871 ** 1872 *******************************************************************************/ 1873 static BOOLEAN nfa_rw_t1t_rid(tNFA_RW_MSG *p_data) 1874 { 1875 if (RW_T1tRid () != NFC_STATUS_OK) 1876 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 1877 1878 return TRUE; 1879 } 1880 1881 /******************************************************************************* 1882 ** 1883 ** Function nfa_rw_t1t_rall 1884 ** 1885 ** Description Handler for T1T_ReadAll API 1886 ** 1887 ** Returns TRUE (message buffer to be freed by caller) 1888 ** 1889 *******************************************************************************/ 1890 static BOOLEAN nfa_rw_t1t_rall(tNFA_RW_MSG *p_data) 1891 { 1892 if (RW_T1tReadAll() != NFC_STATUS_OK) 1893 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 1894 1895 return TRUE; 1896 } 1897 1898 /******************************************************************************* 1899 ** 1900 ** Function nfa_rw_t1t_read 1901 ** 1902 ** Description Handler for T1T_Read API 1903 ** 1904 ** Returns TRUE (message buffer to be freed by caller) 1905 ** 1906 *******************************************************************************/ 1907 static BOOLEAN nfa_rw_t1t_read (tNFA_RW_MSG *p_data) 1908 { 1909 tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read); 1910 1911 if (RW_T1tRead (p_t1t_read->block_number, p_t1t_read->index) != NFC_STATUS_OK) 1912 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 1913 1914 return TRUE; 1915 } 1916 1917 /******************************************************************************* 1918 ** 1919 ** Function nfa_rw_t1t_write 1920 ** 1921 ** Description Handler for T1T_WriteErase/T1T_WriteNoErase API 1922 ** 1923 ** Returns TRUE (message buffer to be freed by caller) 1924 ** 1925 *******************************************************************************/ 1926 static BOOLEAN nfa_rw_t1t_write (tNFA_RW_MSG *p_data) 1927 { 1928 tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write); 1929 tNFC_STATUS status; 1930 1931 if (p_t1t_write->b_erase) 1932 { 1933 status = RW_T1tWriteErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]); 1934 } 1935 else 1936 { 1937 status = RW_T1tWriteNoErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]); 1938 } 1939 1940 if (status != NFC_STATUS_OK) 1941 { 1942 nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT); 1943 } 1944 else 1945 { 1946 if (p_t1t_write->block_number == 0x01) 1947 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 1948 } 1949 1950 return TRUE; 1951 } 1952 1953 /******************************************************************************* 1954 ** 1955 ** Function nfa_rw_t1t_rseg 1956 ** 1957 ** Description Handler for T1t_ReadSeg API 1958 ** 1959 ** Returns TRUE (message buffer to be freed by caller) 1960 ** 1961 *******************************************************************************/ 1962 static BOOLEAN nfa_rw_t1t_rseg (tNFA_RW_MSG *p_data) 1963 { 1964 tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read); 1965 1966 if (RW_T1tReadSeg (p_t1t_read->segment_number) != NFC_STATUS_OK) 1967 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 1968 1969 return TRUE; 1970 } 1971 1972 /******************************************************************************* 1973 ** 1974 ** Function nfa_rw_t1t_read8 1975 ** 1976 ** Description Handler for T1T_Read8 API 1977 ** 1978 ** Returns TRUE (message buffer to be freed by caller) 1979 ** 1980 *******************************************************************************/ 1981 static BOOLEAN nfa_rw_t1t_read8 (tNFA_RW_MSG *p_data) 1982 { 1983 tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read); 1984 1985 if (RW_T1tRead8 (p_t1t_read->block_number) != NFC_STATUS_OK) 1986 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 1987 1988 return TRUE; 1989 } 1990 1991 /******************************************************************************* 1992 ** 1993 ** Function nfa_rw_t1t_write8 1994 ** 1995 ** Description Handler for T1T_WriteErase8/T1T_WriteNoErase8 API 1996 ** 1997 ** Returns TRUE (message buffer to be freed by caller) 1998 ** 1999 *******************************************************************************/ 2000 static BOOLEAN nfa_rw_t1t_write8 (tNFA_RW_MSG *p_data) 2001 { 2002 tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write); 2003 tNFC_STATUS status; 2004 2005 if (p_t1t_write->b_erase) 2006 { 2007 status = RW_T1tWriteErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data); 2008 } 2009 else 2010 { 2011 status = RW_T1tWriteNoErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data); 2012 } 2013 2014 if (status != NFC_STATUS_OK) 2015 { 2016 nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT); 2017 } 2018 else 2019 { 2020 if (p_t1t_write->block_number == 0x01) 2021 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 2022 } 2023 2024 return TRUE; 2025 } 2026 2027 /******************************************************************************* 2028 ** 2029 ** Function nfa_rw_t2t_read 2030 ** 2031 ** Description Handler for T2T_Read API 2032 ** 2033 ** Returns TRUE (message buffer to be freed by caller) 2034 ** 2035 *******************************************************************************/ 2036 static BOOLEAN nfa_rw_t2t_read (tNFA_RW_MSG *p_data) 2037 { 2038 tNFA_RW_OP_PARAMS_T2T_READ *p_t2t_read = (tNFA_RW_OP_PARAMS_T2T_READ *)&(p_data->op_req.params.t2t_read); 2039 tNFC_STATUS status = NFC_STATUS_FAILED; 2040 2041 if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) 2042 status = RW_T2tRead (p_t2t_read->block_number); 2043 2044 if (status != NFC_STATUS_OK) 2045 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 2046 2047 return TRUE; 2048 } 2049 2050 /******************************************************************************* 2051 ** 2052 ** Function nfa_rw_t2t_write 2053 ** 2054 ** Description Handler for T2T_Write API 2055 ** 2056 ** Returns TRUE (message buffer to be freed by caller) 2057 ** 2058 *******************************************************************************/ 2059 static BOOLEAN nfa_rw_t2t_write (tNFA_RW_MSG *p_data) 2060 { 2061 tNFA_RW_OP_PARAMS_T2T_WRITE *p_t2t_write = (tNFA_RW_OP_PARAMS_T2T_WRITE *)&(p_data->op_req.params.t2t_write); 2062 2063 if (RW_T2tWrite (p_t2t_write->block_number,p_t2t_write->p_block_data) != NFC_STATUS_OK) 2064 { 2065 nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT); 2066 } 2067 else 2068 { 2069 if (p_t2t_write->block_number == 0x03) 2070 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 2071 } 2072 2073 return TRUE; 2074 } 2075 2076 /******************************************************************************* 2077 ** 2078 ** Function nfa_rw_t2t_sector_select 2079 ** 2080 ** Description Handler for T2T_Sector_Select API 2081 ** 2082 ** Returns TRUE (message buffer to be freed by caller) 2083 ** 2084 *******************************************************************************/ 2085 static BOOLEAN nfa_rw_t2t_sector_select(tNFA_RW_MSG *p_data) 2086 { 2087 tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *p_t2t_sector_select = (tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *)&(p_data->op_req.params.t2t_sector_select); 2088 2089 if (RW_T2tSectorSelect (p_t2t_sector_select->sector_number) != NFC_STATUS_OK) 2090 nfa_rw_error_cleanup (NFA_SELECT_CPLT_EVT); 2091 2092 return TRUE; 2093 } 2094 2095 /******************************************************************************* 2096 ** 2097 ** Function nfa_rw_t3t_read 2098 ** 2099 ** Description Handler for T3T_Read API 2100 ** 2101 ** Returns TRUE (message buffer to be freed by caller) 2102 ** 2103 *******************************************************************************/ 2104 static BOOLEAN nfa_rw_t3t_read (tNFA_RW_MSG *p_data) 2105 { 2106 tNFA_RW_OP_PARAMS_T3T_READ *p_t3t_read = (tNFA_RW_OP_PARAMS_T3T_READ *)&(p_data->op_req.params.t3t_read); 2107 2108 if (RW_T3tCheck (p_t3t_read->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_read->p_block_desc) != NFC_STATUS_OK) 2109 nfa_rw_error_cleanup (NFA_READ_CPLT_EVT); 2110 2111 return TRUE; 2112 } 2113 2114 /******************************************************************************* 2115 ** 2116 ** Function nfa_rw_t3t_write 2117 ** 2118 ** Description Handler for T3T_Write API 2119 ** 2120 ** Returns TRUE (message buffer to be freed by caller) 2121 ** 2122 *******************************************************************************/ 2123 static BOOLEAN nfa_rw_t3t_write (tNFA_RW_MSG *p_data) 2124 { 2125 tNFA_RW_OP_PARAMS_T3T_WRITE *p_t3t_write = (tNFA_RW_OP_PARAMS_T3T_WRITE *)&(p_data->op_req.params.t3t_write); 2126 2127 if (RW_T3tUpdate (p_t3t_write->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_write->p_block_desc, p_t3t_write->p_block_data) != NFC_STATUS_OK) 2128 nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT); 2129 2130 return TRUE; 2131 } 2132 2133 /******************************************************************************* 2134 ** 2135 ** Function nfa_rw_t3t_get_system_codes 2136 ** 2137 ** Description Get system codes (initiated by NFA after activation) 2138 ** 2139 ** Returns TRUE (message buffer to be freed by caller) 2140 ** 2141 *******************************************************************************/ 2142 static BOOLEAN nfa_rw_t3t_get_system_codes (tNFA_RW_MSG *p_data) 2143 { 2144 tNFC_STATUS status; 2145 tNFA_TAG_PARAMS tag_params; 2146 2147 status = RW_T3tGetSystemCodes(); 2148 2149 if (status != NFC_STATUS_OK) 2150 { 2151 /* Command complete - perform cleanup, notify app */ 2152 nfa_rw_command_complete(); 2153 tag_params.t3t.num_system_codes = 0; 2154 tag_params.t3t.p_system_codes = NULL; 2155 2156 nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params); 2157 } 2158 2159 return TRUE; 2160 } 2161 2162 /******************************************************************************* 2163 ** 2164 ** Function nfa_rw_i93_command 2165 ** 2166 ** Description Handler for ISO 15693 command 2167 ** 2168 ** Returns TRUE (message buffer to be freed by caller) 2169 ** 2170 *******************************************************************************/ 2171 static BOOLEAN nfa_rw_i93_command (tNFA_RW_MSG *p_data) 2172 { 2173 tNFA_CONN_EVT_DATA conn_evt_data; 2174 tNFC_STATUS status = NFC_STATUS_OK; 2175 UINT8 i93_command = I93_CMD_STAY_QUIET; 2176 2177 switch (p_data->op_req.op) 2178 { 2179 case NFA_RW_OP_I93_INVENTORY: 2180 i93_command = I93_CMD_INVENTORY; 2181 if (p_data->op_req.params.i93_cmd.uid_present) 2182 { 2183 status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi, 2184 p_data->op_req.params.i93_cmd.uid); 2185 } 2186 else 2187 { 2188 status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi, NULL); 2189 } 2190 break; 2191 2192 case NFA_RW_OP_I93_STAY_QUIET: 2193 i93_command = I93_CMD_STAY_QUIET; 2194 status = RW_I93StayQuiet (); 2195 break; 2196 2197 case NFA_RW_OP_I93_READ_SINGLE_BLOCK: 2198 i93_command = I93_CMD_READ_SINGLE_BLOCK; 2199 status = RW_I93ReadSingleBlock (p_data->op_req.params.i93_cmd.first_block_number); 2200 break; 2201 2202 case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK: 2203 i93_command = I93_CMD_WRITE_SINGLE_BLOCK; 2204 status = RW_I93WriteSingleBlock (p_data->op_req.params.i93_cmd.first_block_number, 2205 p_data->op_req.params.i93_cmd.p_data); 2206 break; 2207 2208 case NFA_RW_OP_I93_LOCK_BLOCK: 2209 i93_command = I93_CMD_LOCK_BLOCK; 2210 status = RW_I93LockBlock (p_data->op_req.params.i93_cmd.first_block_number); 2211 break; 2212 2213 case NFA_RW_OP_I93_READ_MULTI_BLOCK: 2214 i93_command = I93_CMD_READ_MULTI_BLOCK; 2215 status = RW_I93ReadMultipleBlocks (p_data->op_req.params.i93_cmd.first_block_number, 2216 p_data->op_req.params.i93_cmd.number_blocks); 2217 break; 2218 2219 case NFA_RW_OP_I93_WRITE_MULTI_BLOCK: 2220 i93_command = I93_CMD_WRITE_MULTI_BLOCK; 2221 status = RW_I93WriteMultipleBlocks (p_data->op_req.params.i93_cmd.first_block_number, 2222 p_data->op_req.params.i93_cmd.number_blocks, 2223 p_data->op_req.params.i93_cmd.p_data); 2224 break; 2225 2226 case NFA_RW_OP_I93_SELECT: 2227 i93_command = I93_CMD_SELECT; 2228 status = RW_I93Select (p_data->op_req.params.i93_cmd.p_data); 2229 break; 2230 2231 case NFA_RW_OP_I93_RESET_TO_READY: 2232 i93_command = I93_CMD_RESET_TO_READY; 2233 status = RW_I93ResetToReady (); 2234 break; 2235 2236 case NFA_RW_OP_I93_WRITE_AFI: 2237 i93_command = I93_CMD_WRITE_AFI; 2238 status = RW_I93WriteAFI (p_data->op_req.params.i93_cmd.afi); 2239 break; 2240 2241 case NFA_RW_OP_I93_LOCK_AFI: 2242 i93_command = I93_CMD_LOCK_AFI; 2243 status = RW_I93LockAFI (); 2244 break; 2245 2246 case NFA_RW_OP_I93_WRITE_DSFID: 2247 i93_command = I93_CMD_WRITE_DSFID; 2248 status = RW_I93WriteDSFID (p_data->op_req.params.i93_cmd.dsfid); 2249 break; 2250 2251 case NFA_RW_OP_I93_LOCK_DSFID: 2252 i93_command = I93_CMD_LOCK_DSFID; 2253 status = RW_I93LockDSFID (); 2254 break; 2255 2256 case NFA_RW_OP_I93_GET_SYS_INFO: 2257 i93_command = I93_CMD_GET_SYS_INFO; 2258 if (p_data->op_req.params.i93_cmd.uid_present) 2259 { 2260 status = RW_I93GetSysInfo (p_data->op_req.params.i93_cmd.uid); 2261 } 2262 else 2263 { 2264 status = RW_I93GetSysInfo (NULL); 2265 } 2266 break; 2267 2268 case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS: 2269 i93_command = I93_CMD_GET_MULTI_BLK_SEC; 2270 status = RW_I93GetMultiBlockSecurityStatus (p_data->op_req.params.i93_cmd.first_block_number, 2271 p_data->op_req.params.i93_cmd.number_blocks); 2272 break; 2273 2274 default: 2275 break; 2276 } 2277 2278 if (status != NFC_STATUS_OK) 2279 { 2280 /* Command complete - perform cleanup, notify app */ 2281 nfa_rw_command_complete(); 2282 2283 conn_evt_data.i93_cmd_cplt.status = NFA_STATUS_FAILED; 2284 conn_evt_data.i93_cmd_cplt.sent_command = i93_command; 2285 2286 nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data); 2287 } 2288 2289 return TRUE; 2290 } 2291 2292 /******************************************************************************* 2293 ** 2294 ** Function nfa_rw_raw_mode_data_cback 2295 ** 2296 ** Description Handler for incoming tag data for unsupported tag protocols 2297 ** (forward data to upper layer) 2298 ** 2299 ** Returns nothing 2300 ** 2301 *******************************************************************************/ 2302 static void nfa_rw_raw_mode_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) 2303 { 2304 BT_HDR *p_msg = (BT_HDR *)p_data->data.p_data; 2305 tNFA_CONN_EVT_DATA evt_data; 2306 2307 NFA_TRACE_DEBUG1 ("nfa_rw_raw_mode_data_cback(): event = 0x%X", event); 2308 2309 if ((event == NFC_DATA_CEVT) && (p_data->data.status == NFC_STATUS_OK)) 2310 { 2311 if (p_msg) 2312 { 2313 evt_data.data.p_data = (UINT8 *)(p_msg + 1) + p_msg->offset; 2314 evt_data.data.len = p_msg->len; 2315 2316 nfa_dm_conn_cback_event_notify (NFA_DATA_EVT, &evt_data); 2317 2318 GKI_freebuf (p_msg); 2319 } 2320 else 2321 { 2322 NFA_TRACE_ERROR0 ("nfa_rw_raw_mode_data_cback (): received NFC_DATA_CEVT with NULL data pointer"); 2323 } 2324 } 2325 else if (event == NFC_DEACTIVATE_CEVT) 2326 { 2327 NFC_SetStaticRfCback (NULL); 2328 } 2329 } 2330 2331 2332 /******************************************************************************* 2333 ** 2334 ** Function nfa_rw_activate_ntf 2335 ** 2336 ** Description Handler for NFA_RW_ACTIVATE_NTF 2337 ** 2338 ** Returns TRUE (message buffer to be freed by caller) 2339 ** 2340 *******************************************************************************/ 2341 BOOLEAN nfa_rw_activate_ntf(tNFA_RW_MSG *p_data) 2342 { 2343 tNFC_ACTIVATE_DEVT *p_activate_params = p_data->activate_ntf.p_activate_params; 2344 tNFA_TAG_PARAMS tag_params; 2345 tNFA_RW_OPERATION msg; 2346 BOOLEAN activate_notify = TRUE; 2347 UINT8 *p; 2348 2349 NFA_TRACE_DEBUG0("nfa_rw_activate_ntf"); 2350 2351 /* Initialize control block */ 2352 nfa_rw_cb.protocol = p_activate_params->protocol; 2353 nfa_rw_cb.pa_sel_res = p_activate_params->rf_tech_param.param.pa.sel_rsp; 2354 nfa_rw_cb.flags = NFA_RW_FL_ACTIVATED; 2355 nfa_rw_cb.cur_op = NFA_RW_OP_MAX; 2356 nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN; 2357 nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED; 2358 2359 memset (&tag_params, 0, sizeof(tNFA_TAG_PARAMS)); 2360 2361 /* Check if we are in exclusive RF mode */ 2362 if (p_data->activate_ntf.excl_rf_not_active) 2363 { 2364 /* Not in exclusive RF mode */ 2365 nfa_rw_cb.flags |= NFA_RW_FL_NOT_EXCL_RF_MODE; 2366 } 2367 2368 /* If protocol not supported by RW module, notify app of NFA_ACTIVATED_EVT and start presence check if needed */ 2369 if (!nfa_dm_is_protocol_supported(p_activate_params->protocol, p_activate_params->rf_tech_param.param.pa.sel_rsp)) 2370 { 2371 /* Set data callback (pass all incoming data to upper layer using NFA_DATA_EVT) */ 2372 NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback); 2373 2374 /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */ 2375 nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL); 2376 nfa_rw_check_start_presence_check_timer (); 2377 return TRUE; 2378 } 2379 2380 /* Initialize RW module */ 2381 if ((RW_SetActivatedTagType (p_activate_params, nfa_rw_cback)) != NFC_STATUS_OK) 2382 { 2383 /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */ 2384 NFA_TRACE_ERROR0("RW_SetActivatedTagType failed."); 2385 return TRUE; 2386 } 2387 2388 /* Perform protocol-specific actions */ 2389 switch (nfa_rw_cb.protocol) 2390 { 2391 case NFC_PROTOCOL_T1T: 2392 /* Retrieve HR and UID fields from activation notification */ 2393 memcpy (tag_params.t1t.hr, p_activate_params->intf_param.intf_param.frame.param, NFA_T1T_HR_LEN); 2394 memcpy (tag_params.t1t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len); 2395 break; 2396 2397 case NFC_PROTOCOL_T2T: 2398 /* Retrieve UID fields from activation notification */ 2399 memcpy (tag_params.t2t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len); 2400 break; 2401 2402 case NFC_PROTOCOL_T3T: 2403 /* Issue command to get Felica system codes */ 2404 activate_notify = FALSE; /* Delay notifying upper layer of NFA_ACTIVATED_EVT until system codes are retrieved */ 2405 msg.op = NFA_RW_OP_T3T_GET_SYSTEM_CODES; 2406 nfa_rw_handle_op_req((tNFA_RW_MSG *)&msg); 2407 break; 2408 2409 case NFC_PROTOCOL_15693: 2410 /* Issue INVENTORY command to retrieve additional tag infomation */ 2411 nfa_rw_cb.flags |= NFA_RW_FL_ACTIVATION_NTF_PENDING; 2412 activate_notify = FALSE; /* Delay notifying upper layer of NFA_ACTIVATED_EVT until INVENTORY response is received */ 2413 2414 p = nfa_rw_cb.i93_uid; 2415 ARRAY8_TO_STREAM (p, p_data->activate_ntf.p_activate_params->rf_tech_param.param.pi93.uid); 2416 2417 msg.params.i93_cmd.uid_present = TRUE; 2418 p = msg.params.i93_cmd.uid; 2419 ARRAY8_TO_STREAM (p, p_data->activate_ntf.p_activate_params->rf_tech_param.param.pi93.uid); 2420 2421 if ((nfa_rw_cb.i93_uid[1] == I93_UID_IC_MFG_CODE_TI) 2422 &&(((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) 2423 ||((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY))) 2424 { 2425 /* these don't support Get System Information Command */ 2426 nfa_rw_cb.i93_block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE; 2427 nfa_rw_cb.i93_afi_location = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION; 2428 2429 if ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) 2430 { 2431 nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK; 2432 } 2433 else 2434 { 2435 nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK; 2436 } 2437 2438 msg.op = NFA_RW_OP_I93_INVENTORY; /* Let stack know UID of activated tag */ 2439 msg.params.i93_cmd.afi = 0x00; 2440 } 2441 else 2442 { 2443 /* All of ICODE supports Get System Information Command */ 2444 /* Tag-it HF-I Plus Chip/Inlay supports Get System Information Command */ 2445 /* just try for others */ 2446 2447 nfa_rw_cb.i93_block_size = 0; 2448 nfa_rw_cb.i93_num_block = 0; 2449 2450 msg.op = NFA_RW_OP_I93_GET_SYS_INFO; 2451 } 2452 2453 /* Send the command */ 2454 nfa_rw_handle_op_req((tNFA_RW_MSG *)&msg); 2455 break; 2456 2457 2458 default: 2459 /* No action needed for other protocols */ 2460 break; 2461 } 2462 2463 /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check timer */ 2464 if (activate_notify) 2465 { 2466 nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params); 2467 nfa_rw_check_start_presence_check_timer (); 2468 } 2469 2470 2471 return TRUE; 2472 } 2473 2474 2475 /******************************************************************************* 2476 ** 2477 ** Function nfa_rw_deactivate_ntf 2478 ** 2479 ** Description Handler for NFA_RW_DEACTIVATE_NTF 2480 ** 2481 ** Returns TRUE (message buffer to be freed by caller) 2482 ** 2483 *******************************************************************************/ 2484 BOOLEAN nfa_rw_deactivate_ntf(tNFA_RW_MSG *p_data) 2485 { 2486 /* Clear the activated flag */ 2487 nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATED; 2488 2489 /* Free buffer for incoming NDEF message, in case we were in the middle of a read operation */ 2490 nfa_rw_free_ndef_rx_buf(); 2491 2492 /* If there is a pending command message, then free it */ 2493 if (nfa_rw_cb.p_pending_msg) 2494 { 2495 GKI_freebuf(nfa_rw_cb.p_pending_msg); 2496 nfa_rw_cb.p_pending_msg = NULL; 2497 } 2498 2499 /* Stop presence check timer (if started) */ 2500 nfa_rw_stop_presence_check_timer(); 2501 2502 return TRUE; 2503 } 2504 2505 /******************************************************************************* 2506 ** 2507 ** Function nfa_rw_handle_op_req 2508 ** 2509 ** Description Handler for NFA_RW_OP_REQUEST_EVT, operation request 2510 ** 2511 ** Returns TRUE if caller should free p_data 2512 ** FALSE if caller does not need to free p_data 2513 ** 2514 *******************************************************************************/ 2515 BOOLEAN nfa_rw_handle_op_req (tNFA_RW_MSG *p_data) 2516 { 2517 BOOLEAN freebuf = TRUE; 2518 2519 /* Check if activated */ 2520 if (!(nfa_rw_cb.flags & NFA_RW_FL_ACTIVATED)) 2521 { 2522 NFA_TRACE_ERROR0("nfa_rw_handle_op_req: not activated"); 2523 return TRUE; 2524 } 2525 /* Check if currently busy with another API call */ 2526 else if (nfa_rw_cb.flags & NFA_RW_FL_API_BUSY) 2527 { 2528 return (nfa_rw_op_req_while_busy(p_data)); 2529 } 2530 /* Check if currently busy with auto-presence check */ 2531 else if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) 2532 { 2533 /* Cache the command (will be handled once auto-presence check is completed) */ 2534 NFA_TRACE_DEBUG1("Deferring operation %i until after auto-presence check is completed", p_data->op_req.op); 2535 nfa_rw_cb.p_pending_msg = p_data; 2536 nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY; 2537 return (freebuf); 2538 } 2539 2540 NFA_TRACE_DEBUG1("nfa_rw_handle_op_req: op=0x%02x", p_data->op_req.op); 2541 2542 nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY; 2543 2544 /* Stop the presence check timer */ 2545 nfa_rw_stop_presence_check_timer(); 2546 2547 /* Store the current operation */ 2548 nfa_rw_cb.cur_op = p_data->op_req.op; 2549 2550 /* Call appropriate handler for requested operation */ 2551 switch (p_data->op_req.op) 2552 { 2553 case NFA_RW_OP_DETECT_NDEF: 2554 nfa_rw_detect_ndef(p_data); 2555 break; 2556 2557 case NFA_RW_OP_READ_NDEF: 2558 nfa_rw_read_ndef(p_data); 2559 break; 2560 2561 case NFA_RW_OP_WRITE_NDEF: 2562 nfa_rw_write_ndef(p_data); 2563 break; 2564 2565 case NFA_RW_OP_SEND_RAW_FRAME: 2566 NFC_SendData (NFC_RF_CONN_ID, p_data->op_req.params.send_raw_frame.p_data); 2567 2568 /* Command complete - perform cleanup */ 2569 nfa_rw_command_complete(); 2570 break; 2571 2572 case NFA_RW_OP_PRESENCE_CHECK: 2573 nfa_rw_presence_check(p_data); 2574 break; 2575 2576 case NFA_RW_OP_FORMAT_TAG: 2577 nfa_rw_format_tag(p_data); 2578 break; 2579 2580 case NFA_RW_OP_DETECT_LOCK_TLV: 2581 nfa_rw_detect_tlv(p_data, TAG_LOCK_CTRL_TLV); 2582 break; 2583 2584 case NFA_RW_OP_DETECT_MEM_TLV: 2585 nfa_rw_detect_tlv(p_data, TAG_MEM_CTRL_TLV); 2586 break; 2587 2588 case NFA_RW_OP_SET_TAG_RO: 2589 nfa_rw_cb.b_hard_lock = p_data->op_req.params.set_readonly.b_hard_lock; 2590 nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock); 2591 break; 2592 2593 case NFA_RW_OP_T1T_RID: 2594 nfa_rw_t1t_rid(p_data); 2595 break; 2596 2597 case NFA_RW_OP_T1T_RALL: 2598 nfa_rw_t1t_rall(p_data); 2599 break; 2600 2601 case NFA_RW_OP_T1T_READ: 2602 nfa_rw_t1t_read(p_data); 2603 break; 2604 2605 case NFA_RW_OP_T1T_WRITE: 2606 nfa_rw_t1t_write(p_data); 2607 break; 2608 2609 case NFA_RW_OP_T1T_RSEG: 2610 nfa_rw_t1t_rseg(p_data); 2611 break; 2612 2613 case NFA_RW_OP_T1T_READ8: 2614 nfa_rw_t1t_read8(p_data); 2615 break; 2616 2617 case NFA_RW_OP_T1T_WRITE8: 2618 nfa_rw_t1t_write8(p_data); 2619 break; 2620 2621 /* Type-2 tag commands */ 2622 case NFA_RW_OP_T2T_READ: 2623 nfa_rw_t2t_read(p_data); 2624 break; 2625 2626 case NFA_RW_OP_T2T_WRITE: 2627 nfa_rw_t2t_write(p_data); 2628 break; 2629 2630 case NFA_RW_OP_T2T_SECTOR_SELECT: 2631 nfa_rw_t2t_sector_select(p_data); 2632 break; 2633 2634 /* Type-3 tag commands */ 2635 case NFA_RW_OP_T3T_READ: 2636 nfa_rw_t3t_read(p_data); 2637 break; 2638 2639 case NFA_RW_OP_T3T_WRITE: 2640 nfa_rw_t3t_write(p_data); 2641 break; 2642 2643 case NFA_RW_OP_T3T_GET_SYSTEM_CODES: 2644 nfa_rw_t3t_get_system_codes(p_data); 2645 break; 2646 2647 /* ISO 15693 tag commands */ 2648 case NFA_RW_OP_I93_INVENTORY: 2649 case NFA_RW_OP_I93_STAY_QUIET: 2650 case NFA_RW_OP_I93_READ_SINGLE_BLOCK: 2651 case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK: 2652 case NFA_RW_OP_I93_LOCK_BLOCK: 2653 case NFA_RW_OP_I93_READ_MULTI_BLOCK: 2654 case NFA_RW_OP_I93_WRITE_MULTI_BLOCK: 2655 case NFA_RW_OP_I93_SELECT: 2656 case NFA_RW_OP_I93_RESET_TO_READY: 2657 case NFA_RW_OP_I93_WRITE_AFI: 2658 case NFA_RW_OP_I93_LOCK_AFI: 2659 case NFA_RW_OP_I93_WRITE_DSFID: 2660 case NFA_RW_OP_I93_LOCK_DSFID: 2661 case NFA_RW_OP_I93_GET_SYS_INFO: 2662 case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS: 2663 nfa_rw_i93_command (p_data); 2664 break; 2665 2666 default: 2667 NFA_TRACE_ERROR1("nfa_rw_handle_api: unhandled operation: %i", p_data->op_req.op); 2668 break; 2669 } 2670 2671 return (freebuf); 2672 } 2673 2674 2675 /******************************************************************************* 2676 ** 2677 ** Function nfa_rw_op_req_while_busy 2678 ** 2679 ** Description Handle operation request while busy 2680 ** 2681 ** Returns TRUE if caller should free p_data 2682 ** FALSE if caller does not need to free p_data 2683 ** 2684 *******************************************************************************/ 2685 static BOOLEAN nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data) 2686 { 2687 BOOLEAN freebuf = TRUE; 2688 tNFA_CONN_EVT_DATA conn_evt_data; 2689 UINT8 event; 2690 2691 NFA_TRACE_ERROR0("nfa_rw_op_req_while_busy: unable to handle API"); 2692 2693 /* Return appropriate event for requested API, with status=BUSY */ 2694 conn_evt_data.status = NFA_STATUS_BUSY; 2695 2696 switch (p_data->op_req.op) 2697 { 2698 case NFA_RW_OP_DETECT_NDEF: 2699 conn_evt_data.ndef_detect.cur_size = 0; 2700 conn_evt_data.ndef_detect.max_size = 0; 2701 conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; 2702 event = NFA_NDEF_DETECT_EVT; 2703 break; 2704 case NFA_RW_OP_READ_NDEF: 2705 case NFA_RW_OP_T1T_RID: 2706 case NFA_RW_OP_T1T_RALL: 2707 case NFA_RW_OP_T1T_READ: 2708 case NFA_RW_OP_T1T_RSEG: 2709 case NFA_RW_OP_T1T_READ8: 2710 case NFA_RW_OP_T2T_READ: 2711 case NFA_RW_OP_T3T_READ: 2712 event = NFA_READ_CPLT_EVT; 2713 break; 2714 case NFA_RW_OP_WRITE_NDEF: 2715 case NFA_RW_OP_T1T_WRITE: 2716 case NFA_RW_OP_T1T_WRITE8: 2717 case NFA_RW_OP_T2T_WRITE: 2718 case NFA_RW_OP_T3T_WRITE: 2719 event = NFA_WRITE_CPLT_EVT; 2720 break; 2721 case NFA_RW_OP_FORMAT_TAG: 2722 event = NFA_FORMAT_CPLT_EVT; 2723 break; 2724 case NFA_RW_OP_DETECT_LOCK_TLV: 2725 case NFA_RW_OP_DETECT_MEM_TLV: 2726 event = NFA_TLV_DETECT_EVT; 2727 break; 2728 case NFA_RW_OP_SET_TAG_RO: 2729 event = NFA_SET_TAG_RO_EVT; 2730 break; 2731 case NFA_RW_OP_T2T_SECTOR_SELECT: 2732 event = NFA_SELECT_CPLT_EVT; 2733 break; 2734 case NFA_RW_OP_I93_INVENTORY: 2735 case NFA_RW_OP_I93_STAY_QUIET: 2736 case NFA_RW_OP_I93_READ_SINGLE_BLOCK: 2737 case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK: 2738 case NFA_RW_OP_I93_LOCK_BLOCK: 2739 case NFA_RW_OP_I93_READ_MULTI_BLOCK: 2740 case NFA_RW_OP_I93_WRITE_MULTI_BLOCK: 2741 case NFA_RW_OP_I93_SELECT: 2742 case NFA_RW_OP_I93_RESET_TO_READY: 2743 case NFA_RW_OP_I93_WRITE_AFI: 2744 case NFA_RW_OP_I93_LOCK_AFI: 2745 case NFA_RW_OP_I93_WRITE_DSFID: 2746 case NFA_RW_OP_I93_LOCK_DSFID: 2747 case NFA_RW_OP_I93_GET_SYS_INFO: 2748 case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS: 2749 event = NFA_I93_CMD_CPLT_EVT; 2750 break; 2751 default: 2752 return (freebuf); 2753 } 2754 nfa_dm_act_conn_cback_notify(event, &conn_evt_data); 2755 2756 return (freebuf); 2757 } 2758 2759 /******************************************************************************* 2760 ** 2761 ** Function nfa_rw_command_complete 2762 ** 2763 ** Description Handle command complete: clear the busy flag, 2764 ** and start the presence check timer if applicable. 2765 ** 2766 ** Returns None 2767 ** 2768 *******************************************************************************/ 2769 void nfa_rw_command_complete(void) 2770 { 2771 /* Clear the busy flag */ 2772 nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY; 2773 2774 /* Restart presence_check timer */ 2775 nfa_rw_check_start_presence_check_timer (); 2776 } 2777