nfa_ee_act.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 the action functions for NFA-EE 23 * 24 ******************************************************************************/ 25#include <string.h> 26#include "nfa_sys.h" 27#include "nfa_api.h" 28#include "nfa_dm_int.h" 29#include "nfa_sys_int.h" 30#include "nfc_api.h" 31#include "nfa_ee_int.h" 32 33 34/* the de-bounce timer: 35 * The NFA-EE API functions are called to set the routing and VS configuration. 36 * When this timer expires, the configuration is sent to NFCC all at once. 37 * This is the timeout value for the de-bounce timer. */ 38#ifndef NFA_EE_ROUT_TIMEOUT_VAL 39#define NFA_EE_ROUT_TIMEOUT_VAL 1000 40#endif 41 42#define NFA_EE_ROUT_BUF_SIZE 540 43#define NFA_EE_ROUT_ONE_TECH_CFG_LEN 4 44#define NFA_EE_ROUT_ONE_PROTO_CFG_LEN 4 45#define NFA_EE_ROUT_MAX_TLV_SIZE 0xFD 46 47 48/* the following 2 tables convert the technology mask in API and control block to the command for NFCC */ 49#define NFA_EE_NUM_TECH 3 50const UINT8 nfa_ee_tech_mask_list[NFA_EE_NUM_TECH] = 51{ 52 NFA_TECHNOLOGY_MASK_A, 53 NFA_TECHNOLOGY_MASK_B, 54 NFA_TECHNOLOGY_MASK_F 55}; 56 57const UINT8 nfa_ee_tech_list[NFA_EE_NUM_TECH] = 58{ 59 NFC_RF_TECHNOLOGY_A, 60 NFC_RF_TECHNOLOGY_B, 61 NFC_RF_TECHNOLOGY_F 62}; 63 64/* the following 2 tables convert the protocol mask in API and control block to the command for NFCC */ 65#define NFA_EE_NUM_PROTO 5 66const UINT8 nfa_ee_proto_mask_list[NFA_EE_NUM_PROTO] = 67{ 68 NFA_PROTOCOL_MASK_T1T, 69 NFA_PROTOCOL_MASK_T2T, 70 NFA_PROTOCOL_MASK_T3T, 71 NFA_PROTOCOL_MASK_ISO_DEP, 72 NFA_PROTOCOL_MASK_NFC_DEP 73}; 74 75const UINT8 nfa_ee_proto_list[NFA_EE_NUM_PROTO] = 76{ 77 NFC_PROTOCOL_T1T, 78 NFC_PROTOCOL_T2T, 79 NFC_PROTOCOL_T3T, 80 NFC_PROTOCOL_ISO_DEP, 81 NFC_PROTOCOL_NFC_DEP 82}; 83 84static void nfa_ee_report_discover_req_evt(void); 85static void nfa_ee_build_discover_req_evt (tNFA_EE_DISCOVER_REQ *p_evt_data); 86/******************************************************************************* 87** 88** Function nfa_ee_conn_cback 89** 90** Description process connection callback event from stack 91** 92** Returns void 93** 94*******************************************************************************/ 95static void nfa_ee_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) 96{ 97 BT_HDR *p_msg; 98 tNFA_EE_NCI_CONN cbk; 99 100 NFA_TRACE_DEBUG2("nfa_ee_conn_cback: conn_id: %d, event=0x%02x", conn_id, event); 101 102 cbk.hdr.event = NFA_EE_NCI_CONN_EVT; 103 if (event == NFC_DATA_CEVT) 104 { 105 /* Treat data event specially to avoid potential memory leak */ 106 cbk.hdr.event = NFA_EE_NCI_DATA_EVT; 107 } 108 cbk.conn_id = conn_id; 109 cbk.event = event; 110 cbk.p_data = p_data; 111 p_msg = (BT_HDR *)&cbk; 112 113 nfa_ee_evt_hdlr (p_msg); 114} 115 116 117/******************************************************************************* 118** 119** Function nfa_ee_find_total_aid_len 120** 121** Description Find the total len in aid_cfg from start_entry to the last 122** 123** Returns void 124** 125*******************************************************************************/ 126int nfa_ee_find_total_aid_len(tNFA_EE_ECB *p_cb, int start_entry) 127{ 128 int len = 0, xx; 129 130 if (p_cb->aid_entries > start_entry) 131 { 132 for (xx = start_entry; xx < p_cb->aid_entries; xx++) 133 { 134 len += p_cb->aid_len[xx]; 135 } 136 } 137 return len; 138} 139 140 141 142 143/******************************************************************************* 144** 145** Function nfa_ee_find_aid_offset 146** 147** Description Given the AID, find the associated tNFA_EE_ECB and the 148** offset in aid_cfg[]. *p_entry is the index. 149** 150** Returns void 151** 152*******************************************************************************/ 153tNFA_EE_ECB * nfa_ee_find_aid_offset(UINT8 aid_len, UINT8 *p_aid, int *p_offset, int *p_entry) 154{ 155 int xx, yy, aid_len_offset, offset; 156 tNFA_EE_ECB *p_ret = NULL, *p_ecb; 157 158 p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH]; 159 aid_len_offset = 1; /* skip the tag */ 160 for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_ecb++) 161 { 162 if (p_ecb->aid_entries) 163 { 164 offset = 0; 165 for (xx = 0; xx < p_ecb->aid_entries; xx++) 166 { 167 if ( (p_ecb->aid_cfg[offset + aid_len_offset] == aid_len) 168 &&(memcmp(&p_ecb->aid_cfg[offset + aid_len_offset + 1], p_aid, aid_len) == 0) ) 169 { 170 p_ret = p_ecb; 171 if (p_offset) 172 *p_offset = offset; 173 if (p_entry) 174 *p_entry = xx; 175 break; 176 } 177 offset += p_ecb->aid_len[xx]; 178 } 179 180 if (p_ret) 181 { 182 /* found the entry already */ 183 break; 184 } 185 } 186 p_ecb = &nfa_ee_cb.ecb[yy]; 187 } 188 189 return p_ret; 190} 191 192/******************************************************************************* 193** 194** Function nfa_ee_report_event 195** 196** Description report the given event to the callback 197** 198** Returns void 199** 200*******************************************************************************/ 201void nfa_ee_report_event(tNFA_EE_CBACK *p_cback, tNFA_EE_EVT event, tNFA_EE_CBACK_DATA *p_data) 202{ 203 int xx; 204 205 /* use the given callback, if not NULL */ 206 if (p_cback) 207 { 208 (*p_cback)(event, p_data); 209 return; 210 } 211 /* if the given is NULL, report to all registered ones */ 212 for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) 213 { 214 if (nfa_ee_cb.p_ee_cback[xx] != NULL) 215 { 216 (*nfa_ee_cb.p_ee_cback[xx])(event, p_data); 217 } 218 } 219} 220/******************************************************************************* 221** 222** Function nfa_ee_start_timer 223** 224** Description start the de-bounce timer 225** 226** Returns void 227** 228*******************************************************************************/ 229void nfa_ee_start_timer(void) 230{ 231 nfa_sys_start_timer(&nfa_ee_cb.timer, NFA_EE_ROUT_TIMEOUT_EVT, NFA_EE_ROUT_TIMEOUT_VAL); 232} 233 234/******************************************************************************* 235** 236** Function nfa_ee_api_discover 237** 238** Description process discover command from user 239** 240** Returns void 241** 242*******************************************************************************/ 243void nfa_ee_api_discover(tNFA_EE_MSG *p_data) 244{ 245 tNFA_EE_CBACK *p_cback = p_data->ee_discover.p_cback; 246 tNFA_EE_CBACK_DATA evt_data = {0}; 247 248 NFA_TRACE_DEBUG1 ("nfa_ee_api_discover() in_use:%d", nfa_ee_cb.discv_timer.in_use); 249 if (nfa_ee_cb.discv_timer.in_use) 250 { 251 nfa_sys_stop_timer(&nfa_ee_cb.discv_timer); 252 NFC_NfceeDiscover(FALSE); 253 } 254 if (nfa_ee_cb.p_ee_disc_cback == NULL && NFC_NfceeDiscover(TRUE) == NFC_STATUS_OK) 255 { 256 nfa_ee_cb.p_ee_disc_cback = p_cback; 257 } 258 else 259 { 260 evt_data.status = NFA_STATUS_FAILED; 261 nfa_ee_report_event (p_cback, NFA_EE_DISCOVER_EVT, &evt_data); 262 } 263} 264 265/******************************************************************************* 266** 267** Function nfa_ee_api_register 268** 269** Description process register command from user 270** 271** Returns void 272** 273*******************************************************************************/ 274void nfa_ee_api_register(tNFA_EE_MSG *p_data) 275{ 276 int xx; 277 tNFA_EE_CBACK *p_cback = p_data->ee_register.p_cback; 278 tNFA_EE_CBACK_DATA evt_data = {0}; 279 BOOLEAN found = FALSE; 280 281 evt_data.ee_register = NFA_STATUS_FAILED; 282 /* loop through all entries to see if there's a matching callback */ 283 for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) 284 { 285 if (nfa_ee_cb.p_ee_cback[xx] == p_cback) 286 { 287 evt_data.ee_register = NFA_STATUS_OK; 288 found = TRUE; 289 break; 290 } 291 } 292 293 /* If no matching callback, allocated an entry */ 294 if (!found) 295 { 296 for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) 297 { 298 if (nfa_ee_cb.p_ee_cback[xx] == NULL) 299 { 300 nfa_ee_cb.p_ee_cback[xx] = p_cback; 301 evt_data.ee_register = NFA_STATUS_OK; 302 break; 303 } 304 } 305 } 306 /* This callback is verified (not NULL) in NFA_EeRegister() */ 307 (*p_cback)(NFA_EE_REGISTER_EVT, &evt_data); 308 309 /* report NFCEE Discovery Request collected during booting up */ 310 nfa_ee_build_discover_req_evt (&evt_data.discover_req); 311 (*p_cback)(NFA_EE_DISCOVER_REQ_EVT, &evt_data); 312} 313 314/******************************************************************************* 315** 316** Function nfa_ee_api_deregister 317** 318** Description process de-register command from user 319** 320** Returns void 321** 322*******************************************************************************/ 323void nfa_ee_api_deregister(tNFA_EE_MSG *p_data) 324{ 325 tNFA_EE_CBACK *p_cback = NULL; 326 int index = p_data->deregister.index; 327 tNFA_EE_CBACK_DATA evt_data = {0}; 328 329 NFA_TRACE_DEBUG0 ("nfa_ee_api_deregister"); 330 p_cback = nfa_ee_cb.p_ee_cback[index]; 331 nfa_ee_cb.p_ee_cback[index] = NULL; 332 if (p_cback) 333 (*p_cback)(NFA_EE_DEREGISTER_EVT, &evt_data); 334} 335 336 337/******************************************************************************* 338** 339** Function nfa_ee_api_mode_set 340** 341** Description process mode set command from user 342** 343** Returns void 344** 345*******************************************************************************/ 346void nfa_ee_api_mode_set(tNFA_EE_MSG *p_data) 347{ 348 tNFA_EE_ECB *p_cb= p_data->cfg_hdr.p_cb; 349 350 NFA_TRACE_DEBUG2 ("nfa_ee_api_mode_set() handle:0x%02x mode:%d", p_cb->nfcee_id, p_data->mode_set.mode); 351 NFC_NfceeModeSet (p_cb->nfcee_id, p_data->mode_set.mode); 352 /* set the NFA_EE_STATUS_PENDING bit to indicate the status is not exactly active */ 353 if (p_data->mode_set.mode == NFC_MODE_ACTIVATE) 354 p_cb->ee_status = NFA_EE_STATUS_PENDING | NFA_EE_STATUS_ACTIVE; 355 else 356 { 357 p_cb->ee_status = NFA_EE_STATUS_INACTIVE; 358 /* DH should release the NCI connection before deactivate the NFCEE */ 359 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 360 { 361 p_cb->conn_st = NFA_EE_CONN_ST_DISC; 362 NFC_ConnClose(p_cb->conn_id); 363 } 364 } 365 /* report the NFA_EE_MODE_SET_EVT status on the response from NFCC */ 366} 367 368 369 370/******************************************************************************* 371** 372** Function nfa_ee_api_set_tech_cfg 373** 374** Description process set technology routing configuration from user 375** start a 1 second timer. When the timer expires, 376** the configuration collected in control block is sent to NFCC 377** 378** Returns void 379** 380*******************************************************************************/ 381void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG *p_data) 382{ 383 tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb; 384 tNFA_EE_CBACK_DATA evt_data = {0}; 385 386 p_cb->tech_switch_on = p_data->set_tech.technologies_switch_on; 387 p_cb->tech_switch_off = p_data->set_tech.technologies_switch_off; 388 p_cb->tech_battery_off = p_data->set_tech.technologies_battery_off; 389 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_TECH; 390 if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off) 391 { 392 /* if any technology in any power mode is configured, mark this entry as configured */ 393 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 394 } 395 nfa_ee_start_timer(); 396 nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data); 397} 398 399/******************************************************************************* 400** 401** Function nfa_ee_api_set_proto_cfg 402** 403** Description process set protocol routing configuration from user 404** start a 1 second timer. When the timer expires, 405** the configuration collected in control block is sent to NFCC 406** 407** Returns void 408** 409*******************************************************************************/ 410void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG *p_data) 411{ 412 tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb; 413 tNFA_EE_CBACK_DATA evt_data = {0}; 414 415 p_cb->proto_switch_on = p_data->set_proto.protocols_switch_on; 416 p_cb->proto_switch_off = p_data->set_proto.protocols_switch_off; 417 p_cb->proto_battery_off = p_data->set_proto.protocols_battery_off; 418 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_PROTO; 419 if (p_cb->proto_switch_on | p_cb->proto_switch_off | p_cb->proto_battery_off) 420 { 421 /* if any protocol in any power mode is configured, mark this entry as configured */ 422 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 423 } 424 nfa_ee_start_timer(); 425 nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data); 426} 427 428/******************************************************************************* 429** 430** Function nfa_ee_api_add_aid 431** 432** Description process add an AID routing configuration from user 433** start a 1 second timer. When the timer expires, 434** the configuration collected in control block is sent to NFCC 435** 436** Returns void 437** 438*******************************************************************************/ 439void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data) 440{ 441 tNFA_EE_API_ADD_AID *p_add = &p_data->add_aid; 442 tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb; 443 tNFA_EE_ECB *p_chk_cb; 444 UINT8 *p, *p_start; 445 int len, len_needed; 446 tNFA_EE_CBACK_DATA evt_data = {0}; 447 int offset = 0, entry = 0; 448 449 NFA_TRACE_DEBUG3 ("nfa_ee_api_add_aid nfcee_id:0x%x %02x%02x", 450 p_cb->nfcee_id, p_add->p_aid[0], p_add->p_aid[1]); 451 p_chk_cb = nfa_ee_find_aid_offset(p_add->aid_len, p_add->p_aid, &offset, &entry); 452 if (p_chk_cb) 453 { 454 NFA_TRACE_DEBUG0 ("nfa_ee_api_add_aid The AID entry is already in the database"); 455 if (p_chk_cb == p_cb) 456 { 457 p_cb->aid_rt_info[entry] |= NFA_EE_AE_ROUTE; 458 p_cb->aid_pwr_cfg[entry] = p_add->power_state; 459 } 460 else 461 { 462 NFA_TRACE_ERROR1 ("The AID entry is already in the database for different NFCEE ID:0x%02x", p_chk_cb->nfcee_id); 463 evt_data.status = NFA_STATUS_SEMANTIC_ERROR; 464 } 465 } 466 else 467 { 468 /* Find the total length so far */ 469 len = nfa_ee_find_total_aid_len(p_cb, 0); 470 471 /* make sure the control block has enough room to hold this entry */ 472 len_needed = p_add->aid_len + 2; /* tag/len */ 473 474 if ((len_needed + len) > NFA_EE_MAX_AID_CFG_LEN) 475 { 476 evt_data.status = NFA_STATUS_BUFFER_FULL; 477 } 478 else 479 { 480 /* add AID */ 481 p_cb->aid_pwr_cfg[p_cb->aid_entries] = p_add->power_state; 482 p_cb->aid_rt_info[p_cb->aid_entries] = NFA_EE_AE_ROUTE; 483 p = p_cb->aid_cfg + len; 484 p_start = p; 485 *p++ = NFA_EE_AID_CFG_TAG_NAME; 486 *p++ = p_add->aid_len; 487 memcpy(p, p_add->p_aid, p_add->aid_len); 488 p += p_add->aid_len; 489 490 p_cb->aid_len[p_cb->aid_entries++] = (UINT8)(p - p_start); 491 } 492 } 493 494 if (evt_data.status == NFA_STATUS_OK) 495 { 496 /* mark AID changed */ 497 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID; 498 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 499 nfa_ee_start_timer(); 500 } 501 NFA_TRACE_DEBUG2 ("status:%d ee_cfged:0x%02x ",evt_data.status, nfa_ee_cb.ee_cfged); 502 /* report the status of this operation */ 503 nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_ADD_AID_EVT, &evt_data); 504} 505 506/******************************************************************************* 507** 508** Function nfa_ee_api_remove_aid 509** 510** Description process remove an AID routing configuration from user 511** start a 1 second timer. When the timer expires, 512** the configuration collected in control block is sent to NFCC 513** 514** Returns void 515** 516*******************************************************************************/ 517void nfa_ee_api_remove_aid(tNFA_EE_MSG *p_data) 518{ 519 tNFA_EE_ECB *p_cb; 520 tNFA_EE_CBACK_DATA evt_data = {0}; 521 int offset = 0, entry = 0, len; 522 int rest_len; 523 tNFA_EE_CBACK *p_cback = NULL; 524 525 NFA_TRACE_DEBUG0 ("nfa_ee_api_remove_aid"); 526 p_cb = nfa_ee_find_aid_offset(p_data->rm_aid.aid_len, p_data->rm_aid.p_aid, &offset, &entry); 527 if (p_cb && p_cb->aid_entries) 528 { 529 NFA_TRACE_DEBUG2 ("aid_rt_info[%d]: 0x%02x", entry, p_cb->aid_rt_info[entry]); 530 /* mark routing and VS changed */ 531 if (p_cb->aid_rt_info[entry] & NFA_EE_AE_ROUTE) 532 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID; 533 534 if (p_cb->aid_rt_info[entry] & NFA_EE_AE_VS) 535 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS; 536 537 /* remove the aid */ 538 if ((entry+1) < p_cb->aid_entries) 539 { 540 /* not the last entry, move the aid entries in control block */ 541 /* Find the total len from the next entry to the last one */ 542 rest_len = nfa_ee_find_total_aid_len(p_cb, entry + 1); 543 544 len = p_cb->aid_len[entry]; 545 NFA_TRACE_DEBUG2 ("nfa_ee_api_remove_aid len:%d, rest_len:%d", len, rest_len); 546 GKI_shiftup (&p_cb->aid_cfg[offset], &p_cb->aid_cfg[offset+ len], rest_len); 547 rest_len = p_cb->aid_entries - entry; 548 GKI_shiftup (&p_cb->aid_len[entry], &p_cb->aid_len[entry + 1], rest_len); 549 GKI_shiftup (&p_cb->aid_pwr_cfg[entry], &p_cb->aid_pwr_cfg[entry + 1], rest_len); 550 GKI_shiftup (&p_cb->aid_rt_info[entry], &p_cb->aid_rt_info[entry + 1], rest_len); 551 } 552 /* else the last entry, just reduce the aid_entries by 1 */ 553 p_cb->aid_entries--; 554 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 555 nfa_ee_start_timer(); 556 /* report NFA_EE_REMOVE_AID_EVT to the callback associated the NFCEE */ 557 p_cback = p_cb->p_ee_cback; 558 } 559 else 560 { 561 NFA_TRACE_ERROR0 ("nfa_ee_api_remove_aid The AID entry is not in the database"); 562 evt_data.status = NFA_STATUS_INVALID_PARAM; 563 } 564 nfa_ee_report_event (p_cback, NFA_EE_REMOVE_AID_EVT, &evt_data); 565} 566 567/******************************************************************************* 568** 569** Function nfa_ee_api_update_now 570** 571** Description Initiates connection creation process to the given NFCEE 572** 573** Returns void 574** 575*******************************************************************************/ 576void nfa_ee_api_update_now(tNFA_EE_MSG *p_data) 577{ 578 nfa_sys_stop_timer(&nfa_ee_cb.timer); 579 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_UPDATE_NOW; 580 nfa_ee_rout_timeout(p_data); 581} 582 583/******************************************************************************* 584** 585** Function nfa_ee_api_connect 586** 587** Description Initiates connection creation process to the given NFCEE 588** 589** Returns void 590** 591*******************************************************************************/ 592void nfa_ee_api_connect(tNFA_EE_MSG *p_data) 593{ 594 tNFA_EE_ECB *p_cb = p_data->connect.p_cb; 595 int xx; 596 tNFA_EE_CBACK_DATA evt_data = {0}; 597 598 evt_data.connect.status = NFA_STATUS_FAILED; 599 if (p_cb->conn_st == NFA_EE_CONN_ST_NONE) 600 { 601 for (xx = 0; xx < p_cb->num_interface; xx++) 602 { 603 if (p_data->connect.ee_interface == p_cb->ee_interface[xx]) 604 { 605 p_cb->p_ee_cback = p_data->connect.p_cback; 606 p_cb->conn_st = NFA_EE_CONN_ST_WAIT; 607 p_cb->use_interface = p_data->connect.ee_interface; 608 evt_data.connect.status = NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_data->connect.nfcee_id, 609 p_data->connect.ee_interface, nfa_ee_conn_cback); 610 /* report the NFA_EE_CONNECT_EVT status on the response from NFCC */ 611 break; 612 } 613 } 614 } 615 616 if (evt_data.connect.status != NCI_STATUS_OK) 617 { 618 evt_data.connect.ee_handle = (tNFA_HANDLE)p_data->connect.nfcee_id | NFA_HANDLE_GROUP_EE; 619 evt_data.connect.status = NFA_STATUS_INVALID_PARAM; 620 evt_data.connect.ee_interface = p_data->connect.ee_interface; 621 nfa_ee_report_event (p_data->connect.p_cback, NFA_EE_CONNECT_EVT, &evt_data); 622 } 623} 624 625/******************************************************************************* 626** 627** Function nfa_ee_api_send_data 628** 629** Description Send the given data packet to the given NFCEE 630** 631** Returns void 632** 633*******************************************************************************/ 634void nfa_ee_api_send_data(tNFA_EE_MSG *p_data) 635{ 636 tNFA_EE_ECB *p_cb = p_data->send_data.p_cb; 637 BT_HDR *p_pkt; 638 UINT16 size = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + p_data->send_data.data_len + BT_HDR_SIZE; 639 UINT8 *p; 640 tNFA_STATUS status = NFA_STATUS_FAILED; 641 642 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 643 { 644 p_pkt = (BT_HDR *)GKI_getbuf(size); 645 if (p_pkt) 646 { 647 p_pkt->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 648 p_pkt->len = p_data->send_data.data_len; 649 p = (UINT8 *)(p_pkt+1) + p_pkt->offset; 650 memcpy(p, p_data->send_data.p_data, p_pkt->len); 651 NFC_SendData (p_cb->conn_id, p_pkt); 652 } 653 else 654 { 655 nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 656 } 657 } 658 else 659 { 660 nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_CB_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 661 } 662} 663 664/******************************************************************************* 665** 666** Function nfa_ee_api_disconnect 667** 668** Description Initiates closing of the connection to the given NFCEE 669** 670** Returns void 671** 672*******************************************************************************/ 673void nfa_ee_api_disconnect(tNFA_EE_MSG *p_data) 674{ 675 tNFA_EE_ECB *p_cb = p_data->disconnect.p_cb; 676 tNFA_EE_CBACK_DATA evt_data = {0}; 677 678 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 679 { 680 p_cb->conn_st = NFA_EE_CONN_ST_DISC; 681 NFC_ConnClose(p_cb->conn_id); 682 } 683 evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE; 684 nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCONNECT_EVT, &evt_data); 685} 686 687/******************************************************************************* 688** 689** Function nfa_ee_report_disc_done 690** 691** Description Process the callback for NFCEE discovery response 692** 693** Returns void 694** 695*******************************************************************************/ 696void nfa_ee_report_disc_done(BOOLEAN notify_enable_done) 697{ 698 tNFA_EE_CBACK *p_cback; 699 tNFA_EE_CBACK_DATA evt_data = {0}; 700 701 NFA_TRACE_DEBUG3("nfa_ee_report_disc_done() em_state:%d num_ee_expecting:%d notify_enable_done:%d", nfa_ee_cb.em_state, nfa_ee_cb.num_ee_expecting, notify_enable_done); 702 if (nfa_ee_cb.num_ee_expecting == 0) 703 { 704 if (notify_enable_done) 705 { 706 if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) 707 { 708 nfa_sys_cback_notify_enable_complete (NFA_ID_EE); 709 if (nfa_ee_cb.p_enable_cback) 710 (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON); 711 } 712 else if ((nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) && (nfa_ee_cb.ee_flags & NFA_EE_FLAG_NOTIFY_HCI) ) 713 { 714 nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_NOTIFY_HCI; 715 if (nfa_ee_cb.p_enable_cback) 716 (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON); 717 } 718 } 719 720 721 if (nfa_ee_cb.p_ee_disc_cback) 722 { 723 /* notify API callback */ 724 p_cback = nfa_ee_cb.p_ee_disc_cback; 725 nfa_ee_cb.p_ee_disc_cback = NULL; 726 evt_data.status = NFA_STATUS_OK; 727 evt_data.ee_discover.num_ee = NFA_EE_MAX_EE_SUPPORTED; 728 NFA_EeGetInfo(&evt_data.ee_discover.num_ee, evt_data.ee_discover.ee_info); 729 nfa_ee_report_event (p_cback, NFA_EE_DISCOVER_EVT, &evt_data); 730 } 731 } 732} 733 734/******************************************************************************* 735** 736** Function nfa_ee_restore_ntf_done 737** 738** Description check if any ee_status still has NFA_EE_STATUS_PENDING bit 739** 740** Returns TRUE, if all NFA_EE_STATUS_PENDING bits are removed 741** 742*******************************************************************************/ 743BOOLEAN nfa_ee_restore_ntf_done(void) 744{ 745 tNFA_EE_ECB *p_cb; 746 BOOLEAN is_done = TRUE; 747 int xx; 748 749 p_cb = nfa_ee_cb.ecb; 750 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 751 { 752 if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING)) 753 { 754 is_done = FALSE; 755 break; 756 } 757 } 758 return is_done; 759} 760 761/******************************************************************************* 762** 763** Function nfa_ee_remove_pending 764** 765** Description check if any ee_status still has NFA_EE_STATUS_RESTORING bit 766** 767** Returns TRUE, if all NFA_EE_STATUS_RESTORING bits are removed 768** 769*******************************************************************************/ 770static void nfa_ee_remove_pending(void) 771{ 772 tNFA_EE_ECB *p_cb; 773 tNFA_EE_ECB *p_cb_n, *p_cb_end; 774 int xx, num_removed = 0; 775 int first_removed = NFA_EE_MAX_EE_SUPPORTED; 776 777 p_cb = nfa_ee_cb.ecb; 778 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 779 { 780 if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_status & NFA_EE_STATUS_RESTORING)) 781 { 782 p_cb->nfcee_id = NFA_EE_INVALID; 783 num_removed ++; 784 if (first_removed == NFA_EE_MAX_EE_SUPPORTED) 785 first_removed = xx; 786 } 787 } 788 789 NFA_TRACE_DEBUG3("nfa_ee_remove_pending() cur_ee:%d, num_removed:%d first_removed:%d", nfa_ee_cb.cur_ee, num_removed, first_removed); 790 if (num_removed && (first_removed != (nfa_ee_cb.cur_ee - num_removed))) 791 { 792 /* if the removes ECB entried are not at the end, move the entries up */ 793 p_cb_end = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 794 p_cb = &nfa_ee_cb.ecb[first_removed]; 795 for (p_cb_n = p_cb + 1; p_cb_n <= p_cb_end;) 796 { 797 while ((p_cb_n->nfcee_id == NFA_EE_INVALID) && (p_cb_n <= p_cb_end)) 798 { 799 p_cb_n++; 800 } 801 802 if (p_cb_n <= p_cb_end) 803 { 804 memcpy(p_cb, p_cb_n, sizeof(tNFA_EE_ECB)); 805 p_cb_n->nfcee_id = NFA_EE_INVALID; 806 } 807 p_cb++; 808 p_cb_n++; 809 } 810 } 811 nfa_ee_cb.cur_ee -= (UINT8)num_removed; 812} 813 814 815/******************************************************************************* 816** 817** Function nfa_ee_nci_disc_rsp 818** 819** Description Process the callback for NFCEE discovery response 820** 821** Returns void 822** 823*******************************************************************************/ 824void nfa_ee_nci_disc_rsp(tNFA_EE_MSG *p_data) 825{ 826 tNFC_NFCEE_DISCOVER_REVT *p_evt = p_data->disc_rsp.p_data; 827 tNFA_EE_ECB *p_cb; 828 UINT8 xx; 829 UINT8 num_nfcee = p_evt->num_nfcee; 830 BOOLEAN notify_enable_done = FALSE; 831 832 NFA_TRACE_DEBUG3("nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d, num_nfcee:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, num_nfcee); 833 switch (nfa_ee_cb.em_state) 834 { 835 case NFA_EE_EM_STATE_INIT: 836 nfa_ee_cb.cur_ee = 0; 837 nfa_ee_cb.num_ee_expecting = 0; 838 if (num_nfcee == 0) 839 { 840 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 841 notify_enable_done = TRUE; 842 if (p_evt->status != NFC_STATUS_OK) 843 { 844 nfa_sys_stop_timer(&nfa_ee_cb.discv_timer); 845 } 846 } 847 break; 848 849 case NFA_EE_EM_STATE_INIT_DONE: 850 if (num_nfcee) 851 { 852 /* if this is initiated by api function, 853 * check if the number of NFCEE expected is more than what's currently in CB */ 854 if (num_nfcee > NFA_EE_MAX_EE_SUPPORTED) 855 num_nfcee = NFA_EE_MAX_EE_SUPPORTED; 856 if (nfa_ee_cb.cur_ee < num_nfcee) 857 { 858 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee]; 859 for (xx = nfa_ee_cb.cur_ee; xx < num_nfcee; xx++, p_cb++) 860 { 861 /* mark the new entries as a new one */ 862 p_cb->nfcee_id = NFA_EE_INVALID; 863 } 864 } 865 nfa_ee_cb.cur_ee = num_nfcee; 866 } 867 break; 868 869 case NFA_EE_EM_STATE_RESTORING: 870 if (num_nfcee == 0) 871 { 872 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 873 nfa_ee_remove_pending(); 874 nfa_ee_check_restore_complete(); 875 if (p_evt->status != NFC_STATUS_OK) 876 { 877 nfa_sys_stop_timer(&nfa_ee_cb.discv_timer); 878 } 879 } 880 break; 881 } 882 883 if (p_evt->status == NFC_STATUS_OK) 884 { 885 nfa_ee_cb.num_ee_expecting = p_evt->num_nfcee; 886 if (nfa_ee_cb.num_ee_expecting > NFA_EE_MAX_EE_SUPPORTED) 887 { 888 NFA_TRACE_ERROR2 ("NFA-EE num_ee_expecting:%d > max:%d", nfa_ee_cb.num_ee_expecting, NFA_EE_MAX_EE_SUPPORTED); 889 } 890 } 891 nfa_ee_report_disc_done(notify_enable_done); 892 NFA_TRACE_DEBUG3("nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d num_ee_expecting:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, nfa_ee_cb.num_ee_expecting); 893} 894 895/******************************************************************************* 896** 897** Function nfa_ee_nci_disc_ntf 898** 899** Description Process the callback for NFCEE discovery notification 900** 901** Returns void 902** 903*******************************************************************************/ 904void nfa_ee_nci_disc_ntf(tNFA_EE_MSG *p_data) 905{ 906 tNFC_NFCEE_INFO_REVT *p_ee = p_data->disc_ntf.p_data; 907 tNFA_EE_ECB *p_cb = NULL; 908 BOOLEAN notify_enable_done = FALSE; 909 BOOLEAN notify_new_ee = FALSE; 910 tNFA_EE_CBACK_DATA evt_data = {0}; 911 tNFA_EE_INFO *p_info; 912 tNFA_EE_EM_STATE new_em_state = NFA_EE_EM_STATE_MAX; 913 914 NFA_TRACE_DEBUG4("nfa_ee_nci_disc_ntf() em_state:%d ee_flags:0x%x cur_ee:%d num_ee_expecting:%d", nfa_ee_cb.em_state, nfa_ee_cb.ee_flags, nfa_ee_cb.cur_ee, nfa_ee_cb.num_ee_expecting); 915 if (nfa_ee_cb.num_ee_expecting) 916 { 917 nfa_ee_cb.num_ee_expecting--; 918 if ((nfa_ee_cb.num_ee_expecting == 0) && (nfa_ee_cb.p_ee_disc_cback != NULL)) 919 { 920 /* Discovery triggered by API function */ 921 NFC_NfceeDiscover(FALSE); 922 } 923 } 924 switch (nfa_ee_cb.em_state) 925 { 926 case NFA_EE_EM_STATE_INIT: 927 if (nfa_ee_cb.cur_ee < NFA_EE_MAX_EE_SUPPORTED) 928 { 929 /* the cb can collect up to NFA_EE_MAX_EE_SUPPORTED ee_info */ 930 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee++]; 931 } 932 933 if (nfa_ee_cb.num_ee_expecting == 0) 934 { 935 /* notify init_done callback */ 936 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 937 notify_enable_done = TRUE; 938 } 939 break; 940 941 case NFA_EE_EM_STATE_INIT_DONE: 942 p_cb = nfa_ee_find_ecb (p_ee->nfcee_id); 943 if (p_cb == NULL) 944 { 945 /* the NFCEE ID is not in the last NFCEE discovery 946 * maybe it's a new one */ 947 p_cb = nfa_ee_find_ecb (NFA_EE_INVALID); 948 if (p_cb) 949 { 950 nfa_ee_cb.cur_ee++; 951 notify_new_ee = TRUE; 952 } 953 } 954 else if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) 955 { 956 nfa_ee_cb.cur_ee++; 957 notify_new_ee = TRUE; 958 } 959 else 960 { 961 NFA_TRACE_DEBUG3 ("cur_ee:%d ecb_flags=0x%02x ee_status=0x%x", nfa_ee_cb.cur_ee, p_cb->ecb_flags, p_cb->ee_status); 962 } 963 break; 964 965 case NFA_EE_EM_STATE_RESTORING: 966 p_cb = nfa_ee_find_ecb (p_ee->nfcee_id); 967 if (p_cb == NULL) 968 { 969 /* the NFCEE ID is not in the last NFCEE discovery 970 * maybe it's a new one */ 971 p_cb = nfa_ee_find_ecb (NFA_EE_INVALID); 972 if (p_cb) 973 { 974 nfa_ee_cb.cur_ee++; 975 notify_new_ee = TRUE; 976 } 977 } 978 if (nfa_ee_cb.num_ee_expecting == 0) 979 { 980 /* notify init_done callback */ 981 notify_enable_done = TRUE; 982 if (nfa_ee_restore_ntf_done()) 983 { 984 new_em_state = NFA_EE_EM_STATE_INIT_DONE; 985 } 986 } 987 break; 988 } 989 NFA_TRACE_DEBUG1 ("nfa_ee_nci_disc_ntf cur_ee:%d", nfa_ee_cb.cur_ee); 990 991 if (p_cb) 992 { 993 p_cb->nfcee_id = p_ee->nfcee_id; 994 p_cb->ee_status = p_ee->ee_status; 995 p_cb->num_interface = p_ee->num_interface; 996 memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface); 997 p_cb->num_tlvs = p_ee->num_tlvs; 998 memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV)); 999 1000 if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) 1001 { 1002 /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of "HCI Access" 1003 * SHALL NOT contain any other additional Protocol 1004 * i.e. check only first supported NFCEE interface is HCI access */ 1005 /* NFA_HCI module handles restoring configurations for HCI access */ 1006 if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) 1007 { 1008 if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0) 1009 { 1010 nfa_ee_restore_one_ecb (p_cb); 1011 } 1012 /* else wait for NFA-HCI module to restore the HCI network information before enabling the NFCEE */ 1013 } 1014 } 1015 1016 if ((nfa_ee_cb.p_ee_disc_cback == NULL) && (notify_new_ee == TRUE)) 1017 { 1018 if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED)) 1019 { 1020 /* report this NFA_EE_NEW_EE_EVT only after NFA_DM_ENABLE_EVT is reported */ 1021 p_info = &evt_data.new_ee; 1022 p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id; 1023 p_info->ee_status = p_cb->ee_status; 1024 p_info->num_interface = p_cb->num_interface; 1025 p_info->num_tlvs = p_cb->num_tlvs; 1026 memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface); 1027 memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV)); 1028 nfa_ee_report_event (NULL, NFA_EE_NEW_EE_EVT, &evt_data); 1029 } 1030 } 1031 else 1032 nfa_ee_report_disc_done(notify_enable_done); 1033 1034 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) 1035 { 1036 NFA_TRACE_DEBUG0 ("NFA_EE_ECB_FLAGS_ORDER"); 1037 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_ORDER; 1038 nfa_ee_report_discover_req_evt(); 1039 } 1040 1041 } 1042 1043 if (new_em_state != NFA_EE_EM_STATE_MAX) 1044 { 1045 nfa_ee_cb.em_state = new_em_state; 1046 nfa_ee_check_restore_complete(); 1047 } 1048 1049 if ((nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) && (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) ) 1050 { 1051 if (nfa_ee_cb.discv_timer.in_use) 1052 { 1053 nfa_sys_stop_timer (&nfa_ee_cb.discv_timer); 1054 p_data->hdr.event = NFA_EE_DISCV_TIMEOUT_EVT; 1055 nfa_ee_evt_hdlr((BT_HDR *)p_data); 1056 } 1057 } 1058} 1059 1060/******************************************************************************* 1061** 1062** Function nfa_ee_check_restore_complete 1063** 1064** Description Check if restore the NFA-EE related configuration to the 1065** state prior to low power mode is complete. 1066** If complete, notify sys. 1067** 1068** Returns void 1069** 1070*******************************************************************************/ 1071void nfa_ee_check_restore_complete(void) 1072{ 1073 UINT32 xx; 1074 tNFA_EE_ECB *p_cb; 1075 BOOLEAN proc_complete = TRUE; 1076 1077 p_cb = nfa_ee_cb.ecb; 1078 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1079 { 1080 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1081 { 1082 /* NFA_HCI module handles restoring configurations for HCI access. 1083 * ignore the restoring status for HCI Access */ 1084 if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) 1085 { 1086 proc_complete = FALSE; 1087 break; 1088 } 1089 } 1090 } 1091 1092 NFA_TRACE_DEBUG2 ("nfa_ee_check_restore_complete nfa_ee_cb.ee_cfg_sts:0x%02x proc_complete:%d", nfa_ee_cb.ee_cfg_sts, proc_complete); 1093 if (proc_complete) 1094 { 1095 /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */ 1096 if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) 1097 nfa_ee_api_update_now(NULL); 1098 1099 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 1100 nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_EE); 1101 } 1102} 1103 1104/******************************************************************************* 1105** 1106** Function nfa_ee_build_discover_req_evt 1107** 1108** Description Build NFA_EE_DISCOVER_REQ_EVT for all active NFCEE 1109** 1110** Returns void 1111** 1112*******************************************************************************/ 1113static void nfa_ee_build_discover_req_evt (tNFA_EE_DISCOVER_REQ *p_evt_data) 1114{ 1115 tNFA_EE_ECB *p_cb; 1116 tNFA_EE_DISCOVER_INFO *p_info; 1117 UINT8 xx; 1118 1119 if (!p_evt_data) 1120 return; 1121 1122 p_evt_data->num_ee = 0; 1123 p_cb = nfa_ee_cb.ecb; 1124 p_info = p_evt_data->ee_disc_info; 1125 1126 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1127 { 1128 if ( (p_cb->ee_status & NFA_EE_STATUS_INT_MASK) 1129 ||(p_cb->ee_status != NFA_EE_STATUS_ACTIVE) 1130 ||((p_cb->ecb_flags & NFA_EE_ECB_FLAGS_DISC_REQ) == 0) ) 1131 { 1132 continue; 1133 } 1134 p_info->ee_handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE; 1135 p_info->la_protocol = p_cb->la_protocol; 1136 p_info->lb_protocol = p_cb->lb_protocol; 1137 p_info->lf_protocol = p_cb->lf_protocol; 1138 p_info->lbp_protocol = p_cb->lbp_protocol; 1139 p_evt_data->num_ee++; 1140 p_info++; 1141 1142 NFA_TRACE_DEBUG6 ("[%d] ee_handle:0x%x, listen protocol A:%d, B:%d, F:%d, BP:%d", 1143 p_evt_data->num_ee, p_cb->nfcee_id, 1144 p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol, p_cb->lbp_protocol); 1145 } 1146 1147 p_evt_data->status = NFA_STATUS_OK; 1148} 1149 1150/******************************************************************************* 1151** 1152** Function nfa_ee_report_discover_req_evt 1153** 1154** Description Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE 1155** 1156** Returns void 1157** 1158*******************************************************************************/ 1159static void nfa_ee_report_discover_req_evt(void) 1160{ 1161 tNFA_EE_DISCOVER_REQ evt_data; 1162 1163 if (nfa_ee_cb.p_enable_cback) 1164 (*nfa_ee_cb.p_enable_cback) (NFA_EE_DISC_STS_REQ); 1165 1166 1167 /* if this is restoring NFCC */ 1168 if (!nfa_dm_is_active ()) 1169 { 1170 NFA_TRACE_DEBUG0 ("nfa_ee_report_discover_req_evt DM is not active"); 1171 return; 1172 } 1173 1174 nfa_ee_build_discover_req_evt (&evt_data); 1175 nfa_ee_report_event(NULL, NFA_EE_DISCOVER_REQ_EVT, (tNFA_EE_CBACK_DATA *)&evt_data); 1176} 1177 1178/******************************************************************************* 1179** 1180** Function nfa_ee_nci_mode_set_rsp 1181** 1182** Description Process the result for NFCEE ModeSet response 1183** 1184** Returns void 1185** 1186*******************************************************************************/ 1187void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG *p_data) 1188{ 1189 tNFA_EE_ECB *p_cb; 1190 tNFA_EE_MODE_SET mode_set; 1191 tNFC_NFCEE_MODE_SET_REVT *p_rsp = p_data->mode_set_rsp.p_data; 1192 1193 NFA_TRACE_DEBUG2 ("nfa_ee_nci_mode_set_rsp() handle:0x%02x mode:%d", p_rsp->nfcee_id, p_rsp->mode); 1194 p_cb = nfa_ee_find_ecb (p_rsp->nfcee_id); 1195 if (p_cb == NULL) 1196 { 1197 NFA_TRACE_ERROR1 ("nfa_ee_nci_mode_set_rsp() Can not find cb for handle:0x%02x", p_rsp->nfcee_id); 1198 return; 1199 } 1200 1201 /* update routing table and vs on mode change */ 1202 nfa_ee_start_timer(); 1203 1204 if (p_rsp->status == NFA_STATUS_OK) 1205 { 1206 1207 if (p_rsp->mode == NFA_EE_MD_ACTIVATE) 1208 { 1209 p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE; 1210 } 1211 else 1212 { 1213 if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off | 1214 p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off | 1215 p_cb->aid_entries) 1216 { 1217 /* this NFCEE still has configuration when deactivated. clear the configuration */ 1218 nfa_ee_cb.ee_cfged &= ~nfa_ee_ecb_to_mask(p_cb); 1219 nfa_ee_cb.ee_cfg_sts|= NFA_EE_STS_CHANGED_ROUTING; 1220 NFA_TRACE_DEBUG0("deactivating/still configured. Force update"); 1221 } 1222 p_cb->tech_switch_on = p_cb->tech_switch_off = p_cb->tech_battery_off = 0; 1223 p_cb->proto_switch_on = p_cb->proto_switch_off= p_cb->proto_battery_off = 0; 1224 p_cb->aid_entries = 0; 1225 p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE; 1226 } 1227 } 1228 NFA_TRACE_DEBUG4 ("status:%d ecb_flags :0x%02x ee_cfged:0x%02x ee_status:%d", 1229 p_rsp->status, p_cb->ecb_flags , nfa_ee_cb.ee_cfged, p_cb->ee_status); 1230 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1231 { 1232 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 1233 { 1234 /* NFA_HCI module handles restoring configurations for HCI access */ 1235 if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) 1236 { 1237 NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id, p_cb->use_interface, nfa_ee_conn_cback); 1238 } 1239 } 1240 else 1241 { 1242 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE; 1243 nfa_ee_check_restore_complete(); 1244 } 1245 } 1246 else 1247 { 1248 mode_set.status = p_rsp->status; 1249 mode_set.ee_handle = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE; 1250 mode_set.ee_status = p_cb->ee_status; 1251 1252 nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT, (tNFA_EE_CBACK_DATA *)&mode_set); 1253 if (p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE) 1254 { 1255 /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */ 1256 nfa_ee_report_discover_req_evt(); 1257 } 1258 } 1259} 1260 1261/******************************************************************************* 1262** 1263** Function nfa_ee_nci_conn 1264** 1265** Description process the connection callback events 1266** 1267** Returns void 1268** 1269*******************************************************************************/ 1270void nfa_ee_nci_conn(tNFA_EE_MSG *p_data) 1271{ 1272 tNFA_EE_ECB *p_cb; 1273 tNFA_EE_NCI_CONN *p_cbk = &p_data->conn; 1274 tNFC_CONN *p_conn = p_data->conn.p_data; 1275 BT_HDR *p_pkt = NULL; 1276 tNFA_EE_CBACK_DATA evt_data = {0}; 1277 tNFA_EE_EVT event = NFA_EE_INVALID; 1278 tNFA_EE_CBACK *p_cback = NULL; 1279 1280 if (p_cbk->event == NFC_CONN_CREATE_CEVT) 1281 { 1282 p_cb = nfa_ee_find_ecb (p_cbk->p_data->conn_create.id); 1283 } 1284 else 1285 { 1286 p_cb = nfa_ee_find_ecb_by_conn_id (p_cbk->conn_id); 1287 if (p_cbk->event == NFC_DATA_CEVT) 1288 p_pkt = p_conn->data.p_data; 1289 } 1290 1291 if (p_cb) 1292 { 1293 p_cback = p_cb->p_ee_cback; 1294 evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE; 1295 switch (p_cbk->event) 1296 { 1297 case NFC_CONN_CREATE_CEVT: 1298 if (p_conn->conn_create.status == NFC_STATUS_OK) 1299 { 1300 p_cb->conn_id = p_cbk->conn_id; 1301 p_cb->conn_st = NFA_EE_CONN_ST_CONN; 1302 } 1303 else 1304 { 1305 p_cb->conn_st = NFA_EE_CONN_ST_NONE; 1306 } 1307 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1308 { 1309 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE; 1310 nfa_ee_check_restore_complete(); 1311 } 1312 else 1313 { 1314 evt_data.connect.status = p_conn->conn_create.status; 1315 evt_data.connect.ee_interface = p_cb->use_interface; 1316 event = NFA_EE_CONNECT_EVT; 1317 } 1318 break; 1319 1320 case NFC_CONN_CLOSE_CEVT: 1321 if (p_cb->conn_st != NFA_EE_CONN_ST_DISC) 1322 event = NFA_EE_DISCONNECT_EVT; 1323 p_cb->conn_st = NFA_EE_CONN_ST_NONE; 1324 p_cb->p_ee_cback = NULL; 1325 p_cb->conn_id = 0; 1326 if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING) 1327 { 1328 if (nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN) 1329 { 1330 if (nfa_ee_cb.num_ee_expecting) 1331 { 1332 nfa_ee_cb.num_ee_expecting--; 1333 } 1334 } 1335 if (nfa_ee_cb.num_ee_expecting == 0) 1336 { 1337 nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_DISCONN; 1338 nfa_ee_check_disable(); 1339 } 1340 } 1341 break; 1342 1343 case NFC_DATA_CEVT: 1344 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 1345 { 1346 /* report data event only in connected state */ 1347 if (p_cb->p_ee_cback && p_pkt) 1348 { 1349 evt_data.data.len = p_pkt->len; 1350 evt_data.data.p_buf = (UINT8 *)(p_pkt+1) + p_pkt->offset; 1351 event = NFA_EE_DATA_EVT; 1352 p_pkt = NULL; /* so this function does not free this GKI buffer */ 1353 } 1354 } 1355 break; 1356 } 1357 1358 if ((event != NFA_EE_INVALID) && (p_cback)) 1359 (*p_cback)(event, &evt_data); 1360 } 1361 if (p_pkt) 1362 GKI_freebuf (p_pkt); 1363} 1364 1365 1366/******************************************************************************* 1367** 1368** Function nfa_ee_nci_action_ntf 1369** 1370** Description process the NFCEE action callback event 1371** 1372** Returns void 1373** 1374*******************************************************************************/ 1375void nfa_ee_nci_action_ntf(tNFA_EE_MSG *p_data) 1376{ 1377 tNFC_EE_ACTION_REVT *p_cbk = p_data->act.p_data; 1378 tNFA_EE_ACTION evt_data; 1379 1380 evt_data.ee_handle = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE; 1381 evt_data.trigger = p_cbk->act_data.trigger; 1382 memcpy (&(evt_data.param), &(p_cbk->act_data.param), sizeof (tNFA_EE_ACTION_PARAM)); 1383 nfa_ee_report_event(NULL, NFA_EE_ACTION_EVT, (tNFA_EE_CBACK_DATA *)&evt_data); 1384} 1385 1386/******************************************************************************* 1387** 1388** Function nfa_ee_nci_disc_req_ntf 1389** 1390** Description process the NFCEE discover request callback event 1391** 1392** Returns void 1393** 1394*******************************************************************************/ 1395void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG *p_data) 1396{ 1397 tNFC_EE_DISCOVER_REQ_REVT *p_cbk = p_data->disc_req.p_data; 1398 tNFA_HANDLE ee_handle; 1399 tNFA_EE_ECB *p_cb = NULL; 1400 UINT8 report_ntf = 0; 1401 UINT8 xx; 1402 1403 NFA_TRACE_DEBUG2 ("nfa_ee_nci_disc_req_ntf () num_info: %d cur_ee:%d", p_cbk->num_info, nfa_ee_cb.cur_ee ); 1404 1405 for (xx = 0; xx < p_cbk->num_info; xx++) 1406 { 1407 ee_handle = NFA_HANDLE_GROUP_EE|p_cbk->info[xx].nfcee_id; 1408 1409 p_cb = nfa_ee_find_ecb (p_cbk->info[xx].nfcee_id); 1410 if (!p_cb) 1411 { 1412 NFA_TRACE_DEBUG1 ("Cannot find cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id); 1413 p_cb = nfa_ee_find_ecb (NFA_EE_INVALID); 1414 if (p_cb) 1415 { 1416 p_cb->nfcee_id = p_cbk->info[xx].nfcee_id; 1417 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER; 1418 } 1419 else 1420 { 1421 NFA_TRACE_ERROR1 ("Cannot allocate cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id); 1422 continue; 1423 } 1424 } 1425 else 1426 { 1427 report_ntf |= nfa_ee_ecb_to_mask (p_cb); 1428 } 1429 1430 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ; 1431 if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD) 1432 { 1433 if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) 1434 { 1435 p_cb->la_protocol = p_cbk->info[xx].protocol; 1436 } 1437 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) 1438 { 1439 p_cb->lb_protocol = p_cbk->info[xx].protocol; 1440 } 1441 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) 1442 { 1443 p_cb->lf_protocol = p_cbk->info[xx].protocol; 1444 } 1445 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) 1446 { 1447 p_cb->lbp_protocol = p_cbk->info[xx].protocol; 1448 } 1449 NFA_TRACE_DEBUG6 ("nfcee_id=0x%x ee_status=0x%x ecb_flags=0x%x la_protocol=0x%x la_protocol=0x%x la_protocol=0x%x", 1450 p_cb->nfcee_id, p_cb->ee_status, p_cb->ecb_flags, 1451 p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol); 1452 } 1453 else 1454 { 1455 if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) 1456 { 1457 p_cb->la_protocol = 0; 1458 } 1459 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) 1460 { 1461 p_cb->lb_protocol = 0; 1462 } 1463 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) 1464 { 1465 p_cb->lf_protocol = 0; 1466 } 1467 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) 1468 { 1469 p_cb->lbp_protocol = 0; 1470 } 1471 } 1472 } 1473 1474 1475 /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */ 1476 if (report_ntf) 1477 nfa_ee_report_discover_req_evt(); 1478 1479} 1480 1481/******************************************************************************* 1482** 1483** Function nfa_ee_is_active 1484** 1485** Description Check if the given NFCEE is active 1486** 1487** Returns TRUE if the given NFCEE is active 1488** 1489*******************************************************************************/ 1490BOOLEAN nfa_ee_is_active (tNFA_HANDLE nfcee_id) 1491{ 1492 BOOLEAN is_active = FALSE; 1493 int xx; 1494 tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb; 1495 1496 if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE) 1497 nfcee_id &= NFA_HANDLE_MASK; 1498 1499 /* compose output */ 1500 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1501 { 1502 if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id) 1503 { 1504 if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE) 1505 { 1506 is_active = TRUE; 1507 } 1508 break; 1509 } 1510 } 1511 return is_active; 1512} 1513 1514/******************************************************************************* 1515** 1516** Function nfa_ee_get_tech_route 1517** 1518** Description Given a power state, find the technology routing destination. 1519** The result is filled in the given p_handles 1520** in the order of A, B, F, Bprime 1521** 1522** Returns None 1523** 1524*******************************************************************************/ 1525void nfa_ee_get_tech_route (UINT8 power_state, UINT8 *p_handles) 1526{ 1527 int xx, yy; 1528 tNFA_EE_ECB *p_cb; 1529 UINT8 tech_mask_list[NFA_EE_MAX_TECH_ROUTE] = 1530 { 1531 NFA_TECHNOLOGY_MASK_A, 1532 NFA_TECHNOLOGY_MASK_B, 1533 NFA_TECHNOLOGY_MASK_F, 1534 NFA_TECHNOLOGY_MASK_B_PRIME 1535 }; 1536 1537 NFA_TRACE_DEBUG1("nfa_ee_get_tech_route(): %d", power_state); 1538 1539 for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++) 1540 { 1541 p_handles[xx] = NFC_DH_ID; 1542 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 1543 for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--) 1544 { 1545 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 1546 { 1547 switch (power_state) 1548 { 1549 case NFA_EE_PWR_STATE_ON: 1550 if (p_cb->tech_switch_on & tech_mask_list[xx]) 1551 p_handles[xx] = p_cb->nfcee_id; 1552 break; 1553 case NFA_EE_PWR_STATE_SWITCH_OFF: 1554 if (p_cb->tech_switch_off & tech_mask_list[xx]) 1555 p_handles[xx] = p_cb->nfcee_id; 1556 break; 1557 case NFA_EE_PWR_STATE_BATT_OFF: 1558 if (p_cb->tech_battery_off & tech_mask_list[xx]) 1559 p_handles[xx] = p_cb->nfcee_id; 1560 break; 1561 } 1562 } 1563 } 1564 } 1565 NFA_TRACE_DEBUG4("0x%x, 0x%x, 0x%x, 0x%x", p_handles[0], p_handles[1], p_handles[2], p_handles[3]); 1566} 1567 1568/******************************************************************************* 1569** 1570** Function nfa_ee_route_add_one_ecb 1571** 1572** Description Add the routing entries for one NFCEE/DH 1573** 1574** Returns NFA_STATUS_OK, if ok to continue 1575** 1576*******************************************************************************/ 1577tNFA_STATUS nfa_ee_route_add_one_ecb(tNFA_EE_ECB *p_cb, int max_len, BOOLEAN more, UINT8 *ps, int *p_cur_offset) 1578{ 1579 UINT8 *p, tlv_size, *pa; 1580 UINT8 num_tlv, len; 1581 int xx; 1582 int start_offset; 1583 UINT8 power_cfg = 0; 1584 UINT8 *pp = ps + *p_cur_offset; 1585 UINT8 entry_size; 1586 UINT8 max_tlv = (UINT8)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:max_len); 1587 tNFA_STATUS status = NFA_STATUS_OK; 1588 1589 /* use the first byte of the buffer (ps) to keep the num_tlv */ 1590 num_tlv = *ps; 1591 NFA_TRACE_DEBUG5 ("nfa_ee_route_add_one_ecb max_len:%d, max_tlv:%d, cur_offset:%d, more:%d, num_tlv:%d", 1592 max_len, max_tlv, *p_cur_offset, more, num_tlv); 1593 pp = ps + 1 + *p_cur_offset; 1594 p = pp; 1595 tlv_size = (UINT8)*p_cur_offset; 1596 /* add the Technology based routing */ 1597 for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) 1598 { 1599 power_cfg = 0; 1600 if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx]) 1601 power_cfg |= NCI_ROUTE_PWR_STATE_ON; 1602 if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx]) 1603 power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF; 1604 if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx]) 1605 power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF; 1606 if (power_cfg) 1607 { 1608 *pp++ = NFC_ROUTE_TAG_TECH; 1609 *pp++ = 3; 1610 *pp++ = p_cb->nfcee_id; 1611 *pp++ = power_cfg; 1612 *pp++ = nfa_ee_tech_list[xx]; 1613 num_tlv++; 1614 if (power_cfg != NCI_ROUTE_PWR_STATE_ON) 1615 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING; 1616 } 1617 } 1618 1619 /* add the Protocol based routing */ 1620 for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) 1621 { 1622 power_cfg = 0; 1623 if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx]) 1624 power_cfg |= NCI_ROUTE_PWR_STATE_ON; 1625 if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx]) 1626 power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF; 1627 if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx]) 1628 power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF; 1629 if (power_cfg) 1630 { 1631 *pp++ = NFC_ROUTE_TAG_PROTO; 1632 *pp++ = 3; 1633 *pp++ = p_cb->nfcee_id; 1634 *pp++ = power_cfg; 1635 *pp++ = nfa_ee_proto_list[xx]; 1636 num_tlv++; 1637 if (power_cfg != NCI_ROUTE_PWR_STATE_ON) 1638 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING; 1639 } 1640 } 1641 1642 /* add the AID routing */ 1643 if (p_cb->aid_entries) 1644 { 1645 start_offset = 0; 1646 for (xx = 0; xx < p_cb->aid_entries; xx++) 1647 { 1648 /* add one AID entry */ 1649 if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) 1650 { 1651 num_tlv++; 1652 pa = &p_cb->aid_cfg[start_offset]; 1653 pa ++; /* EMV tag */ 1654 len = *pa++; /* aid_len */ 1655 *pp++ = NFC_ROUTE_TAG_AID; 1656 *pp++ = len + 2; 1657 *pp++ = p_cb->nfcee_id; 1658 *pp++ = p_cb->aid_pwr_cfg[xx]; 1659 /* copy the AID */ 1660 memcpy(pp, pa, len); 1661 pp += len; 1662 } 1663 start_offset += p_cb->aid_len[xx]; 1664 } 1665 } 1666 entry_size = (UINT8)(pp - p); 1667 tlv_size += entry_size; 1668 if (entry_size) 1669 { 1670 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 1671 } 1672 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) 1673 { 1674 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING; 1675 } 1676 NFA_TRACE_DEBUG3 ("ee_cfg_sts:0x%02x entry_size:%d, tlv_size:%d", nfa_ee_cb.ee_cfg_sts, entry_size, tlv_size); 1677 1678 if (tlv_size > max_tlv) 1679 { 1680 /* exceeds routing table size - report ERROR */ 1681 status = NFA_STATUS_BUFFER_FULL; 1682 } 1683 1684 else if (more == FALSE) 1685 { 1686 /* last entry. update routing table now */ 1687 if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) 1688 { 1689 if (tlv_size) 1690 { 1691 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING; 1692 } 1693 else 1694 { 1695 nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING; 1696 } 1697 NFC_SetRouting(more, p_cb->nfcee_id, num_tlv, tlv_size, ps + 1); 1698 } 1699 else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) 1700 { 1701 if (tlv_size == 0) 1702 { 1703 nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING; 1704 /* indicated routing is configured to NFCC */ 1705 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING; 1706 NFC_SetRouting(more, p_cb->nfcee_id, 0, 0, ps + 1); 1707 } 1708 } 1709 } 1710 else 1711 { 1712 /* update the total num_tlv current offset */ 1713 *ps = num_tlv; 1714 *p_cur_offset += entry_size; 1715 } 1716 1717 return status; 1718} 1719 1720 1721/******************************************************************************* 1722** 1723** Function nfa_ee_need_recfg 1724** 1725** Description Check if any API function to configure the routing table or 1726** VS is called since last update 1727** 1728** The algorithm for the NFCEE configuration handling is as follows: 1729** 1730** Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB 1731** Each control block uses ecb_flags to keep track if an API 1732** that changes routing/VS is invoked. 1733** This ecb_flags is cleared at the end of nfa_ee_update_rout(). 1734** 1735** nfa_ee_cb.ee_cfged is the bitmask of the control blocks with 1736** routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW. 1737** nfa_ee_cb.ee_cfged is cleared and re-calculated at the end of 1738** nfa_ee_update_rout(). 1739** 1740** nfa_ee_cb.ee_cfg_sts is used to check is any status is changed 1741** and the associated command is issued to NFCC. 1742** nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end of 1743** nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits 1744** (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in nfa_ee_vs_cback) 1745** 1746** Returns TRUE if any configuration is changed 1747** 1748*******************************************************************************/ 1749static BOOLEAN nfa_ee_need_recfg(void) 1750{ 1751 BOOLEAN needed = FALSE; 1752 UINT32 xx; 1753 tNFA_EE_ECB *p_cb; 1754 UINT8 mask; 1755 1756 NFA_TRACE_DEBUG2("nfa_ee_need_recfg() ee_cfged: 0x%02x ee_cfg_sts: 0x%02x", nfa_ee_cb.ee_cfged, nfa_ee_cb.ee_cfg_sts); 1757 /* if no routing/vs is configured, do not need to send the info to NFCC */ 1758 if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts) 1759 { 1760 if (nfa_ee_cb.ee_cfged & NFA_EE_CFGED_UPDATE_NOW) 1761 { 1762 needed = TRUE; 1763 } 1764 else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED) 1765 { 1766 needed = TRUE; 1767 } 1768 else 1769 { 1770 p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH]; 1771 mask = 1 << NFA_EE_CB_4_DH; 1772 for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++) 1773 { 1774 NFA_TRACE_DEBUG3("%d: ecb_flags : 0x%02x, mask: 0x%02x", xx, p_cb->ecb_flags , mask); 1775 if ((p_cb->ecb_flags ) && (nfa_ee_cb.ee_cfged & mask)) 1776 { 1777 needed = TRUE; 1778 break; 1779 } 1780 p_cb = &nfa_ee_cb.ecb[xx]; 1781 mask = 1 << xx; 1782 } 1783 } 1784 } 1785 1786 return needed; 1787} 1788 1789/******************************************************************************* 1790** 1791** Function nfa_ee_rout_timeout 1792** 1793** Description Anytime VS or routing entries are changed, 1794** a 1 second timer is started. This function is called when 1795** the timer expires or NFA_EeUpdateNow() is called. 1796** 1797** Returns void 1798** 1799*******************************************************************************/ 1800void nfa_ee_rout_timeout(tNFA_EE_MSG *p_data) 1801{ 1802 NFA_TRACE_DEBUG0("nfa_ee_rout_timeout()"); 1803 if (nfa_ee_need_recfg()) 1804 { 1805 /* discovery is not started */ 1806 nfa_ee_update_rout(); 1807 } 1808} 1809 1810/******************************************************************************* 1811** 1812** Function nfa_ee_discv_timeout 1813** 1814** Description 1815** 1816** 1817** 1818** Returns void 1819** 1820*******************************************************************************/ 1821void nfa_ee_discv_timeout(tNFA_EE_MSG *p_data) 1822{ 1823 NFC_NfceeDiscover(FALSE); 1824 if (nfa_ee_cb.p_enable_cback) 1825 (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_OFF); 1826} 1827 1828/******************************************************************************* 1829** 1830** Function nfa_ee_lmrt_to_nfcc 1831** 1832** Description This function would set the listen mode routing table 1833** to NFCC. 1834** 1835** Returns void 1836** 1837*******************************************************************************/ 1838void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG *p_data) 1839{ 1840 int xx; 1841 tNFA_EE_ECB *p_cb; 1842 UINT8 *p = NULL; 1843 BOOLEAN more = TRUE; 1844 UINT8 last_active = NFA_EE_INVALID; 1845 int max_len, len; 1846 tNFA_STATUS status = NFA_STATUS_FAILED; 1847 int cur_offset; 1848 1849 /* update routing table: DH and the activated NFCEEs */ 1850 p = (UINT8 *)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE); 1851 if (p == NULL) 1852 { 1853 NFA_TRACE_ERROR0 ("nfa_ee_lmrt_to_nfcc() no buffer to send routing info."); 1854 nfa_ee_report_event( NULL, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 1855 return; 1856 } 1857 1858 /* find the last active NFCEE. */ 1859 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 1860 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) 1861 { 1862 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 1863 { 1864 if (last_active == NFA_EE_INVALID) 1865 { 1866 last_active = p_cb->nfcee_id; 1867 NFA_TRACE_DEBUG1 ("last_active: 0x%x", last_active); 1868 } 1869 } 1870 } 1871 if (last_active == NFA_EE_INVALID) 1872 { 1873 more = FALSE; 1874 } 1875 1876 /* add the routing for DH first */ 1877 status = NFA_STATUS_OK; 1878 max_len = NFC_GetLmrtSize(); 1879 cur_offset = 0; 1880 /* use the first byte of the buffer (p) to keep the num_tlv */ 1881 *p = 0; 1882 status = nfa_ee_route_add_one_ecb(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], max_len, more, p, &cur_offset); 1883 1884 /* add only what is supported by NFCC. report overflow */ 1885 if (status == NFA_STATUS_OK) 1886 { 1887 /* add the routing for NFCEEs */ 1888 p_cb = &nfa_ee_cb.ecb[0]; 1889 for (xx = 0; (xx < nfa_ee_cb.cur_ee) && more; xx++, p_cb++) 1890 { 1891 len = 0; 1892 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 1893 { 1894 NFA_TRACE_DEBUG2 ("nfcee_id:0x%x, last_active: 0x%x", p_cb->nfcee_id, last_active); 1895 if (last_active == p_cb->nfcee_id) 1896 more = FALSE; 1897 status = nfa_ee_route_add_one_ecb(p_cb, max_len, more, p, &cur_offset); 1898 if (status != NFA_STATUS_OK) 1899 { 1900 more = FALSE; 1901 } 1902 } 1903 } 1904 } 1905 if (status != NFA_STATUS_OK) 1906 { 1907 nfa_ee_report_event( NULL, NFA_EE_ROUT_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 1908 } 1909 GKI_freebuf(p); 1910} 1911 1912/******************************************************************************* 1913** 1914** Function nfa_ee_update_rout 1915** 1916** Description This function would set the VS and listen mode routing table 1917** to NFCC. 1918** 1919** Returns void 1920** 1921*******************************************************************************/ 1922void nfa_ee_update_rout(void) 1923{ 1924 int xx; 1925 tNFA_EE_ECB *p_cb; 1926 UINT8 mask; 1927 BT_HDR msg; 1928 1929 NFA_TRACE_DEBUG1 ("nfa_ee_update_rout ee_cfg_sts:0x%02x", nfa_ee_cb.ee_cfg_sts); 1930 1931 /* use action function to send routing and VS configuration to NFCC */ 1932 msg.event = NFA_EE_CFG_TO_NFCC_EVT; 1933 nfa_ee_evt_hdlr (&msg); 1934 1935 /* all configuration is updated to NFCC, clear the status mask */ 1936 nfa_ee_cb.ee_cfg_sts &= NFA_EE_STS_PREV; 1937 nfa_ee_cb.ee_cfged = 0; 1938 p_cb = &nfa_ee_cb.ecb[0]; 1939 for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++) 1940 { 1941 p_cb->ecb_flags = 0; 1942 mask = (1 << xx); 1943 if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off | 1944 p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off | 1945 p_cb->aid_entries) 1946 { 1947 /* this entry has routing configuration. mark it configured */ 1948 nfa_ee_cb.ee_cfged |= mask; 1949 } 1950 } 1951 NFA_TRACE_DEBUG2 ("ee_cfg_sts:0x%02x ee_cfged:0x%02x", nfa_ee_cb.ee_cfg_sts, nfa_ee_cb.ee_cfged); 1952} 1953 1954 1955