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