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