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