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