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