1 /****************************************************************************** 2 * 3 * Copyright (C) 2011-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_CE 22 * 23 ******************************************************************************/ 24 #include <string.h> 25 #include "nfa_ce_api.h" 26 #include "nfa_ce_int.h" 27 #include "nfa_dm_int.h" 28 #include "nfa_sys.h" 29 #include "nfa_sys_int.h" 30 31 /* NFA_CE control block */ 32 tNFA_CE_CB nfa_ce_cb; 33 34 /***************************************************************************** 35 ** Constants and types 36 *****************************************************************************/ 37 #define NFA_CE_DEFAULT_ISODEP_DISC_MASK \ 38 (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LB_ISO_DEP) 39 static void nfa_ce_proc_nfcc_power_mode(uint8_t nfcc_power_mode); 40 41 static const tNFA_SYS_REG nfa_ce_sys_reg = { 42 NULL, nfa_ce_hdl_event, nfa_ce_sys_disable, nfa_ce_proc_nfcc_power_mode}; 43 44 /* NFA_CE actions */ 45 const tNFA_CE_ACTION nfa_ce_action_tbl[] = { 46 nfa_ce_api_cfg_local_tag, /* NFA_CE_API_CFG_LOCAL_TAG_EVT */ 47 nfa_ce_api_reg_listen, /* NFA_CE_API_REG_LISTEN_EVT */ 48 nfa_ce_api_dereg_listen, /* NFA_CE_API_DEREG_LISTEN_EVT */ 49 nfa_ce_api_cfg_isodep_tech, /* NFA_CE_API_CFG_ISODEP_TECH_EVT*/ 50 nfa_ce_activate_ntf, /* NFA_CE_ACTIVATE_NTF_EVT */ 51 nfa_ce_deactivate_ntf, /* NFA_CE_DEACTIVATE_NTF_EVT */ 52 }; 53 #define NFA_CE_ACTION_TBL_SIZE \ 54 (sizeof(nfa_ce_action_tbl) / sizeof(tNFA_CE_ACTION)) 55 56 /***************************************************************************** 57 ** Local function prototypes 58 *****************************************************************************/ 59 #if (BT_TRACE_VERBOSE == TRUE) 60 static char* nfa_ce_evt_2_str(uint16_t event); 61 #endif 62 63 /******************************************************************************* 64 ** 65 ** Function nfa_ce_init 66 ** 67 ** Description Initialize NFA CE 68 ** 69 ** Returns None 70 ** 71 *******************************************************************************/ 72 void nfa_ce_init(void) { 73 NFA_TRACE_DEBUG0("nfa_ce_init ()"); 74 75 /* initialize control block */ 76 memset(&nfa_ce_cb, 0, sizeof(tNFA_CE_CB)); 77 78 /* Generate a random NFCID for Type-3 NDEF emulation (Type-3 tag NFCID2 must 79 * start with 02:FE) */ 80 nfa_ce_t3t_generate_rand_nfcid( 81 nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_nfcid2); 82 nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = 83 NFA_HANDLE_INVALID; 84 nfa_ce_cb.isodep_disc_mask = NFA_CE_DEFAULT_ISODEP_DISC_MASK; 85 nfa_ce_cb.idx_wild_card = NFA_CE_LISTEN_INFO_IDX_INVALID; 86 87 /* register message handler on NFA SYS */ 88 nfa_sys_register(NFA_ID_CE, &nfa_ce_sys_reg); 89 } 90 91 /******************************************************************************* 92 ** 93 ** Function nfa_ce_sys_disable 94 ** 95 ** Description Clean up ce sub-system 96 ** 97 ** 98 ** Returns void 99 ** 100 *******************************************************************************/ 101 void nfa_ce_sys_disable(void) { 102 tNFA_CE_LISTEN_INFO* p_info; 103 uint8_t xx; 104 105 NFC_SetStaticRfCback(NULL); 106 107 /* Free scratch buf if any */ 108 nfa_ce_free_scratch_buf(); 109 110 /* Delete discovery handles */ 111 for (xx = 0, p_info = nfa_ce_cb.listen_info; xx < NFA_CE_LISTEN_INFO_MAX; 112 xx++, p_info++) { 113 if ((p_info->flags & NFA_CE_LISTEN_INFO_IN_USE) && 114 (p_info->rf_disc_handle != NFA_HANDLE_INVALID)) { 115 nfa_dm_delete_rf_discover(p_info->rf_disc_handle); 116 p_info->rf_disc_handle = NFA_HANDLE_INVALID; 117 } 118 } 119 120 nfa_sys_deregister(NFA_ID_CE); 121 } 122 123 /******************************************************************************* 124 ** 125 ** Function nfa_ce_proc_nfcc_power_mode 126 ** 127 ** Description Processing NFCC power mode changes 128 ** 129 ** Returns None 130 ** 131 *******************************************************************************/ 132 static void nfa_ce_proc_nfcc_power_mode(uint8_t nfcc_power_mode) { 133 tNFA_CE_CB* p_cb = &nfa_ce_cb; 134 uint8_t listen_info_idx; 135 136 NFA_TRACE_DEBUG1("nfa_ce_proc_nfcc_power_mode (): nfcc_power_mode=%d", 137 nfcc_power_mode); 138 139 /* if NFCC power mode is change to full power */ 140 if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) { 141 nfa_ce_restart_listen_check(); 142 } else { 143 for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID; 144 listen_info_idx++) { 145 /* add RF discovery to DM only if it is not added yet */ 146 if ((p_cb->listen_info[listen_info_idx].flags & 147 NFA_CE_LISTEN_INFO_IN_USE) && 148 (p_cb->listen_info[listen_info_idx].rf_disc_handle != 149 NFA_HANDLE_INVALID)) { 150 nfa_dm_delete_rf_discover( 151 p_cb->listen_info[listen_info_idx].rf_disc_handle); 152 p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID; 153 } 154 } 155 } 156 157 nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_CE); 158 } 159 160 /******************************************************************************* 161 ** 162 ** Function nfa_ce_hdl_event 163 ** 164 ** Description nfa rw main event handling function. 165 ** 166 ** Returns bool 167 ** 168 *******************************************************************************/ 169 bool nfa_ce_hdl_event(NFC_HDR* p_msg) { 170 uint16_t act_idx; 171 bool freebuf = true; 172 173 #if (BT_TRACE_VERBOSE == TRUE) 174 NFA_TRACE_EVENT3("nfa_ce_handle_event event: %s (0x%02x), flags: %08x", 175 nfa_ce_evt_2_str(p_msg->event), p_msg->event, 176 nfa_ce_cb.flags); 177 #else 178 NFA_TRACE_EVENT2("nfa_ce_handle_event event: 0x%x, flags: %08x", p_msg->event, 179 nfa_ce_cb.flags); 180 #endif 181 182 /* Get NFA_RW sub-event */ 183 act_idx = (p_msg->event & 0x00FF); 184 if (act_idx < NFA_CE_ACTION_TBL_SIZE) { 185 freebuf = (*nfa_ce_action_tbl[act_idx])((tNFA_CE_MSG*)p_msg); 186 } 187 188 /* if vendor specific event handler is registered */ 189 if (nfa_ce_cb.p_vs_evt_hdlr) { 190 (*nfa_ce_cb.p_vs_evt_hdlr)(p_msg); 191 } 192 193 return freebuf; 194 } 195 196 #if (BT_TRACE_VERBOSE == TRUE) 197 /******************************************************************************* 198 ** 199 ** Function nfa_ce_evt_2_str 200 ** 201 ** Description convert nfc evt to string 202 ** 203 *******************************************************************************/ 204 static char* nfa_ce_evt_2_str(uint16_t event) { 205 switch (event) { 206 case NFA_CE_API_CFG_LOCAL_TAG_EVT: 207 return "NFA_CE_API_CFG_LOCAL_TAG_EVT"; 208 209 case NFA_CE_API_REG_LISTEN_EVT: 210 return "NFA_CE_API_REG_LISTEN_EVT"; 211 212 case NFA_CE_API_DEREG_LISTEN_EVT: 213 return "NFA_CE_API_DEREG_LISTEN_EVT"; 214 215 case NFA_CE_API_CFG_ISODEP_TECH_EVT: 216 return "NFA_CE_API_CFG_ISODEP_TECH_EVT"; 217 218 case NFA_CE_ACTIVATE_NTF_EVT: 219 return "NFA_CE_ACTIVATE_NTF_EVT"; 220 221 case NFA_CE_DEACTIVATE_NTF_EVT: 222 return "NFA_CE_DEACTIVATE_NTF_EVT"; 223 224 default: 225 return "Unknown"; 226 } 227 } 228 #endif /* BT_TRACE_VERBOSE */ 229