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