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