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 if ( (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 { 544 /* nothing to change */ 545 evt_data.status = NFA_STATUS_OK; 546 nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data); 547 return; 548 } 549 550 p_cb->tech_switch_on = p_data->set_tech.technologies_switch_on; 551 p_cb->tech_switch_off = p_data->set_tech.technologies_switch_off; 552 p_cb->tech_battery_off = p_data->set_tech.technologies_battery_off; 553 nfa_ee_update_route_size(p_cb); 554 if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) 555 { 556 NFA_TRACE_ERROR0 ("nfa_ee_api_set_tech_cfg Exceed LMRT size"); 557 evt_data.status = NFA_STATUS_BUFFER_FULL; 558 p_cb->tech_switch_on = old_tech_switch_on; 559 p_cb->tech_switch_off = old_tech_switch_off; 560 p_cb->tech_battery_off = old_tech_battery_off; 561 p_cb->size_mask = old_size_mask; 562 } 563 else 564 { 565 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_TECH; 566 if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off) 567 { 568 /* if any technology in any power mode is configured, mark this entry as configured */ 569 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 570 } 571 nfa_ee_start_timer(); 572 } 573 nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data); 574 } 575 576 /******************************************************************************* 577 ** 578 ** Function nfa_ee_api_set_proto_cfg 579 ** 580 ** Description process set protocol routing configuration from user 581 ** start a 1 second timer. When the timer expires, 582 ** the configuration collected in control block is sent to NFCC 583 ** 584 ** Returns void 585 ** 586 *******************************************************************************/ 587 void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG *p_data) 588 { 589 tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb; 590 tNFA_EE_CBACK_DATA evt_data = {0}; 591 tNFA_PROTOCOL_MASK old_proto_switch_on = p_cb->proto_switch_on; 592 tNFA_PROTOCOL_MASK old_proto_switch_off = p_cb->proto_switch_off; 593 tNFA_PROTOCOL_MASK old_proto_battery_off = p_cb->proto_battery_off; 594 UINT8 old_size_mask = p_cb->size_mask; 595 596 if ( (p_cb->proto_switch_on == p_data->set_proto.protocols_switch_on) 597 && (p_cb->proto_switch_off == p_data->set_proto.protocols_switch_off) 598 && (p_cb->proto_battery_off == p_data->set_proto.protocols_battery_off) ) 599 { 600 /* nothing to change */ 601 evt_data.status = NFA_STATUS_OK; 602 nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data); 603 return; 604 } 605 606 p_cb->proto_switch_on = p_data->set_proto.protocols_switch_on; 607 p_cb->proto_switch_off = p_data->set_proto.protocols_switch_off; 608 p_cb->proto_battery_off = p_data->set_proto.protocols_battery_off; 609 nfa_ee_update_route_size(p_cb); 610 if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) 611 { 612 NFA_TRACE_ERROR0 ("nfa_ee_api_set_proto_cfg Exceed LMRT size"); 613 evt_data.status = NFA_STATUS_BUFFER_FULL; 614 p_cb->proto_switch_on = old_proto_switch_on; 615 p_cb->proto_switch_off = old_proto_switch_off; 616 p_cb->proto_battery_off = old_proto_battery_off; 617 p_cb->size_mask = old_size_mask; 618 } 619 else 620 { 621 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_PROTO; 622 if (p_cb->proto_switch_on | p_cb->proto_switch_off | p_cb->proto_battery_off) 623 { 624 /* if any protocol in any power mode is configured, mark this entry as configured */ 625 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 626 } 627 nfa_ee_start_timer(); 628 } 629 nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data); 630 } 631 632 /******************************************************************************* 633 ** 634 ** Function nfa_ee_api_add_aid 635 ** 636 ** Description process add an AID routing configuration from user 637 ** start a 1 second timer. When the timer expires, 638 ** the configuration collected in control block is sent to NFCC 639 ** 640 ** Returns void 641 ** 642 *******************************************************************************/ 643 void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data) 644 { 645 tNFA_EE_API_ADD_AID *p_add = &p_data->add_aid; 646 tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb; 647 tNFA_EE_ECB *p_chk_cb; 648 UINT8 *p, *p_start; 649 int len, len_needed; 650 tNFA_EE_CBACK_DATA evt_data = {0}; 651 int offset = 0, entry = 0; 652 UINT16 new_size; 653 654 nfa_ee_trace_aid ("nfa_ee_api_add_aid", p_cb->nfcee_id, p_add->aid_len, p_add->p_aid); 655 p_chk_cb = nfa_ee_find_aid_offset(p_add->aid_len, p_add->p_aid, &offset, &entry); 656 if (p_chk_cb) 657 { 658 NFA_TRACE_DEBUG0 ("nfa_ee_api_add_aid The AID entry is already in the database"); 659 if (p_chk_cb == p_cb) 660 { 661 p_cb->aid_rt_info[entry] |= NFA_EE_AE_ROUTE; 662 new_size = nfa_ee_total_lmrt_size(); 663 if (new_size > NFC_GetLmrtSize()) 664 { 665 NFA_TRACE_ERROR1 ("Exceed LMRT size:%d (add ROUTE)", new_size); 666 evt_data.status = NFA_STATUS_BUFFER_FULL; 667 p_cb->aid_rt_info[entry] &= ~NFA_EE_AE_ROUTE; 668 } 669 else 670 { 671 p_cb->aid_pwr_cfg[entry] = p_add->power_state; 672 } 673 } 674 else 675 { 676 NFA_TRACE_ERROR1 ("The AID entry is already in the database for different NFCEE ID:0x%02x", p_chk_cb->nfcee_id); 677 evt_data.status = NFA_STATUS_SEMANTIC_ERROR; 678 } 679 } 680 else 681 { 682 /* Find the total length so far */ 683 len = nfa_ee_find_total_aid_len(p_cb, 0); 684 685 /* make sure the control block has enough room to hold this entry */ 686 len_needed = p_add->aid_len + 2; /* tag/len */ 687 688 if ((len_needed + len) > NFA_EE_MAX_AID_CFG_LEN) 689 { 690 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); 691 evt_data.status = NFA_STATUS_BUFFER_FULL; 692 } 693 else if (p_cb->aid_entries < NFA_EE_MAX_AID_ENTRIES) 694 { 695 new_size = nfa_ee_total_lmrt_size() + 4 + p_add->aid_len; /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */ 696 if (new_size > NFC_GetLmrtSize()) 697 { 698 NFA_TRACE_ERROR1 ("Exceed LMRT size:%d", new_size); 699 evt_data.status = NFA_STATUS_BUFFER_FULL; 700 } 701 else 702 { 703 /* add AID */ 704 p_cb->aid_pwr_cfg[p_cb->aid_entries] = p_add->power_state; 705 p_cb->aid_rt_info[p_cb->aid_entries] = NFA_EE_AE_ROUTE; 706 p = p_cb->aid_cfg + len; 707 p_start = p; 708 *p++ = NFA_EE_AID_CFG_TAG_NAME; 709 *p++ = p_add->aid_len; 710 memcpy(p, p_add->p_aid, p_add->aid_len); 711 p += p_add->aid_len; 712 713 p_cb->aid_len[p_cb->aid_entries++] = (UINT8)(p - p_start); 714 } 715 } 716 else 717 { 718 NFA_TRACE_ERROR1 ("Exceed NFA_EE_MAX_AID_ENTRIES:%d", NFA_EE_MAX_AID_ENTRIES); 719 evt_data.status = NFA_STATUS_BUFFER_FULL; 720 } 721 } 722 723 if (evt_data.status == NFA_STATUS_OK) 724 { 725 /* mark AID changed */ 726 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID; 727 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 728 nfa_ee_update_route_aid_size(p_cb); 729 nfa_ee_start_timer(); 730 } 731 NFA_TRACE_DEBUG2 ("status:%d ee_cfged:0x%02x ",evt_data.status, nfa_ee_cb.ee_cfged); 732 /* report the status of this operation */ 733 nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_ADD_AID_EVT, &evt_data); 734 } 735 736 /******************************************************************************* 737 ** 738 ** Function nfa_ee_api_remove_aid 739 ** 740 ** Description process remove an AID routing configuration from user 741 ** start a 1 second timer. When the timer expires, 742 ** the configuration collected in control block is sent to NFCC 743 ** 744 ** Returns void 745 ** 746 *******************************************************************************/ 747 void nfa_ee_api_remove_aid(tNFA_EE_MSG *p_data) 748 { 749 tNFA_EE_ECB *p_cb; 750 tNFA_EE_CBACK_DATA evt_data = {0}; 751 int offset = 0, entry = 0, len; 752 int rest_len; 753 tNFA_EE_CBACK *p_cback = NULL; 754 755 nfa_ee_trace_aid ("nfa_ee_api_remove_aid", 0, p_data->rm_aid.aid_len, p_data->rm_aid.p_aid); 756 p_cb = nfa_ee_find_aid_offset(p_data->rm_aid.aid_len, p_data->rm_aid.p_aid, &offset, &entry); 757 if (p_cb && p_cb->aid_entries) 758 { 759 NFA_TRACE_DEBUG2 ("aid_rt_info[%d]: 0x%02x", entry, p_cb->aid_rt_info[entry]); 760 /* mark routing and VS changed */ 761 if (p_cb->aid_rt_info[entry] & NFA_EE_AE_ROUTE) 762 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID; 763 764 if (p_cb->aid_rt_info[entry] & NFA_EE_AE_VS) 765 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS; 766 767 /* remove the aid */ 768 if ((entry+1) < p_cb->aid_entries) 769 { 770 /* not the last entry, move the aid entries in control block */ 771 /* Find the total len from the next entry to the last one */ 772 rest_len = nfa_ee_find_total_aid_len(p_cb, entry + 1); 773 774 len = p_cb->aid_len[entry]; 775 NFA_TRACE_DEBUG2 ("nfa_ee_api_remove_aid len:%d, rest_len:%d", len, rest_len); 776 GKI_shiftup (&p_cb->aid_cfg[offset], &p_cb->aid_cfg[offset+ len], rest_len); 777 rest_len = p_cb->aid_entries - entry; 778 GKI_shiftup (&p_cb->aid_len[entry], &p_cb->aid_len[entry + 1], rest_len); 779 GKI_shiftup (&p_cb->aid_pwr_cfg[entry], &p_cb->aid_pwr_cfg[entry + 1], rest_len); 780 GKI_shiftup (&p_cb->aid_rt_info[entry], &p_cb->aid_rt_info[entry + 1], rest_len); 781 } 782 /* else the last entry, just reduce the aid_entries by 1 */ 783 p_cb->aid_entries--; 784 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 785 nfa_ee_update_route_aid_size(p_cb); 786 nfa_ee_start_timer(); 787 /* report NFA_EE_REMOVE_AID_EVT to the callback associated the NFCEE */ 788 p_cback = p_cb->p_ee_cback; 789 } 790 else 791 { 792 NFA_TRACE_ERROR0 ("nfa_ee_api_remove_aid The AID entry is not in the database"); 793 evt_data.status = NFA_STATUS_INVALID_PARAM; 794 } 795 nfa_ee_report_event (p_cback, NFA_EE_REMOVE_AID_EVT, &evt_data); 796 } 797 798 /******************************************************************************* 799 ** 800 ** Function nfa_ee_api_lmrt_size 801 ** 802 ** Description Reports the remaining size in the Listen Mode Routing Table 803 ** 804 ** Returns void 805 ** 806 *******************************************************************************/ 807 void nfa_ee_api_lmrt_size(tNFA_EE_MSG *p_data) 808 { 809 tNFA_EE_CBACK_DATA evt_data = {0}; 810 UINT16 total_size = NFC_GetLmrtSize(); 811 812 evt_data.size = total_size - nfa_ee_total_lmrt_size(); 813 NFA_TRACE_DEBUG2 ("nfa_ee_api_lmrt_size total size:%d remaining size:%d", total_size, evt_data.size); 814 815 nfa_ee_report_event (NULL, NFA_EE_REMAINING_SIZE_EVT, &evt_data); 816 } 817 818 /******************************************************************************* 819 ** 820 ** Function nfa_ee_api_update_now 821 ** 822 ** Description Initiates connection creation process to the given NFCEE 823 ** 824 ** Returns void 825 ** 826 *******************************************************************************/ 827 void nfa_ee_api_update_now(tNFA_EE_MSG *p_data) 828 { 829 tNFA_EE_CBACK_DATA evt_data; 830 831 if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE_ALL) 832 { 833 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); 834 evt_data.status = NFA_STATUS_SEMANTIC_ERROR; 835 nfa_ee_report_event (NULL, NFA_EE_UPDATED_EVT, &evt_data); 836 return; 837 } 838 nfa_sys_stop_timer(&nfa_ee_cb.timer); 839 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_UPDATE_NOW; 840 nfa_ee_rout_timeout(p_data); 841 } 842 843 /******************************************************************************* 844 ** 845 ** Function nfa_ee_api_connect 846 ** 847 ** Description Initiates connection creation process to the given NFCEE 848 ** 849 ** Returns void 850 ** 851 *******************************************************************************/ 852 void nfa_ee_api_connect(tNFA_EE_MSG *p_data) 853 { 854 tNFA_EE_ECB *p_cb = p_data->connect.p_cb; 855 int xx; 856 tNFA_EE_CBACK_DATA evt_data = {0}; 857 858 evt_data.connect.status = NFA_STATUS_FAILED; 859 if (p_cb->conn_st == NFA_EE_CONN_ST_NONE) 860 { 861 for (xx = 0; xx < p_cb->num_interface; xx++) 862 { 863 if (p_data->connect.ee_interface == p_cb->ee_interface[xx]) 864 { 865 p_cb->p_ee_cback = p_data->connect.p_cback; 866 p_cb->conn_st = NFA_EE_CONN_ST_WAIT; 867 p_cb->use_interface = p_data->connect.ee_interface; 868 evt_data.connect.status = NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_data->connect.nfcee_id, 869 p_data->connect.ee_interface, nfa_ee_conn_cback); 870 /* report the NFA_EE_CONNECT_EVT status on the response from NFCC */ 871 break; 872 } 873 } 874 } 875 876 if (evt_data.connect.status != NCI_STATUS_OK) 877 { 878 evt_data.connect.ee_handle = (tNFA_HANDLE)p_data->connect.nfcee_id | NFA_HANDLE_GROUP_EE; 879 evt_data.connect.status = NFA_STATUS_INVALID_PARAM; 880 evt_data.connect.ee_interface = p_data->connect.ee_interface; 881 nfa_ee_report_event (p_data->connect.p_cback, NFA_EE_CONNECT_EVT, &evt_data); 882 } 883 } 884 885 /******************************************************************************* 886 ** 887 ** Function nfa_ee_api_send_data 888 ** 889 ** Description Send the given data packet to the given NFCEE 890 ** 891 ** Returns void 892 ** 893 *******************************************************************************/ 894 void nfa_ee_api_send_data(tNFA_EE_MSG *p_data) 895 { 896 tNFA_EE_ECB *p_cb = p_data->send_data.p_cb; 897 BT_HDR *p_pkt; 898 UINT16 size = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + p_data->send_data.data_len + BT_HDR_SIZE; 899 UINT8 *p; 900 tNFA_STATUS status = NFA_STATUS_FAILED; 901 902 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 903 { 904 p_pkt = (BT_HDR *)GKI_getbuf(size); 905 if (p_pkt) 906 { 907 p_pkt->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 908 p_pkt->len = p_data->send_data.data_len; 909 p = (UINT8 *)(p_pkt+1) + p_pkt->offset; 910 memcpy(p, p_data->send_data.p_data, p_pkt->len); 911 NFC_SendData (p_cb->conn_id, p_pkt); 912 } 913 else 914 { 915 nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 916 } 917 } 918 else 919 { 920 nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_CB_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 921 } 922 } 923 924 /******************************************************************************* 925 ** 926 ** Function nfa_ee_api_disconnect 927 ** 928 ** Description Initiates closing of the connection to the given NFCEE 929 ** 930 ** Returns void 931 ** 932 *******************************************************************************/ 933 void nfa_ee_api_disconnect(tNFA_EE_MSG *p_data) 934 { 935 tNFA_EE_ECB *p_cb = p_data->disconnect.p_cb; 936 tNFA_EE_CBACK_DATA evt_data = {0}; 937 938 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 939 { 940 p_cb->conn_st = NFA_EE_CONN_ST_DISC; 941 NFC_ConnClose(p_cb->conn_id); 942 } 943 evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE; 944 nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCONNECT_EVT, &evt_data); 945 } 946 947 /******************************************************************************* 948 ** 949 ** Function nfa_ee_report_disc_done 950 ** 951 ** Description Process the callback for NFCEE discovery response 952 ** 953 ** Returns void 954 ** 955 *******************************************************************************/ 956 void nfa_ee_report_disc_done(BOOLEAN notify_enable_done) 957 { 958 tNFA_EE_CBACK *p_cback; 959 tNFA_EE_CBACK_DATA evt_data = {0}; 960 961 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); 962 if (nfa_ee_cb.num_ee_expecting == 0) 963 { 964 if (notify_enable_done) 965 { 966 if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) 967 { 968 nfa_sys_cback_notify_enable_complete (NFA_ID_EE); 969 if (nfa_ee_cb.p_enable_cback) 970 (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON); 971 } 972 else if ((nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) && (nfa_ee_cb.ee_flags & NFA_EE_FLAG_NOTIFY_HCI) ) 973 { 974 nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_NOTIFY_HCI; 975 if (nfa_ee_cb.p_enable_cback) 976 (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON); 977 } 978 } 979 980 981 if (nfa_ee_cb.p_ee_disc_cback) 982 { 983 /* notify API callback */ 984 p_cback = nfa_ee_cb.p_ee_disc_cback; 985 nfa_ee_cb.p_ee_disc_cback = NULL; 986 evt_data.status = NFA_STATUS_OK; 987 evt_data.ee_discover.num_ee = NFA_EE_MAX_EE_SUPPORTED; 988 NFA_EeGetInfo(&evt_data.ee_discover.num_ee, evt_data.ee_discover.ee_info); 989 nfa_ee_report_event (p_cback, NFA_EE_DISCOVER_EVT, &evt_data); 990 } 991 } 992 } 993 994 /******************************************************************************* 995 ** 996 ** Function nfa_ee_restore_ntf_done 997 ** 998 ** Description check if any ee_status still has NFA_EE_STATUS_PENDING bit 999 ** 1000 ** Returns TRUE, if all NFA_EE_STATUS_PENDING bits are removed 1001 ** 1002 *******************************************************************************/ 1003 BOOLEAN nfa_ee_restore_ntf_done(void) 1004 { 1005 tNFA_EE_ECB *p_cb; 1006 BOOLEAN is_done = TRUE; 1007 int xx; 1008 1009 p_cb = nfa_ee_cb.ecb; 1010 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1011 { 1012 if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING)) 1013 { 1014 is_done = FALSE; 1015 break; 1016 } 1017 } 1018 return is_done; 1019 } 1020 1021 /******************************************************************************* 1022 ** 1023 ** Function nfa_ee_remove_pending 1024 ** 1025 ** Description check if any ee_status still has NFA_EE_STATUS_RESTORING bit 1026 ** 1027 ** Returns TRUE, if all NFA_EE_STATUS_RESTORING bits are removed 1028 ** 1029 *******************************************************************************/ 1030 static void nfa_ee_remove_pending(void) 1031 { 1032 tNFA_EE_ECB *p_cb; 1033 tNFA_EE_ECB *p_cb_n, *p_cb_end; 1034 int xx, num_removed = 0; 1035 int first_removed = NFA_EE_MAX_EE_SUPPORTED; 1036 1037 p_cb = nfa_ee_cb.ecb; 1038 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1039 { 1040 if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_status & NFA_EE_STATUS_RESTORING)) 1041 { 1042 p_cb->nfcee_id = NFA_EE_INVALID; 1043 num_removed ++; 1044 if (first_removed == NFA_EE_MAX_EE_SUPPORTED) 1045 first_removed = xx; 1046 } 1047 } 1048 1049 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); 1050 if (num_removed && (first_removed != (nfa_ee_cb.cur_ee - num_removed))) 1051 { 1052 /* if the removes ECB entried are not at the end, move the entries up */ 1053 p_cb_end = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 1054 p_cb = &nfa_ee_cb.ecb[first_removed]; 1055 for (p_cb_n = p_cb + 1; p_cb_n <= p_cb_end;) 1056 { 1057 while ((p_cb_n->nfcee_id == NFA_EE_INVALID) && (p_cb_n <= p_cb_end)) 1058 { 1059 p_cb_n++; 1060 } 1061 1062 if (p_cb_n <= p_cb_end) 1063 { 1064 memcpy(p_cb, p_cb_n, sizeof(tNFA_EE_ECB)); 1065 p_cb_n->nfcee_id = NFA_EE_INVALID; 1066 } 1067 p_cb++; 1068 p_cb_n++; 1069 } 1070 } 1071 nfa_ee_cb.cur_ee -= (UINT8)num_removed; 1072 } 1073 1074 1075 /******************************************************************************* 1076 ** 1077 ** Function nfa_ee_nci_disc_rsp 1078 ** 1079 ** Description Process the callback for NFCEE discovery response 1080 ** 1081 ** Returns void 1082 ** 1083 *******************************************************************************/ 1084 void nfa_ee_nci_disc_rsp(tNFA_EE_MSG *p_data) 1085 { 1086 tNFC_NFCEE_DISCOVER_REVT *p_evt = p_data->disc_rsp.p_data; 1087 tNFA_EE_ECB *p_cb; 1088 UINT8 xx; 1089 UINT8 num_nfcee = p_evt->num_nfcee; 1090 BOOLEAN notify_enable_done = FALSE; 1091 1092 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); 1093 switch (nfa_ee_cb.em_state) 1094 { 1095 case NFA_EE_EM_STATE_INIT: 1096 nfa_ee_cb.cur_ee = 0; 1097 nfa_ee_cb.num_ee_expecting = 0; 1098 if (num_nfcee == 0) 1099 { 1100 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 1101 notify_enable_done = TRUE; 1102 if (p_evt->status != NFC_STATUS_OK) 1103 { 1104 nfa_sys_stop_timer(&nfa_ee_cb.discv_timer); 1105 } 1106 } 1107 break; 1108 1109 case NFA_EE_EM_STATE_INIT_DONE: 1110 if (num_nfcee) 1111 { 1112 /* if this is initiated by api function, 1113 * check if the number of NFCEE expected is more than what's currently in CB */ 1114 if (num_nfcee > NFA_EE_MAX_EE_SUPPORTED) 1115 num_nfcee = NFA_EE_MAX_EE_SUPPORTED; 1116 if (nfa_ee_cb.cur_ee < num_nfcee) 1117 { 1118 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee]; 1119 for (xx = nfa_ee_cb.cur_ee; xx < num_nfcee; xx++, p_cb++) 1120 { 1121 /* mark the new entries as a new one */ 1122 p_cb->nfcee_id = NFA_EE_INVALID; 1123 } 1124 } 1125 nfa_ee_cb.cur_ee = num_nfcee; 1126 } 1127 break; 1128 1129 case NFA_EE_EM_STATE_RESTORING: 1130 if (num_nfcee == 0) 1131 { 1132 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 1133 nfa_ee_remove_pending(); 1134 nfa_ee_check_restore_complete(); 1135 if (p_evt->status != NFC_STATUS_OK) 1136 { 1137 nfa_sys_stop_timer(&nfa_ee_cb.discv_timer); 1138 } 1139 } 1140 break; 1141 } 1142 1143 if (p_evt->status == NFC_STATUS_OK) 1144 { 1145 nfa_ee_cb.num_ee_expecting = p_evt->num_nfcee; 1146 if (nfa_ee_cb.num_ee_expecting > NFA_EE_MAX_EE_SUPPORTED) 1147 { 1148 NFA_TRACE_ERROR2 ("NFA-EE num_ee_expecting:%d > max:%d", nfa_ee_cb.num_ee_expecting, NFA_EE_MAX_EE_SUPPORTED); 1149 } 1150 } 1151 nfa_ee_report_disc_done(notify_enable_done); 1152 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); 1153 } 1154 1155 /******************************************************************************* 1156 ** 1157 ** Function nfa_ee_nci_disc_ntf 1158 ** 1159 ** Description Process the callback for NFCEE discovery notification 1160 ** 1161 ** Returns void 1162 ** 1163 *******************************************************************************/ 1164 void nfa_ee_nci_disc_ntf(tNFA_EE_MSG *p_data) 1165 { 1166 tNFC_NFCEE_INFO_REVT *p_ee = p_data->disc_ntf.p_data; 1167 tNFA_EE_ECB *p_cb = NULL; 1168 BOOLEAN notify_enable_done = FALSE; 1169 BOOLEAN notify_new_ee = FALSE; 1170 tNFA_EE_CBACK_DATA evt_data = {0}; 1171 tNFA_EE_INFO *p_info; 1172 tNFA_EE_EM_STATE new_em_state = NFA_EE_EM_STATE_MAX; 1173 1174 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); 1175 if (nfa_ee_cb.num_ee_expecting) 1176 { 1177 nfa_ee_cb.num_ee_expecting--; 1178 if ((nfa_ee_cb.num_ee_expecting == 0) && (nfa_ee_cb.p_ee_disc_cback != NULL)) 1179 { 1180 /* Discovery triggered by API function */ 1181 NFC_NfceeDiscover(FALSE); 1182 } 1183 } 1184 switch (nfa_ee_cb.em_state) 1185 { 1186 case NFA_EE_EM_STATE_INIT: 1187 if (nfa_ee_cb.cur_ee < NFA_EE_MAX_EE_SUPPORTED) 1188 { 1189 /* the cb can collect up to NFA_EE_MAX_EE_SUPPORTED ee_info */ 1190 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee++]; 1191 } 1192 1193 if (nfa_ee_cb.num_ee_expecting == 0) 1194 { 1195 /* notify init_done callback */ 1196 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 1197 notify_enable_done = TRUE; 1198 } 1199 break; 1200 1201 case NFA_EE_EM_STATE_INIT_DONE: 1202 p_cb = nfa_ee_find_ecb (p_ee->nfcee_id); 1203 if (p_cb == NULL) 1204 { 1205 /* the NFCEE ID is not in the last NFCEE discovery 1206 * maybe it's a new one */ 1207 p_cb = nfa_ee_find_ecb (NFA_EE_INVALID); 1208 if (p_cb) 1209 { 1210 nfa_ee_cb.cur_ee++; 1211 notify_new_ee = TRUE; 1212 } 1213 } 1214 else if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) 1215 { 1216 nfa_ee_cb.cur_ee++; 1217 notify_new_ee = TRUE; 1218 } 1219 else 1220 { 1221 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); 1222 } 1223 break; 1224 1225 case NFA_EE_EM_STATE_RESTORING: 1226 p_cb = nfa_ee_find_ecb (p_ee->nfcee_id); 1227 if (p_cb == NULL) 1228 { 1229 /* the NFCEE ID is not in the last NFCEE discovery 1230 * maybe it's a new one */ 1231 p_cb = nfa_ee_find_ecb (NFA_EE_INVALID); 1232 if (p_cb) 1233 { 1234 nfa_ee_cb.cur_ee++; 1235 notify_new_ee = TRUE; 1236 } 1237 } 1238 if (nfa_ee_cb.num_ee_expecting == 0) 1239 { 1240 /* notify init_done callback */ 1241 notify_enable_done = TRUE; 1242 if (nfa_ee_restore_ntf_done()) 1243 { 1244 new_em_state = NFA_EE_EM_STATE_INIT_DONE; 1245 } 1246 } 1247 break; 1248 } 1249 NFA_TRACE_DEBUG1 ("nfa_ee_nci_disc_ntf cur_ee:%d", nfa_ee_cb.cur_ee); 1250 1251 if (p_cb) 1252 { 1253 p_cb->nfcee_id = p_ee->nfcee_id; 1254 p_cb->ee_status = p_ee->ee_status; 1255 p_cb->num_interface = p_ee->num_interface; 1256 memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface); 1257 p_cb->num_tlvs = p_ee->num_tlvs; 1258 memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV)); 1259 1260 if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) 1261 { 1262 /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of "HCI Access" 1263 * SHALL NOT contain any other additional Protocol 1264 * i.e. check only first supported NFCEE interface is HCI access */ 1265 /* NFA_HCI module handles restoring configurations for HCI access */ 1266 if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) 1267 { 1268 if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0) 1269 { 1270 nfa_ee_restore_one_ecb (p_cb); 1271 } 1272 /* else wait for NFA-HCI module to restore the HCI network information before enabling the NFCEE */ 1273 } 1274 } 1275 1276 if ((nfa_ee_cb.p_ee_disc_cback == NULL) && (notify_new_ee == TRUE)) 1277 { 1278 if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED)) 1279 { 1280 /* report this NFA_EE_NEW_EE_EVT only after NFA_DM_ENABLE_EVT is reported */ 1281 p_info = &evt_data.new_ee; 1282 p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id; 1283 p_info->ee_status = p_cb->ee_status; 1284 p_info->num_interface = p_cb->num_interface; 1285 p_info->num_tlvs = p_cb->num_tlvs; 1286 memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface); 1287 memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV)); 1288 nfa_ee_report_event (NULL, NFA_EE_NEW_EE_EVT, &evt_data); 1289 } 1290 } 1291 else 1292 nfa_ee_report_disc_done(notify_enable_done); 1293 1294 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) 1295 { 1296 NFA_TRACE_DEBUG0 ("NFA_EE_ECB_FLAGS_ORDER"); 1297 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_ORDER; 1298 nfa_ee_report_discover_req_evt(); 1299 } 1300 1301 } 1302 1303 if (new_em_state != NFA_EE_EM_STATE_MAX) 1304 { 1305 nfa_ee_cb.em_state = new_em_state; 1306 nfa_ee_check_restore_complete(); 1307 } 1308 1309 if ((nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) && (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) ) 1310 { 1311 if (nfa_ee_cb.discv_timer.in_use) 1312 { 1313 nfa_sys_stop_timer (&nfa_ee_cb.discv_timer); 1314 p_data->hdr.event = NFA_EE_DISCV_TIMEOUT_EVT; 1315 nfa_ee_evt_hdlr((BT_HDR *)p_data); 1316 } 1317 } 1318 } 1319 1320 /******************************************************************************* 1321 ** 1322 ** Function nfa_ee_check_restore_complete 1323 ** 1324 ** Description Check if restore the NFA-EE related configuration to the 1325 ** state prior to low power mode is complete. 1326 ** If complete, notify sys. 1327 ** 1328 ** Returns void 1329 ** 1330 *******************************************************************************/ 1331 void nfa_ee_check_restore_complete(void) 1332 { 1333 UINT32 xx; 1334 tNFA_EE_ECB *p_cb; 1335 BOOLEAN proc_complete = TRUE; 1336 1337 p_cb = nfa_ee_cb.ecb; 1338 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1339 { 1340 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1341 { 1342 /* NFA_HCI module handles restoring configurations for HCI access. 1343 * ignore the restoring status for HCI Access */ 1344 if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) 1345 { 1346 proc_complete = FALSE; 1347 break; 1348 } 1349 } 1350 } 1351 1352 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); 1353 if (proc_complete) 1354 { 1355 /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */ 1356 if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) 1357 nfa_ee_api_update_now(NULL); 1358 1359 nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE; 1360 nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_EE); 1361 } 1362 } 1363 1364 /******************************************************************************* 1365 ** 1366 ** Function nfa_ee_build_discover_req_evt 1367 ** 1368 ** Description Build NFA_EE_DISCOVER_REQ_EVT for all active NFCEE 1369 ** 1370 ** Returns void 1371 ** 1372 *******************************************************************************/ 1373 static void nfa_ee_build_discover_req_evt (tNFA_EE_DISCOVER_REQ *p_evt_data) 1374 { 1375 tNFA_EE_ECB *p_cb; 1376 tNFA_EE_DISCOVER_INFO *p_info; 1377 UINT8 xx; 1378 1379 if (!p_evt_data) 1380 return; 1381 1382 p_evt_data->num_ee = 0; 1383 p_cb = nfa_ee_cb.ecb; 1384 p_info = p_evt_data->ee_disc_info; 1385 1386 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1387 { 1388 if ( (p_cb->ee_status & NFA_EE_STATUS_INT_MASK) 1389 ||(p_cb->ee_status != NFA_EE_STATUS_ACTIVE) 1390 ||((p_cb->ecb_flags & NFA_EE_ECB_FLAGS_DISC_REQ) == 0) ) 1391 { 1392 continue; 1393 } 1394 p_info->ee_handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE; 1395 p_info->la_protocol = p_cb->la_protocol; 1396 p_info->lb_protocol = p_cb->lb_protocol; 1397 p_info->lf_protocol = p_cb->lf_protocol; 1398 p_info->lbp_protocol = p_cb->lbp_protocol; 1399 p_evt_data->num_ee++; 1400 p_info++; 1401 1402 NFA_TRACE_DEBUG6 ("[%d] ee_handle:0x%x, listen protocol A:%d, B:%d, F:%d, BP:%d", 1403 p_evt_data->num_ee, p_cb->nfcee_id, 1404 p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol, p_cb->lbp_protocol); 1405 } 1406 1407 p_evt_data->status = NFA_STATUS_OK; 1408 } 1409 1410 /******************************************************************************* 1411 ** 1412 ** Function nfa_ee_report_discover_req_evt 1413 ** 1414 ** Description Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE 1415 ** 1416 ** Returns void 1417 ** 1418 *******************************************************************************/ 1419 static void nfa_ee_report_discover_req_evt(void) 1420 { 1421 tNFA_EE_DISCOVER_REQ evt_data; 1422 1423 if (nfa_ee_cb.p_enable_cback) 1424 (*nfa_ee_cb.p_enable_cback) (NFA_EE_DISC_STS_REQ); 1425 1426 1427 /* if this is restoring NFCC */ 1428 if (!nfa_dm_is_active ()) 1429 { 1430 NFA_TRACE_DEBUG0 ("nfa_ee_report_discover_req_evt DM is not active"); 1431 return; 1432 } 1433 1434 nfa_ee_build_discover_req_evt (&evt_data); 1435 nfa_ee_report_event(NULL, NFA_EE_DISCOVER_REQ_EVT, (tNFA_EE_CBACK_DATA *)&evt_data); 1436 } 1437 1438 /******************************************************************************* 1439 ** 1440 ** Function nfa_ee_nci_mode_set_rsp 1441 ** 1442 ** Description Process the result for NFCEE ModeSet response 1443 ** 1444 ** Returns void 1445 ** 1446 *******************************************************************************/ 1447 void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG *p_data) 1448 { 1449 tNFA_EE_ECB *p_cb; 1450 tNFA_EE_MODE_SET mode_set; 1451 tNFC_NFCEE_MODE_SET_REVT *p_rsp = p_data->mode_set_rsp.p_data; 1452 1453 NFA_TRACE_DEBUG2 ("nfa_ee_nci_mode_set_rsp() handle:0x%02x mode:%d", p_rsp->nfcee_id, p_rsp->mode); 1454 p_cb = nfa_ee_find_ecb (p_rsp->nfcee_id); 1455 if (p_cb == NULL) 1456 { 1457 NFA_TRACE_ERROR1 ("nfa_ee_nci_mode_set_rsp() Can not find cb for handle:0x%02x", p_rsp->nfcee_id); 1458 return; 1459 } 1460 1461 /* update routing table and vs on mode change */ 1462 nfa_ee_start_timer(); 1463 1464 if (p_rsp->status == NFA_STATUS_OK) 1465 { 1466 1467 if (p_rsp->mode == NFA_EE_MD_ACTIVATE) 1468 { 1469 p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE; 1470 } 1471 else 1472 { 1473 if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off | 1474 p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off | 1475 p_cb->aid_entries) 1476 { 1477 /* this NFCEE still has configuration when deactivated. clear the configuration */ 1478 nfa_ee_cb.ee_cfged &= ~nfa_ee_ecb_to_mask(p_cb); 1479 nfa_ee_cb.ee_cfg_sts|= NFA_EE_STS_CHANGED_ROUTING; 1480 NFA_TRACE_DEBUG0("deactivating/still configured. Force update"); 1481 } 1482 p_cb->tech_switch_on = p_cb->tech_switch_off = p_cb->tech_battery_off = 0; 1483 p_cb->proto_switch_on = p_cb->proto_switch_off= p_cb->proto_battery_off = 0; 1484 p_cb->aid_entries = 0; 1485 p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE; 1486 } 1487 } 1488 NFA_TRACE_DEBUG4 ("status:%d ecb_flags :0x%02x ee_cfged:0x%02x ee_status:%d", 1489 p_rsp->status, p_cb->ecb_flags , nfa_ee_cb.ee_cfged, p_cb->ee_status); 1490 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1491 { 1492 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 1493 { 1494 /* NFA_HCI module handles restoring configurations for HCI access */ 1495 if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) 1496 { 1497 NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id, p_cb->use_interface, nfa_ee_conn_cback); 1498 } 1499 } 1500 else 1501 { 1502 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE; 1503 nfa_ee_check_restore_complete(); 1504 } 1505 } 1506 else 1507 { 1508 mode_set.status = p_rsp->status; 1509 mode_set.ee_handle = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE; 1510 mode_set.ee_status = p_cb->ee_status; 1511 1512 nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT, (tNFA_EE_CBACK_DATA *)&mode_set); 1513 1514 if ((p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE) 1515 || (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)) 1516 { 1517 /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */ 1518 nfa_ee_report_discover_req_evt(); 1519 } 1520 } 1521 } 1522 1523 /******************************************************************************* 1524 ** 1525 ** Function nfa_ee_report_update_evt 1526 ** 1527 ** Description Check if need to report NFA_EE_UPDATED_EVT 1528 ** 1529 ** Returns void 1530 ** 1531 *******************************************************************************/ 1532 void nfa_ee_report_update_evt (void) 1533 { 1534 tNFA_EE_CBACK_DATA evt_data; 1535 1536 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); 1537 if (nfa_ee_cb.wait_rsp == 0) 1538 { 1539 nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE_RSP; 1540 1541 if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE) 1542 { 1543 nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE; 1544 /* finished updating NFCC; report NFA_EE_UPDATED_EVT now */ 1545 evt_data.status = NFA_STATUS_OK; 1546 nfa_ee_report_event (NULL, NFA_EE_UPDATED_EVT, &evt_data); 1547 } 1548 } 1549 } 1550 1551 /******************************************************************************* 1552 ** 1553 ** Function nfa_ee_nci_wait_rsp 1554 ** 1555 ** Description Process the result for NCI response 1556 ** 1557 ** Returns void 1558 ** 1559 *******************************************************************************/ 1560 void nfa_ee_nci_wait_rsp(tNFA_EE_MSG *p_data) 1561 { 1562 tNFA_EE_NCI_WAIT_RSP *p_rsp = &p_data->wait_rsp; 1563 1564 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); 1565 if (nfa_ee_cb.wait_rsp) 1566 { 1567 if (p_rsp->opcode == NCI_MSG_RF_SET_ROUTING) 1568 nfa_ee_cb.wait_rsp--; 1569 } 1570 nfa_ee_report_update_evt (); 1571 } 1572 1573 /******************************************************************************* 1574 ** 1575 ** Function nfa_ee_nci_conn 1576 ** 1577 ** Description process the connection callback events 1578 ** 1579 ** Returns void 1580 ** 1581 *******************************************************************************/ 1582 void nfa_ee_nci_conn(tNFA_EE_MSG *p_data) 1583 { 1584 tNFA_EE_ECB *p_cb; 1585 tNFA_EE_NCI_CONN *p_cbk = &p_data->conn; 1586 tNFC_CONN *p_conn = p_data->conn.p_data; 1587 BT_HDR *p_pkt = NULL; 1588 tNFA_EE_CBACK_DATA evt_data = {0}; 1589 tNFA_EE_EVT event = NFA_EE_INVALID; 1590 tNFA_EE_CBACK *p_cback = NULL; 1591 1592 if (p_cbk->event == NFC_CONN_CREATE_CEVT) 1593 { 1594 p_cb = nfa_ee_find_ecb (p_cbk->p_data->conn_create.id); 1595 } 1596 else 1597 { 1598 p_cb = nfa_ee_find_ecb_by_conn_id (p_cbk->conn_id); 1599 if (p_cbk->event == NFC_DATA_CEVT) 1600 p_pkt = p_conn->data.p_data; 1601 } 1602 1603 if (p_cb) 1604 { 1605 p_cback = p_cb->p_ee_cback; 1606 evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE; 1607 switch (p_cbk->event) 1608 { 1609 case NFC_CONN_CREATE_CEVT: 1610 if (p_conn->conn_create.status == NFC_STATUS_OK) 1611 { 1612 p_cb->conn_id = p_cbk->conn_id; 1613 p_cb->conn_st = NFA_EE_CONN_ST_CONN; 1614 } 1615 else 1616 { 1617 p_cb->conn_st = NFA_EE_CONN_ST_NONE; 1618 } 1619 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) 1620 { 1621 p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE; 1622 nfa_ee_check_restore_complete(); 1623 } 1624 else 1625 { 1626 evt_data.connect.status = p_conn->conn_create.status; 1627 evt_data.connect.ee_interface = p_cb->use_interface; 1628 event = NFA_EE_CONNECT_EVT; 1629 } 1630 break; 1631 1632 case NFC_CONN_CLOSE_CEVT: 1633 if (p_cb->conn_st != NFA_EE_CONN_ST_DISC) 1634 event = NFA_EE_DISCONNECT_EVT; 1635 p_cb->conn_st = NFA_EE_CONN_ST_NONE; 1636 p_cb->p_ee_cback = NULL; 1637 p_cb->conn_id = 0; 1638 if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING) 1639 { 1640 if (nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN) 1641 { 1642 if (nfa_ee_cb.num_ee_expecting) 1643 { 1644 nfa_ee_cb.num_ee_expecting--; 1645 } 1646 } 1647 if (nfa_ee_cb.num_ee_expecting == 0) 1648 { 1649 nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_DISCONN; 1650 nfa_ee_check_disable(); 1651 } 1652 } 1653 break; 1654 1655 case NFC_DATA_CEVT: 1656 if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) 1657 { 1658 /* report data event only in connected state */ 1659 if (p_cb->p_ee_cback && p_pkt) 1660 { 1661 evt_data.data.len = p_pkt->len; 1662 evt_data.data.p_buf = (UINT8 *)(p_pkt+1) + p_pkt->offset; 1663 event = NFA_EE_DATA_EVT; 1664 p_pkt = NULL; /* so this function does not free this GKI buffer */ 1665 } 1666 } 1667 break; 1668 } 1669 1670 if ((event != NFA_EE_INVALID) && (p_cback)) 1671 (*p_cback)(event, &evt_data); 1672 } 1673 if (p_pkt) 1674 GKI_freebuf (p_pkt); 1675 } 1676 1677 1678 /******************************************************************************* 1679 ** 1680 ** Function nfa_ee_nci_action_ntf 1681 ** 1682 ** Description process the NFCEE action callback event 1683 ** 1684 ** Returns void 1685 ** 1686 *******************************************************************************/ 1687 void nfa_ee_nci_action_ntf(tNFA_EE_MSG *p_data) 1688 { 1689 tNFC_EE_ACTION_REVT *p_cbk = p_data->act.p_data; 1690 tNFA_EE_ACTION evt_data; 1691 1692 evt_data.ee_handle = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE; 1693 evt_data.trigger = p_cbk->act_data.trigger; 1694 memcpy (&(evt_data.param), &(p_cbk->act_data.param), sizeof (tNFA_EE_ACTION_PARAM)); 1695 nfa_ee_report_event(NULL, NFA_EE_ACTION_EVT, (tNFA_EE_CBACK_DATA *)&evt_data); 1696 } 1697 1698 /******************************************************************************* 1699 ** 1700 ** Function nfa_ee_nci_disc_req_ntf 1701 ** 1702 ** Description process the NFCEE discover request callback event 1703 ** 1704 ** Returns void 1705 ** 1706 *******************************************************************************/ 1707 void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG *p_data) 1708 { 1709 tNFC_EE_DISCOVER_REQ_REVT *p_cbk = p_data->disc_req.p_data; 1710 tNFA_HANDLE ee_handle; 1711 tNFA_EE_ECB *p_cb = NULL; 1712 UINT8 report_ntf = 0; 1713 UINT8 xx; 1714 1715 NFA_TRACE_DEBUG2 ("nfa_ee_nci_disc_req_ntf () num_info: %d cur_ee:%d", p_cbk->num_info, nfa_ee_cb.cur_ee ); 1716 1717 for (xx = 0; xx < p_cbk->num_info; xx++) 1718 { 1719 ee_handle = NFA_HANDLE_GROUP_EE|p_cbk->info[xx].nfcee_id; 1720 1721 p_cb = nfa_ee_find_ecb (p_cbk->info[xx].nfcee_id); 1722 if (!p_cb) 1723 { 1724 NFA_TRACE_DEBUG1 ("Cannot find cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id); 1725 p_cb = nfa_ee_find_ecb (NFA_EE_INVALID); 1726 if (p_cb) 1727 { 1728 p_cb->nfcee_id = p_cbk->info[xx].nfcee_id; 1729 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER; 1730 } 1731 else 1732 { 1733 NFA_TRACE_ERROR1 ("Cannot allocate cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id); 1734 continue; 1735 } 1736 } 1737 else 1738 { 1739 report_ntf |= nfa_ee_ecb_to_mask (p_cb); 1740 } 1741 1742 p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ; 1743 if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD) 1744 { 1745 if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) 1746 { 1747 p_cb->la_protocol = p_cbk->info[xx].protocol; 1748 } 1749 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) 1750 { 1751 p_cb->lb_protocol = p_cbk->info[xx].protocol; 1752 } 1753 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) 1754 { 1755 p_cb->lf_protocol = p_cbk->info[xx].protocol; 1756 } 1757 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) 1758 { 1759 p_cb->lbp_protocol = p_cbk->info[xx].protocol; 1760 } 1761 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", 1762 p_cb->nfcee_id, p_cb->ee_status, p_cb->ecb_flags, 1763 p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol); 1764 } 1765 else 1766 { 1767 if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) 1768 { 1769 p_cb->la_protocol = 0; 1770 } 1771 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) 1772 { 1773 p_cb->lb_protocol = 0; 1774 } 1775 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) 1776 { 1777 p_cb->lf_protocol = 0; 1778 } 1779 else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) 1780 { 1781 p_cb->lbp_protocol = 0; 1782 } 1783 } 1784 } 1785 1786 1787 /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */ 1788 if (report_ntf) 1789 nfa_ee_report_discover_req_evt(); 1790 1791 } 1792 1793 /******************************************************************************* 1794 ** 1795 ** Function nfa_ee_is_active 1796 ** 1797 ** Description Check if the given NFCEE is active 1798 ** 1799 ** Returns TRUE if the given NFCEE is active 1800 ** 1801 *******************************************************************************/ 1802 BOOLEAN nfa_ee_is_active (tNFA_HANDLE nfcee_id) 1803 { 1804 BOOLEAN is_active = FALSE; 1805 int xx; 1806 tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb; 1807 1808 if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE) 1809 nfcee_id &= NFA_HANDLE_MASK; 1810 1811 /* compose output */ 1812 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) 1813 { 1814 if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id) 1815 { 1816 if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE) 1817 { 1818 is_active = TRUE; 1819 } 1820 break; 1821 } 1822 } 1823 return is_active; 1824 } 1825 1826 /******************************************************************************* 1827 ** 1828 ** Function nfa_ee_get_tech_route 1829 ** 1830 ** Description Given a power state, find the technology routing destination. 1831 ** The result is filled in the given p_handles 1832 ** in the order of A, B, F, Bprime 1833 ** 1834 ** Returns None 1835 ** 1836 *******************************************************************************/ 1837 void nfa_ee_get_tech_route (UINT8 power_state, UINT8 *p_handles) 1838 { 1839 int xx, yy; 1840 tNFA_EE_ECB *p_cb; 1841 UINT8 tech_mask_list[NFA_EE_MAX_TECH_ROUTE] = 1842 { 1843 NFA_TECHNOLOGY_MASK_A, 1844 NFA_TECHNOLOGY_MASK_B, 1845 NFA_TECHNOLOGY_MASK_F, 1846 NFA_TECHNOLOGY_MASK_B_PRIME 1847 }; 1848 1849 NFA_TRACE_DEBUG1("nfa_ee_get_tech_route(): %d", power_state); 1850 1851 for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++) 1852 { 1853 p_handles[xx] = NFC_DH_ID; 1854 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 1855 for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--) 1856 { 1857 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 1858 { 1859 switch (power_state) 1860 { 1861 case NFA_EE_PWR_STATE_ON: 1862 if (p_cb->tech_switch_on & tech_mask_list[xx]) 1863 p_handles[xx] = p_cb->nfcee_id; 1864 break; 1865 case NFA_EE_PWR_STATE_SWITCH_OFF: 1866 if (p_cb->tech_switch_off & tech_mask_list[xx]) 1867 p_handles[xx] = p_cb->nfcee_id; 1868 break; 1869 case NFA_EE_PWR_STATE_BATT_OFF: 1870 if (p_cb->tech_battery_off & tech_mask_list[xx]) 1871 p_handles[xx] = p_cb->nfcee_id; 1872 break; 1873 } 1874 } 1875 } 1876 } 1877 NFA_TRACE_DEBUG4("0x%x, 0x%x, 0x%x, 0x%x", p_handles[0], p_handles[1], p_handles[2], p_handles[3]); 1878 } 1879 1880 /******************************************************************************* 1881 ** 1882 ** Function nfa_ee_check_set_routing 1883 ** 1884 ** Description If the new size exceeds the capacity of next block, 1885 ** send the routing command now and reset the related parameters 1886 ** 1887 ** Returns void 1888 ** 1889 *******************************************************************************/ 1890 void nfa_ee_check_set_routing(UINT16 new_size, int *p_max_len, UINT8 *p, int *p_cur_offset) 1891 { 1892 UINT8 max_tlv = (UINT8)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:*p_max_len); 1893 tNFA_STATUS status = NFA_STATUS_OK; 1894 1895 if (new_size + *p_cur_offset > max_tlv) 1896 { 1897 if (NFC_SetRouting(TRUE, *p, *p_cur_offset, p + 1) == NFA_STATUS_OK) 1898 { 1899 nfa_ee_cb.wait_rsp++; 1900 } 1901 /* after the routing command is sent, re-use the same buffer to send the next routing command. 1902 * reset the related parameters */ 1903 if (*p_max_len > *p_cur_offset) 1904 *p_max_len -= *p_cur_offset;/* the max is reduced */ 1905 else 1906 *p_max_len = 0; 1907 *p_cur_offset = 0; /* nothing is in queue any more */ 1908 *p = 0; /* num_tlv=0 */ 1909 } 1910 } 1911 1912 /******************************************************************************* 1913 ** 1914 ** Function nfa_ee_route_add_one_ecb 1915 ** 1916 ** Description Add the routing entries for one NFCEE/DH 1917 ** 1918 ** Returns NFA_STATUS_OK, if ok to continue 1919 ** 1920 *******************************************************************************/ 1921 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) 1922 { 1923 UINT8 *p, *pa; 1924 UINT16 tlv_size; 1925 UINT8 num_tlv, len; 1926 int xx; 1927 int start_offset; 1928 UINT8 power_cfg = 0; 1929 UINT8 *pp = ps + *p_cur_offset; 1930 UINT8 entry_size; 1931 UINT8 max_tlv; 1932 UINT8 *p_start; 1933 UINT8 new_size; 1934 tNFA_STATUS status = NFA_STATUS_OK; 1935 1936 nfa_ee_check_set_routing (p_cb->size_mask, p_max_len, ps, p_cur_offset); 1937 max_tlv = (UINT8)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:*p_max_len); 1938 /* use the first byte of the buffer (ps) to keep the num_tlv */ 1939 num_tlv = *ps; 1940 NFA_TRACE_DEBUG5 ("nfa_ee_route_add_one_ecb max_len:%d, max_tlv:%d, cur_offset:%d, more:%d, num_tlv:%d", 1941 *p_max_len, max_tlv, *p_cur_offset, more, num_tlv); 1942 pp = ps + 1 + *p_cur_offset; 1943 p = pp; 1944 tlv_size = (UINT8)*p_cur_offset; 1945 /* add the Technology based routing */ 1946 for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) 1947 { 1948 power_cfg = 0; 1949 if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx]) 1950 power_cfg |= NCI_ROUTE_PWR_STATE_ON; 1951 if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx]) 1952 power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF; 1953 if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx]) 1954 power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF; 1955 if (power_cfg) 1956 { 1957 *pp++ = NFC_ROUTE_TAG_TECH; 1958 *pp++ = 3; 1959 *pp++ = p_cb->nfcee_id; 1960 *pp++ = power_cfg; 1961 *pp++ = nfa_ee_tech_list[xx]; 1962 num_tlv++; 1963 if (power_cfg != NCI_ROUTE_PWR_STATE_ON) 1964 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING; 1965 } 1966 } 1967 1968 /* add the Protocol based routing */ 1969 for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) 1970 { 1971 power_cfg = 0; 1972 if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx]) 1973 power_cfg |= NCI_ROUTE_PWR_STATE_ON; 1974 if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx]) 1975 power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF; 1976 if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx]) 1977 power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF; 1978 if (power_cfg) 1979 { 1980 *pp++ = NFC_ROUTE_TAG_PROTO; 1981 *pp++ = 3; 1982 *pp++ = p_cb->nfcee_id; 1983 *pp++ = power_cfg; 1984 *pp++ = nfa_ee_proto_list[xx]; 1985 num_tlv++; 1986 if (power_cfg != NCI_ROUTE_PWR_STATE_ON) 1987 nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING; 1988 } 1989 } 1990 1991 /* add NFC-DEP routing to HOST */ 1992 if (p_cb->nfcee_id == NFC_DH_ID) 1993 { 1994 *pp++ = NFC_ROUTE_TAG_PROTO; 1995 *pp++ = 3; 1996 *pp++ = NFC_DH_ID; 1997 *pp++ = NCI_ROUTE_PWR_STATE_ON; 1998 *pp++ = NFC_PROTOCOL_NFC_DEP; 1999 num_tlv++; 2000 } 2001 2002 /* update the num_tlv and current offset */ 2003 entry_size = (UINT8)(pp - p); 2004 *p_cur_offset += entry_size; 2005 *ps = num_tlv; 2006 /* add the AID routing */ 2007 if (p_cb->aid_entries) 2008 { 2009 start_offset = 0; 2010 for (xx = 0; xx < p_cb->aid_entries; xx++) 2011 { 2012 p_start = pp; /* rememebr the beginning of this AID routing entry, just in case we need to put it in next command */ 2013 /* add one AID entry */ 2014 if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) 2015 { 2016 num_tlv++; 2017 pa = &p_cb->aid_cfg[start_offset]; 2018 pa ++; /* EMV tag */ 2019 len = *pa++; /* aid_len */ 2020 *pp++ = NFC_ROUTE_TAG_AID; 2021 *pp++ = len + 2; 2022 *pp++ = p_cb->nfcee_id; 2023 *pp++ = p_cb->aid_pwr_cfg[xx]; 2024 /* copy the AID */ 2025 memcpy(pp, pa, len); 2026 pp += len; 2027 } 2028 start_offset += p_cb->aid_len[xx]; 2029 new_size = (UINT8)(pp - p_start); 2030 nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset); 2031 if (*ps == 0) 2032 { 2033 /* just sent routing command, update local */ 2034 *ps = 1; 2035 num_tlv = *ps; 2036 *p_cur_offset = new_size; 2037 pp = ps + 1; 2038 p = pp; 2039 tlv_size = (UINT8)*p_cur_offset; 2040 max_tlv = (UINT8)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:*p_max_len); 2041 memcpy (p, p_start, new_size); 2042 pp += new_size; 2043 } 2044 else 2045 { 2046 /* add the new entry */ 2047 *ps = num_tlv; 2048 *p_cur_offset += new_size; 2049 } 2050 } 2051 } 2052 2053 tlv_size = nfa_ee_total_lmrt_size(); 2054 if (tlv_size) 2055 { 2056 nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb); 2057 } 2058 if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) 2059 { 2060 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING; 2061 } 2062 NFA_TRACE_DEBUG2 ("ee_cfg_sts:0x%02x lmrt_size:%d", nfa_ee_cb.ee_cfg_sts, tlv_size); 2063 2064 if (more == FALSE) 2065 { 2066 /* last entry. update routing table now */ 2067 if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) 2068 { 2069 if (tlv_size) 2070 { 2071 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING; 2072 } 2073 else 2074 { 2075 nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING; 2076 } 2077 NFA_TRACE_DEBUG2 ("nfa_ee_route_add_one_ecb: set routing num_tlv:%d tlv_size:%d", num_tlv, tlv_size); 2078 if (NFC_SetRouting(more, num_tlv, (UINT8)(*p_cur_offset), ps + 1) == NFA_STATUS_OK) 2079 { 2080 nfa_ee_cb.wait_rsp++; 2081 } 2082 } 2083 else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) 2084 { 2085 if (tlv_size == 0) 2086 { 2087 nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING; 2088 /* indicated routing is configured to NFCC */ 2089 nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING; 2090 if (NFC_SetRouting(more, 0, 0, ps + 1) == NFA_STATUS_OK) 2091 { 2092 nfa_ee_cb.wait_rsp++; 2093 } 2094 } 2095 } 2096 } 2097 2098 return status; 2099 } 2100 2101 2102 /******************************************************************************* 2103 ** 2104 ** Function nfa_ee_need_recfg 2105 ** 2106 ** Description Check if any API function to configure the routing table or 2107 ** VS is called since last update 2108 ** 2109 ** The algorithm for the NFCEE configuration handling is as follows: 2110 ** 2111 ** Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB 2112 ** Each control block uses ecb_flags to keep track if an API 2113 ** that changes routing/VS is invoked. 2114 ** This ecb_flags is cleared at the end of nfa_ee_update_rout(). 2115 ** 2116 ** nfa_ee_cb.ee_cfged is the bitmask of the control blocks with 2117 ** routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW. 2118 ** nfa_ee_cb.ee_cfged is cleared and re-calculated at the end of 2119 ** nfa_ee_update_rout(). 2120 ** 2121 ** nfa_ee_cb.ee_cfg_sts is used to check is any status is changed 2122 ** and the associated command is issued to NFCC. 2123 ** nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end of 2124 ** nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits 2125 ** (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in nfa_ee_vs_cback) 2126 ** 2127 ** Returns TRUE if any configuration is changed 2128 ** 2129 *******************************************************************************/ 2130 static BOOLEAN nfa_ee_need_recfg(void) 2131 { 2132 BOOLEAN needed = FALSE; 2133 UINT32 xx; 2134 tNFA_EE_ECB *p_cb; 2135 UINT8 mask; 2136 2137 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); 2138 /* if no routing/vs is configured, do not need to send the info to NFCC */ 2139 if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts) 2140 { 2141 if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED) 2142 { 2143 needed = TRUE; 2144 } 2145 else 2146 { 2147 p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH]; 2148 mask = 1 << NFA_EE_CB_4_DH; 2149 for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++) 2150 { 2151 NFA_TRACE_DEBUG3("%d: ecb_flags : 0x%02x, mask: 0x%02x", xx, p_cb->ecb_flags , mask); 2152 if ((p_cb->ecb_flags ) && (nfa_ee_cb.ee_cfged & mask)) 2153 { 2154 needed = TRUE; 2155 break; 2156 } 2157 p_cb = &nfa_ee_cb.ecb[xx]; 2158 mask = 1 << xx; 2159 } 2160 } 2161 } 2162 2163 return needed; 2164 } 2165 2166 /******************************************************************************* 2167 ** 2168 ** Function nfa_ee_rout_timeout 2169 ** 2170 ** Description Anytime VS or routing entries are changed, 2171 ** a 1 second timer is started. This function is called when 2172 ** the timer expires or NFA_EeUpdateNow() is called. 2173 ** 2174 ** Returns void 2175 ** 2176 *******************************************************************************/ 2177 void nfa_ee_rout_timeout(tNFA_EE_MSG *p_data) 2178 { 2179 UINT8 ee_cfged = nfa_ee_cb.ee_cfged; 2180 2181 NFA_TRACE_DEBUG0("nfa_ee_rout_timeout()"); 2182 if (nfa_ee_need_recfg()) 2183 { 2184 /* discovery is not started */ 2185 nfa_ee_update_rout(); 2186 } 2187 2188 if (nfa_ee_cb.wait_rsp) 2189 nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE_RSP; 2190 if (ee_cfged & NFA_EE_CFGED_UPDATE_NOW) 2191 { 2192 /* need to report NFA_EE_UPDATED_EVT when done updating NFCC */ 2193 nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE; 2194 if (!nfa_ee_cb.wait_rsp) 2195 { 2196 nfa_ee_report_update_evt(); 2197 } 2198 } 2199 } 2200 2201 /******************************************************************************* 2202 ** 2203 ** Function nfa_ee_discv_timeout 2204 ** 2205 ** Description 2206 ** 2207 ** 2208 ** 2209 ** Returns void 2210 ** 2211 *******************************************************************************/ 2212 void nfa_ee_discv_timeout(tNFA_EE_MSG *p_data) 2213 { 2214 NFC_NfceeDiscover(FALSE); 2215 if (nfa_ee_cb.p_enable_cback) 2216 (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_OFF); 2217 } 2218 2219 /******************************************************************************* 2220 ** 2221 ** Function nfa_ee_lmrt_to_nfcc 2222 ** 2223 ** Description This function would set the listen mode routing table 2224 ** to NFCC. 2225 ** 2226 ** Returns void 2227 ** 2228 *******************************************************************************/ 2229 void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG *p_data) 2230 { 2231 int xx; 2232 tNFA_EE_ECB *p_cb; 2233 UINT8 *p = NULL; 2234 BOOLEAN more = TRUE; 2235 UINT8 last_active = NFA_EE_INVALID; 2236 int max_len, len; 2237 tNFA_STATUS status = NFA_STATUS_FAILED; 2238 int cur_offset; 2239 UINT8 max_tlv; 2240 2241 /* update routing table: DH and the activated NFCEEs */ 2242 p = (UINT8 *)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE); 2243 if (p == NULL) 2244 { 2245 NFA_TRACE_ERROR0 ("nfa_ee_lmrt_to_nfcc() no buffer to send routing info."); 2246 nfa_ee_report_event( NULL, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 2247 return; 2248 } 2249 2250 /* find the last active NFCEE. */ 2251 p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1]; 2252 for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) 2253 { 2254 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 2255 { 2256 if (last_active == NFA_EE_INVALID) 2257 { 2258 last_active = p_cb->nfcee_id; 2259 NFA_TRACE_DEBUG1 ("last_active: 0x%x", last_active); 2260 } 2261 } 2262 } 2263 if (last_active == NFA_EE_INVALID) 2264 { 2265 more = FALSE; 2266 } 2267 2268 /* add the routing for DH first */ 2269 status = NFA_STATUS_OK; 2270 max_len = NFC_GetLmrtSize(); 2271 max_tlv = (UINT8)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:max_len); 2272 cur_offset = 0; 2273 /* use the first byte of the buffer (p) to keep the num_tlv */ 2274 *p = 0; 2275 status = nfa_ee_route_add_one_ecb(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], &max_len, more, p, &cur_offset); 2276 2277 /* add only what is supported by NFCC. report overflow */ 2278 if (status == NFA_STATUS_OK) 2279 { 2280 /* add the routing for NFCEEs */ 2281 p_cb = &nfa_ee_cb.ecb[0]; 2282 for (xx = 0; (xx < nfa_ee_cb.cur_ee) && more; xx++, p_cb++) 2283 { 2284 len = 0; 2285 if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) 2286 { 2287 NFA_TRACE_DEBUG2 ("nfcee_id:0x%x, last_active: 0x%x", p_cb->nfcee_id, last_active); 2288 if (last_active == p_cb->nfcee_id) 2289 more = FALSE; 2290 status = nfa_ee_route_add_one_ecb(p_cb, &max_len, more, p, &cur_offset); 2291 if (status != NFA_STATUS_OK) 2292 { 2293 more = FALSE; 2294 } 2295 } 2296 } 2297 } 2298 if (status != NFA_STATUS_OK) 2299 { 2300 nfa_ee_report_event( NULL, NFA_EE_ROUT_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status); 2301 } 2302 GKI_freebuf(p); 2303 } 2304 2305 /******************************************************************************* 2306 ** 2307 ** Function nfa_ee_update_rout 2308 ** 2309 ** Description This function would set the VS and listen mode routing table 2310 ** to NFCC. 2311 ** 2312 ** Returns void 2313 ** 2314 *******************************************************************************/ 2315 void nfa_ee_update_rout(void) 2316 { 2317 int xx; 2318 tNFA_EE_ECB *p_cb; 2319 UINT8 mask; 2320 BT_HDR msg; 2321 2322 NFA_TRACE_DEBUG1 ("nfa_ee_update_rout ee_cfg_sts:0x%02x", nfa_ee_cb.ee_cfg_sts); 2323 2324 /* use action function to send routing and VS configuration to NFCC */ 2325 msg.event = NFA_EE_CFG_TO_NFCC_EVT; 2326 nfa_ee_evt_hdlr (&msg); 2327 2328 /* all configuration is updated to NFCC, clear the status mask */ 2329 nfa_ee_cb.ee_cfg_sts &= NFA_EE_STS_PREV; 2330 nfa_ee_cb.ee_cfged = 0; 2331 p_cb = &nfa_ee_cb.ecb[0]; 2332 for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++) 2333 { 2334 p_cb->ecb_flags = 0; 2335 mask = (1 << xx); 2336 if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off | 2337 p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off | 2338 p_cb->aid_entries) 2339 { 2340 /* this entry has routing configuration. mark it configured */ 2341 nfa_ee_cb.ee_cfged |= mask; 2342 } 2343 } 2344 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); 2345 } 2346 2347 2348