nfa_ee_act.c revision 43ef645f118877526ae57eebe35229eb52492211
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 if (p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE) 1464 { 1465 /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */ 1466 nfa_ee_report_discover_req_evt(); 1467 } 1468 } 1469} 1470 1471/******************************************************************************* 1472** 1473** Function nfa_ee_nci_conn 1474** 1475** Description process the connection callback events 1476** 1477** Returns void 1478** 1479*******************************************************************************/ 1480void nfa_ee_nci_conn(tNFA_EE_MSG *p_data) 1481{ 1482 tNFA_EE_ECB *p_cb; 1483 tNFA_EE_NCI_CONN *p_cbk = &p_data->conn; 1484 tNFC_CONN *p_conn = p_data->conn.p_data; 1485 BT_HDR *p_pkt = NULL; 1486 tNFA_EE_CBACK_DATA evt_data = {0}; 1487 tNFA_EE_EVT event = NFA_EE_INVALID; 1488 tNFA_EE_CBACK *p_cback = NULL; 1489 1490 if (p_cbk->event == NFC_CONN_CREATE_CEVT) 1491 { 1492 p_cb = nfa_ee_find_ecb (p_cbk->p_data->conn_create.id); 1493 } 1494 else 1495 { 1496 p_cb = nfa_ee_find_ecb_by_conn_id (p_cbk->conn_id); 1497 if (p_cbk->event == NFC_DATA_CEVT) 1498 p_pkt = p_conn->data.p_data; 1499 } 1500 1501 if (p_cb) 1502 { 1503 p_cback = p_cb->p_ee_cback; 1504 evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE; 1505 switch (p_cbk->event) 1506 { 1507 case NFC_CONN_CREATE_CEVT: 1508 if (p_conn->conn_create.status == NFC_STATUS_OK) 1509 { 1510 p_cb->conn_id = p_cbk->conn_id; 1511 p_cb->conn_st = NFA_EE_CONN_ST_CONN; 1512 } 1513 else 1514 { 1515 p_cb->conn_st = NFA_EE_CONN_ST_NONE; 1516 } 1517 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1518 { 1519 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE; 1520 nfa_ee_check_restore_complete(); 1521 } 1522 else 1523 { 1524 evt_data.connect.status = p_conn->conn_create.status; 1525 evt_data.connect.ee_interface = p_cb->use_interface; 1526 event = NFA_EE_CONNECT_EVT; 1527 } 1528 break; 1529 1530 case NFC_CONN_CLOSE_CEVT: 1531 if (p_cb->conn_st != NFA_EE_CONN_ST_DISC) 1532 event = NFA_EE_DISCONNECT_EVT; 1533 p_cb->conn_st = NFA_EE_CONN_ST_NONE; 1534 p_cb->p_ee_cback = NULL; 1535 p_cb->conn_id = 0; 1536 if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING) 1537 { 1538 if (nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN) 1539 { 1540 if (nfa_ee_cb.num_ee_expecting) 1541 { 1542 nfa_ee_cb.num_ee_expecting--; 1543 } 1544 } 1545 if (nfa_ee_cb.num_ee_expecting == 0) 1546 { 1547 nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_DISCONN; 1548 nfa_ee_check_disable(); 1549 } 1550 } 1551 break; 1552 1553 case NFC_DATA_CEVT: 1554 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 1555 { 1556 /* report data event only in connected state */ 1557 if (p_cb->p_ee_cback && p_pkt) 1558 { 1559 evt_data.data.len = p_pkt->len; 1560 evt_data.data.p_buf = (UINT8 *)(p_pkt+1) + p_pkt->offset; 1561 event = NFA_EE_DATA_EVT; 1562 p_pkt = NULL; /* so this function does not free this GKI buffer */ 1563 } 1564 } 1565 break; 1566 } 1567 1568 if ((event != NFA_EE_INVALID) && (p_cback)) 1569 (*p_cback)(event, &evt_data); 1570 } 1571 if (p_pkt) 1572 GKI_freebuf (p_pkt); 1573} 1574 1575 1576/******************************************************************************* 1577** 1578** Function nfa_ee_nci_action_ntf 1579** 1580** Description process the NFCEE action callback event 1581** 1582** Returns void 1583** 1584*******************************************************************************/ 1585void nfa_ee_nci_action_ntf(tNFA_EE_MSG *p_data) 1586{ 1587 tNFC_EE_ACTION_REVT *p_cbk = p_data->act.p_data; 1588 tNFA_EE_ACTION evt_data; 1589 1590 evt_data.ee_handle = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE; 1591 evt_data.trigger = p_cbk->act_data.trigger; 1592 memcpy (&(evt_data.param), &(p_cbk->act_data.param), sizeof (tNFA_EE_ACTION_PARAM)); 1593 nfa_ee_report_event(NULL, NFA_EE_ACTION_EVT, (tNFA_EE_CBACK_DATA *)&evt_data); 1594} 1595 1596/******************************************************************************* 1597** 1598** Function nfa_ee_nci_disc_req_ntf 1599** 1600** Description process the NFCEE discover request callback event 1601** 1602** Returns void 1603** 1604*******************************************************************************/ 1605void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG *p_data) 1606{ 1607 tNFC_EE_DISCOVER_REQ_REVT *p_cbk = p_data->disc_req.p_data; 1608 tNFA_HANDLE ee_handle; 1609 tNFA_EE_ECB *p_cb = NULL; 1610 UINT8 report_ntf = 0; 1611 UINT8 xx; 1612 1613 NFA_TRACE_DEBUG2 ("nfa_ee_nci_disc_req_ntf () num_info: %d cur_ee:%d", p_cbk->num_info, nfa_ee_cb.cur_ee ); 1614 1615 for (xx = 0; xx < p_cbk->num_info; xx++) 1616 { 1617 ee_handle = NFA_HANDLE_GROUP_EE|p_cbk->info[xx].nfcee_id; 1618 1619 p_cb = nfa_ee_find_ecb (p_cbk->info[xx].nfcee_id); 1620 if (!p_cb) 1621 { 1622 NFA_TRACE_DEBUG1 ("Cannot find cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id); 1623 p_cb = nfa_ee_find_ecb (NFA_EE_INVALID); 1624 if (p_cb) 1625 { 1626 p_cb->nfcee_id = p_cbk->info[xx].nfcee_id; 1627 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER; 1628 } 1629 else 1630 { 1631 NFA_TRACE_ERROR1 ("Cannot allocate cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id); 1632 continue; 1633 } 1634 } 1635 else 1636 { 1637 report_ntf |= nfa_ee_ecb_to_mask (p_cb); 1638 } 1639 1640 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ; 1641 if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD) 1642 { 1643 if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) 1644 { 1645 p_cb->la_protocol = p_cbk->info[xx].protocol; 1646 } 1647 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) 1648 { 1649 p_cb->lb_protocol = p_cbk->info[xx].protocol; 1650 } 1651 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) 1652 { 1653 p_cb->lf_protocol = p_cbk->info[xx].protocol; 1654 } 1655 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) 1656 { 1657 p_cb->lbp_protocol = p_cbk->info[xx].protocol; 1658 } 1659 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", 1660 p_cb->nfcee_id, p_cb->ee_status, p_cb->ecb_flags, 1661 p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol); 1662 } 1663 else 1664 { 1665 if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) 1666 { 1667 p_cb->la_protocol = 0; 1668 } 1669 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) 1670 { 1671 p_cb->lb_protocol = 0; 1672 } 1673 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) 1674 { 1675 p_cb->lf_protocol = 0; 1676 } 1677 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) 1678 { 1679 p_cb->lbp_protocol = 0; 1680 } 1681 } 1682 } 1683 1684 1685 /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */ 1686 if (report_ntf) 1687 nfa_ee_report_discover_req_evt(); 1688 1689} 1690 1691/******************************************************************************* 1692** 1693** Function nfa_ee_is_active 1694** 1695** Description Check if the given NFCEE is active 1696** 1697** Returns TRUE if the given NFCEE is active 1698** 1699*******************************************************************************/ 1700BOOLEAN nfa_ee_is_active (tNFA_HANDLE nfcee_id) 1701{ 1702 BOOLEAN is_active = FALSE; 1703 int xx; 1704 tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb; 1705 1706 if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE) 1707 nfcee_id &= NFA_HANDLE_MASK; 1708 1709 /* compose output */ 1710 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1711 { 1712 if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id) 1713 { 1714 if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE) 1715 { 1716 is_active = TRUE; 1717 } 1718 break; 1719 } 1720 } 1721 return is_active; 1722} 1723 1724/******************************************************************************* 1725** 1726** Function nfa_ee_get_tech_route 1727** 1728** Description Given a power state, find the technology routing destination. 1729** The result is filled in the given p_handles 1730** in the order of A, B, F, Bprime 1731** 1732** Returns None 1733** 1734*******************************************************************************/ 1735void nfa_ee_get_tech_route (UINT8 power_state, UINT8 *p_handles) 1736{ 1737 int xx, yy; 1738 tNFA_EE_ECB *p_cb; 1739 UINT8 tech_mask_list[NFA_EE_MAX_TECH_ROUTE] = 1740 { 1741 NFA_TECHNOLOGY_MASK_A, 1742 NFA_TECHNOLOGY_MASK_B, 1743 NFA_TECHNOLOGY_MASK_F, 1744 NFA_TECHNOLOGY_MASK_B_PRIME 1745 }; 1746 1747 NFA_TRACE_DEBUG1("nfa_ee_get_tech_route(): %d", power_state); 1748 1749 for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++) 1750 { 1751 p_handles[xx] = NFC_DH_ID; 1752 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 1753 for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--) 1754 { 1755 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 1756 { 1757 switch (power_state) 1758 { 1759 case NFA_EE_PWR_STATE_ON: 1760 if (p_cb->tech_switch_on & tech_mask_list[xx]) 1761 p_handles[xx] = p_cb->nfcee_id; 1762 break; 1763 case NFA_EE_PWR_STATE_SWITCH_OFF: 1764 if (p_cb->tech_switch_off & tech_mask_list[xx]) 1765 p_handles[xx] = p_cb->nfcee_id; 1766 break; 1767 case NFA_EE_PWR_STATE_BATT_OFF: 1768 if (p_cb->tech_battery_off & tech_mask_list[xx]) 1769 p_handles[xx] = p_cb->nfcee_id; 1770 break; 1771 } 1772 } 1773 } 1774 } 1775 NFA_TRACE_DEBUG4("0x%x, 0x%x, 0x%x, 0x%x", p_handles[0], p_handles[1], p_handles[2], p_handles[3]); 1776} 1777 1778/******************************************************************************* 1779** 1780** Function nfa_ee_route_add_one_ecb 1781** 1782** Description Add the routing entries for one NFCEE/DH 1783** 1784** Returns NFA_STATUS_OK, if ok to continue 1785** 1786*******************************************************************************/ 1787tNFA_STATUS nfa_ee_route_add_one_ecb(tNFA_EE_ECB *p_cb, int max_len, BOOLEAN more, UINT8 *ps, int *p_cur_offset) 1788{ 1789 UINT8 *p, *pa; 1790 UINT16 tlv_size; 1791 UINT8 num_tlv, len; 1792 int xx; 1793 int start_offset; 1794 UINT8 power_cfg = 0; 1795 UINT8 *pp = ps + *p_cur_offset; 1796 UINT8 entry_size; 1797 UINT8 max_tlv = (UINT8)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:max_len); 1798 tNFA_STATUS status = NFA_STATUS_OK; 1799 1800 /* use the first byte of the buffer (ps) to keep the num_tlv */ 1801 num_tlv = *ps; 1802 NFA_TRACE_DEBUG5 ("nfa_ee_route_add_one_ecb max_len:%d, max_tlv:%d, cur_offset:%d, more:%d, num_tlv:%d", 1803 max_len, max_tlv, *p_cur_offset, more, num_tlv); 1804 pp = ps + 1 + *p_cur_offset; 1805 p = pp; 1806 tlv_size = (UINT8)*p_cur_offset; 1807 /* add the Technology based routing */ 1808 for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) 1809 { 1810 power_cfg = 0; 1811 if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx]) 1812 power_cfg |= NCI_ROUTE_PWR_STATE_ON; 1813 if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx]) 1814 power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF; 1815 if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx]) 1816 power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF; 1817 if (power_cfg) 1818 { 1819 *pp++ = NFC_ROUTE_TAG_TECH; 1820 *pp++ = 3; 1821 *pp++ = p_cb->nfcee_id; 1822 *pp++ = power_cfg; 1823 *pp++ = nfa_ee_tech_list[xx]; 1824 num_tlv++; 1825 if (power_cfg != NCI_ROUTE_PWR_STATE_ON) 1826 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING; 1827 } 1828 } 1829 1830 /* add the Protocol based routing */ 1831 for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) 1832 { 1833 power_cfg = 0; 1834 if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx]) 1835 power_cfg |= NCI_ROUTE_PWR_STATE_ON; 1836 if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx]) 1837 power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF; 1838 if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx]) 1839 power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF; 1840 if (power_cfg) 1841 { 1842 *pp++ = NFC_ROUTE_TAG_PROTO; 1843 *pp++ = 3; 1844 *pp++ = p_cb->nfcee_id; 1845 *pp++ = power_cfg; 1846 *pp++ = nfa_ee_proto_list[xx]; 1847 num_tlv++; 1848 if (power_cfg != NCI_ROUTE_PWR_STATE_ON) 1849 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING; 1850 } 1851 } 1852 1853 /* add the AID routing */ 1854 if (p_cb->aid_entries) 1855 { 1856 start_offset = 0; 1857 for (xx = 0; xx < p_cb->aid_entries; xx++) 1858 { 1859 /* add one AID entry */ 1860 if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) 1861 { 1862 num_tlv++; 1863 pa = &p_cb->aid_cfg[start_offset]; 1864 pa ++; /* EMV tag */ 1865 len = *pa++; /* aid_len */ 1866 *pp++ = NFC_ROUTE_TAG_AID; 1867 *pp++ = len + 2; 1868 *pp++ = p_cb->nfcee_id; 1869 *pp++ = p_cb->aid_pwr_cfg[xx]; 1870 /* copy the AID */ 1871 memcpy(pp, pa, len); 1872 pp += len; 1873 } 1874 start_offset += p_cb->aid_len[xx]; 1875 } 1876 } 1877 entry_size = (UINT8)(pp - p); 1878 tlv_size += entry_size; 1879 if (entry_size) 1880 { 1881 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 1882 } 1883 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) 1884 { 1885 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING; 1886 } 1887 NFA_TRACE_DEBUG3 ("ee_cfg_sts:0x%02x entry_size:%d, tlv_size:%d", nfa_ee_cb.ee_cfg_sts, entry_size, tlv_size); 1888 1889 if (tlv_size > max_tlv) 1890 { 1891 /* exceeds routing table size - report ERROR */ 1892 status = NFA_STATUS_BUFFER_FULL; 1893 NFA_TRACE_DEBUG2 ("nfa_ee_route_add_one_ecb: BUFFER_FULL tlv_size(%d) > max_tlv(%d)", tlv_size, max_tlv); 1894 } 1895 1896 else if (more == FALSE) 1897 { 1898 /* last entry. update routing table now */ 1899 if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) 1900 { 1901 if (tlv_size) 1902 { 1903 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING; 1904 } 1905 else 1906 { 1907 nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING; 1908 } 1909 NFA_TRACE_DEBUG2 ("nfa_ee_route_add_one_ecb: set routing num_tlv:%d tlv_size:%d", num_tlv, tlv_size); 1910 NFC_SetRouting(more, p_cb->nfcee_id, num_tlv, (UINT8)tlv_size, ps + 1); 1911 } 1912 else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) 1913 { 1914 if (tlv_size == 0) 1915 { 1916 nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING; 1917 /* indicated routing is configured to NFCC */ 1918 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING; 1919 NFC_SetRouting(more, p_cb->nfcee_id, 0, 0, ps + 1); 1920 } 1921 } 1922 } 1923 else 1924 { 1925 /* update the total num_tlv current offset */ 1926 *ps = num_tlv; 1927 *p_cur_offset += entry_size; 1928 NFA_TRACE_DEBUG2 ("nfa_ee_route_add_one_ecb: updated num_tlv:%d cur_offset:%d", *ps, *p_cur_offset); 1929 } 1930 1931 return status; 1932} 1933 1934 1935/******************************************************************************* 1936** 1937** Function nfa_ee_need_recfg 1938** 1939** Description Check if any API function to configure the routing table or 1940** VS is called since last update 1941** 1942** The algorithm for the NFCEE configuration handling is as follows: 1943** 1944** Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB 1945** Each control block uses ecb_flags to keep track if an API 1946** that changes routing/VS is invoked. 1947** This ecb_flags is cleared at the end of nfa_ee_update_rout(). 1948** 1949** nfa_ee_cb.ee_cfged is the bitmask of the control blocks with 1950** routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW. 1951** nfa_ee_cb.ee_cfged is cleared and re-calculated at the end of 1952** nfa_ee_update_rout(). 1953** 1954** nfa_ee_cb.ee_cfg_sts is used to check is any status is changed 1955** and the associated command is issued to NFCC. 1956** nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end of 1957** nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits 1958** (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in nfa_ee_vs_cback) 1959** 1960** Returns TRUE if any configuration is changed 1961** 1962*******************************************************************************/ 1963static BOOLEAN nfa_ee_need_recfg(void) 1964{ 1965 BOOLEAN needed = FALSE; 1966 UINT32 xx; 1967 tNFA_EE_ECB *p_cb; 1968 UINT8 mask; 1969 1970 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); 1971 /* if no routing/vs is configured, do not need to send the info to NFCC */ 1972 if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts) 1973 { 1974 if (nfa_ee_cb.ee_cfged & NFA_EE_CFGED_UPDATE_NOW) 1975 { 1976 needed = TRUE; 1977 } 1978 else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED) 1979 { 1980 needed = TRUE; 1981 } 1982 else 1983 { 1984 p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH]; 1985 mask = 1 << NFA_EE_CB_4_DH; 1986 for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++) 1987 { 1988 NFA_TRACE_DEBUG3("%d: ecb_flags : 0x%02x, mask: 0x%02x", xx, p_cb->ecb_flags , mask); 1989 if ((p_cb->ecb_flags ) && (nfa_ee_cb.ee_cfged & mask)) 1990 { 1991 needed = TRUE; 1992 break; 1993 } 1994 p_cb = &nfa_ee_cb.ecb[xx]; 1995 mask = 1 << xx; 1996 } 1997 } 1998 } 1999 2000 return needed; 2001} 2002 2003/******************************************************************************* 2004** 2005** Function nfa_ee_rout_timeout 2006** 2007** Description Anytime VS or routing entries are changed, 2008** a 1 second timer is started. This function is called when 2009** the timer expires or NFA_EeUpdateNow() is called. 2010** 2011** Returns void 2012** 2013*******************************************************************************/ 2014void nfa_ee_rout_timeout(tNFA_EE_MSG *p_data) 2015{ 2016 NFA_TRACE_DEBUG0("nfa_ee_rout_timeout()"); 2017 if (nfa_ee_need_recfg()) 2018 { 2019 /* discovery is not started */ 2020 nfa_ee_update_rout(); 2021 } 2022} 2023 2024/******************************************************************************* 2025** 2026** Function nfa_ee_discv_timeout 2027** 2028** Description 2029** 2030** 2031** 2032** Returns void 2033** 2034*******************************************************************************/ 2035void nfa_ee_discv_timeout(tNFA_EE_MSG *p_data) 2036{ 2037 NFC_NfceeDiscover(FALSE); 2038 if (nfa_ee_cb.p_enable_cback) 2039 (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_OFF); 2040} 2041 2042/******************************************************************************* 2043** 2044** Function nfa_ee_lmrt_to_nfcc 2045** 2046** Description This function would set the listen mode routing table 2047** to NFCC. 2048** 2049** Returns void 2050** 2051*******************************************************************************/ 2052void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG *p_data) 2053{ 2054 int xx; 2055 tNFA_EE_ECB *p_cb; 2056 UINT8 *p = NULL; 2057 BOOLEAN more = TRUE; 2058 UINT8 last_active = NFA_EE_INVALID; 2059 int max_len, len; 2060 tNFA_STATUS status = NFA_STATUS_FAILED; 2061 int cur_offset; 2062 2063 /* update routing table: DH and the activated NFCEEs */ 2064 p = (UINT8 *)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE); 2065 if (p == NULL) 2066 { 2067 NFA_TRACE_ERROR0 ("nfa_ee_lmrt_to_nfcc() no buffer to send routing info."); 2068 nfa_ee_report_event( NULL, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 2069 return; 2070 } 2071 2072 /* find the last active NFCEE. */ 2073 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 2074 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) 2075 { 2076 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 2077 { 2078 if (last_active == NFA_EE_INVALID) 2079 { 2080 last_active = p_cb->nfcee_id; 2081 NFA_TRACE_DEBUG1 ("last_active: 0x%x", last_active); 2082 } 2083 } 2084 } 2085 if (last_active == NFA_EE_INVALID) 2086 { 2087 more = FALSE; 2088 } 2089 2090 /* add the routing for DH first */ 2091 status = NFA_STATUS_OK; 2092 max_len = NFC_GetLmrtSize(); 2093 cur_offset = 0; 2094 /* use the first byte of the buffer (p) to keep the num_tlv */ 2095 *p = 0; 2096 status = nfa_ee_route_add_one_ecb(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], max_len, more, p, &cur_offset); 2097 2098 /* add only what is supported by NFCC. report overflow */ 2099 if (status == NFA_STATUS_OK) 2100 { 2101 /* add the routing for NFCEEs */ 2102 p_cb = &nfa_ee_cb.ecb[0]; 2103 for (xx = 0; (xx < nfa_ee_cb.cur_ee) && more; xx++, p_cb++) 2104 { 2105 len = 0; 2106 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 2107 { 2108 NFA_TRACE_DEBUG2 ("nfcee_id:0x%x, last_active: 0x%x", p_cb->nfcee_id, last_active); 2109 if (last_active == p_cb->nfcee_id) 2110 more = FALSE; 2111 status = nfa_ee_route_add_one_ecb(p_cb, max_len, more, p, &cur_offset); 2112 if (status != NFA_STATUS_OK) 2113 { 2114 more = FALSE; 2115 } 2116 } 2117 } 2118 } 2119 if (status != NFA_STATUS_OK) 2120 { 2121 nfa_ee_report_event( NULL, NFA_EE_ROUT_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 2122 } 2123 GKI_freebuf(p); 2124} 2125 2126/******************************************************************************* 2127** 2128** Function nfa_ee_update_rout 2129** 2130** Description This function would set the VS and listen mode routing table 2131** to NFCC. 2132** 2133** Returns void 2134** 2135*******************************************************************************/ 2136void nfa_ee_update_rout(void) 2137{ 2138 int xx; 2139 tNFA_EE_ECB *p_cb; 2140 UINT8 mask; 2141 BT_HDR msg; 2142 2143 NFA_TRACE_DEBUG1 ("nfa_ee_update_rout ee_cfg_sts:0x%02x", nfa_ee_cb.ee_cfg_sts); 2144 2145 /* use action function to send routing and VS configuration to NFCC */ 2146 msg.event = NFA_EE_CFG_TO_NFCC_EVT; 2147 nfa_ee_evt_hdlr (&msg); 2148 2149 /* all configuration is updated to NFCC, clear the status mask */ 2150 nfa_ee_cb.ee_cfg_sts &= NFA_EE_STS_PREV; 2151 nfa_ee_cb.ee_cfged = 0; 2152 p_cb = &nfa_ee_cb.ecb[0]; 2153 for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++) 2154 { 2155 p_cb->ecb_flags = 0; 2156 mask = (1 << xx); 2157 if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off | 2158 p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off | 2159 p_cb->aid_entries) 2160 { 2161 /* this entry has routing configuration. mark it configured */ 2162 nfa_ee_cb.ee_cfged |= mask; 2163 } 2164 } 2165 NFA_TRACE_DEBUG2 ("ee_cfg_sts:0x%02x ee_cfged:0x%02x", nfa_ee_cb.ee_cfg_sts, nfa_ee_cb.ee_cfged); 2166} 2167 2168 2169