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*******************************************************************************/ 43tNFA_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*******************************************************************************/ 113tNFA_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*******************************************************************************/ 193tNFA_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*******************************************************************************/ 246tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH(uint16_t system_code, 247 uint8_t nfcid2[NCI_RF_F_UID_LEN], 248 uint8_t t3tPmm[NCI_T3T_PMM_LEN], 249 tNFA_CONN_CBACK* p_conn_cback) { 250 tNFA_CE_MSG* p_msg; 251 252 NFA_TRACE_API0("NFA_CeRegisterFelicaSystemCodeOnDH ()"); 253 254 /* Validate parameters */ 255 if (p_conn_cback == NULL) return (NFA_STATUS_INVALID_PARAM); 256 257 p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG)); 258 if (p_msg != NULL) { 259 p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT; 260 p_msg->reg_listen.p_conn_cback = p_conn_cback; 261 p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_FELICA; 262 263 /* Listen info */ 264 memcpy(p_msg->reg_listen.nfcid2, nfcid2, NCI_RF_F_UID_LEN); 265 memcpy(p_msg->reg_listen.t3tPmm, t3tPmm, NCI_T3T_PMM_LEN); 266 p_msg->reg_listen.system_code = system_code; 267 268 nfa_sys_sendmsg(p_msg); 269 270 return (NFA_STATUS_OK); 271 } 272 273 return (NFA_STATUS_FAILED); 274} 275 276/******************************************************************************* 277** 278** Function NFA_CeDeregisterFelicaSystemCodeOnDH 279** 280** Description Deregister listening callback for Felica 281** (previously registered using 282** NFA_CeRegisterFelicaSystemCodeOnDH) 283** 284** The NFA_CE_DEREGISTERED_EVT reports the status of the 285** operation. 286** 287** Note: If RF discovery is started, 288** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 289** happen before calling this function 290** 291** Returns NFA_STATUS_OK if successfully initiated 292** NFA_STATUS_BAD_HANDLE if invalid handle 293** NFA_STATUS_FAILED otherwise 294** 295*******************************************************************************/ 296tNFA_STATUS NFA_CeDeregisterFelicaSystemCodeOnDH(tNFA_HANDLE handle) { 297 NFA_TRACE_API1("NFA_CeDeregisterFelicaSystemCodeOnDH (): handle:0x%X", 298 handle); 299 return (nfa_ce_api_deregister_listen(handle, NFA_CE_LISTEN_INFO_FELICA)); 300} 301 302/******************************************************************************* 303** 304** Function NFA_CeRegisterAidOnDH 305** 306** Description Register listening callback for the specified ISODEP AID 307** 308** The NFA_CE_REGISTERED_EVT reports the status of the 309** operation. 310** 311** If no AID is specified (aid_len=0), then p_conn_cback will 312** will get notifications for any AIDs routed to the DH. This 313** over-rides callbacks registered for specific AIDs. 314** 315** Note: If RF discovery is started, 316** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 317** happen before calling this function 318** 319** Returns: 320** NFA_STATUS_OK, if command accepted 321** NFA_STATUS_FAILED: otherwise 322** 323*******************************************************************************/ 324tNFA_STATUS NFA_CeRegisterAidOnDH(uint8_t aid[NFC_MAX_AID_LEN], uint8_t aid_len, 325 tNFA_CONN_CBACK* p_conn_cback) { 326 tNFA_CE_MSG* p_msg; 327 328 NFA_TRACE_API0("NFA_CeRegisterAidOnDH ()"); 329 330 /* Validate parameters */ 331 if (p_conn_cback == NULL) return (NFA_STATUS_INVALID_PARAM); 332 333 p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG)); 334 if (p_msg != NULL) { 335 p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT; 336 p_msg->reg_listen.p_conn_cback = p_conn_cback; 337 p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_ISO_DEP; 338 339 /* Listen info */ 340 memcpy(p_msg->reg_listen.aid, aid, aid_len); 341 p_msg->reg_listen.aid_len = aid_len; 342 343 nfa_sys_sendmsg(p_msg); 344 345 return (NFA_STATUS_OK); 346 } 347 348 return (NFA_STATUS_FAILED); 349} 350 351/******************************************************************************* 352** 353** Function NFA_CeDeregisterAidOnDH 354** 355** Description Deregister listening callback for ISODEP AID 356** (previously registered using NFA_CeRegisterAidOnDH) 357** 358** The NFA_CE_DEREGISTERED_EVT reports the status of the 359** operation. 360** 361** Note: If RF discovery is started, 362** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 363** happen before calling this function 364** 365** Returns NFA_STATUS_OK if successfully initiated 366** NFA_STATUS_BAD_HANDLE if invalid handle 367** NFA_STATUS_FAILED otherwise 368** 369*******************************************************************************/ 370tNFA_STATUS NFA_CeDeregisterAidOnDH(tNFA_HANDLE handle) { 371 NFA_TRACE_API1("NFA_CeDeregisterAidOnDH (): handle:0x%X", handle); 372 return (nfa_ce_api_deregister_listen(handle, NFA_CE_LISTEN_INFO_T4T_AID)); 373} 374 375/******************************************************************************* 376** 377** Function NFA_CeSetIsoDepListenTech 378** 379** Description Set the technologies (NFC-A and/or NFC-B) to listen for when 380** NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are 381** called. 382** 383** By default (if this API is not called), NFA will listen 384** for both NFC-A and NFC-B for ISODEP. 385** 386** Note: If listening for ISODEP on UICC, the DH listen callbacks 387** may still get activate notifications for ISODEP if the 388** reader/writer selects an AID that is not routed to the UICC 389** (regardless of whether A or B was disabled using 390** NFA_CeSetIsoDepListenTech) 391** 392** Note: If RF discovery is started, 393** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 394** happen before calling this function 395** 396** Returns: 397** NFA_STATUS_OK, if command accepted 398** NFA_STATUS_FAILED: otherwise 399** 400*******************************************************************************/ 401tNFA_STATUS NFA_CeSetIsoDepListenTech(tNFA_TECHNOLOGY_MASK tech_mask) { 402 tNFA_CE_MSG* p_msg; 403 tNFA_TECHNOLOGY_MASK use_mask = 404 (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B); 405 406 NFA_TRACE_API1("NFA_CeSetIsoDepListenTech (): 0x%x", tech_mask); 407 if (((tech_mask & use_mask) == 0) || ((tech_mask & ~use_mask) != 0)) { 408 NFA_TRACE_ERROR0("NFA_CeSetIsoDepListenTech: Invalid technology mask"); 409 return (NFA_STATUS_INVALID_PARAM); 410 } 411 412 p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG)); 413 if (p_msg != NULL) { 414 p_msg->hdr.event = NFA_CE_API_CFG_ISODEP_TECH_EVT; 415 p_msg->hdr.layer_specific = tech_mask; 416 417 nfa_sys_sendmsg(p_msg); 418 419 return (NFA_STATUS_OK); 420 } 421 422 return (NFA_STATUS_FAILED); 423} 424