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