1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-2014 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This file contains functions that interface with the NFC NCI transport. 22 * On the receive side, it routes events to the appropriate handler 23 * (callback). On the transmit side, it manages the command transmission. 24 * 25 ******************************************************************************/ 26 #include <stdlib.h> 27 #include <string.h> 28 #include "nfc_target.h" 29 30 #include "nci_defs.h" 31 #include "nci_hmsgs.h" 32 #include "nfc_api.h" 33 #include "nfc_hal_api.h" 34 #include "nfc_int.h" 35 #include "rw_api.h" 36 #include "rw_int.h" 37 38 #if (NFC_RW_ONLY == FALSE) 39 static const uint8_t nfc_mpl_code_to_size[] = {64, 128, 192, 254}; 40 41 #endif /* NFC_RW_ONLY */ 42 43 #define NFC_PB_ATTRIB_REQ_FIXED_BYTES 1 44 #define NFC_LB_ATTRIB_REQ_FIXED_BYTES 8 45 46 /******************************************************************************* 47 ** 48 ** Function nfc_ncif_update_window 49 ** 50 ** Description Update tx cmd window to indicate that NFCC can received 51 ** 52 ** Returns void 53 ** 54 *******************************************************************************/ 55 void nfc_ncif_update_window(void) { 56 /* Sanity check - see if we were expecting a update_window */ 57 if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW) { 58 if (nfc_cb.nfc_state != NFC_STATE_W4_HAL_CLOSE) { 59 NFC_TRACE_ERROR0("nfc_ncif_update_window: Unexpected call"); 60 } 61 return; 62 } 63 64 /* Stop command-pending timer */ 65 nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer); 66 67 nfc_cb.p_vsc_cback = NULL; 68 nfc_cb.nci_cmd_window++; 69 70 /* Check if there were any commands waiting to be sent */ 71 nfc_ncif_check_cmd_queue(NULL); 72 } 73 74 /******************************************************************************* 75 ** 76 ** Function nfc_ncif_cmd_timeout 77 ** 78 ** Description Handle a command timeout 79 ** 80 ** Returns void 81 ** 82 *******************************************************************************/ 83 void nfc_ncif_cmd_timeout(void) { 84 NFC_TRACE_ERROR0("nfc_ncif_cmd_timeout"); 85 86 /* report an error */ 87 nfc_ncif_event_status(NFC_GEN_ERROR_REVT, NFC_STATUS_HW_TIMEOUT); 88 nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT); 89 90 /* if enabling NFC, notify upper layer of failure */ 91 if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT) { 92 nfc_enabled(NFC_STATUS_FAILED, NULL); 93 } 94 95 /* XXX maco since this failure is unrecoverable, abort the process */ 96 abort(); 97 } 98 99 /******************************************************************************* 100 ** 101 ** Function nfc_wait_2_deactivate_timeout 102 ** 103 ** Description Handle a command timeout 104 ** 105 ** Returns void 106 ** 107 *******************************************************************************/ 108 void nfc_wait_2_deactivate_timeout(void) { 109 NFC_TRACE_ERROR0("nfc_wait_2_deactivate_timeout"); 110 nfc_cb.flags &= ~NFC_FL_DEACTIVATING; 111 nci_snd_deactivate_cmd((uint8_t)nfc_cb.deactivate_timer.param); 112 } 113 114 /******************************************************************************* 115 ** 116 ** Function nfc_ncif_send_data 117 ** 118 ** Description This function is called to add the NCI data header 119 ** and send it to NCIT task for sending it to transport 120 ** as credits are available. 121 ** 122 ** Returns void 123 ** 124 *******************************************************************************/ 125 uint8_t nfc_ncif_send_data(tNFC_CONN_CB* p_cb, NFC_HDR* p_data) { 126 uint8_t* pp; 127 uint8_t* ps; 128 uint8_t ulen = NCI_MAX_PAYLOAD_SIZE; 129 NFC_HDR* p; 130 uint8_t pbf = 1; 131 uint8_t buffer_size = p_cb->buff_size; 132 uint8_t hdr0 = p_cb->conn_id; 133 bool fragmented = false; 134 135 NFC_TRACE_DEBUG3("nfc_ncif_send_data :%d, num_buff:%d qc:%d", p_cb->conn_id, 136 p_cb->num_buff, p_cb->tx_q.count); 137 if (p_cb->id == NFC_RF_CONN_ID) { 138 if (nfc_cb.nfc_state != NFC_STATE_OPEN) { 139 if (nfc_cb.nfc_state == NFC_STATE_CLOSING) { 140 if ((p_data == NULL) && /* called because credit from NFCC */ 141 (nfc_cb.flags & NFC_FL_DEACTIVATING)) { 142 if (p_cb->init_credits == p_cb->num_buff) { 143 /* all the credits are back */ 144 nfc_cb.flags &= ~NFC_FL_DEACTIVATING; 145 NFC_TRACE_DEBUG2( 146 "deactivating NFC-DEP init_credits:%d, num_buff:%d", 147 p_cb->init_credits, p_cb->num_buff); 148 nfc_stop_timer(&nfc_cb.deactivate_timer); 149 nci_snd_deactivate_cmd((uint8_t)nfc_cb.deactivate_timer.param); 150 } 151 } 152 } 153 return NCI_STATUS_FAILED; 154 } 155 } 156 157 if (p_data) { 158 /* always enqueue the data to the tx queue */ 159 GKI_enqueue(&p_cb->tx_q, p_data); 160 } 161 162 /* try to send the first data packet in the tx queue */ 163 p_data = (NFC_HDR*)GKI_getfirst(&p_cb->tx_q); 164 165 /* post data fragment to NCIT task as credits are available */ 166 while (p_data && (p_data->len >= 0) && (p_cb->num_buff > 0)) { 167 if (p_data->len <= buffer_size) { 168 pbf = 0; /* last fragment */ 169 ulen = (uint8_t)(p_data->len); 170 fragmented = false; 171 } else { 172 fragmented = true; 173 ulen = buffer_size; 174 } 175 176 if (!fragmented) { 177 /* if data packet is not fragmented, use the original buffer */ 178 p = p_data; 179 p_data = (NFC_HDR*)GKI_dequeue(&p_cb->tx_q); 180 } else { 181 /* the data packet is too big and need to be fragmented 182 * prepare a new GKI buffer 183 * (even the last fragment to avoid issues) */ 184 p = NCI_GET_CMD_BUF(ulen); 185 if (p == NULL) return (NCI_STATUS_BUFFER_FULL); 186 p->len = ulen; 187 p->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1; 188 if (p->len) { 189 pp = (uint8_t*)(p + 1) + p->offset; 190 ps = (uint8_t*)(p_data + 1) + p_data->offset; 191 memcpy(pp, ps, ulen); 192 } 193 /* adjust the NFC_HDR on the old fragment */ 194 p_data->len -= ulen; 195 p_data->offset += ulen; 196 } 197 198 p->event = BT_EVT_TO_NFC_NCI; 199 p->layer_specific = pbf; 200 p->len += NCI_DATA_HDR_SIZE; 201 p->offset -= NCI_DATA_HDR_SIZE; 202 pp = (uint8_t*)(p + 1) + p->offset; 203 /* build NCI Data packet header */ 204 NCI_DATA_PBLD_HDR(pp, pbf, hdr0, ulen); 205 206 if (p_cb->num_buff != NFC_CONN_NO_FC) p_cb->num_buff--; 207 208 /* send to HAL */ 209 HAL_WRITE(p); 210 211 if (!fragmented) { 212 /* check if there are more data to send */ 213 p_data = (NFC_HDR*)GKI_getfirst(&p_cb->tx_q); 214 } 215 } 216 217 return (NCI_STATUS_OK); 218 } 219 220 /******************************************************************************* 221 ** 222 ** Function nfc_ncif_check_cmd_queue 223 ** 224 ** Description Send NCI command to the transport 225 ** 226 ** Returns void 227 ** 228 *******************************************************************************/ 229 void nfc_ncif_check_cmd_queue(NFC_HDR* p_buf) { 230 uint8_t* ps; 231 /* If there are commands waiting in the xmit queue, or if the controller 232 * cannot accept any more commands, */ 233 /* then enqueue this command */ 234 if (p_buf) { 235 if ((nfc_cb.nci_cmd_xmit_q.count) || (nfc_cb.nci_cmd_window == 0)) { 236 GKI_enqueue(&nfc_cb.nci_cmd_xmit_q, p_buf); 237 p_buf = NULL; 238 } 239 } 240 241 /* If controller can accept another command, then send the next command */ 242 if (nfc_cb.nci_cmd_window > 0) { 243 /* If no command was provided, or if older commands were in the queue, then 244 * get cmd from the queue */ 245 if (!p_buf) p_buf = (NFC_HDR*)GKI_dequeue(&nfc_cb.nci_cmd_xmit_q); 246 247 if (p_buf) { 248 /* save the message header to double check the response */ 249 ps = (uint8_t*)(p_buf + 1) + p_buf->offset; 250 memcpy(nfc_cb.last_hdr, ps, NFC_SAVED_HDR_SIZE); 251 memcpy(nfc_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_SAVED_CMD_SIZE); 252 if (p_buf->layer_specific == NFC_WAIT_RSP_VSC) { 253 /* save the callback for NCI VSCs) */ 254 nfc_cb.p_vsc_cback = (void*)((tNFC_NCI_VS_MSG*)p_buf)->p_cback; 255 } 256 257 /* send to HAL */ 258 HAL_WRITE(p_buf); 259 260 /* Indicate command is pending */ 261 nfc_cb.nci_cmd_window--; 262 263 /* start NFC command-timeout timer */ 264 nfc_start_timer(&nfc_cb.nci_wait_rsp_timer, 265 (uint16_t)(NFC_TTYPE_NCI_WAIT_RSP), 266 nfc_cb.nci_wait_rsp_tout); 267 } 268 } 269 270 if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW) { 271 /* the command queue must be empty now */ 272 if (nfc_cb.flags & NFC_FL_CONTROL_REQUESTED) { 273 /* HAL requested control or stack needs to handle pre-discover */ 274 nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED; 275 if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING) { 276 if (nfc_cb.p_hal->prediscover()) { 277 /* HAL has the command window now */ 278 nfc_cb.flags |= NFC_FL_CONTROL_GRANTED; 279 nfc_cb.nci_cmd_window = 0; 280 } else { 281 /* HAL does not need to send command, 282 * - restore the command window and issue the discovery command now */ 283 nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING; 284 ps = (uint8_t*)nfc_cb.p_disc_pending; 285 nci_snd_discover_cmd(*ps, (tNFC_DISCOVER_PARAMS*)(ps + 1)); 286 GKI_freebuf(nfc_cb.p_disc_pending); 287 nfc_cb.p_disc_pending = NULL; 288 } 289 } else if (nfc_cb.flags & NFC_FL_HAL_REQUESTED) { 290 /* grant the control to HAL */ 291 nfc_cb.flags &= ~NFC_FL_HAL_REQUESTED; 292 nfc_cb.flags |= NFC_FL_CONTROL_GRANTED; 293 nfc_cb.nci_cmd_window = 0; 294 nfc_cb.p_hal->control_granted(); 295 } 296 } 297 } 298 } 299 300 /******************************************************************************* 301 ** 302 ** Function nfc_ncif_send_cmd 303 ** 304 ** Description Send NCI command to the NCIT task 305 ** 306 ** Returns void 307 ** 308 *******************************************************************************/ 309 void nfc_ncif_send_cmd(NFC_HDR* p_buf) { 310 /* post the p_buf to NCIT task */ 311 p_buf->event = BT_EVT_TO_NFC_NCI; 312 p_buf->layer_specific = 0; 313 nfc_ncif_check_cmd_queue(p_buf); 314 } 315 316 /******************************************************************************* 317 ** 318 ** Function nfc_ncif_process_event 319 ** 320 ** Description This function is called to process the 321 ** data/response/notification from NFCC 322 ** 323 ** Returns TRUE if need to free buffer 324 ** 325 *******************************************************************************/ 326 bool nfc_ncif_process_event(NFC_HDR* p_msg) { 327 uint8_t mt, pbf, gid, *p, *pp; 328 bool free = true; 329 uint8_t oid; 330 uint8_t *p_old, old_gid, old_oid, old_mt; 331 332 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 333 334 pp = p; 335 NCI_MSG_PRS_HDR0(pp, mt, pbf, gid); 336 337 switch (mt) { 338 case NCI_MT_DATA: 339 NFC_TRACE_DEBUG0("NFC received data"); 340 nfc_ncif_proc_data(p_msg); 341 free = false; 342 break; 343 344 case NCI_MT_RSP: 345 NFC_TRACE_DEBUG1("NFC received rsp gid:%d", gid); 346 oid = ((*pp) & NCI_OID_MASK); 347 p_old = nfc_cb.last_hdr; 348 NCI_MSG_PRS_HDR0(p_old, old_mt, pbf, old_gid); 349 old_oid = ((*p_old) & NCI_OID_MASK); 350 /* make sure this is the RSP we are waiting for before updating the 351 * command window */ 352 if ((old_gid != gid) || (old_oid != oid)) { 353 NFC_TRACE_ERROR2( 354 "nfc_ncif_process_event unexpected rsp: gid:0x%x, oid:0x%x", gid, 355 oid); 356 return true; 357 } 358 359 switch (gid) { 360 case NCI_GID_CORE: /* 0000b NCI Core group */ 361 free = nci_proc_core_rsp(p_msg); 362 break; 363 case NCI_GID_RF_MANAGE: /* 0001b NCI Discovery group */ 364 nci_proc_rf_management_rsp(p_msg); 365 break; 366 #if (NFC_NFCEE_INCLUDED == TRUE) 367 #if (NFC_RW_ONLY == FALSE) 368 case NCI_GID_EE_MANAGE: /* 0x02 0010b NFCEE Discovery group */ 369 nci_proc_ee_management_rsp(p_msg); 370 break; 371 #endif 372 #endif 373 case NCI_GID_PROP: /* 1111b Proprietary */ 374 nci_proc_prop_rsp(p_msg); 375 break; 376 default: 377 NFC_TRACE_ERROR1("NFC: Unknown gid:%d", gid); 378 break; 379 } 380 381 nfc_ncif_update_window(); 382 break; 383 384 case NCI_MT_NTF: 385 NFC_TRACE_DEBUG1("NFC received ntf gid:%d", gid); 386 switch (gid) { 387 case NCI_GID_CORE: /* 0000b NCI Core group */ 388 nci_proc_core_ntf(p_msg); 389 break; 390 case NCI_GID_RF_MANAGE: /* 0001b NCI Discovery group */ 391 nci_proc_rf_management_ntf(p_msg); 392 break; 393 #if (NFC_NFCEE_INCLUDED == TRUE) 394 #if (NFC_RW_ONLY == FALSE) 395 case NCI_GID_EE_MANAGE: /* 0x02 0010b NFCEE Discovery group */ 396 nci_proc_ee_management_ntf(p_msg); 397 break; 398 #endif 399 #endif 400 case NCI_GID_PROP: /* 1111b Proprietary */ 401 nci_proc_prop_ntf(p_msg); 402 break; 403 default: 404 NFC_TRACE_ERROR1("NFC: Unknown gid:%d", gid); 405 break; 406 } 407 break; 408 409 default: 410 NFC_TRACE_DEBUG2("NFC received unknown mt:0x%x, gid:%d", mt, gid); 411 } 412 413 return (free); 414 } 415 416 /******************************************************************************* 417 ** 418 ** Function nfc_ncif_rf_management_status 419 ** 420 ** Description This function is called to report an event 421 ** 422 ** Returns void 423 ** 424 *******************************************************************************/ 425 void nfc_ncif_rf_management_status(tNFC_DISCOVER_EVT event, uint8_t status) { 426 tNFC_DISCOVER evt_data; 427 if (nfc_cb.p_discv_cback) { 428 evt_data.status = (tNFC_STATUS)status; 429 (*nfc_cb.p_discv_cback)(event, &evt_data); 430 } 431 } 432 433 /******************************************************************************* 434 ** 435 ** Function nfc_ncif_set_config_status 436 ** 437 ** Description This function is called to report NFC_SET_CONFIG_REVT 438 ** 439 ** Returns void 440 ** 441 *******************************************************************************/ 442 void nfc_ncif_set_config_status(uint8_t* p, uint8_t len) { 443 tNFC_RESPONSE evt_data; 444 if (nfc_cb.p_resp_cback) { 445 evt_data.set_config.status = (tNFC_STATUS)*p++; 446 evt_data.set_config.num_param_id = NFC_STATUS_OK; 447 if (evt_data.set_config.status != NFC_STATUS_OK) { 448 evt_data.set_config.num_param_id = *p++; 449 STREAM_TO_ARRAY(evt_data.set_config.param_ids, p, 450 evt_data.set_config.num_param_id); 451 } 452 453 (*nfc_cb.p_resp_cback)(NFC_SET_CONFIG_REVT, &evt_data); 454 } 455 } 456 457 /******************************************************************************* 458 ** 459 ** Function nfc_ncif_event_status 460 ** 461 ** Description This function is called to report an event 462 ** 463 ** Returns void 464 ** 465 *******************************************************************************/ 466 void nfc_ncif_event_status(tNFC_RESPONSE_EVT event, uint8_t status) { 467 tNFC_RESPONSE evt_data; 468 if (nfc_cb.p_resp_cback) { 469 evt_data.status = (tNFC_STATUS)status; 470 (*nfc_cb.p_resp_cback)(event, &evt_data); 471 } 472 } 473 474 /******************************************************************************* 475 ** 476 ** Function nfc_ncif_error_status 477 ** 478 ** Description This function is called to report an error event to data 479 ** cback 480 ** 481 ** Returns void 482 ** 483 *******************************************************************************/ 484 void nfc_ncif_error_status(uint8_t conn_id, uint8_t status) { 485 tNFC_CONN_CB* p_cb; 486 p_cb = nfc_find_conn_cb_by_conn_id(conn_id); 487 if (p_cb && p_cb->p_cback) { 488 (*p_cb->p_cback)(conn_id, NFC_ERROR_CEVT, (tNFC_CONN*)&status); 489 } 490 } 491 492 /******************************************************************************* 493 ** 494 ** Function nfc_ncif_proc_rf_field_ntf 495 ** 496 ** Description This function is called to process RF field notification 497 ** 498 ** Returns void 499 ** 500 *******************************************************************************/ 501 #if (NFC_RW_ONLY == FALSE) 502 void nfc_ncif_proc_rf_field_ntf(uint8_t rf_status) { 503 tNFC_RESPONSE evt_data; 504 if (nfc_cb.p_resp_cback) { 505 evt_data.status = (tNFC_STATUS)NFC_STATUS_OK; 506 evt_data.rf_field.rf_field = rf_status; 507 (*nfc_cb.p_resp_cback)(NFC_RF_FIELD_REVT, &evt_data); 508 } 509 } 510 #endif 511 512 /******************************************************************************* 513 ** 514 ** Function nfc_ncif_proc_credits 515 ** 516 ** Description This function is called to process data credits 517 ** 518 ** Returns void 519 ** 520 *******************************************************************************/ 521 void nfc_ncif_proc_credits(uint8_t* p, uint16_t plen) { 522 uint8_t num, xx; 523 tNFC_CONN_CB* p_cb; 524 525 num = *p++; 526 for (xx = 0; xx < num; xx++) { 527 p_cb = nfc_find_conn_cb_by_conn_id(*p++); 528 if (p_cb && p_cb->num_buff != NFC_CONN_NO_FC) { 529 p_cb->num_buff += (*p); 530 #if (BT_USE_TRACES == TRUE) 531 if (p_cb->num_buff > p_cb->init_credits) { 532 if (nfc_cb.nfc_state == NFC_STATE_OPEN) { 533 /* if this happens in activated state, it's very likely that our NFCC 534 * has issues */ 535 /* However, credit may be returned after deactivation */ 536 NFC_TRACE_ERROR2("num_buff:0x%x, init_credits:0x%x", p_cb->num_buff, 537 p_cb->init_credits); 538 } 539 p_cb->num_buff = p_cb->init_credits; 540 } 541 #endif 542 /* check if there's nay data in tx q to be sent */ 543 nfc_ncif_send_data(p_cb, NULL); 544 } 545 p++; 546 } 547 } 548 /******************************************************************************* 549 ** 550 ** Function nfc_ncif_decode_rf_params 551 ** 552 ** Description This function is called to process the detected technology 553 ** and mode and the associated parameters for DISCOVER_NTF and 554 ** ACTIVATE_NTF 555 ** 556 ** Returns void 557 ** 558 *******************************************************************************/ 559 uint8_t* nfc_ncif_decode_rf_params(tNFC_RF_TECH_PARAMS* p_param, uint8_t* p) { 560 tNFC_RF_PA_PARAMS* p_pa; 561 uint8_t len, *p_start, u8; 562 tNFC_RF_PB_PARAMS* p_pb; 563 tNFC_RF_LF_PARAMS* p_lf; 564 tNFC_RF_PF_PARAMS* p_pf; 565 tNFC_RF_PISO15693_PARAMS* p_i93; 566 567 len = *p++; 568 p_start = p; 569 memset(&p_param->param, 0, sizeof(tNFC_RF_TECH_PARAMU)); 570 571 if (NCI_DISCOVERY_TYPE_POLL_A == p_param->mode || 572 NCI_DISCOVERY_TYPE_POLL_A_ACTIVE == p_param->mode) { 573 p_pa = &p_param->param.pa; 574 /* 575 SENS_RES Response 2 bytes Defined in [DIGPROT] Available after Technology 576 Detection 577 NFCID1 length 1 byte Length of NFCID1 Available after Collision Resolution 578 NFCID1 4, 7, or 10 bytes Defined in [DIGPROT]Available after Collision 579 Resolution 580 SEL_RES Response 1 byte Defined in [DIGPROT]Available after Collision 581 Resolution 582 HRx Length 1 Octets Length of HRx Parameters collected from the response to 583 the T1T RID command. 584 HRx 0 or 2 Octets If present, the first byte SHALL contain HR0 and the second 585 byte SHALL contain HR1 as defined in [DIGITAL]. 586 */ 587 STREAM_TO_ARRAY(p_pa->sens_res, p, 2); 588 p_pa->nfcid1_len = *p++; 589 if (p_pa->nfcid1_len > NCI_NFCID1_MAX_LEN) 590 p_pa->nfcid1_len = NCI_NFCID1_MAX_LEN; 591 STREAM_TO_ARRAY(p_pa->nfcid1, p, p_pa->nfcid1_len); 592 u8 = *p++; 593 if (u8) p_pa->sel_rsp = *p++; 594 if (len == 595 (7 + p_pa->nfcid1_len + u8)) /* 2(sens_res) + 1(len) + 596 p_pa->nfcid1_len + 1(len) + u8 + hr 597 (1:len + 2) */ 598 { 599 p_pa->hr_len = *p++; 600 if (p_pa->hr_len == NCI_T1T_HR_LEN) { 601 p_pa->hr[0] = *p++; 602 p_pa->hr[1] = *p; 603 } 604 } 605 } else if (NCI_DISCOVERY_TYPE_POLL_B == p_param->mode) { 606 /* 607 SENSB_RES Response length (n) 1 byte Length of SENSB_RES Response (Byte 2 - 608 Byte 12 or 13)Available after Technology Detection 609 SENSB_RES Response Byte 2 - Byte 12 or 13 11 or 12 bytes Defined in [DIGPROT] 610 Available after Technology Detection 611 */ 612 p_pb = &p_param->param.pb; 613 p_pb->sensb_res_len = *p++; 614 if (p_pb->sensb_res_len > NCI_MAX_SENSB_RES_LEN) 615 p_pb->sensb_res_len = NCI_MAX_SENSB_RES_LEN; 616 STREAM_TO_ARRAY(p_pb->sensb_res, p, p_pb->sensb_res_len); 617 memcpy(p_pb->nfcid0, p_pb->sensb_res, NFC_NFCID0_MAX_LEN); 618 } else if (NCI_DISCOVERY_TYPE_POLL_F == p_param->mode || 619 NCI_DISCOVERY_TYPE_POLL_F_ACTIVE == p_param->mode) { 620 /* 621 Bit Rate 1 byte 1 212 kbps/2 424 kbps/0 and 3 to 255 RFU 622 SENSF_RES Response length.(n) 1 byte Length of SENSF_RES (Byte 2 - Byte 17 or 623 19).Available after Technology Detection 624 SENSF_RES Response Byte 2 - Byte 17 or 19 n bytes Defined in [DIGPROT] 625 Available after Technology Detection 626 */ 627 p_pf = &p_param->param.pf; 628 p_pf->bit_rate = *p++; 629 p_pf->sensf_res_len = *p++; 630 if (p_pf->sensf_res_len > NCI_MAX_SENSF_RES_LEN) 631 p_pf->sensf_res_len = NCI_MAX_SENSF_RES_LEN; 632 STREAM_TO_ARRAY(p_pf->sensf_res, p, p_pf->sensf_res_len); 633 memcpy(p_pf->nfcid2, p_pf->sensf_res, NCI_NFCID2_LEN); 634 p_pf->mrti_check = p_pf->sensf_res[NCI_MRTI_CHECK_INDEX]; 635 p_pf->mrti_update = p_pf->sensf_res[NCI_MRTI_UPDATE_INDEX]; 636 } else if (NCI_DISCOVERY_TYPE_LISTEN_F == p_param->mode || 637 NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE == p_param->mode) { 638 p_lf = &p_param->param.lf; 639 u8 = *p++; 640 if (u8) { 641 STREAM_TO_ARRAY(p_lf->nfcid2, p, NCI_NFCID2_LEN); 642 } 643 } else if (NCI_DISCOVERY_TYPE_POLL_ISO15693 == p_param->mode) { 644 p_i93 = &p_param->param.pi93; 645 p_i93->flag = *p++; 646 p_i93->dsfid = *p++; 647 STREAM_TO_ARRAY(p_i93->uid, p, NFC_ISO15693_UID_LEN); 648 } else if (NCI_DISCOVERY_TYPE_POLL_KOVIO == p_param->mode) { 649 p_param->param.pk.uid_len = *p++; 650 if (p_param->param.pk.uid_len > NFC_KOVIO_MAX_LEN) { 651 NFC_TRACE_ERROR2("Kovio UID len:0x%x exceeds max(0x%x)", 652 p_param->param.pk.uid_len, NFC_KOVIO_MAX_LEN); 653 p_param->param.pk.uid_len = NFC_KOVIO_MAX_LEN; 654 } 655 STREAM_TO_ARRAY(p_param->param.pk.uid, p, p_param->param.pk.uid_len); 656 } 657 658 return (p_start + len); 659 } 660 661 /******************************************************************************* 662 ** 663 ** Function nfc_ncif_proc_discover_ntf 664 ** 665 ** Description This function is called to process discover notification 666 ** 667 ** Returns void 668 ** 669 *******************************************************************************/ 670 void nfc_ncif_proc_discover_ntf(uint8_t* p, uint16_t plen) { 671 tNFC_DISCOVER evt_data; 672 673 if (nfc_cb.p_discv_cback) { 674 p += NCI_MSG_HDR_SIZE; 675 evt_data.status = NCI_STATUS_OK; 676 evt_data.result.rf_disc_id = *p++; 677 evt_data.result.protocol = *p++; 678 679 /* fill in tNFC_RESULT_DEVT */ 680 evt_data.result.rf_tech_param.mode = *p++; 681 p = nfc_ncif_decode_rf_params(&evt_data.result.rf_tech_param, p); 682 683 evt_data.result.more = *p++; 684 (*nfc_cb.p_discv_cback)(NFC_RESULT_DEVT, &evt_data); 685 } 686 } 687 688 /******************************************************************************* 689 ** 690 ** Function nfc_ncif_proc_activate 691 ** 692 ** Description This function is called to process de-activate 693 ** response and notification 694 ** 695 ** Returns void 696 ** 697 *******************************************************************************/ 698 void nfc_ncif_proc_activate(uint8_t* p, uint8_t len) { 699 tNFC_DISCOVER evt_data; 700 tNFC_INTF_PARAMS* p_intf = &evt_data.activate.intf_param; 701 tNFC_INTF_PA_ISO_DEP* p_pa_iso; 702 tNFC_INTF_LB_ISO_DEP* p_lb_iso; 703 tNFC_INTF_PB_ISO_DEP* p_pb_iso; 704 #if (NFC_RW_ONLY == FALSE) 705 tNFC_INTF_PA_NFC_DEP* p_pa_nfc; 706 int mpl_idx = 0; 707 uint8_t gb_idx = 0, mpl; 708 #endif 709 uint8_t t0; 710 tNCI_DISCOVERY_TYPE mode; 711 tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID]; 712 uint8_t *pp, len_act; 713 uint8_t buff_size, num_buff; 714 tNFC_RF_PA_PARAMS* p_pa; 715 716 nfc_set_state(NFC_STATE_OPEN); 717 718 memset(p_intf, 0, sizeof(tNFC_INTF_PARAMS)); 719 evt_data.activate.rf_disc_id = *p++; 720 p_intf->type = *p++; 721 evt_data.activate.protocol = *p++; 722 723 if (evt_data.activate.protocol == NCI_PROTOCOL_18092_ACTIVE) 724 evt_data.activate.protocol = NCI_PROTOCOL_NFC_DEP; 725 726 evt_data.activate.rf_tech_param.mode = *p++; 727 buff_size = *p++; 728 num_buff = *p++; 729 /* fill in tNFC_activate_DEVT */ 730 p = nfc_ncif_decode_rf_params(&evt_data.activate.rf_tech_param, p); 731 732 evt_data.activate.data_mode = *p++; 733 evt_data.activate.tx_bitrate = *p++; 734 evt_data.activate.rx_bitrate = *p++; 735 mode = evt_data.activate.rf_tech_param.mode; 736 len_act = *p++; 737 NFC_TRACE_DEBUG3("nfc_ncif_proc_activate:%d %d, mode:0x%02x", len, len_act, 738 mode); 739 /* just in case the interface reports activation parameters not defined in the 740 * NCI spec */ 741 p_intf->intf_param.frame.param_len = len_act; 742 if (p_intf->intf_param.frame.param_len > NFC_MAX_RAW_PARAMS) 743 p_intf->intf_param.frame.param_len = NFC_MAX_RAW_PARAMS; 744 pp = p; 745 STREAM_TO_ARRAY(p_intf->intf_param.frame.param, pp, 746 p_intf->intf_param.frame.param_len); 747 if (evt_data.activate.intf_param.type == NCI_INTERFACE_ISO_DEP) { 748 /* Make max payload of NCI aligned to max payload of ISO-DEP for better 749 * performance */ 750 if (buff_size > NCI_ISO_DEP_MAX_INFO) buff_size = NCI_ISO_DEP_MAX_INFO; 751 752 switch (mode) { 753 case NCI_DISCOVERY_TYPE_POLL_A: 754 p_pa_iso = &p_intf->intf_param.pa_iso; 755 p_pa_iso->ats_res_len = *p++; 756 757 if (p_pa_iso->ats_res_len == 0) break; 758 759 if (p_pa_iso->ats_res_len > NFC_MAX_ATS_LEN) 760 p_pa_iso->ats_res_len = NFC_MAX_ATS_LEN; 761 STREAM_TO_ARRAY(p_pa_iso->ats_res, p, p_pa_iso->ats_res_len); 762 pp = &p_pa_iso->ats_res[NCI_ATS_T0_INDEX]; 763 t0 = p_pa_iso->ats_res[NCI_ATS_T0_INDEX]; 764 pp++; /* T0 */ 765 if (t0 & NCI_ATS_TA_MASK) pp++; /* TA */ 766 if (t0 & NCI_ATS_TB_MASK) { 767 /* FWI (Frame Waiting time Integer) & SPGI (Start-up Frame Guard time 768 * Integer) */ 769 p_pa_iso->fwi = (((*pp) >> 4) & 0x0F); 770 p_pa_iso->sfgi = ((*pp) & 0x0F); 771 pp++; /* TB */ 772 } 773 if (t0 & NCI_ATS_TC_MASK) { 774 p_pa_iso->nad_used = ((*pp) & 0x01); 775 pp++; /* TC */ 776 } 777 p_pa_iso->his_byte_len = 778 (uint8_t)(p_pa_iso->ats_res_len - (pp - p_pa_iso->ats_res)); 779 if (p_pa_iso->his_byte_len > NFC_MAX_HIS_BYTES_LEN) 780 p_pa_iso->his_byte_len = NFC_MAX_HIS_BYTES_LEN; 781 memcpy(p_pa_iso->his_byte, pp, p_pa_iso->his_byte_len); 782 break; 783 784 case NCI_DISCOVERY_TYPE_LISTEN_A: 785 p_intf->intf_param.la_iso.rats = *p++; 786 break; 787 788 case NCI_DISCOVERY_TYPE_POLL_B: 789 /* ATTRIB RSP 790 Byte 1 Byte 2 ~ 2+n-1 791 MBLI/DID Higher layer - Response 792 */ 793 p_pb_iso = &p_intf->intf_param.pb_iso; 794 p_pb_iso->attrib_res_len = *p++; 795 796 if (p_pb_iso->attrib_res_len == 0) break; 797 798 if (p_pb_iso->attrib_res_len > NFC_MAX_ATTRIB_LEN) 799 p_pb_iso->attrib_res_len = NFC_MAX_ATTRIB_LEN; 800 STREAM_TO_ARRAY(p_pb_iso->attrib_res, p, p_pb_iso->attrib_res_len); 801 p_pb_iso->mbli = (p_pb_iso->attrib_res[0]) >> 4; 802 if (p_pb_iso->attrib_res_len > NFC_PB_ATTRIB_REQ_FIXED_BYTES) { 803 p_pb_iso->hi_info_len = 804 p_pb_iso->attrib_res_len - NFC_PB_ATTRIB_REQ_FIXED_BYTES; 805 if (p_pb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN) 806 p_pb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN; 807 memcpy(p_pb_iso->hi_info, 808 &p_pb_iso->attrib_res[NFC_PB_ATTRIB_REQ_FIXED_BYTES], 809 p_pb_iso->hi_info_len); 810 } 811 break; 812 813 case NCI_DISCOVERY_TYPE_LISTEN_B: 814 /* ATTRIB CMD 815 Byte 2~5 Byte 6 Byte 7 Byte 8 Byte 9 Byte 10 ~ 10+k-1 816 NFCID0 Param 1 Param 2 Param 3 Param 4 Higher layer - INF 817 */ 818 p_lb_iso = &p_intf->intf_param.lb_iso; 819 p_lb_iso->attrib_req_len = *p++; 820 821 if (p_lb_iso->attrib_req_len == 0) break; 822 823 if (p_lb_iso->attrib_req_len > NFC_MAX_ATTRIB_LEN) 824 p_lb_iso->attrib_req_len = NFC_MAX_ATTRIB_LEN; 825 STREAM_TO_ARRAY(p_lb_iso->attrib_req, p, p_lb_iso->attrib_req_len); 826 memcpy(p_lb_iso->nfcid0, p_lb_iso->attrib_req, NFC_NFCID0_MAX_LEN); 827 if (p_lb_iso->attrib_req_len > NFC_LB_ATTRIB_REQ_FIXED_BYTES) { 828 p_lb_iso->hi_info_len = 829 p_lb_iso->attrib_req_len - NFC_LB_ATTRIB_REQ_FIXED_BYTES; 830 if (p_lb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN) 831 p_lb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN; 832 memcpy(p_lb_iso->hi_info, 833 &p_lb_iso->attrib_req[NFC_LB_ATTRIB_REQ_FIXED_BYTES], 834 p_lb_iso->hi_info_len); 835 } 836 break; 837 } 838 839 } 840 #if (NFC_RW_ONLY == FALSE) 841 else if (evt_data.activate.intf_param.type == NCI_INTERFACE_NFC_DEP) { 842 /* Make max payload of NCI aligned to max payload of NFC-DEP for better 843 * performance */ 844 if (buff_size > NCI_NFC_DEP_MAX_DATA) buff_size = NCI_NFC_DEP_MAX_DATA; 845 846 p_pa_nfc = &p_intf->intf_param.pa_nfc; 847 p_pa_nfc->atr_res_len = *p++; 848 849 if (p_pa_nfc->atr_res_len > 0) { 850 if (p_pa_nfc->atr_res_len > NFC_MAX_ATS_LEN) 851 p_pa_nfc->atr_res_len = NFC_MAX_ATS_LEN; 852 STREAM_TO_ARRAY(p_pa_nfc->atr_res, p, p_pa_nfc->atr_res_len); 853 if ((mode == NCI_DISCOVERY_TYPE_POLL_A) || 854 (mode == NCI_DISCOVERY_TYPE_POLL_F) || 855 (mode == NCI_DISCOVERY_TYPE_POLL_A_ACTIVE) || 856 (mode == NCI_DISCOVERY_TYPE_POLL_F_ACTIVE)) { 857 /* ATR_RES 858 Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17 Byte 18~18+n 859 NFCID3T DIDT BST BRT TO PPT [GT0 ... GTn] */ 860 mpl_idx = 14; 861 gb_idx = NCI_P_GEN_BYTE_INDEX; 862 p_pa_nfc->waiting_time = 863 p_pa_nfc->atr_res[NCI_L_NFC_DEP_TO_INDEX] & 0x0F; 864 } else if ((mode == NCI_DISCOVERY_TYPE_LISTEN_A) || 865 (mode == NCI_DISCOVERY_TYPE_LISTEN_F) || 866 (mode == NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE) || 867 (mode == NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE)) { 868 /* ATR_REQ 869 Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17~17+n 870 NFCID3I DIDI BSI BRI PPI [GI0 ... GIn] */ 871 mpl_idx = 13; 872 gb_idx = NCI_L_GEN_BYTE_INDEX; 873 } 874 875 mpl = ((p_pa_nfc->atr_res[mpl_idx]) >> 4) & 0x03; 876 p_pa_nfc->max_payload_size = nfc_mpl_code_to_size[mpl]; 877 if (p_pa_nfc->atr_res_len > gb_idx) { 878 p_pa_nfc->gen_bytes_len = p_pa_nfc->atr_res_len - gb_idx; 879 if (p_pa_nfc->gen_bytes_len > NFC_MAX_GEN_BYTES_LEN) 880 p_pa_nfc->gen_bytes_len = NFC_MAX_GEN_BYTES_LEN; 881 memcpy(p_pa_nfc->gen_bytes, &p_pa_nfc->atr_res[gb_idx], 882 p_pa_nfc->gen_bytes_len); 883 } 884 } 885 } 886 #endif 887 else if ((evt_data.activate.intf_param.type == NCI_INTERFACE_FRAME) && 888 (evt_data.activate.protocol == NCI_PROTOCOL_T1T)) { 889 p_pa = &evt_data.activate.rf_tech_param.param.pa; 890 if ((len_act == NCI_T1T_HR_LEN) && (p_pa->hr_len == 0)) { 891 p_pa->hr_len = NCI_T1T_HR_LEN; 892 p_pa->hr[0] = *p++; 893 p_pa->hr[1] = *p++; 894 } 895 } 896 897 p_cb->act_protocol = evt_data.activate.protocol; 898 p_cb->buff_size = buff_size; 899 p_cb->num_buff = num_buff; 900 p_cb->init_credits = num_buff; 901 902 if (nfc_cb.p_discv_cback) { 903 (*nfc_cb.p_discv_cback)(NFC_ACTIVATE_DEVT, &evt_data); 904 } 905 } 906 907 /******************************************************************************* 908 ** 909 ** Function nfc_ncif_proc_deactivate 910 ** 911 ** Description This function is called to process de-activate 912 ** response and notification 913 ** 914 ** Returns void 915 ** 916 *******************************************************************************/ 917 void nfc_ncif_proc_deactivate(uint8_t status, uint8_t deact_type, bool is_ntf) { 918 tNFC_DISCOVER evt_data; 919 tNFC_DEACTIVATE_DEVT* p_deact; 920 tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID]; 921 void* p_data; 922 923 nfc_set_state(NFC_STATE_IDLE); 924 p_deact = &evt_data.deactivate; 925 p_deact->status = status; 926 p_deact->type = deact_type; 927 p_deact->is_ntf = is_ntf; 928 929 while ((p_data = GKI_dequeue(&p_cb->rx_q)) != NULL) { 930 GKI_freebuf(p_data); 931 } 932 933 while ((p_data = GKI_dequeue(&p_cb->tx_q)) != NULL) { 934 GKI_freebuf(p_data); 935 } 936 937 if (p_cb->p_cback) 938 (*p_cb->p_cback)(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, (tNFC_CONN*)p_deact); 939 940 if (nfc_cb.p_discv_cback) { 941 (*nfc_cb.p_discv_cback)(NFC_DEACTIVATE_DEVT, &evt_data); 942 } 943 } 944 /******************************************************************************* 945 ** 946 ** Function nfc_ncif_proc_ee_action 947 ** 948 ** Description This function is called to process NFCEE ACTION NTF 949 ** 950 ** Returns void 951 ** 952 *******************************************************************************/ 953 #if (NFC_NFCEE_INCLUDED == TRUE && NFC_RW_ONLY == FALSE) 954 void nfc_ncif_proc_ee_action(uint8_t* p, uint16_t plen) { 955 tNFC_EE_ACTION_REVT evt_data; 956 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback; 957 uint8_t data_len, ulen, tag, *p_data; 958 uint8_t max_len; 959 960 if (p_cback) { 961 memset(&evt_data.act_data, 0, sizeof(tNFC_ACTION_DATA)); 962 evt_data.status = NFC_STATUS_OK; 963 evt_data.nfcee_id = *p++; 964 evt_data.act_data.trigger = *p++; 965 data_len = *p++; 966 if (plen >= 3) plen -= 3; 967 if (data_len > plen) data_len = (uint8_t)plen; 968 969 switch (evt_data.act_data.trigger) { 970 case NCI_EE_TRIG_7816_SELECT: 971 if (data_len > NFC_MAX_AID_LEN) data_len = NFC_MAX_AID_LEN; 972 evt_data.act_data.param.aid.len_aid = data_len; 973 STREAM_TO_ARRAY(evt_data.act_data.param.aid.aid, p, data_len); 974 break; 975 case NCI_EE_TRIG_RF_PROTOCOL: 976 evt_data.act_data.param.protocol = *p++; 977 break; 978 case NCI_EE_TRIG_RF_TECHNOLOGY: 979 evt_data.act_data.param.technology = *p++; 980 break; 981 case NCI_EE_TRIG_APP_INIT: 982 while (data_len > NFC_TL_SIZE) { 983 data_len -= NFC_TL_SIZE; 984 tag = *p++; 985 ulen = *p++; 986 if (ulen > data_len) ulen = data_len; 987 p_data = NULL; 988 max_len = ulen; 989 switch (tag) { 990 case NCI_EE_ACT_TAG_AID: /* AID */ 991 if (max_len > NFC_MAX_AID_LEN) max_len = NFC_MAX_AID_LEN; 992 evt_data.act_data.param.app_init.len_aid = max_len; 993 p_data = evt_data.act_data.param.app_init.aid; 994 break; 995 case NCI_EE_ACT_TAG_DATA: /* hex data for app */ 996 if (max_len > NFC_MAX_APP_DATA_LEN) 997 max_len = NFC_MAX_APP_DATA_LEN; 998 evt_data.act_data.param.app_init.len_data = max_len; 999 p_data = evt_data.act_data.param.app_init.data; 1000 break; 1001 } 1002 if (p_data) { 1003 STREAM_TO_ARRAY(p_data, p, max_len); 1004 } 1005 data_len -= ulen; 1006 } 1007 break; 1008 } 1009 (*p_cback)(NFC_EE_ACTION_REVT, (tNFC_RESPONSE*)&evt_data); 1010 } 1011 } 1012 1013 /******************************************************************************* 1014 ** 1015 ** Function nfc_ncif_proc_ee_discover_req 1016 ** 1017 ** Description This function is called to process NFCEE DISCOVER REQ NTF 1018 ** 1019 ** Returns void 1020 ** 1021 *******************************************************************************/ 1022 void nfc_ncif_proc_ee_discover_req(uint8_t* p, uint16_t plen) { 1023 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback; 1024 tNFC_EE_DISCOVER_REQ_REVT ee_disc_req; 1025 tNFC_EE_DISCOVER_INFO* p_info; 1026 uint8_t u8; 1027 1028 NFC_TRACE_DEBUG2("nfc_ncif_proc_ee_discover_req %d len:%d", *p, plen); 1029 if (p_cback) { 1030 u8 = *p; 1031 ee_disc_req.status = NFC_STATUS_OK; 1032 ee_disc_req.num_info = *p++; 1033 p_info = ee_disc_req.info; 1034 if (plen) plen--; 1035 while ((u8 > 0) && (plen >= NFC_EE_DISCOVER_ENTRY_LEN)) { 1036 p_info->op = *p++; /* T */ 1037 if (*p != NFC_EE_DISCOVER_INFO_LEN) /* L */ 1038 { 1039 NFC_TRACE_DEBUG1("bad entry len:%d", *p); 1040 return; 1041 } 1042 p++; 1043 /* V */ 1044 p_info->nfcee_id = *p++; 1045 p_info->tech_n_mode = *p++; 1046 p_info->protocol = *p++; 1047 u8--; 1048 plen -= NFC_EE_DISCOVER_ENTRY_LEN; 1049 p_info++; 1050 } 1051 (*p_cback)(NFC_EE_DISCOVER_REQ_REVT, (tNFC_RESPONSE*)&ee_disc_req); 1052 } 1053 } 1054 1055 /******************************************************************************* 1056 ** 1057 ** Function nfc_ncif_proc_get_routing 1058 ** 1059 ** Description This function is called to process get routing notification 1060 ** 1061 ** Returns void 1062 ** 1063 *******************************************************************************/ 1064 void nfc_ncif_proc_get_routing(uint8_t* p, uint8_t len) { 1065 tNFC_GET_ROUTING_REVT evt_data; 1066 uint8_t more, num_entries, xx, yy, *pn, tl; 1067 tNFC_STATUS status = NFC_STATUS_CONTINUE; 1068 1069 if (nfc_cb.p_resp_cback) { 1070 more = *p++; 1071 num_entries = *p++; 1072 for (xx = 0; xx < num_entries; xx++) { 1073 if ((more == false) && (xx == (num_entries - 1))) status = NFC_STATUS_OK; 1074 evt_data.status = (tNFC_STATUS)status; 1075 evt_data.nfcee_id = *p++; 1076 evt_data.num_tlvs = *p++; 1077 evt_data.tlv_size = 0; 1078 pn = evt_data.param_tlvs; 1079 for (yy = 0; yy < evt_data.num_tlvs; yy++) { 1080 tl = *(p + 1); 1081 tl += NFC_TL_SIZE; 1082 STREAM_TO_ARRAY(pn, p, tl); 1083 evt_data.tlv_size += tl; 1084 pn += tl; 1085 } 1086 (*nfc_cb.p_resp_cback)(NFC_GET_ROUTING_REVT, (tNFC_RESPONSE*)&evt_data); 1087 } 1088 } 1089 } 1090 #endif 1091 1092 /******************************************************************************* 1093 ** 1094 ** Function nfc_ncif_proc_conn_create_rsp 1095 ** 1096 ** Description This function is called to process connection create 1097 ** response 1098 ** 1099 ** Returns void 1100 ** 1101 *******************************************************************************/ 1102 void nfc_ncif_proc_conn_create_rsp(uint8_t* p, uint16_t plen, 1103 uint8_t dest_type) { 1104 tNFC_CONN_CB* p_cb; 1105 tNFC_STATUS status; 1106 tNFC_CONN_CBACK* p_cback; 1107 tNFC_CONN evt_data; 1108 uint8_t conn_id; 1109 1110 /* find the pending connection control block */ 1111 p_cb = nfc_find_conn_cb_by_conn_id(NFC_PEND_CONN_ID); 1112 if (p_cb) { 1113 p += NCI_MSG_HDR_SIZE; 1114 status = *p++; 1115 p_cb->buff_size = *p++; 1116 p_cb->num_buff = p_cb->init_credits = *p++; 1117 conn_id = *p++; 1118 evt_data.conn_create.status = status; 1119 evt_data.conn_create.dest_type = dest_type; 1120 evt_data.conn_create.id = p_cb->id; 1121 evt_data.conn_create.buff_size = p_cb->buff_size; 1122 evt_data.conn_create.num_buffs = p_cb->num_buff; 1123 p_cback = p_cb->p_cback; 1124 if (status == NCI_STATUS_OK) { 1125 nfc_set_conn_id(p_cb, conn_id); 1126 } else { 1127 nfc_free_conn_cb(p_cb); 1128 } 1129 1130 if (p_cback) (*p_cback)(conn_id, NFC_CONN_CREATE_CEVT, &evt_data); 1131 } 1132 } 1133 1134 /******************************************************************************* 1135 ** 1136 ** Function nfc_ncif_report_conn_close_evt 1137 ** 1138 ** Description This function is called to report connection close event 1139 ** 1140 ** Returns void 1141 ** 1142 *******************************************************************************/ 1143 void nfc_ncif_report_conn_close_evt(uint8_t conn_id, tNFC_STATUS status) { 1144 tNFC_CONN evt_data; 1145 tNFC_CONN_CBACK* p_cback; 1146 tNFC_CONN_CB* p_cb; 1147 1148 p_cb = nfc_find_conn_cb_by_conn_id(conn_id); 1149 if (p_cb) { 1150 p_cback = p_cb->p_cback; 1151 nfc_free_conn_cb(p_cb); 1152 evt_data.status = status; 1153 if (p_cback) (*p_cback)(conn_id, NFC_CONN_CLOSE_CEVT, &evt_data); 1154 } 1155 } 1156 1157 /******************************************************************************* 1158 ** 1159 ** Function nfc_ncif_proc_reset_rsp 1160 ** 1161 ** Description This function is called to process reset 1162 ** response/notification 1163 ** 1164 ** Returns void 1165 ** 1166 *******************************************************************************/ 1167 void nfc_ncif_proc_reset_rsp(uint8_t* p, bool is_ntf) { 1168 uint8_t status = *p++; 1169 1170 if (is_ntf) { 1171 NFC_TRACE_ERROR1("reset notification!!:0x%x ", status); 1172 /* clean up, if the state is OPEN 1173 * FW does not report reset ntf right now */ 1174 if (nfc_cb.nfc_state == NFC_STATE_OPEN) { 1175 /*if any conn_cb is connected, close it. 1176 if any pending outgoing packets are dropped.*/ 1177 nfc_reset_all_conn_cbs(); 1178 } 1179 status = NCI_STATUS_OK; 1180 } 1181 1182 if (nfc_cb.flags & (NFC_FL_RESTARTING | NFC_FL_POWER_CYCLE_NFCC)) { 1183 nfc_reset_all_conn_cbs(); 1184 } 1185 1186 if (!is_ntf && status == NCI_STATUS_OK) { 1187 if ((*p) != NCI_VERSION) { 1188 NFC_TRACE_ERROR2("NCI version mismatch!!:0x%02x != 0x%02x ", NCI_VERSION, 1189 *p); 1190 if ((*p) < NCI_VERSION_0_F) { 1191 NFC_TRACE_ERROR0("NFCC version is too old"); 1192 status = NCI_STATUS_FAILED; 1193 } 1194 } 1195 } 1196 1197 if (status == NCI_STATUS_OK) { 1198 nci_snd_core_init(); 1199 } else { 1200 NFC_TRACE_ERROR0("Failed to reset NFCC"); 1201 nfc_enabled(status, NULL); 1202 } 1203 } 1204 1205 /******************************************************************************* 1206 ** 1207 ** Function nfc_ncif_proc_init_rsp 1208 ** 1209 ** Description This function is called to process init response 1210 ** 1211 ** Returns void 1212 ** 1213 *******************************************************************************/ 1214 void nfc_ncif_proc_init_rsp(NFC_HDR* p_msg) { 1215 uint8_t *p, status; 1216 tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID]; 1217 1218 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 1219 1220 /* handle init params in nfc_enabled */ 1221 status = *(p + NCI_MSG_HDR_SIZE); 1222 if (status == NCI_STATUS_OK) { 1223 p_cb->id = NFC_RF_CONN_ID; 1224 p_cb->act_protocol = NCI_PROTOCOL_UNKNOWN; 1225 1226 nfc_set_state(NFC_STATE_W4_POST_INIT_CPLT); 1227 1228 nfc_cb.p_nci_init_rsp = p_msg; 1229 nfc_cb.p_hal->core_initialized(p_msg->len - p_msg->offset, p); 1230 } else { 1231 nfc_enabled(status, NULL); 1232 GKI_freebuf(p_msg); 1233 } 1234 } 1235 1236 /******************************************************************************* 1237 ** 1238 ** Function nfc_ncif_proc_get_config_rsp 1239 ** 1240 ** Description This function is called to process get config response 1241 ** 1242 ** Returns void 1243 ** 1244 *******************************************************************************/ 1245 void nfc_ncif_proc_get_config_rsp(NFC_HDR* p_evt) { 1246 uint8_t* p; 1247 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback; 1248 tNFC_RESPONSE evt_data; 1249 1250 p_evt->offset += NCI_MSG_HDR_SIZE; 1251 p_evt->len -= NCI_MSG_HDR_SIZE; 1252 if (p_cback) { 1253 p = (uint8_t*)(p_evt + 1) + p_evt->offset; 1254 evt_data.get_config.status = *p++; 1255 evt_data.get_config.tlv_size = p_evt->len; 1256 evt_data.get_config.p_param_tlvs = p; 1257 (*p_cback)(NFC_GET_CONFIG_REVT, &evt_data); 1258 } 1259 } 1260 1261 /******************************************************************************* 1262 ** 1263 ** Function nfc_ncif_proc_t3t_polling_ntf 1264 ** 1265 ** Description Handle NCI_MSG_RF_T3T_POLLING NTF 1266 ** 1267 ** Returns void 1268 ** 1269 *******************************************************************************/ 1270 void nfc_ncif_proc_t3t_polling_ntf(uint8_t* p, uint16_t plen) { 1271 uint8_t status; 1272 uint8_t num_responses; 1273 1274 /* Pass result to RW_T3T for processing */ 1275 STREAM_TO_UINT8(status, p); 1276 STREAM_TO_UINT8(num_responses, p); 1277 plen -= NFC_TL_SIZE; 1278 rw_t3t_handle_nci_poll_ntf(status, num_responses, (uint8_t)plen, p); 1279 } 1280 1281 /******************************************************************************* 1282 ** 1283 ** Function nfc_data_event 1284 ** 1285 ** Description Report Data event on the given connection control block 1286 ** 1287 ** Returns void 1288 ** 1289 *******************************************************************************/ 1290 void nfc_data_event(tNFC_CONN_CB* p_cb) { 1291 NFC_HDR* p_evt; 1292 tNFC_DATA_CEVT data_cevt; 1293 uint8_t* p; 1294 1295 if (p_cb->p_cback) { 1296 while ((p_evt = (NFC_HDR*)GKI_getfirst(&p_cb->rx_q)) != NULL) { 1297 if (p_evt->layer_specific & NFC_RAS_FRAGMENTED) { 1298 /* Not the last fragment */ 1299 if (!(p_evt->layer_specific & NFC_RAS_TOO_BIG)) { 1300 /* buffer can hold more */ 1301 if ((p_cb->conn_id != NFC_RF_CONN_ID) || (nfc_cb.reassembly)) { 1302 /* If not rf connection or If rf connection and reassembly 1303 * requested, 1304 * try to Reassemble next packet */ 1305 break; 1306 } 1307 } 1308 } 1309 1310 p_evt = (NFC_HDR*)GKI_dequeue(&p_cb->rx_q); 1311 /* report data event */ 1312 p_evt->offset += NCI_MSG_HDR_SIZE; 1313 p_evt->len -= NCI_MSG_HDR_SIZE; 1314 1315 if (p_evt->layer_specific) 1316 data_cevt.status = NFC_STATUS_CONTINUE; 1317 else { 1318 nfc_cb.reassembly = true; 1319 data_cevt.status = NFC_STATUS_OK; 1320 } 1321 1322 data_cevt.p_data = p_evt; 1323 /* adjust payload, if needed */ 1324 if (p_cb->conn_id == NFC_RF_CONN_ID) { 1325 /* if NCI_PROTOCOL_T1T/NCI_PROTOCOL_T2T/NCI_PROTOCOL_T3T, the status 1326 * byte needs to be removed 1327 */ 1328 if ((p_cb->act_protocol >= NCI_PROTOCOL_T1T) && 1329 (p_cb->act_protocol <= NCI_PROTOCOL_T3T)) { 1330 p_evt->len--; 1331 p = (uint8_t*)(p_evt + 1); 1332 data_cevt.status = *(p + p_evt->offset + p_evt->len); 1333 } 1334 } 1335 (*p_cb->p_cback)(p_cb->conn_id, NFC_DATA_CEVT, (tNFC_CONN*)&data_cevt); 1336 p_evt = NULL; 1337 } 1338 } 1339 } 1340 1341 /******************************************************************************* 1342 ** 1343 ** Function nfc_ncif_proc_data 1344 ** 1345 ** Description Find the connection control block associated with the data 1346 ** packet. Assemble the data packet, if needed. 1347 ** Report the Data event. 1348 ** 1349 ** Returns void 1350 ** 1351 *******************************************************************************/ 1352 void nfc_ncif_proc_data(NFC_HDR* p_msg) { 1353 uint8_t *pp, cid; 1354 tNFC_CONN_CB* p_cb; 1355 uint8_t pbf; 1356 NFC_HDR* p_last; 1357 uint8_t *ps, *pd; 1358 uint16_t size; 1359 NFC_HDR* p_max = NULL; 1360 uint16_t len; 1361 1362 pp = (uint8_t*)(p_msg + 1) + p_msg->offset; 1363 NFC_TRACE_DEBUG3("nfc_ncif_proc_data 0x%02x%02x%02x", pp[0], pp[1], pp[2]); 1364 NCI_DATA_PRS_HDR(pp, pbf, cid, len); 1365 p_cb = nfc_find_conn_cb_by_conn_id(cid); 1366 if (p_cb && (p_msg->len >= NCI_DATA_HDR_SIZE)) { 1367 NFC_TRACE_DEBUG1("nfc_ncif_proc_data len:%d", len); 1368 1369 p_msg->layer_specific = 0; 1370 if (pbf) p_msg->layer_specific = NFC_RAS_FRAGMENTED; 1371 p_last = (NFC_HDR*)GKI_getlast(&p_cb->rx_q); 1372 if (p_last && (p_last->layer_specific & NFC_RAS_FRAGMENTED)) { 1373 /* last data buffer is not last fragment, append this new packet to the 1374 * last */ 1375 size = GKI_get_buf_size(p_last); 1376 if (size < (NFC_HDR_SIZE + p_last->len + p_last->offset + len)) { 1377 /* the current size of p_last is not big enough to hold the new 1378 * fragment, p_msg */ 1379 if (size != GKI_MAX_BUF_SIZE) { 1380 /* try the biggest GKI pool */ 1381 p_max = (NFC_HDR*)GKI_getpoolbuf(GKI_MAX_BUF_SIZE_POOL_ID); 1382 if (p_max) { 1383 /* copy the content of last buffer to the new buffer */ 1384 memcpy(p_max, p_last, NFC_HDR_SIZE); 1385 pd = (uint8_t*)(p_max + 1) + p_max->offset; 1386 ps = (uint8_t*)(p_last + 1) + p_last->offset; 1387 memcpy(pd, ps, p_last->len); 1388 1389 /* place the new buffer in the queue instead */ 1390 GKI_remove_from_queue(&p_cb->rx_q, p_last); 1391 GKI_freebuf(p_last); 1392 GKI_enqueue(&p_cb->rx_q, p_max); 1393 p_last = p_max; 1394 } 1395 } 1396 if (p_max == NULL) { 1397 /* Biggest GKI Pool not available (or) 1398 * Biggest available GKI Pool is not big enough to hold the new 1399 * fragment, p_msg */ 1400 p_last->layer_specific |= NFC_RAS_TOO_BIG; 1401 } 1402 } 1403 1404 ps = (uint8_t*)(p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE; 1405 len = p_msg->len - NCI_MSG_HDR_SIZE; 1406 1407 if (!(p_last->layer_specific & NFC_RAS_TOO_BIG)) { 1408 pd = (uint8_t*)(p_last + 1) + p_last->offset + p_last->len; 1409 memcpy(pd, ps, len); 1410 p_last->len += len; 1411 /* do not need to update pbf and len in NCI header. 1412 * They are stripped off at NFC_DATA_CEVT and len may exceed 255 */ 1413 NFC_TRACE_DEBUG1("nfc_ncif_proc_data len:%d", p_last->len); 1414 p_last->layer_specific = p_msg->layer_specific; 1415 GKI_freebuf(p_msg); 1416 #ifdef DISP_NCI 1417 if (!(p_last->layer_specific & NFC_RAS_FRAGMENTED)) { 1418 /* this packet was reassembled. display the complete packet */ 1419 DISP_NCI((uint8_t*)(p_last + 1) + p_last->offset, p_last->len, true); 1420 } 1421 #endif 1422 nfc_data_event(p_cb); 1423 } else { 1424 /* Not enough memory to add new buffer 1425 * Send data already in queue first with status Continue */ 1426 nfc_data_event(p_cb); 1427 /* now enqueue the new buffer to the rx queue */ 1428 GKI_enqueue(&p_cb->rx_q, p_msg); 1429 } 1430 } else { 1431 /* if this is the first fragment on RF link */ 1432 if ((p_msg->layer_specific & NFC_RAS_FRAGMENTED) && 1433 (p_cb->conn_id == NFC_RF_CONN_ID) && (p_cb->p_cback)) { 1434 /* Indicate upper layer that local device started receiving data */ 1435 (*p_cb->p_cback)(p_cb->conn_id, NFC_DATA_START_CEVT, NULL); 1436 } 1437 /* enqueue the new buffer to the rx queue */ 1438 GKI_enqueue(&p_cb->rx_q, p_msg); 1439 nfc_data_event(p_cb); 1440 } 1441 return; 1442 } 1443 GKI_freebuf(p_msg); 1444 } 1445