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 is the main implementation file for the NFA device manager. 22 * 23 ******************************************************************************/ 24 25#include <string.h> 26#include "nfa_api.h" 27#include "nfa_dm_int.h" 28#include "nfa_sys.h" 29#include "nfa_sys_int.h" 30 31/***************************************************************************** 32** Constants and types 33*****************************************************************************/ 34static const tNFA_SYS_REG nfa_dm_sys_reg = {nfa_dm_sys_enable, nfa_dm_evt_hdlr, 35 nfa_dm_sys_disable, 36 nfa_dm_proc_nfcc_power_mode}; 37 38tNFA_DM_CB nfa_dm_cb = { 39 0, 40}; 41 42#define NFA_DM_NUM_ACTIONS (NFA_DM_MAX_EVT & 0x00ff) 43 44/* type for action functions */ 45typedef bool (*tNFA_DM_ACTION)(tNFA_DM_MSG* p_data); 46 47/* action function list */ 48const tNFA_DM_ACTION nfa_dm_action[] = { 49 /* device manager local device API events */ 50 nfa_dm_enable, /* NFA_DM_API_ENABLE_EVT */ 51 nfa_dm_disable, /* NFA_DM_API_DISABLE_EVT */ 52 nfa_dm_set_config, /* NFA_DM_API_SET_CONFIG_EVT */ 53 nfa_dm_get_config, /* NFA_DM_API_GET_CONFIG_EVT */ 54 nfa_dm_act_request_excl_rf_ctrl, /* NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT */ 55 nfa_dm_act_release_excl_rf_ctrl, /* NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT */ 56 nfa_dm_act_enable_polling, /* NFA_DM_API_ENABLE_POLLING_EVT */ 57 nfa_dm_act_disable_polling, /* NFA_DM_API_DISABLE_POLLING_EVT */ 58 nfa_dm_act_enable_listening, /* NFA_DM_API_ENABLE_LISTENING_EVT */ 59 nfa_dm_act_disable_listening, /* NFA_DM_API_DISABLE_LISTENING_EVT */ 60 nfa_dm_act_pause_p2p, /* NFA_DM_API_PAUSE_P2P_EVT */ 61 nfa_dm_act_resume_p2p, /* NFA_DM_API_RESUME_P2P_EVT */ 62 nfa_dm_act_send_raw_frame, /* NFA_DM_API_RAW_FRAME_EVT */ 63 nfa_dm_set_p2p_listen_tech, /* NFA_DM_API_SET_P2P_LISTEN_TECH_EVT */ 64 nfa_dm_act_start_rf_discovery, /* NFA_DM_API_START_RF_DISCOVERY_EVT */ 65 nfa_dm_act_stop_rf_discovery, /* NFA_DM_API_STOP_RF_DISCOVERY_EVT */ 66 nfa_dm_act_set_rf_disc_duration, /* NFA_DM_API_SET_RF_DISC_DURATION_EVT */ 67 nfa_dm_act_select, /* NFA_DM_API_SELECT_EVT */ 68 nfa_dm_act_update_rf_params, /* NFA_DM_API_UPDATE_RF_PARAMS_EVT */ 69 nfa_dm_act_deactivate, /* NFA_DM_API_DEACTIVATE_EVT */ 70 nfa_dm_act_power_off_sleep, /* NFA_DM_API_POWER_OFF_SLEEP_EVT */ 71 nfa_dm_ndef_reg_hdlr, /* NFA_DM_API_REG_NDEF_HDLR_EVT */ 72 nfa_dm_ndef_dereg_hdlr, /* NFA_DM_API_DEREG_NDEF_HDLR_EVT */ 73 nfa_dm_act_reg_vsc, /* NFA_DM_API_REG_VSC_EVT */ 74 nfa_dm_act_send_vsc, /* NFA_DM_API_SEND_VSC_EVT */ 75 nfa_dm_act_disable_timeout, /* NFA_DM_TIMEOUT_DISABLE_EVT */ 76 nfa_dm_set_power_sub_state, /* NFA_DM_API_SET_POWER_SUB_STATE_EVT */ 77 nfa_dm_act_send_raw_vs /* NFA_DM_API_SEND_RAW_VS_EVT */ 78}; 79 80/***************************************************************************** 81** Local function prototypes 82*****************************************************************************/ 83#if (BT_TRACE_VERBOSE == TRUE) 84static char* nfa_dm_evt_2_str(uint16_t event); 85#endif 86/******************************************************************************* 87** 88** Function nfa_dm_init 89** 90** Description Initialises the NFC device manager 91** 92** Returns void 93** 94*******************************************************************************/ 95void nfa_dm_init(void) { 96 NFA_TRACE_DEBUG0("nfa_dm_init ()"); 97 memset(&nfa_dm_cb, 0, sizeof(tNFA_DM_CB)); 98 nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID; 99 nfa_dm_cb.disc_cb.disc_duration = NFA_DM_DISC_DURATION_POLL; 100 nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_FULL; 101 102 /* register message handler on NFA SYS */ 103 nfa_sys_register(NFA_ID_DM, &nfa_dm_sys_reg); 104} 105 106/******************************************************************************* 107** 108** Function nfa_dm_evt_hdlr 109** 110** Description Event handling function for DM 111** 112** 113** Returns void 114** 115*******************************************************************************/ 116bool nfa_dm_evt_hdlr(NFC_HDR* p_msg) { 117 bool freebuf = true; 118 uint16_t event = p_msg->event & 0x00ff; 119 120#if (BT_TRACE_VERBOSE == TRUE) 121 NFA_TRACE_EVENT2("nfa_dm_evt_hdlr event: %s (0x%02x)", 122 nfa_dm_evt_2_str(event), event); 123#else 124 NFA_TRACE_EVENT1("nfa_dm_evt_hdlr event: 0x%x", event); 125#endif 126 127 /* execute action functions */ 128 if (event < NFA_DM_NUM_ACTIONS) { 129 freebuf = (*nfa_dm_action[event])((tNFA_DM_MSG*)p_msg); 130 } 131 return freebuf; 132} 133 134/******************************************************************************* 135** 136** Function nfa_dm_sys_disable 137** 138** Description This function is called after all subsystems have been 139** disabled. 140** 141** Returns void 142** 143*******************************************************************************/ 144void nfa_dm_sys_disable(void) { 145 /* Disable the DM sub-system */ 146 /* If discovery state is not IDLE or DEACTIVATED and graceful disable, */ 147 /* then we need to deactivate link or stop discovery */ 148 149 if (nfa_sys_is_graceful_disable()) { 150 if ((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) && 151 ((nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING) == 0)) { 152 /* discovery is not started */ 153 nfa_dm_disable_complete(); 154 } else { 155 /* probably waiting to be disabled */ 156 NFA_TRACE_WARNING2("DM disc_state state = %d disc_flags:0x%x", 157 nfa_dm_cb.disc_cb.disc_state, 158 nfa_dm_cb.disc_cb.disc_flags); 159 } 160 161 } else { 162 nfa_dm_disable_complete(); 163 } 164} 165 166/******************************************************************************* 167** 168** Function nfa_dm_is_protocol_supported 169** 170** Description Check if protocol is supported by RW module 171** 172** Returns TRUE if protocol is supported by NFA 173** 174*******************************************************************************/ 175bool nfa_dm_is_protocol_supported(tNFC_PROTOCOL protocol, uint8_t sel_res) { 176 return ((protocol == NFC_PROTOCOL_T1T) || 177 ((protocol == NFC_PROTOCOL_T2T) && 178 (sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) || 179 (protocol == NFC_PROTOCOL_T3T) || 180 (protocol == NFC_PROTOCOL_ISO_DEP) || 181 (protocol == NFC_PROTOCOL_NFC_DEP) || (protocol == NFC_PROTOCOL_T5T)); 182} 183/******************************************************************************* 184** 185** Function nfa_dm_is_active 186** 187** Description check if all modules of NFA is done with enable process and 188** NFA is not restoring NFCC. 189** 190** Returns TRUE, if NFA_DM_ENABLE_EVT is reported and it is not 191** restoring NFCC 192** 193*******************************************************************************/ 194bool nfa_dm_is_active(void) { 195 NFA_TRACE_DEBUG1("nfa_dm_is_active () flags:0x%x", nfa_dm_cb.flags); 196 if ((nfa_dm_cb.flags & NFA_DM_FLAGS_DM_IS_ACTIVE) && 197 ((nfa_dm_cb.flags & 198 (NFA_DM_FLAGS_ENABLE_EVT_PEND | NFA_DM_FLAGS_NFCC_IS_RESTORING | 199 NFA_DM_FLAGS_POWER_OFF_SLEEP)) == 0)) { 200 return true; 201 } else 202 return false; 203} 204/******************************************************************************* 205** 206** Function nfa_dm_check_set_config 207** 208** Description Update config parameters only if it's different from NFCC 209** 210** 211** Returns tNFA_STATUS 212** 213*******************************************************************************/ 214tNFA_STATUS nfa_dm_check_set_config(uint8_t tlv_list_len, uint8_t* p_tlv_list, 215 bool app_init) { 216 uint8_t type, len, *p_value, *p_stored, max_len; 217 uint8_t xx = 0, updated_len = 0, *p_cur_len; 218 bool update; 219 tNFC_STATUS nfc_status; 220 uint32_t cur_bit; 221 222 NFA_TRACE_DEBUG0("nfa_dm_check_set_config ()"); 223 224 /* We only allow 32 pending SET_CONFIGs */ 225 if (nfa_dm_cb.setcfg_pending_num >= NFA_DM_SETCONFIG_PENDING_MAX) { 226 NFA_TRACE_ERROR0( 227 "nfa_dm_check_set_config () error: pending number of SET_CONFIG " 228 "exceeded"); 229 return NFA_STATUS_FAILED; 230 } 231 232 while (tlv_list_len - xx >= 2) /* at least type and len */ 233 { 234 update = false; 235 type = *(p_tlv_list + xx); 236 len = *(p_tlv_list + xx + 1); 237 p_value = p_tlv_list + xx + 2; 238 p_cur_len = NULL; 239 240 switch (type) { 241 /* 242 ** Poll F Configuration 243 */ 244 case NFC_PMID_PF_RC: 245 p_stored = nfa_dm_cb.params.pf_rc; 246 max_len = NCI_PARAM_LEN_PF_RC; 247 break; 248 case NFC_PMID_TOTAL_DURATION: 249 p_stored = nfa_dm_cb.params.total_duration; 250 max_len = NCI_PARAM_LEN_TOTAL_DURATION; 251 break; 252 253 /* 254 ** Listen A Configuration 255 */ 256 case NFC_PMID_LA_BIT_FRAME_SDD: 257 p_stored = nfa_dm_cb.params.la_bit_frame_sdd; 258 max_len = NCI_PARAM_LEN_LA_BIT_FRAME_SDD; 259 p_cur_len = &nfa_dm_cb.params.la_bit_frame_sdd_len; 260 break; 261 case NFC_PMID_LA_PLATFORM_CONFIG: 262 p_stored = nfa_dm_cb.params.la_platform_config; 263 max_len = NCI_PARAM_LEN_LA_PLATFORM_CONFIG; 264 p_cur_len = &nfa_dm_cb.params.la_platform_config_len; 265 break; 266 case NFC_PMID_LA_SEL_INFO: 267 p_stored = nfa_dm_cb.params.la_sel_info; 268 max_len = NCI_PARAM_LEN_LA_SEL_INFO; 269 p_cur_len = &nfa_dm_cb.params.la_sel_info_len; 270 break; 271 case NFC_PMID_LA_NFCID1: 272 p_stored = nfa_dm_cb.params.la_nfcid1; 273 max_len = NCI_NFCID1_MAX_LEN; 274 p_cur_len = &nfa_dm_cb.params.la_nfcid1_len; 275 break; 276 case NFC_PMID_LA_HIST_BY: 277 p_stored = nfa_dm_cb.params.la_hist_by; 278 max_len = NCI_MAX_HIS_BYTES_LEN; 279 p_cur_len = &nfa_dm_cb.params.la_hist_by_len; 280 break; 281 282 /* 283 ** Listen B Configuration 284 */ 285 case NFC_PMID_LB_SENSB_INFO: 286 p_stored = nfa_dm_cb.params.lb_sensb_info; 287 max_len = NCI_PARAM_LEN_LB_SENSB_INFO; 288 p_cur_len = &nfa_dm_cb.params.lb_sensb_info_len; 289 break; 290 case NFC_PMID_LB_NFCID0: 291 p_stored = nfa_dm_cb.params.lb_nfcid0; 292 max_len = NCI_PARAM_LEN_LB_NFCID0; 293 p_cur_len = &nfa_dm_cb.params.lb_nfcid0_len; 294 break; 295 case NFC_PMID_LB_APPDATA: 296 p_stored = nfa_dm_cb.params.lb_appdata; 297 max_len = NCI_PARAM_LEN_LB_APPDATA; 298 p_cur_len = &nfa_dm_cb.params.lb_appdata_len; 299 break; 300 case NFC_PMID_LB_ADC_FO: 301 p_stored = nfa_dm_cb.params.lb_adc_fo; 302 max_len = NCI_PARAM_LEN_LB_ADC_FO; 303 p_cur_len = &nfa_dm_cb.params.lb_adc_fo_len; 304 break; 305 case NFC_PMID_LB_H_INFO: 306 p_stored = nfa_dm_cb.params.lb_h_info; 307 max_len = NCI_MAX_ATTRIB_LEN; 308 p_cur_len = &nfa_dm_cb.params.lb_h_info_len; 309 break; 310 311 /* 312 ** Listen F Configuration 313 */ 314 case NFC_PMID_LF_PROTOCOL: 315 p_stored = nfa_dm_cb.params.lf_protocol; 316 max_len = NCI_PARAM_LEN_LF_PROTOCOL; 317 p_cur_len = &nfa_dm_cb.params.lf_protocol_len; 318 break; 319 case NFC_PMID_LF_T3T_FLAGS2: 320 p_stored = nfa_dm_cb.params.lf_t3t_flags2; 321 max_len = NCI_PARAM_LEN_LF_T3T_FLAGS2; 322 p_cur_len = &nfa_dm_cb.params.lf_t3t_flags2_len; 323 break; 324 case NFC_PMID_LF_T3T_PMM: 325 p_stored = nfa_dm_cb.params.lf_t3t_pmm; 326 max_len = NCI_PARAM_LEN_LF_T3T_PMM; 327 break; 328 329 /* 330 ** ISO-DEP and NFC-DEP Configuration 331 */ 332 case NFC_PMID_FWI: 333 p_stored = nfa_dm_cb.params.fwi; 334 max_len = NCI_PARAM_LEN_FWI; 335 break; 336 case NFC_PMID_WT: 337 p_stored = nfa_dm_cb.params.wt; 338 max_len = NCI_PARAM_LEN_WT; 339 break; 340 case NFC_PMID_ATR_REQ_GEN_BYTES: 341 p_stored = nfa_dm_cb.params.atr_req_gen_bytes; 342 max_len = NCI_MAX_GEN_BYTES_LEN; 343 p_cur_len = &nfa_dm_cb.params.atr_req_gen_bytes_len; 344 break; 345 case NFC_PMID_ATR_RES_GEN_BYTES: 346 p_stored = nfa_dm_cb.params.atr_res_gen_bytes; 347 max_len = NCI_MAX_GEN_BYTES_LEN; 348 p_cur_len = &nfa_dm_cb.params.atr_res_gen_bytes_len; 349 break; 350 default: 351 /* 352 ** Listen F Configuration 353 */ 354 if ((type >= NFC_PMID_LF_T3T_ID1) && 355 (type < NFC_PMID_LF_T3T_ID1 + NFA_CE_LISTEN_INFO_MAX)) { 356 p_stored = nfa_dm_cb.params.lf_t3t_id[type - NFC_PMID_LF_T3T_ID1]; 357 max_len = NCI_PARAM_LEN_LF_T3T_ID(NFC_GetNCIVersion()); 358 } else { 359 /* we don't stored this config items */ 360 update = true; 361 p_stored = NULL; 362 } 363 break; 364 } 365 366 if ((p_stored) && (len <= max_len)) { 367 if (p_cur_len) { 368 if (*p_cur_len != len) { 369 *p_cur_len = len; 370 update = true; 371 } else if (memcmp(p_value, p_stored, len)) { 372 update = true; 373 } else if (appl_dta_mode_flag && app_init) { 374 /* In DTA mode, config update is forced so that length of config 375 * params (i.e update_len) is updated accordingly even for setconfig 376 * have only one tlv */ 377 update = true; 378 } 379 } else if (len == max_len) /* fixed length */ 380 { 381 if (memcmp(p_value, p_stored, len)) { 382 update = true; 383 } else if (appl_dta_mode_flag && app_init) { 384 /* In DTA mode, config update is forced so that length of config 385 * params (i.e update_len) is updated accordingly even for setconfig 386 * have only one tlv */ 387 update = true; 388 } 389 } 390 } 391 392 if (update) { 393 /* we don't store this type */ 394 if (p_stored) { 395 memcpy(p_stored, p_value, len); 396 } 397 398 /* If need to change TLV in the original list. (Do not modify list if 399 * app_init) */ 400 if ((updated_len != xx) && (!app_init)) { 401 memcpy(p_tlv_list + updated_len, p_tlv_list + xx, (len + 2)); 402 } 403 updated_len += (len + 2); 404 } 405 xx += len + 2; /* move to next TLV */ 406 } 407 408 /* If any TVLs to update, or if the SetConfig was initiated by the 409 * application, then send the SET_CONFIG command */ 410 if (((updated_len || app_init) && 411 (appl_dta_mode_flag == 0x00 || 412 (nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_HCEF_MODE)) || 413 (appl_dta_mode_flag && app_init)) { 414 nfc_status = NFC_SetConfig(updated_len, p_tlv_list); 415 416 if (nfc_status == NFC_STATUS_OK) { 417 if ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_HCEF_MODE) { 418 nfa_dm_cb.eDtaMode &= ~NFA_DTA_HCEF_MODE; 419 nfa_dm_cb.eDtaMode |= NFA_DTA_DEFAULT_MODE; 420 } 421 /* Keep track of whether we will need to notify NFA_DM_SET_CONFIG_EVT on 422 * NFC_SET_CONFIG_REVT */ 423 424 /* Get the next available bit offset for this setconfig (based on how many 425 * SetConfigs are outstanding) */ 426 cur_bit = (uint32_t)(1 << nfa_dm_cb.setcfg_pending_num); 427 428 /* If setconfig is due to NFA_SetConfig: then set the bit 429 * (NFA_DM_SET_CONFIG_EVT needed on NFC_SET_CONFIG_REVT) */ 430 if (app_init) { 431 nfa_dm_cb.setcfg_pending_mask |= cur_bit; 432 } 433 /* Otherwise setconfig is internal: clear the bit (NFA_DM_SET_CONFIG_EVT 434 not needed on NFC_SET_CONFIG_REVT) */ 435 else { 436 nfa_dm_cb.setcfg_pending_mask &= ~cur_bit; 437 } 438 439 /* Increment setcfg_pending counter */ 440 nfa_dm_cb.setcfg_pending_num++; 441 } 442 return (nfc_status); 443 444 } else { 445 return NFA_STATUS_OK; 446 } 447} 448 449#if (BT_TRACE_VERBOSE == TRUE) 450/******************************************************************************* 451** 452** Function nfa_dm_nfc_revt_2_str 453** 454** Description convert nfc revt to string 455** 456*******************************************************************************/ 457static char* nfa_dm_evt_2_str(uint16_t event) { 458 switch (NFA_SYS_EVT_START(NFA_ID_DM) | event) { 459 case NFA_DM_API_ENABLE_EVT: 460 return "NFA_DM_API_ENABLE_EVT"; 461 462 case NFA_DM_API_DISABLE_EVT: 463 return "NFA_DM_API_DISABLE_EVT"; 464 465 case NFA_DM_API_SET_CONFIG_EVT: 466 return "NFA_DM_API_SET_CONFIG_EVT"; 467 468 case NFA_DM_API_GET_CONFIG_EVT: 469 return "NFA_DM_API_GET_CONFIG_EVT"; 470 471 case NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT: 472 return "NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT"; 473 474 case NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT: 475 return "NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT"; 476 477 case NFA_DM_API_ENABLE_POLLING_EVT: 478 return "NFA_DM_API_ENABLE_POLLING_EVT"; 479 480 case NFA_DM_API_DISABLE_POLLING_EVT: 481 return "NFA_DM_API_DISABLE_POLLING_EVT"; 482 483 case NFA_DM_API_ENABLE_LISTENING_EVT: 484 return "NFA_DM_API_ENABLE_LISTENING_EVT"; 485 486 case NFA_DM_API_DISABLE_LISTENING_EVT: 487 return "NFA_DM_API_DISABLE_LISTENING_EVT"; 488 489 case NFA_DM_API_PAUSE_P2P_EVT: 490 return "NFA_DM_API_PAUSE_P2P_EVT"; 491 492 case NFA_DM_API_RESUME_P2P_EVT: 493 return "NFA_DM_API_RESUME_P2P_EVT"; 494 495 case NFA_DM_API_RAW_FRAME_EVT: 496 return "NFA_DM_API_RAW_FRAME_EVT"; 497 498 case NFA_DM_API_SET_P2P_LISTEN_TECH_EVT: 499 return "NFA_DM_API_SET_P2P_LISTEN_TECH_EVT"; 500 501 case NFA_DM_API_START_RF_DISCOVERY_EVT: 502 return "NFA_DM_API_START_RF_DISCOVERY_EVT"; 503 504 case NFA_DM_API_STOP_RF_DISCOVERY_EVT: 505 return "NFA_DM_API_STOP_RF_DISCOVERY_EVT"; 506 507 case NFA_DM_API_SET_RF_DISC_DURATION_EVT: 508 return "NFA_DM_API_SET_RF_DISC_DURATION_EVT"; 509 510 case NFA_DM_API_SELECT_EVT: 511 return "NFA_DM_API_SELECT_EVT"; 512 513 case NFA_DM_API_UPDATE_RF_PARAMS_EVT: 514 return "NFA_DM_API_UPDATE_RF_PARAMS_EVT"; 515 516 case NFA_DM_API_DEACTIVATE_EVT: 517 return "NFA_DM_API_DEACTIVATE_EVT"; 518 519 case NFA_DM_API_POWER_OFF_SLEEP_EVT: 520 return "NFA_DM_API_POWER_OFF_SLEEP_EVT"; 521 522 case NFA_DM_API_REG_NDEF_HDLR_EVT: 523 return "NFA_DM_API_REG_NDEF_HDLR_EVT"; 524 525 case NFA_DM_API_DEREG_NDEF_HDLR_EVT: 526 return "NFA_DM_API_DEREG_NDEF_HDLR_EVT"; 527 528 case NFA_DM_TIMEOUT_DISABLE_EVT: 529 return "NFA_DM_TIMEOUT_DISABLE_EVT"; 530 531 case NFA_DM_API_SET_POWER_SUB_STATE_EVT: 532 return "NFA_DM_API_SET_POWER_SUB_STATE_EVT"; 533 } 534 535 return "Unknown or Vendor Specific"; 536} 537#endif /* BT_TRACE_VERBOSE */ 538