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