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