nfc_hal_nci.c revision a24be4f06674b2707b57904deaa0dff5a95823bd
1/****************************************************************************** 2 * 3 * Copyright (C) 2010-2014 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 20/****************************************************************************** 21 * 22 * This file contains function of the NFC unit to receive/process NCI/VS 23 * commands/responses. 24 * 25 ******************************************************************************/ 26#include <string.h> 27#include "nfc_hal_int.h" 28#include "nfc_hal_post_reset.h" 29#include "userial.h" 30#include "nci_defs.h" 31 32 33/***************************************************************************** 34** Constants and types 35*****************************************************************************/ 36 37/***************************************************************************** 38** Local function prototypes 39*****************************************************************************/ 40 41/******************************************************************************* 42** 43** Function nfc_hal_nci_assemble_nci_msg 44** 45** Description This function is called to reassemble the received NCI 46** response/notification packet, if required. 47** (The data packets are posted to NFC task for reassembly) 48** 49** Returns void. 50** 51*******************************************************************************/ 52void nfc_hal_nci_assemble_nci_msg (void) 53{ 54 NFC_HDR *p_msg = nfc_hal_cb.ncit_cb.p_rcv_msg; 55 UINT8 u8; 56 UINT8 *p, *pp; 57 UINT8 hdr[2]; 58 UINT8 *ps, *pd; 59 UINT16 size, needed; 60 BOOLEAN disp_again = FALSE; 61 62 if ((p_msg == NULL) || (p_msg->len < NCI_MSG_HDR_SIZE)) 63 return; 64 65#ifdef DISP_NCI 66 DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE); 67#endif 68 69 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 70 u8 = *p++; 71 /* remove the PBF bit for potential reassembly later */ 72 hdr[0] = u8 & ~NCI_PBF_MASK; 73 if ((u8 & NCI_MT_MASK) == NCI_MT_DATA) 74 { 75 /* clear the RFU in octet1 */ 76 *(p) = 0; 77 /* data packet reassembly is performed in NFC task */ 78 return; 79 } 80 else 81 { 82 *(p) &= NCI_OID_MASK; 83 } 84 85 hdr[1] = *p; 86 pp = hdr; 87 /* save octet0 and octet1 of an NCI header in layer_specific for the received packet */ 88 STREAM_TO_UINT16 (p_msg->layer_specific, pp); 89 90 if (nfc_hal_cb.ncit_cb.p_frag_msg) 91 { 92 if (nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific != p_msg->layer_specific) 93 { 94 /* check if these fragments are of the same NCI message */ 95 HAL_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() - different messages 0x%x, 0x%x!!", nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific, p_msg->layer_specific); 96 nfc_hal_cb.ncit_cb.nci_ras |= NFC_HAL_NCI_RAS_ERROR; 97 } 98 else if (nfc_hal_cb.ncit_cb.nci_ras == 0) 99 { 100 disp_again = TRUE; 101 /* if not previous reassembly error, append the new fragment */ 102 p_msg->offset += NCI_MSG_HDR_SIZE; 103 p_msg->len -= NCI_MSG_HDR_SIZE; 104 size = GKI_get_buf_size (nfc_hal_cb.ncit_cb.p_frag_msg); 105 needed = (NFC_HDR_SIZE + nfc_hal_cb.ncit_cb.p_frag_msg->len + nfc_hal_cb.ncit_cb.p_frag_msg->offset + p_msg->len); 106 if (size >= needed) 107 { 108 /* the buffer for reassembly is big enough to append the new fragment */ 109 ps = (UINT8 *) (p_msg + 1) + p_msg->offset; 110 pd = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + nfc_hal_cb.ncit_cb.p_frag_msg->len; 111 memcpy (pd, ps, p_msg->len); 112 nfc_hal_cb.ncit_cb.p_frag_msg->len += p_msg->len; 113 /* adjust the NCI packet length */ 114 pd = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + 2; 115 *pd = (UINT8) (nfc_hal_cb.ncit_cb.p_frag_msg->len - NCI_MSG_HDR_SIZE); 116 } 117 else 118 { 119 nfc_hal_cb.ncit_cb.nci_ras |= NFC_HAL_NCI_RAS_TOO_BIG; 120 HAL_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() buffer overrun (%d + %d)!!", nfc_hal_cb.ncit_cb.p_frag_msg->len, p_msg->len); 121 } 122 } 123 /* we are done with this new fragment, free it */ 124 GKI_freebuf (p_msg); 125 } 126 else 127 { 128 nfc_hal_cb.ncit_cb.p_frag_msg = p_msg; 129 } 130 131 132 if ((u8 & NCI_PBF_MASK) == NCI_PBF_NO_OR_LAST) 133 { 134 /* last fragment */ 135 p_msg = nfc_hal_cb.ncit_cb.p_frag_msg; 136 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 137 *p = u8; /* this should make the PBF flag as Last Fragment */ 138 nfc_hal_cb.ncit_cb.p_frag_msg = NULL; 139 140 p_msg->layer_specific = nfc_hal_cb.ncit_cb.nci_ras; 141 /* still report the data packet, if the incoming packet is too big */ 142 if (nfc_hal_cb.ncit_cb.nci_ras & NFC_HAL_NCI_RAS_ERROR) 143 { 144 /* NFCC reported NCI fragments for different NCI messages and this is the last fragment - drop it */ 145 HAL_TRACE_ERROR0 ("nfc_hal_nci_assemble_nci_msg() clearing NCI_RAS_ERROR"); 146 GKI_freebuf (p_msg); 147 p_msg = NULL; 148 } 149#ifdef DISP_NCI 150 if ((nfc_hal_cb.ncit_cb.nci_ras == 0) && (disp_again)) 151 { 152 DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE); 153 } 154#endif 155 /* clear the error flags, so the next NCI packet is clean */ 156 nfc_hal_cb.ncit_cb.nci_ras = 0; 157 } 158 else 159 { 160 /* still reassembling */ 161 p_msg = NULL; 162 } 163 164 nfc_hal_cb.ncit_cb.p_rcv_msg = p_msg; 165} 166 167/***************************************************************************** 168** 169** Function nfc_hal_nci_receive_nci_msg 170** 171** Description 172** Handle incoming data (NCI events) from the serial port. 173** 174** If there is data waiting from the serial port, this funciton reads the 175** data and parses it. Once an entire NCI message has been read, it sends 176** the message the the NFC_TASK for processing 177** 178*****************************************************************************/ 179static BOOLEAN nfc_hal_nci_receive_nci_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte) 180{ 181 UINT16 len; 182 BOOLEAN msg_received = FALSE; 183 184 switch (p_cb->rcv_state) 185 { 186 case NFC_HAL_RCV_NCI_MSG_ST: 187 188 /* Initialize rx parameters */ 189 p_cb->rcv_state = NFC_HAL_RCV_NCI_HDR_ST; 190 p_cb->rcv_len = NCI_MSG_HDR_SIZE; 191 192 /* Start of new message. Allocate a buffer for message */ 193 if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) 194 { 195 /* Initialize NFC_HDR */ 196 p_cb->p_rcv_msg->len = 0; 197 p_cb->p_rcv_msg->event = 0; 198 p_cb->p_rcv_msg->offset = 0; 199 200 *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte; 201 } 202 else 203 { 204 HAL_TRACE_ERROR0 ("Unable to allocate buffer for incoming NCI message."); 205 } 206 p_cb->rcv_len--; 207 break; 208 209 case NFC_HAL_RCV_NCI_HDR_ST: 210 211 if (p_cb->p_rcv_msg) 212 { 213 *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte; 214 } 215 216 p_cb->rcv_len--; 217 218 /* Check if we read in entire NFC message header yet */ 219 if (p_cb->rcv_len == 0) 220 { 221 p_cb->rcv_len = byte; 222 223 /* If non-zero payload, then go to receive-data state */ 224 if (byte > 0) 225 { 226 p_cb->rcv_state = NFC_HAL_RCV_NCI_PAYLOAD_ST; 227 } 228 else 229 { 230 msg_received = TRUE; 231 p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST; 232 } 233 } 234 break; 235 236 case NFC_HAL_RCV_NCI_PAYLOAD_ST: 237 238 p_cb->rcv_len--; 239 if (p_cb->p_rcv_msg) 240 { 241 *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte; 242 243 if (p_cb->rcv_len > 0) 244 { 245 /* Read in the rest of the message */ 246 len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len), p_cb->rcv_len); 247 p_cb->p_rcv_msg->len += len; 248 p_cb->rcv_len -= len; 249 } 250 } 251 252 /* Check if we read in entire message yet */ 253 if (p_cb->rcv_len == 0) 254 { 255 msg_received = TRUE; 256 p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST; 257 } 258 break; 259 } 260 261 return (msg_received); 262} 263 264/***************************************************************************** 265** 266** Function nfc_hal_nci_receive_bt_msg 267** 268** Description 269** Handle incoming BRCM specific data from the serial port. 270** 271** If there is data waiting from the serial port, this funciton reads the 272** data and parses it. Once an entire message has been read, it returns 273** TRUE. 274** 275*****************************************************************************/ 276static BOOLEAN nfc_hal_nci_receive_bt_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte) 277{ 278 UINT16 len; 279 BOOLEAN msg_received = FALSE; 280 281 switch (p_cb->rcv_state) 282 { 283 case NFC_HAL_RCV_BT_MSG_ST: 284 285 /* Initialize rx parameters */ 286 p_cb->rcv_state = NFC_HAL_RCV_BT_HDR_ST; 287 p_cb->rcv_len = HCIE_PREAMBLE_SIZE; 288 289 if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL) 290 { 291 /* Initialize NFC_HDR */ 292 p_cb->p_rcv_msg->len = 0; 293 p_cb->p_rcv_msg->event = 0; 294 p_cb->p_rcv_msg->offset = 0; 295 296 *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte; 297 } 298 else 299 { 300 HAL_TRACE_ERROR0 ("[nfc] Unable to allocate buffer for incoming NCI message."); 301 } 302 p_cb->rcv_len--; 303 break; 304 305 case NFC_HAL_RCV_BT_HDR_ST: 306 if (p_cb->p_rcv_msg) 307 { 308 *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte; 309 } 310 p_cb->rcv_len--; 311 312 /* Check if we received entire preamble yet */ 313 if (p_cb->rcv_len == 0) 314 { 315 /* Received entire preamble. Length is in the last byte(s) of the preamble */ 316 p_cb->rcv_len = byte; 317 318 /* Verify that buffer is big enough to fit message */ 319 if ((p_cb->p_rcv_msg) && 320 ((sizeof (NFC_HDR) + HCIE_PREAMBLE_SIZE + byte) > GKI_get_buf_size (p_cb->p_rcv_msg)) ) 321 { 322 /* Message cannot fit into buffer */ 323 GKI_freebuf (p_cb->p_rcv_msg); 324 p_cb->p_rcv_msg = NULL; 325 326 HAL_TRACE_ERROR0 ("Invalid length for incoming BT HCI message."); 327 } 328 329 /* Message length is valid */ 330 if (byte) 331 { 332 /* Read rest of message */ 333 p_cb->rcv_state = NFC_HAL_RCV_BT_PAYLOAD_ST; 334 } 335 else 336 { 337 /* Message has no additional parameters. (Entire message has been received) */ 338 msg_received = TRUE; 339 p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST; /* Next, wait for packet type of next message */ 340 } 341 } 342 break; 343 344 case NFC_HAL_RCV_BT_PAYLOAD_ST: 345 p_cb->rcv_len--; 346 if (p_cb->p_rcv_msg) 347 { 348 *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte; 349 350 if (p_cb->rcv_len > 0) 351 { 352 /* Read in the rest of the message */ 353 len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len), p_cb->rcv_len); 354 p_cb->p_rcv_msg->len += len; 355 p_cb->rcv_len -= len; 356 } 357 } 358 359 /* Check if we read in entire message yet */ 360 if (p_cb->rcv_len == 0) 361 { 362 msg_received = TRUE; 363 p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST; /* Next, wait for packet type of next message */ 364 } 365 break; 366 } 367 368 /* If we received entire message */ 369#if (NFC_HAL_TRACE_PROTOCOL == TRUE) 370 if (msg_received && p_cb->p_rcv_msg) 371 { 372 /* Display protocol trace message */ 373 DispHciEvt (p_cb->p_rcv_msg); 374 } 375#endif 376 377 return (msg_received); 378} 379 380/******************************************************************************* 381** 382** Function nfc_hal_nci_proc_rx_bt_msg 383** 384** Description Received BT message from NFCC 385** 386** Notify command complete if initializing NFCC 387** Forward BT message to NFC task 388** 389** Returns void 390** 391*******************************************************************************/ 392static void nfc_hal_nci_proc_rx_bt_msg (void) 393{ 394 UINT8 *p; 395 NFC_HDR *p_msg; 396 UINT16 opcode, old_opcode; 397 tNFC_HAL_BTVSC_CPLT vcs_cplt_params; 398 tNFC_HAL_BTVSC_CPLT_CBACK *p_cback = NULL; 399 400 /* if complete BT message is received successfully */ 401 if (nfc_hal_cb.ncit_cb.p_rcv_msg) 402 { 403 p_msg = nfc_hal_cb.ncit_cb.p_rcv_msg; 404 HAL_TRACE_DEBUG1 ("nfc_hal_nci_proc_rx_bt_msg (): GOT an BT msgs init_sta:%d", nfc_hal_cb.dev_cb.initializing_state); 405 HAL_TRACE_DEBUG2 ("event: 0x%x, wait_rsp:0x%x", p_msg->event, nfc_hal_cb.ncit_cb.nci_wait_rsp); 406 /* increase the cmd window here */ 407 if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP) 408 { 409 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 410 if (*p == HCI_COMMAND_COMPLETE_EVT) 411 { 412 p += 3; /* code, len, cmd window */ 413 STREAM_TO_UINT16 (opcode, p); 414 p = nfc_hal_cb.ncit_cb.last_hdr; 415 STREAM_TO_UINT16 (old_opcode, p); 416 if (opcode == old_opcode) 417 { 418 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; 419 p_cback = (tNFC_HAL_BTVSC_CPLT_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback; 420 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL; 421 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); 422 } 423 } 424 } 425 426 /* if initializing BRCM NFCC */ 427 if ((nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE) || 428 (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE)) 429 { 430 /* this is command complete event for baud rate update or download patch */ 431 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 432 433 p += 1; /* skip opcode */ 434 STREAM_TO_UINT8 (vcs_cplt_params.param_len, p); 435 436 p += 1; /* skip num command packets */ 437 STREAM_TO_UINT16 (vcs_cplt_params.opcode, p); 438 439 vcs_cplt_params.param_len -= 3; 440 vcs_cplt_params.p_param_buf = p; 441 442 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE) 443 { 444 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE); 445 nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_OK); 446 } 447 if (p_cback) 448 { 449 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL; 450 (*p_cback) (&vcs_cplt_params); 451 } 452 453 /* do not BT send message to NFC task */ 454 GKI_freebuf (p_msg); 455 } 456 else 457 { 458 /* do not BT send message to NFC task */ 459 GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg); 460 } 461 nfc_hal_cb.ncit_cb.p_rcv_msg = NULL; 462 } 463} 464 465/***************************************************************************** 466** 467** Function nfc_hal_nci_receive_msg 468** 469** Description 470** Handle incoming data (NCI events) from the serial port. 471** 472** If there is data waiting from the serial port, this funciton reads the 473** data and parses it. Once an entire NCI message has been read, it sends 474** the message the the NFC_TASK for processing 475** 476*****************************************************************************/ 477BOOLEAN nfc_hal_nci_receive_msg (UINT8 byte) 478{ 479 tNFC_HAL_NCIT_CB *p_cb = &(nfc_hal_cb.ncit_cb); 480 BOOLEAN msg_received = FALSE; 481 482 if (p_cb->rcv_state == NFC_HAL_RCV_IDLE_ST) 483 { 484 /* if this is NCI message */ 485 if (byte == HCIT_TYPE_NFC) 486 { 487 p_cb->rcv_state = NFC_HAL_RCV_NCI_MSG_ST; 488 } 489 /* if this is BT message */ 490 else if (byte == HCIT_TYPE_EVENT) 491 { 492 p_cb->rcv_state = NFC_HAL_RCV_BT_MSG_ST; 493 } 494 else 495 { 496 HAL_TRACE_ERROR1 ("Unknown packet type drop this byte 0x%x", byte); 497 } 498 } 499 else if (p_cb->rcv_state <= NFC_HAL_RCV_NCI_PAYLOAD_ST) 500 { 501 msg_received = nfc_hal_nci_receive_nci_msg (p_cb, byte); 502 } 503 else 504 { 505 if (nfc_hal_nci_receive_bt_msg (p_cb, byte)) 506 { 507 /* received BT message */ 508 nfc_hal_nci_proc_rx_bt_msg (); 509 } 510 } 511 512 return (msg_received); 513} 514 515/******************************************************************************* 516** 517** Function nfc_hal_nci_preproc_rx_nci_msg 518** 519** Description NFCC sends NCI message to DH while initializing NFCC 520** processing low power mode 521** 522** Returns TRUE, if NFC task need to receive NCI message 523** 524*******************************************************************************/ 525BOOLEAN nfc_hal_nci_preproc_rx_nci_msg (NFC_HDR *p_msg) 526{ 527 UINT8 *p, *pp; 528 UINT8 mt, pbf, gid, op_code; 529 UINT8 payload_len; 530#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE)) 531 UINT8 cid; 532 UINT16 data_len; 533#endif 534 535 HAL_TRACE_DEBUG0 ("nfc_hal_nci_preproc_rx_nci_msg()"); 536 537 /* if initializing BRCM NFCC */ 538 if (nfc_hal_cb.dev_cb.initializing_state != NFC_HAL_INIT_STATE_IDLE) 539 { 540 nfc_hal_dm_proc_msg_during_init (p_msg); 541 /* do not send message to NFC task while initializing NFCC */ 542 return (FALSE); 543 } 544 else 545 { 546 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 547 pp = p; 548 NCI_MSG_PRS_HDR0 (p, mt, pbf, gid); 549 NCI_MSG_PRS_HDR1 (p, op_code); 550 payload_len = *p++; 551 552#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE)) 553 if (mt == NCI_MT_DATA) 554 { 555 if (nfc_hal_cb.hci_cb.hcp_conn_id) 556 { 557 NCI_DATA_PRS_HDR(pp, pbf, cid, data_len); 558 if (cid == nfc_hal_cb.hci_cb.hcp_conn_id) 559 { 560 nfc_hal_hci_handle_hcp_pkt_from_hc (pp); 561 } 562 563 } 564 } 565 566 if (gid == NCI_GID_PROP) /* this is for hci netwk ntf */ 567 { 568 if (mt == NCI_MT_NTF) 569 { 570 if (op_code == NCI_MSG_HCI_NETWK) 571 { 572 nfc_hal_hci_handle_hci_netwk_info ((UINT8 *) (p_msg + 1) + p_msg->offset); 573 } 574 } 575 } 576 else 577#endif 578 if (gid == NCI_GID_RF_MANAGE) 579 { 580 if (mt == NCI_MT_NTF) 581 { 582 if (op_code == NCI_MSG_RF_INTF_ACTIVATED) 583 { 584 if ((nfc_hal_cb.max_rf_credits) && (payload_len > 5)) 585 { 586 /* API used wants to limit the RF data credits */ 587 p += 5; /* skip RF disc id, interface, protocol, tech&mode, payload size */ 588 if (*p > nfc_hal_cb.max_rf_credits) 589 { 590 HAL_TRACE_DEBUG2 ("RfDataCredits %d->%d", *p, nfc_hal_cb.max_rf_credits); 591 *p = nfc_hal_cb.max_rf_credits; 592 } 593 } 594 } 595 } 596 } 597#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE)) 598 else if (gid == NCI_GID_CORE) 599 { 600 if (mt == NCI_MT_RSP) 601 { 602 if (op_code == NCI_MSG_CORE_CONN_CREATE) 603 { 604 if (nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp) 605 { 606 p++; /* skip status byte */ 607 nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE; 608 p++; /* skip buff size */ 609 p++; /* num of buffers */ 610 nfc_hal_cb.hci_cb.hcp_conn_id = *p; 611 } 612 } 613 } 614 } 615#endif 616 } 617 618 if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL) 619 { 620 if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) 621 { 622 /* extend idle timer */ 623 nfc_hal_dm_power_mode_execute (NFC_HAL_LP_RX_DATA_EVT); 624 } 625 } 626 627 return (TRUE); 628} 629 630/******************************************************************************* 631** 632** Function nfc_hal_nci_add_nfc_pkt_type 633** 634** Description Add packet type (HCIT_TYPE_NFC) 635** 636** Returns TRUE, if NFCC can receive NCI message 637** 638*******************************************************************************/ 639void nfc_hal_nci_add_nfc_pkt_type (NFC_HDR *p_msg) 640{ 641 UINT8 *p; 642 UINT8 hcit; 643 644 /* add packet type in front of NCI header */ 645 if (p_msg->offset > 0) 646 { 647 p_msg->offset--; 648 p_msg->len++; 649 650 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 651 *p = HCIT_TYPE_NFC; 652 } 653 else 654 { 655 HAL_TRACE_ERROR0 ("nfc_hal_nci_add_nfc_pkt_type () : No space for packet type"); 656 hcit = HCIT_TYPE_NFC; 657 USERIAL_Write (USERIAL_NFC_PORT, &hcit, 1); 658 } 659} 660 661#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE)) 662/******************************************************************************* 663** 664** Function nci_brcm_check_cmd_create_hcp_connection 665** 666** Description Check if this is command to create HCP connection 667** 668** Returns None 669** 670*******************************************************************************/ 671static void nci_brcm_check_cmd_create_hcp_connection (NFC_HDR *p_msg) 672{ 673 UINT8 *p; 674 UINT8 mt, pbf, gid, op_code; 675 676 nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE; 677 678 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 679 680 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE) 681 { 682 NCI_MSG_PRS_HDR0 (p, mt, pbf, gid); 683 NCI_MSG_PRS_HDR1 (p, op_code); 684 685 if (gid == NCI_GID_CORE) 686 { 687 if (mt == NCI_MT_CMD) 688 { 689 if (op_code == NCI_MSG_CORE_CONN_CREATE) 690 { 691 if ( ((NCI_CORE_PARAM_SIZE_CON_CREATE + 4) == *p++) 692 &&(NCI_DEST_TYPE_NFCEE == *p++) 693 &&(1 == *p++) 694 &&(NCI_CON_CREATE_TAG_NFCEE_VAL == *p++) 695 &&(2 == *p++) ) 696 { 697 p++; 698 if (NCI_NFCEE_INTERFACE_HCI_ACCESS == *p) 699 { 700 nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = TRUE; 701 return; 702 } 703 } 704 705 } 706 } 707 } 708 } 709} 710 711#endif 712 713/******************************************************************************* 714** 715** Function nfc_hal_nci_send_cmd 716** 717** Description Send NCI command to the transport 718** 719** Returns void 720** 721*******************************************************************************/ 722void nfc_hal_nci_send_cmd (NFC_HDR *p_buf) 723{ 724 BOOLEAN continue_to_process = TRUE; 725 UINT8 *ps, *pd; 726 UINT16 max_len; 727 UINT16 buf_len, offset; 728 UINT8 *p; 729 UINT8 hdr[NCI_MSG_HDR_SIZE]; 730 UINT8 nci_ctrl_size = nfc_hal_cb.ncit_cb.nci_ctrl_size; 731 UINT8 delta = 0; 732 733#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE)) 734 if ( (nfc_hal_cb.hci_cb.hcp_conn_id == 0) 735 &&(nfc_hal_cb.nvm_cb.nvm_type != NCI_SPD_NVM_TYPE_NONE) ) 736 nci_brcm_check_cmd_create_hcp_connection ((NFC_HDR*) p_buf); 737#endif 738 739 /* check low power mode state */ 740 continue_to_process = nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT); 741 742 if (!continue_to_process) 743 { 744 /* save the command to be sent until NFCC is free. */ 745 nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf; 746 return; 747 } 748 749 max_len = nci_ctrl_size + NCI_MSG_HDR_SIZE; 750 buf_len = p_buf->len; 751 offset = p_buf->offset; 752#ifdef DISP_NCI 753 if (buf_len > max_len) 754 { 755 /* this command needs to be fragmented. display the complete packet first */ 756 DISP_NCI ((UINT8 *) (p_buf + 1) + p_buf->offset, p_buf->len, FALSE); 757 } 758#endif 759 ps = (UINT8 *) (p_buf + 1) + p_buf->offset; 760 memcpy (hdr, ps, NCI_MSG_HDR_SIZE); 761 while (buf_len > max_len) 762 { 763 HAL_TRACE_DEBUG2 ("buf_len (%d) > max_len (%d)", buf_len, max_len); 764 /* the NCI command is bigger than the NFCC Max Control Packet Payload Length 765 * fragment the command */ 766 767 p_buf->len = max_len; 768 ps = (UINT8 *) (p_buf + 1) + p_buf->offset; 769 /* mark the control packet as fragmented */ 770 *ps |= NCI_PBF_ST_CONT; 771 /* adjust the length of this fragment */ 772 ps += 2; 773 *ps = nci_ctrl_size; 774 775 /* add NCI packet type in front of message */ 776 nfc_hal_nci_add_nfc_pkt_type (p_buf); 777 778 /* send this fragment to transport */ 779 p = (UINT8 *) (p_buf + 1) + p_buf->offset; 780 781#ifdef DISP_NCI 782 delta = p_buf->len - max_len; 783 DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE); 784#endif 785 USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len); 786 787 /* adjust the len and offset to reflect that part of the command is already sent */ 788 buf_len -= nci_ctrl_size; 789 offset += nci_ctrl_size; 790 HAL_TRACE_DEBUG2 ("p_buf->len: %d buf_len (%d)", p_buf->len, buf_len); 791 p_buf->len = buf_len; 792 p_buf->offset = offset; 793 pd = (UINT8 *) (p_buf + 1) + p_buf->offset; 794 /* restore the NCI header */ 795 memcpy (pd, hdr, NCI_MSG_HDR_SIZE); 796 pd += 2; 797 *pd = (UINT8) (p_buf->len - NCI_MSG_HDR_SIZE); 798 } 799 800 HAL_TRACE_DEBUG1 ("p_buf->len: %d", p_buf->len); 801 802 /* add NCI packet type in front of message */ 803 nfc_hal_nci_add_nfc_pkt_type (p_buf); 804 805 /* send this fragment to transport */ 806 p = (UINT8 *) (p_buf + 1) + p_buf->offset; 807 808#ifdef DISP_NCI 809 delta = p_buf->len - buf_len; 810 DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE); 811#endif 812 USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len); 813 814 GKI_freebuf (p_buf); 815} 816 817/******************************************************************************* 818** 819** Function nfc_hal_nci_cmd_timeout_cback 820** 821** Description callback function for timeout 822** 823** Returns void 824** 825*******************************************************************************/ 826void nfc_hal_nci_cmd_timeout_cback (void *p_tle) 827{ 828 TIMER_LIST_ENT *p_tlent = (TIMER_LIST_ENT *)p_tle; 829 830 HAL_TRACE_DEBUG0 ("nfc_hal_nci_cmd_timeout_cback ()"); 831 832 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; 833 834 if (p_tlent->event == NFC_HAL_TTYPE_NCI_WAIT_RSP) 835 { 836 if (nfc_hal_cb.dev_cb.initializing_state <= NFC_HAL_INIT_STATE_W4_PATCH_INFO) 837 { 838 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 839 nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT); 840 } 841 else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE) 842 { 843 if (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_IDLE) 844 { 845 nfc_hal_prm_process_timeout (NULL); 846 } 847 else 848 { 849 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 850 nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT); 851 } 852 } 853 else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_POST_INIT_DONE) 854 { 855 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE); 856 nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT); 857 } 858 else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE) 859 { 860 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE); 861 nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT); 862 } 863 else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE) 864 { 865 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE); 866 nfc_hal_cb.p_stack_cback (HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT); 867 } 868 } 869} 870 871 872/******************************************************************************* 873** 874** Function HAL_NfcSetMaxRfDataCredits 875** 876** Description This function sets the maximum RF data credit for HAL. 877** If 0, use the value reported from NFCC. 878** 879** Returns none 880** 881*******************************************************************************/ 882void HAL_NfcSetMaxRfDataCredits (UINT8 max_credits) 883{ 884 HAL_TRACE_DEBUG2 ("HAL_NfcSetMaxRfDataCredits %d->%d", nfc_hal_cb.max_rf_credits, max_credits); 885 nfc_hal_cb.max_rf_credits = max_credits; 886} 887