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