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