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