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