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 * NFA interface for card emulation 22 * 23 ******************************************************************************/ 24 #include <string.h> 25 #include "nfa_api.h" 26 #include "nfa_ce_int.h" 27 #include "nfa_sys.h" 28 #include "nfa_sys_int.h" 29 30 /******************************************************************************* 31 ** 32 ** Function nfa_ce_api_deregister_listen 33 ** 34 ** Description Internal function called by listening for Felica system 35 ** code, ISO-DEP AID, or UICC technology 36 ** 37 ** Returns: 38 ** NFA_STATUS_OK, if command accepted 39 ** NFA_STATUS_BAD_HANDLE invalid handle 40 ** NFA_STATUS_FAILED: otherwise 41 ** 42 *******************************************************************************/ 43 tNFA_STATUS nfa_ce_api_deregister_listen(tNFA_HANDLE handle, 44 uint32_t listen_info) { 45 tNFA_CE_MSG* p_ce_msg; 46 47 /* Validate handle */ 48 if ((listen_info != NFA_CE_LISTEN_INFO_UICC) && 49 ((handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_CE)) { 50 NFA_TRACE_ERROR0("nfa_ce_api_reregister_listen: Invalid handle"); 51 return (NFA_STATUS_BAD_HANDLE); 52 } 53 54 p_ce_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)(sizeof(tNFA_CE_MSG))); 55 if (p_ce_msg != NULL) { 56 p_ce_msg->hdr.event = NFA_CE_API_DEREG_LISTEN_EVT; 57 p_ce_msg->dereg_listen.handle = handle; 58 p_ce_msg->dereg_listen.listen_info = listen_info; 59 60 nfa_sys_sendmsg(p_ce_msg); 61 62 return (NFA_STATUS_OK); 63 } else { 64 NFA_TRACE_ERROR0("nfa_ce_api_reregister_listen: Out of buffers"); 65 return (NFA_STATUS_FAILED); 66 } 67 } 68 69 /***************************************************************************** 70 ** APIs 71 *****************************************************************************/ 72 73 /******************************************************************************* 74 ** 75 ** Function NFA_CeConfigureLocalTag 76 ** 77 ** Description Configure local NDEF tag. 78 ** 79 ** Tag events will be notifed using the tNFA_CONN_CBACK 80 ** (registered during NFA_Enable) 81 ** 82 ** The NFA_CE_LOCAL_TAG_CONFIGURED_EVT reports the status of 83 ** the operation. 84 ** 85 ** Activation and deactivation are reported using the 86 ** NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events 87 ** 88 ** If a write-request is received to update the tag memory, 89 ** an NFA_CE_NDEF_WRITE_CPLT_EVT will notify the application, 90 ** along with a buffer containing the updated contents. 91 ** 92 ** To disable the local NDEF tag, set protocol_mask=0 93 ** 94 ** The NDEF data provided by p_ndef_data must be persistent 95 ** as long as the local NDEF tag is enabled. 96 ** 97 ** 98 ** Note: If RF discovery is started, 99 ** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 100 ** happen before calling this function. Also, Input parameters 101 ** p_uid and uid_len are reserved for future use. 102 ** 103 ** Returns: 104 ** NFA_STATUS_OK, if command accepted 105 ** NFA_STATUS_INVALID_PARAM, 106 ** if protocol_maks is not 0 and p_ndef_data is NULL 107 ** (or)uid_len is not 0 108 ** (or)if protocol mask is set for Type 1 or Type 2 109 ** 110 ** NFA_STATUS_FAILED: otherwise 111 ** 112 *******************************************************************************/ 113 tNFA_STATUS NFA_CeConfigureLocalTag(tNFA_PROTOCOL_MASK protocol_mask, 114 uint8_t* p_ndef_data, 115 uint16_t ndef_cur_size, 116 uint16_t ndef_max_size, bool read_only, 117 uint8_t uid_len, uint8_t* p_uid) 118 119 { 120 tNFA_CE_MSG* p_msg; 121 122 NFA_TRACE_API0("NFA_CeConfigureLocalTag ()"); 123 124 if (protocol_mask) { 125 /* If any protocols are specified, then NDEF buffer pointer must be non-NULL 126 */ 127 if (p_ndef_data == NULL) { 128 NFA_TRACE_ERROR0("NFA_CeConfigureLocalTag: NULL ndef data pointer"); 129 return (NFA_STATUS_INVALID_PARAM); 130 } 131 132 if ((protocol_mask & NFA_PROTOCOL_MASK_T1T) || 133 (protocol_mask & NFA_PROTOCOL_MASK_T2T)) { 134 NFA_TRACE_ERROR0( 135 "NFA_CeConfigureLocalTag: Cannot emulate Type 1 / Type 2 tag"); 136 return (NFA_STATUS_INVALID_PARAM); 137 } 138 139 if (uid_len) { 140 NFA_TRACE_ERROR1( 141 "NFA_CeConfigureLocalTag: Cannot Set UID for Protocol_mask: 0x%x", 142 protocol_mask); 143 return (NFA_STATUS_INVALID_PARAM); 144 } 145 } 146 p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG)); 147 if (p_msg != NULL) { 148 p_msg->local_tag.hdr.event = NFA_CE_API_CFG_LOCAL_TAG_EVT; 149 150 /* Copy ndef info */ 151 p_msg->local_tag.protocol_mask = protocol_mask; 152 p_msg->local_tag.p_ndef_data = p_ndef_data; 153 p_msg->local_tag.ndef_cur_size = ndef_cur_size; 154 p_msg->local_tag.ndef_max_size = ndef_max_size; 155 p_msg->local_tag.read_only = read_only; 156 p_msg->local_tag.uid_len = uid_len; 157 158 if (uid_len) memcpy(p_msg->local_tag.uid, p_uid, uid_len); 159 160 nfa_sys_sendmsg(p_msg); 161 162 return (NFA_STATUS_OK); 163 } 164 165 return (NFA_STATUS_FAILED); 166 } 167 168 /******************************************************************************* 169 ** 170 ** Function NFA_CeConfigureUiccListenTech 171 ** 172 ** Description Configure listening for the UICC, using the specified 173 ** technologies. 174 ** 175 ** Events will be notifed using the tNFA_CONN_CBACK 176 ** (registered during NFA_Enable) 177 ** 178 ** The NFA_CE_UICC_LISTEN_CONFIGURED_EVT reports the status of 179 ** the operation. 180 ** 181 ** Activation and deactivation are reported using the 182 ** NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events 183 ** 184 ** Note: If RF discovery is started, 185 ** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 186 ** happen before calling this function 187 ** 188 ** Returns: 189 ** NFA_STATUS_OK, if command accepted 190 ** NFA_STATUS_FAILED: otherwise 191 ** 192 *******************************************************************************/ 193 tNFA_STATUS NFA_CeConfigureUiccListenTech(tNFA_HANDLE ee_handle, 194 tNFA_TECHNOLOGY_MASK tech_mask) { 195 #if (NFC_NFCEE_INCLUDED == TRUE) 196 tNFA_CE_MSG* p_msg; 197 198 NFA_TRACE_API1("NFA_CeConfigureUiccListenTech () ee_handle = 0x%x", 199 ee_handle); 200 201 /* If tech_mask is zero, then app is disabling listening for specified uicc */ 202 if (tech_mask == 0) { 203 return (nfa_ce_api_deregister_listen(ee_handle, NFA_CE_LISTEN_INFO_UICC)); 204 } 205 206 /* Otherwise then app is configuring uicc listen for the specificed 207 * technologies */ 208 p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG)); 209 if (p_msg != NULL) { 210 p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT; 211 p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_UICC; 212 213 p_msg->reg_listen.ee_handle = ee_handle; 214 p_msg->reg_listen.tech_mask = tech_mask; 215 216 nfa_sys_sendmsg(p_msg); 217 218 return (NFA_STATUS_OK); 219 } 220 #else 221 NFA_TRACE_ERROR0( 222 "NFA_CeConfigureUiccListenTech () NFCEE related functions are not " 223 "enabled!"); 224 #endif 225 return (NFA_STATUS_FAILED); 226 } 227 228 /******************************************************************************* 229 ** 230 ** Function NFA_CeRegisterFelicaSystemCodeOnDH 231 ** 232 ** Description Register listening callback for Felica system code 233 ** 234 ** The NFA_CE_REGISTERED_EVT reports the status of the 235 ** operation. 236 ** 237 ** Note: If RF discovery is started, 238 ** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 239 ** happen before calling this function 240 ** 241 ** Returns: 242 ** NFA_STATUS_OK, if command accepted 243 ** NFA_STATUS_FAILED: otherwise 244 ** 245 *******************************************************************************/ 246 tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH(uint16_t system_code, 247 uint8_t nfcid2[NCI_RF_F_UID_LEN], 248 tNFA_CONN_CBACK* p_conn_cback) { 249 tNFA_CE_MSG* p_msg; 250 251 NFA_TRACE_API0("NFA_CeRegisterFelicaSystemCodeOnDH ()"); 252 253 /* Validate parameters */ 254 if (p_conn_cback == NULL) return (NFA_STATUS_INVALID_PARAM); 255 256 p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG)); 257 if (p_msg != NULL) { 258 p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT; 259 p_msg->reg_listen.p_conn_cback = p_conn_cback; 260 p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_FELICA; 261 262 /* Listen info */ 263 memcpy(p_msg->reg_listen.nfcid2, nfcid2, NCI_RF_F_UID_LEN); 264 p_msg->reg_listen.system_code = system_code; 265 266 nfa_sys_sendmsg(p_msg); 267 268 return (NFA_STATUS_OK); 269 } 270 271 return (NFA_STATUS_FAILED); 272 } 273 274 /******************************************************************************* 275 ** 276 ** Function NFA_CeDeregisterFelicaSystemCodeOnDH 277 ** 278 ** Description Deregister listening callback for Felica 279 ** (previously registered using 280 ** NFA_CeRegisterFelicaSystemCodeOnDH) 281 ** 282 ** The NFA_CE_DEREGISTERED_EVT reports the status of the 283 ** operation. 284 ** 285 ** Note: If RF discovery is started, 286 ** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 287 ** happen before calling this function 288 ** 289 ** Returns NFA_STATUS_OK if successfully initiated 290 ** NFA_STATUS_BAD_HANDLE if invalid handle 291 ** NFA_STATUS_FAILED otherwise 292 ** 293 *******************************************************************************/ 294 tNFA_STATUS NFA_CeDeregisterFelicaSystemCodeOnDH(tNFA_HANDLE handle) { 295 NFA_TRACE_API1("NFA_CeDeregisterFelicaSystemCodeOnDH (): handle:0x%X", 296 handle); 297 return (nfa_ce_api_deregister_listen(handle, NFA_CE_LISTEN_INFO_FELICA)); 298 } 299 300 /******************************************************************************* 301 ** 302 ** Function NFA_CeRegisterAidOnDH 303 ** 304 ** Description Register listening callback for the specified ISODEP AID 305 ** 306 ** The NFA_CE_REGISTERED_EVT reports the status of the 307 ** operation. 308 ** 309 ** If no AID is specified (aid_len=0), then p_conn_cback will 310 ** will get notifications for any AIDs routed to the DH. This 311 ** over-rides callbacks registered for specific AIDs. 312 ** 313 ** Note: If RF discovery is started, 314 ** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 315 ** happen before calling this function 316 ** 317 ** Returns: 318 ** NFA_STATUS_OK, if command accepted 319 ** NFA_STATUS_FAILED: otherwise 320 ** 321 *******************************************************************************/ 322 tNFA_STATUS NFA_CeRegisterAidOnDH(uint8_t aid[NFC_MAX_AID_LEN], uint8_t aid_len, 323 tNFA_CONN_CBACK* p_conn_cback) { 324 tNFA_CE_MSG* p_msg; 325 326 NFA_TRACE_API0("NFA_CeRegisterAidOnDH ()"); 327 328 /* Validate parameters */ 329 if (p_conn_cback == NULL) return (NFA_STATUS_INVALID_PARAM); 330 331 p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG)); 332 if (p_msg != NULL) { 333 p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT; 334 p_msg->reg_listen.p_conn_cback = p_conn_cback; 335 p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_ISO_DEP; 336 337 /* Listen info */ 338 memcpy(p_msg->reg_listen.aid, aid, aid_len); 339 p_msg->reg_listen.aid_len = aid_len; 340 341 nfa_sys_sendmsg(p_msg); 342 343 return (NFA_STATUS_OK); 344 } 345 346 return (NFA_STATUS_FAILED); 347 } 348 349 /******************************************************************************* 350 ** 351 ** Function NFA_CeDeregisterAidOnDH 352 ** 353 ** Description Deregister listening callback for ISODEP AID 354 ** (previously registered using NFA_CeRegisterAidOnDH) 355 ** 356 ** The NFA_CE_DEREGISTERED_EVT reports the status of the 357 ** operation. 358 ** 359 ** Note: If RF discovery is started, 360 ** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 361 ** happen before calling this function 362 ** 363 ** Returns NFA_STATUS_OK if successfully initiated 364 ** NFA_STATUS_BAD_HANDLE if invalid handle 365 ** NFA_STATUS_FAILED otherwise 366 ** 367 *******************************************************************************/ 368 tNFA_STATUS NFA_CeDeregisterAidOnDH(tNFA_HANDLE handle) { 369 NFA_TRACE_API1("NFA_CeDeregisterAidOnDH (): handle:0x%X", handle); 370 return (nfa_ce_api_deregister_listen(handle, NFA_CE_LISTEN_INFO_T4T_AID)); 371 } 372 373 /******************************************************************************* 374 ** 375 ** Function NFA_CeSetIsoDepListenTech 376 ** 377 ** Description Set the technologies (NFC-A and/or NFC-B) to listen for when 378 ** NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are 379 ** called. 380 ** 381 ** By default (if this API is not called), NFA will listen 382 ** for both NFC-A and NFC-B for ISODEP. 383 ** 384 ** Note: If listening for ISODEP on UICC, the DH listen callbacks 385 ** may still get activate notifications for ISODEP if the 386 ** reader/writer selects an AID that is not routed to the UICC 387 ** (regardless of whether A or B was disabled using 388 ** NFA_CeSetIsoDepListenTech) 389 ** 390 ** Note: If RF discovery is started, 391 ** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 392 ** happen before calling this function 393 ** 394 ** Returns: 395 ** NFA_STATUS_OK, if command accepted 396 ** NFA_STATUS_FAILED: otherwise 397 ** 398 *******************************************************************************/ 399 tNFA_STATUS NFA_CeSetIsoDepListenTech(tNFA_TECHNOLOGY_MASK tech_mask) { 400 tNFA_CE_MSG* p_msg; 401 tNFA_TECHNOLOGY_MASK use_mask = 402 (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B); 403 404 NFA_TRACE_API1("NFA_CeSetIsoDepListenTech (): 0x%x", tech_mask); 405 if (((tech_mask & use_mask) == 0) || ((tech_mask & ~use_mask) != 0)) { 406 NFA_TRACE_ERROR0("NFA_CeSetIsoDepListenTech: Invalid technology mask"); 407 return (NFA_STATUS_INVALID_PARAM); 408 } 409 410 p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG)); 411 if (p_msg != NULL) { 412 p_msg->hdr.event = NFA_CE_API_CFG_ISODEP_TECH_EVT; 413 p_msg->hdr.layer_specific = tech_mask; 414 415 nfa_sys_sendmsg(p_msg); 416 417 return (NFA_STATUS_OK); 418 } 419 420 return (NFA_STATUS_FAILED); 421 } 422