nfa_ee_act.c revision 26620e3108f6a0f32f5f0a0725e28e5ae66017d6
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); 71 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 break; 937 938 case NFA_EE_EM_STATE_RESTORING: 939 p_cb = nfa_ee_find_ecb (p_ee->nfcee_id); 940 if (p_cb == NULL) 941 { 942 /* the NFCEE ID is not in the last NFCEE discovery 943 * maybe it's a new one */ 944 p_cb = nfa_ee_find_ecb (NFA_EE_INVALID); 945 if (p_cb) 946 { 947 nfa_ee_cb.cur_ee++; 948 notify_new_ee = TRUE; 949 } 950 } 951 if (nfa_ee_cb.num_ee_expecting == 0) 952 { 953 /* notify init_done callback */ 954 notify_enable_done = TRUE; 955 if (nfa_ee_restore_ntf_done()) 956 { 957 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 958 } 959 } 960 break; 961 } 962 NFA_TRACE_DEBUG1 ("nfa_ee_nci_disc_ntf cur_ee:%d", nfa_ee_cb.cur_ee); 963 964 if (p_cb) 965 { 966 p_cb->nfcee_id = p_ee->nfcee_id; 967 p_cb->ee_status = p_ee->ee_status; 968 p_cb->num_interface = p_ee->num_interface; 969 memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface); 970 p_cb->num_tlvs = p_ee->num_tlvs; 971 memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV)); 972 973 if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) 974 { 975 /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of "HCI Access" 976 * SHALL NOT contain any other additional Protocol 977 * i.e. check only first supported NFCEE interface is HCI access */ 978 /* NFA_HCI module handles restoring configurations for HCI access */ 979 if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) 980 { 981 if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0) 982 { 983 nfa_ee_restore_one_ecb (p_cb); 984 } 985 /* else wait for NFA-HCI module to restore the HCI network information before enabling the NFCEE */ 986 } 987 } 988 989 if ((nfa_ee_cb.p_ee_disc_cback == NULL) && (notify_new_ee == TRUE)) 990 { 991 if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED)) 992 { 993 /* report this NFA_EE_NEW_EE_EVT only after NFA_ENABLE_EVT is reported */ 994 p_info = &evt_data.new_ee; 995 p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id; 996 p_info->ee_status = p_cb->ee_status; 997 p_info->num_interface = p_cb->num_interface; 998 p_info->num_tlvs = p_cb->num_tlvs; 999 memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface); 1000 memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV)); 1001 nfa_ee_report_event (NULL, NFA_EE_NEW_EE_EVT, &evt_data); 1002 } 1003 } 1004 else 1005 nfa_ee_report_disc_done(notify_enable_done); 1006 } 1007} 1008 1009/******************************************************************************* 1010** 1011** Function nfa_ee_check_restore_complete 1012** 1013** Description Check if restore the NFA-EE related configuration to the 1014** state prior to low power mode is complete. 1015** If complete, notify sys. 1016** 1017** Returns void 1018** 1019*******************************************************************************/ 1020static void nfa_ee_check_restore_complete(void) 1021{ 1022 UINT32 xx; 1023 tNFA_EE_ECB *p_cb; 1024 BOOLEAN proc_complete = TRUE; 1025 1026 p_cb = nfa_ee_cb.ecb; 1027 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1028 { 1029 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1030 { 1031 /* NFA_HCI module handles restoring configurations for HCI access. 1032 * ignore the restoring status for HCI Access */ 1033 if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) 1034 { 1035 proc_complete = FALSE; 1036 break; 1037 } 1038 } 1039 } 1040 1041 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); 1042 if (proc_complete) 1043 { 1044 /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */ 1045 if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) 1046 nfa_ee_api_update_now(NULL); 1047 1048 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 1049 nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_EE); 1050 } 1051} 1052 1053/******************************************************************************* 1054** 1055** Function nfa_ee_report_discover_req_evt 1056** 1057** Description Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE 1058** 1059** Returns void 1060** 1061*******************************************************************************/ 1062static void nfa_ee_report_discover_req_evt(void) 1063{ 1064 tNFA_EE_DISCOVER_REQ evt_data; 1065 tNFA_EE_DISCOVER_INFO *p_info; 1066 UINT8 xx; 1067 tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb; 1068 1069 /* if this is restoring NFCC */ 1070 if (!nfa_dm_is_active ()) 1071 return; 1072 1073 evt_data.num_ee = 0; 1074 p_cb = nfa_ee_cb.ecb; 1075 p_info = evt_data.ee_disc_info; 1076 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1077 { 1078 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)) 1079 { 1080 continue; 1081 } 1082 p_info->la_protocol = p_cb->la_protocol; 1083 p_info->lb_protocol = p_cb->lb_protocol; 1084 p_info->lf_protocol = p_cb->lf_protocol; 1085 p_info->lbp_protocol = p_cb->lbp_protocol; 1086 evt_data.num_ee++; 1087 p_info++; 1088 1089 NFA_TRACE_DEBUG6 ("[%d] ee_handle:0x%x, listen protocol A:%d, B:%d, F:%d, BP:%d", 1090 evt_data.num_ee, p_cb->nfcee_id, 1091 p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol, p_cb->lbp_protocol); 1092 } 1093 1094 evt_data.status = NFA_STATUS_OK; 1095 nfa_ee_report_event(NULL, NFA_EE_DISCOVER_REQ_EVT, (tNFA_EE_CBACK_DATA *)&evt_data); 1096} 1097 1098/******************************************************************************* 1099** 1100** Function nfa_ee_nci_mode_set_rsp 1101** 1102** Description Process the result for NFCEE ModeSet response 1103** 1104** Returns void 1105** 1106*******************************************************************************/ 1107void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG *p_data) 1108{ 1109 tNFA_EE_ECB *p_cb; 1110 tNFA_EE_MODE_SET mode_set; 1111 tNFC_NFCEE_MODE_SET_REVT *p_rsp = p_data->mode_set_rsp.p_data; 1112 1113 NFA_TRACE_DEBUG2 ("nfa_ee_nci_mode_set_rsp() handle:0x%02x mode:%d", p_rsp->nfcee_id, p_rsp->mode); 1114 p_cb = nfa_ee_find_ecb (p_rsp->nfcee_id); 1115 if (p_cb == NULL) 1116 { 1117 NFA_TRACE_ERROR1 ("nfa_ee_nci_mode_set_rsp() Can not find cb for handle:0x%02x", p_rsp->nfcee_id); 1118 return; 1119 } 1120 1121 /* update routing table and vs on mode change */ 1122 nfa_ee_start_timer(); 1123 1124 if (p_rsp->status == NFA_STATUS_OK) 1125 { 1126 1127 if (p_rsp->mode == NFA_EE_MD_ACTIVATE) 1128 { 1129 p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE; 1130 } 1131 else 1132 { 1133 if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off | 1134 p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off | 1135 p_cb->aid_entries) 1136 { 1137 /* this NFCEE still has configuration when deactivated. clear the configuration */ 1138 nfa_ee_cb.ee_cfged &= ~nfa_ee_ecb_to_mask(p_cb); 1139 nfa_ee_cb.ee_cfg_sts|= NFA_EE_STS_CHANGED_ROUTING; 1140 NFA_TRACE_DEBUG0("deactivating/still configured. Force update"); 1141 } 1142 p_cb->tech_switch_on = p_cb->tech_switch_off = p_cb->tech_battery_off = 0; 1143 p_cb->proto_switch_on = p_cb->proto_switch_off= p_cb->proto_battery_off = 0; 1144 p_cb->aid_entries = 0; 1145 p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE; 1146 } 1147 } 1148 NFA_TRACE_DEBUG4 ("status:%d ecb_flags :0x%02x ee_cfged:0x%02x ee_status:%d", 1149 p_rsp->status, p_cb->ecb_flags , nfa_ee_cb.ee_cfged, p_cb->ee_status); 1150 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1151 { 1152 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 1153 { 1154 /* NFA_HCI module handles restoring configurations for HCI access */ 1155 if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) 1156 { 1157 NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id, p_cb->use_interface, nfa_ee_conn_cback); 1158 } 1159 } 1160 else 1161 { 1162 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE; 1163 nfa_ee_check_restore_complete(); 1164 } 1165 } 1166 else 1167 { 1168 mode_set.status = p_rsp->status; 1169 mode_set.ee_handle = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE; 1170 mode_set.ee_status = p_cb->ee_status; 1171 1172 nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT, (tNFA_EE_CBACK_DATA *)&mode_set); 1173 if (p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE) 1174 { 1175 /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */ 1176 nfa_ee_report_discover_req_evt(); 1177 } 1178 } 1179} 1180 1181/******************************************************************************* 1182** 1183** Function nfa_ee_nci_conn 1184** 1185** Description process the connection callback events 1186** 1187** Returns void 1188** 1189*******************************************************************************/ 1190void nfa_ee_nci_conn(tNFA_EE_MSG *p_data) 1191{ 1192 tNFA_EE_ECB *p_cb; 1193 tNFA_EE_NCI_CONN *p_cbk = &p_data->conn; 1194 tNFC_CONN *p_conn = p_data->conn.p_data; 1195 BT_HDR *p_pkt = NULL; 1196 tNFA_EE_CBACK_DATA evt_data = {0}; 1197 tNFA_EE_EVT event = NFA_EE_INVALID; 1198 tNFA_EE_CBACK *p_cback = NULL; 1199 1200 if (p_cbk->event == NFC_CONN_CREATE_CEVT) 1201 { 1202 p_cb = nfa_ee_find_ecb (p_cbk->p_data->conn_create.id); 1203 } 1204 else 1205 { 1206 p_cb = nfa_ee_find_ecb_by_conn_id (p_cbk->conn_id); 1207 if (p_cbk->event == NFC_DATA_CEVT) 1208 p_pkt = p_conn->data.p_data; 1209 } 1210 1211 if (p_cb) 1212 { 1213 p_cback = p_cb->p_ee_cback; 1214 evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE; 1215 switch (p_cbk->event) 1216 { 1217 case NFC_CONN_CREATE_CEVT: 1218 if (p_conn->conn_create.status == NFC_STATUS_OK) 1219 { 1220 p_cb->conn_id = p_cbk->conn_id; 1221 p_cb->conn_st = NFA_EE_CONN_ST_CONN; 1222 } 1223 else 1224 { 1225 p_cb->conn_st = NFA_EE_CONN_ST_NONE; 1226 } 1227 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1228 { 1229 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE; 1230 nfa_ee_check_restore_complete(); 1231 } 1232 else 1233 { 1234 evt_data.connect.status = p_conn->conn_create.status; 1235 evt_data.connect.ee_interface = p_cb->use_interface; 1236 event = NFA_EE_CONNECT_EVT; 1237 } 1238 break; 1239 1240 case NFC_CONN_CLOSE_CEVT: 1241 if (p_cb->conn_st != NFA_EE_CONN_ST_DISC) 1242 event = NFA_EE_DISCONNECT_EVT; 1243 p_cb->conn_st = NFA_EE_CONN_ST_NONE; 1244 p_cb->p_ee_cback = NULL; 1245 p_cb->conn_id = 0; 1246 if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING) 1247 nfa_ee_sys_disable(); 1248 break; 1249 1250 case NFC_DATA_CEVT: 1251 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 1252 { 1253 /* report data event only in connected state */ 1254 if (p_cb->p_ee_cback && p_pkt) 1255 { 1256 evt_data.data.len = p_pkt->len; 1257 evt_data.data.p_buf = (UINT8 *)(p_pkt+1) + p_pkt->offset; 1258 event = NFA_EE_DATA_EVT; 1259 p_pkt = NULL; /* so this function does not free this GKI buffer */ 1260 } 1261 } 1262 break; 1263 } 1264 1265 if ((event != NFA_EE_INVALID) && (p_cback)) 1266 (*p_cback)(event, &evt_data); 1267 } 1268 if (p_pkt) 1269 GKI_freebuf (p_pkt); 1270} 1271 1272 1273/******************************************************************************* 1274** 1275** Function nfa_ee_nci_action_ntf 1276** 1277** Description process the NFCEE action callback event 1278** 1279** Returns void 1280** 1281*******************************************************************************/ 1282void nfa_ee_nci_action_ntf(tNFA_EE_MSG *p_data) 1283{ 1284 tNFC_EE_ACTION_REVT *p_cbk = p_data->act.p_data; 1285 tNFA_EE_ACTION evt_data; 1286 1287 evt_data.ee_handle = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE; 1288 evt_data.trigger = p_cbk->act_data.trigger; 1289 memcpy (&(evt_data.param), &(p_cbk->act_data.param), sizeof (tNFA_EE_ACTION_PARAM)); 1290 nfa_ee_report_event(NULL, NFA_EE_ACTION_EVT, (tNFA_EE_CBACK_DATA *)&evt_data); 1291} 1292 1293/******************************************************************************* 1294** 1295** Function nfa_ee_nci_disc_req_ntf 1296** 1297** Description process the NFCEE discover request callback event 1298** 1299** Returns void 1300** 1301*******************************************************************************/ 1302void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG *p_data) 1303{ 1304 tNFC_EE_DISCOVER_REQ_REVT *p_cbk = p_data->disc_req.p_data; 1305 tNFA_HANDLE ee_handle; 1306 tNFA_EE_ECB *p_cb = NULL; 1307 UINT8 xx; 1308 1309 NFA_TRACE_DEBUG0 ("nfa_ee_nci_disc_req_ntf ()"); 1310 1311 for (xx = 0; xx < p_cbk->num_info; xx++) 1312 { 1313 ee_handle = NFA_HANDLE_GROUP_EE|p_cbk->info[xx].nfcee_id; 1314 1315 p_cb = nfa_ee_find_ecb (p_cbk->info[xx].nfcee_id); 1316 if (!p_cb) 1317 { 1318 NFA_TRACE_ERROR1 ("Cannot find cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id); 1319 continue; 1320 } 1321 1322 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ; 1323 if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD) 1324 { 1325 if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) 1326 { 1327 p_cb->la_protocol = p_cbk->info[xx].protocol; 1328 } 1329 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) 1330 { 1331 p_cb->lb_protocol = p_cbk->info[xx].protocol; 1332 } 1333 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) 1334 { 1335 p_cb->lf_protocol = p_cbk->info[xx].protocol; 1336 } 1337 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) 1338 { 1339 p_cb->lbp_protocol = p_cbk->info[xx].protocol; 1340 } 1341 } 1342 else 1343 { 1344 if (p_cb) 1345 { 1346 if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) 1347 { 1348 p_cb->la_protocol = 0; 1349 } 1350 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) 1351 { 1352 p_cb->lb_protocol = 0; 1353 } 1354 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) 1355 { 1356 p_cb->lf_protocol = 0; 1357 } 1358 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) 1359 { 1360 p_cb->lbp_protocol = 0; 1361 } 1362 } 1363 } 1364 } 1365 1366 /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */ 1367 nfa_ee_report_discover_req_evt(); 1368} 1369 1370/******************************************************************************* 1371** 1372** Function nfa_ee_is_active 1373** 1374** Description Check if the given NFCEE is active 1375** 1376** Returns TRUE if the given NFCEE is active 1377** 1378*******************************************************************************/ 1379BOOLEAN nfa_ee_is_active (tNFA_HANDLE nfcee_id) 1380{ 1381 BOOLEAN is_active = FALSE; 1382 int xx; 1383 tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb; 1384 1385 if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE) 1386 nfcee_id &= NFA_HANDLE_MASK; 1387 1388 /* compose output */ 1389 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1390 { 1391 if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id) 1392 { 1393 if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE) 1394 { 1395 is_active = TRUE; 1396 } 1397 break; 1398 } 1399 } 1400 return is_active; 1401} 1402 1403/******************************************************************************* 1404** 1405** Function nfa_ee_get_tech_route 1406** 1407** Description Given a power state, find the technology routing destination. 1408** The result is filled in the given p_handles 1409** in the order of A, B, F, Bprime 1410** 1411** Returns None 1412** 1413*******************************************************************************/ 1414void nfa_ee_get_tech_route (UINT8 power_state, UINT8 *p_handles) 1415{ 1416 int xx, yy; 1417 tNFA_EE_ECB *p_cb; 1418 UINT8 tech_mask_list[NFA_EE_MAX_TECH_ROUTE] = 1419 { 1420 NFA_TECHNOLOGY_MASK_A, 1421 NFA_TECHNOLOGY_MASK_B, 1422 NFA_TECHNOLOGY_MASK_F, 1423 NFA_TECHNOLOGY_MASK_B_PRIME 1424 }; 1425 1426 NFA_TRACE_DEBUG1("nfa_ee_get_tech_route(): %d", power_state); 1427 1428 for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++) 1429 { 1430 p_handles[xx] = NFC_DH_ID; 1431 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 1432 for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--) 1433 { 1434 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 1435 { 1436 switch (power_state) 1437 { 1438 case NFA_EE_PWR_STATE_ON: 1439 if (p_cb->tech_switch_on & tech_mask_list[xx]) 1440 p_handles[xx] = p_cb->nfcee_id; 1441 break; 1442 case NFA_EE_PWR_STATE_SWITCH_OFF: 1443 if (p_cb->tech_switch_off & tech_mask_list[xx]) 1444 p_handles[xx] = p_cb->nfcee_id; 1445 break; 1446 case NFA_EE_PWR_STATE_BATT_OFF: 1447 if (p_cb->tech_battery_off & tech_mask_list[xx]) 1448 p_handles[xx] = p_cb->nfcee_id; 1449 break; 1450 } 1451 } 1452 } 1453 } 1454 NFA_TRACE_DEBUG4("0x%x, 0x%x, 0x%x, 0x%x", p_handles[0], p_handles[1], p_handles[2], p_handles[3]); 1455} 1456 1457/******************************************************************************* 1458** 1459** Function nfa_ee_route_add_one_ecb 1460** 1461** Description Add the routing entries for one NFCEE/DH 1462** 1463** Returns NFA_STATUS_OK, if ok to continue 1464** 1465*******************************************************************************/ 1466tNFA_STATUS nfa_ee_route_add_one_ecb(tNFA_EE_ECB *p_cb, int max_len, BOOLEAN more, UINT8 *ps, int *p_cur_offset) 1467{ 1468 UINT8 *p, tlv_size, *pa; 1469 UINT8 num_tlv, len; 1470 int xx; 1471 int start_offset; 1472 UINT8 power_cfg = 0; 1473 UINT8 *pp = ps + *p_cur_offset; 1474 UINT8 entry_size; 1475 UINT8 max_tlv = (UINT8)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:max_len); 1476 tNFA_STATUS status = NFA_STATUS_OK; 1477 1478 /* use the first byte of the buffer (ps) to keep the num_tlv */ 1479 num_tlv = *ps; 1480 NFA_TRACE_DEBUG5 ("nfa_ee_route_add_one_ecb max_len:%d, max_tlv:%d, cur_offset:%d, more:%d, num_tlv:%d", 1481 max_len, max_tlv, *p_cur_offset, more, num_tlv); 1482 pp = ps + 1 + *p_cur_offset; 1483 p = pp; 1484 tlv_size = (UINT8)*p_cur_offset; 1485 /* add the Technology based routing */ 1486 for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) 1487 { 1488 power_cfg = 0; 1489 if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx]) 1490 power_cfg |= NCI_ROUTE_PWR_STATE_ON; 1491 if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx]) 1492 power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF; 1493 if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx]) 1494 power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF; 1495 if (power_cfg) 1496 { 1497 *pp++ = NFC_ROUTE_TAG_TECH; 1498 *pp++ = 3; 1499 *pp++ = p_cb->nfcee_id; 1500 *pp++ = power_cfg; 1501 *pp++ = nfa_ee_tech_list[xx]; 1502 num_tlv++; 1503 if (power_cfg != NCI_ROUTE_PWR_STATE_ON) 1504 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING; 1505 } 1506 } 1507 1508 /* add the Protocol based routing */ 1509 for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) 1510 { 1511 power_cfg = 0; 1512 if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx]) 1513 power_cfg |= NCI_ROUTE_PWR_STATE_ON; 1514 if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx]) 1515 power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF; 1516 if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx]) 1517 power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF; 1518 if (power_cfg) 1519 { 1520 *pp++ = NFC_ROUTE_TAG_PROTO; 1521 *pp++ = 3; 1522 *pp++ = p_cb->nfcee_id; 1523 *pp++ = power_cfg; 1524 *pp++ = nfa_ee_proto_list[xx]; 1525 num_tlv++; 1526 if (power_cfg != NCI_ROUTE_PWR_STATE_ON) 1527 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING; 1528 } 1529 } 1530 1531 /* add the AID routing */ 1532 if (p_cb->aid_entries) 1533 { 1534 start_offset = 0; 1535 for (xx = 0; xx < p_cb->aid_entries; xx++) 1536 { 1537 /* add one AID entry */ 1538 if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) 1539 { 1540 num_tlv++; 1541 pa = &p_cb->aid_cfg[start_offset]; 1542 pa ++; /* EMV tag */ 1543 len = *pa++; /* aid_len */ 1544 *pp++ = NFC_ROUTE_TAG_AID; 1545 *pp++ = len + 2; 1546 *pp++ = p_cb->nfcee_id; 1547 *pp++ = p_cb->aid_pwr_cfg[xx]; 1548 /* copy the AID */ 1549 memcpy(pp, pa, len); 1550 pp += len; 1551 } 1552 start_offset += p_cb->aid_len[xx]; 1553 } 1554 } 1555 entry_size = (UINT8)(pp - p); 1556 tlv_size += entry_size; 1557 if (entry_size) 1558 { 1559 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 1560 } 1561 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) 1562 { 1563 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING; 1564 } 1565 NFA_TRACE_DEBUG3 ("ee_cfg_sts:0x%02x entry_size:%d, tlv_size:%d", nfa_ee_cb.ee_cfg_sts, entry_size, tlv_size); 1566 1567 if (tlv_size > max_tlv) 1568 { 1569 /* exceeds routing table size - report ERROR */ 1570 status = NFA_STATUS_BUFFER_FULL; 1571 } 1572 1573 else if (more == FALSE) 1574 { 1575 /* last entry. update routing table now */ 1576 if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) 1577 { 1578 if (tlv_size) 1579 { 1580 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING; 1581 } 1582 else 1583 { 1584 nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING; 1585 } 1586 NFC_SetRouting(more, p_cb->nfcee_id, num_tlv, tlv_size, ps + 1); 1587 } 1588 else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) 1589 { 1590 if (tlv_size == 0) 1591 { 1592 nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING; 1593 /* indicated routing is configured to NFCC */ 1594 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING; 1595 NFC_SetRouting(more, p_cb->nfcee_id, 0, 0, ps + 1); 1596 } 1597 } 1598 } 1599 else 1600 { 1601 /* update the total num_tlv current offset */ 1602 *ps = num_tlv; 1603 *p_cur_offset += entry_size; 1604 } 1605 1606 return status; 1607} 1608 1609 1610/******************************************************************************* 1611** 1612** Function nfa_ee_need_recfg 1613** 1614** Description Check if any API function to configure the routing table or 1615** VS is called since last update 1616** 1617** The algorithm for the NFCEE configuration handling is as follows: 1618** 1619** Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB 1620** Each control block uses ecb_flags to keep track if an API 1621** that changes routing/VS is invoked. 1622** This ecb_flags is cleared at the end of nfa_ee_update_rout(). 1623** 1624** nfa_ee_cb.ee_cfged is the bitmask of the control blocks with 1625** routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW. 1626** nfa_ee_cb.ee_cfged is cleared and re-calculated at the end of 1627** nfa_ee_update_rout(). 1628** 1629** nfa_ee_cb.ee_cfg_sts is used to check is any status is changed 1630** and the associated command is issued to NFCC. 1631** nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end of 1632** nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits 1633** (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in nfa_ee_vs_cback) 1634** 1635** Returns TRUE if any configuration is changed 1636** 1637*******************************************************************************/ 1638static BOOLEAN nfa_ee_need_recfg(void) 1639{ 1640 BOOLEAN needed = FALSE; 1641 UINT32 xx; 1642 tNFA_EE_ECB *p_cb; 1643 UINT8 mask; 1644 1645 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); 1646 /* if no routing/vs is configured, do not need to send the info to NFCC */ 1647 if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts) 1648 { 1649 if (nfa_ee_cb.ee_cfged & NFA_EE_CFGED_UPDATE_NOW) 1650 { 1651 needed = TRUE; 1652 } 1653 else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED) 1654 { 1655 needed = TRUE; 1656 } 1657 else 1658 { 1659 p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH]; 1660 mask = 1 << NFA_EE_CB_4_DH; 1661 for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++) 1662 { 1663 NFA_TRACE_DEBUG3("%d: ecb_flags : 0x%02x, mask: 0x%02x", xx, p_cb->ecb_flags , mask); 1664 if ((p_cb->ecb_flags ) && (nfa_ee_cb.ee_cfged & mask)) 1665 { 1666 needed = TRUE; 1667 break; 1668 } 1669 p_cb = &nfa_ee_cb.ecb[xx]; 1670 mask = 1 << xx; 1671 } 1672 } 1673 } 1674 1675 return needed; 1676} 1677 1678/******************************************************************************* 1679** 1680** Function nfa_ee_rout_timeout 1681** 1682** Description Anytime VS or routing entries are changed, 1683** a 1 second timer is started. This function is called when 1684** the timer expires or NFA_EeUpdateNow() is called. 1685** 1686** Returns void 1687** 1688*******************************************************************************/ 1689void nfa_ee_rout_timeout(tNFA_EE_MSG *p_data) 1690{ 1691 NFA_TRACE_DEBUG0("nfa_ee_rout_timeout()"); 1692 if (nfa_ee_need_recfg()) 1693 { 1694 /* discovery is not started */ 1695 nfa_ee_update_rout(); 1696 } 1697} 1698 1699/******************************************************************************* 1700** 1701** Function nfa_ee_discv_timeout 1702** 1703** Description 1704** 1705** 1706** 1707** Returns void 1708** 1709*******************************************************************************/ 1710void nfa_ee_discv_timeout(tNFA_EE_MSG *p_data) 1711{ 1712 NFC_NfceeDiscover(FALSE); 1713 if (nfa_ee_cb.p_enable_cback) 1714 (*nfa_ee_cb.p_enable_cback)(TRUE); 1715} 1716 1717/******************************************************************************* 1718** 1719** Function nfa_ee_lmrt_to_nfcc 1720** 1721** Description This function would set the listen mode routing table 1722** to NFCC. 1723** 1724** Returns void 1725** 1726*******************************************************************************/ 1727void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG *p_data) 1728{ 1729 int xx; 1730 tNFA_EE_ECB *p_cb; 1731 UINT8 *p = NULL; 1732 BOOLEAN more = TRUE; 1733 UINT8 last_active = NFA_EE_INVALID; 1734 int max_len, len; 1735 tNFA_STATUS status = NFA_STATUS_FAILED; 1736 int cur_offset; 1737 1738 /* update routing table: DH and the activated NFCEEs */ 1739 p = (UINT8 *)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE); 1740 if (p == NULL) 1741 { 1742 NFA_TRACE_ERROR0 ("nfa_ee_lmrt_to_nfcc() no buffer to send routing info."); 1743 nfa_ee_report_event( NULL, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 1744 return; 1745 } 1746 1747 /* find the last active NFCEE. */ 1748 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 1749 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) 1750 { 1751 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 1752 { 1753 if (last_active == NFA_EE_INVALID) 1754 { 1755 last_active = p_cb->nfcee_id; 1756 NFA_TRACE_DEBUG1 ("last_active: 0x%x", last_active); 1757 } 1758 } 1759 } 1760 if (last_active == NFA_EE_INVALID) 1761 { 1762 more = FALSE; 1763 } 1764 1765 /* add the routing for DH first */ 1766 status = NFA_STATUS_OK; 1767 max_len = NFC_GetLmrtSize(); 1768 cur_offset = 0; 1769 /* use the first byte of the buffer (p) to keep the num_tlv */ 1770 *p = 0; 1771 status = nfa_ee_route_add_one_ecb(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], max_len, more, p, &cur_offset); 1772 1773 /* add only what is supported by NFCC. report overflow */ 1774 if (status == NFA_STATUS_OK) 1775 { 1776 /* add the routing for NFCEEs */ 1777 p_cb = &nfa_ee_cb.ecb[0]; 1778 for (xx = 0; (xx < nfa_ee_cb.cur_ee) && more; xx++, p_cb++) 1779 { 1780 len = 0; 1781 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 1782 { 1783 NFA_TRACE_DEBUG2 ("nfcee_id:0x%x, last_active: 0x%x", p_cb->nfcee_id, last_active); 1784 if (last_active == p_cb->nfcee_id) 1785 more = FALSE; 1786 status = nfa_ee_route_add_one_ecb(p_cb, max_len, more, p, &cur_offset); 1787 if (status != NFA_STATUS_OK) 1788 { 1789 more = FALSE; 1790 } 1791 } 1792 } 1793 } 1794 if (status != NFA_STATUS_OK) 1795 { 1796 nfa_ee_report_event( NULL, NFA_EE_ROUT_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 1797 } 1798 GKI_freebuf(p); 1799} 1800 1801/******************************************************************************* 1802** 1803** Function nfa_ee_update_rout 1804** 1805** Description This function would set the VS and listen mode routing table 1806** to NFCC. 1807** 1808** Returns void 1809** 1810*******************************************************************************/ 1811void nfa_ee_update_rout(void) 1812{ 1813 int xx; 1814 tNFA_EE_ECB *p_cb; 1815 UINT8 mask; 1816 BT_HDR msg; 1817 1818 NFA_TRACE_DEBUG1 ("nfa_ee_update_rout ee_cfg_sts:0x%02x", nfa_ee_cb.ee_cfg_sts); 1819 1820 /* use action function to send routing and VS configuration to NFCC */ 1821 msg.event = NFA_EE_CFG_TO_NFCC_EVT; 1822 nfa_ee_evt_hdlr (&msg); 1823 1824 /* all configuration is updated to NFCC, clear the status mask */ 1825 nfa_ee_cb.ee_cfg_sts &= NFA_EE_STS_PREV; 1826 nfa_ee_cb.ee_cfged = 0; 1827 p_cb = &nfa_ee_cb.ecb[0]; 1828 for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++) 1829 { 1830 p_cb->ecb_flags = 0; 1831 mask = (1 << xx); 1832 if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off | 1833 p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off | 1834 p_cb->aid_entries) 1835 { 1836 /* this entry has routing configuration. mark it configured */ 1837 nfa_ee_cb.ee_cfged |= mask; 1838 } 1839 } 1840 NFA_TRACE_DEBUG2 ("ee_cfg_sts:0x%02x ee_cfged:0x%02x", nfa_ee_cb.ee_cfg_sts, nfa_ee_cb.ee_cfged); 1841} 1842 1843 1844