1/******************************************************************************
2 *
3 *  Copyright (C) 2010-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 *  This file contains functions that interface with the NFC NCI transport.
23 *  On the receive side, it routes events to the appropriate handler
24 *  (callback). On the transmit side, it manages the command transmission.
25 *
26 ******************************************************************************/
27#include <string.h>
28#include "gki.h"
29#include "nfc_target.h"
30#include "bt_types.h"
31#include "hcidefs.h"
32
33#if (NFC_INCLUDED == TRUE)
34#include "nfc_hal_api.h"
35#include "nfc_api.h"
36#include "nfc_int.h"
37#include "nci_hmsgs.h"
38#include "rw_int.h"
39#include "ce_int.h"
40
41
42#if (NFC_RW_ONLY == FALSE)
43#include "ce_api.h"
44#include "ce_int.h"
45#include "llcp_int.h"
46
47/* NFC mandates support for at least one logical connection;
48 * Update max_conn to the NFCC capability on InitRsp */
49#define NFC_SET_MAX_CONN_DEFAULT()    {nfc_cb.max_conn = 1;}
50
51#else /* NFC_RW_ONLY */
52#define ce_init()
53#define llcp_init()
54
55#define NFC_SET_MAX_CONN_DEFAULT()
56
57#endif /* NFC_RW_ONLY */
58/****************************************************************************
59** Declarations
60****************************************************************************/
61#if NFC_DYNAMIC_MEMORY == FALSE
62tNFC_CB nfc_cb;
63#endif
64
65#if (NFC_RW_ONLY == FALSE)
66#define NFC_NUM_INTERFACE_MAP   2
67#else
68#define NFC_NUM_INTERFACE_MAP   1
69#endif
70
71static const tNCI_DISCOVER_MAPS nfc_interface_mapping[NFC_NUM_INTERFACE_MAP] =
72{
73    /* Protocols that use Frame Interface do not need to be included in the interface mapping */
74    {
75        NCI_PROTOCOL_ISO_DEP,
76        NCI_INTERFACE_MODE_POLL_N_LISTEN,
77        NCI_INTERFACE_ISO_DEP
78    }
79#if (NFC_RW_ONLY == FALSE)
80    ,
81    /* this can not be set here due to 2079xB0 NFCC issues */
82    {
83        NCI_PROTOCOL_NFC_DEP,
84        NCI_INTERFACE_MODE_POLL_N_LISTEN,
85        NCI_INTERFACE_NFC_DEP
86    }
87#endif
88};
89
90
91#if (BT_TRACE_VERBOSE == TRUE)
92/*******************************************************************************
93**
94** Function         nfc_state_name
95**
96** Description      This function returns the state name.
97**
98** NOTE             conditionally compiled to save memory.
99**
100** Returns          pointer to the name
101**
102*******************************************************************************/
103static char *nfc_state_name (UINT8 state)
104{
105    switch (state)
106    {
107    case NFC_STATE_NONE:
108        return ("NONE");
109    case NFC_STATE_W4_HAL_OPEN:
110        return ("W4_HAL_OPEN");
111    case NFC_STATE_CORE_INIT:
112        return ("CORE_INIT");
113    case NFC_STATE_W4_POST_INIT_CPLT:
114        return ("W4_POST_INIT_CPLT");
115    case NFC_STATE_IDLE:
116        return ("IDLE");
117    case NFC_STATE_OPEN:
118        return ("OPEN");
119    case NFC_STATE_CLOSING:
120        return ("CLOSING");
121    case NFC_STATE_W4_HAL_CLOSE:
122        return ("W4_HAL_CLOSE");
123    case NFC_STATE_NFCC_POWER_OFF_SLEEP:
124        return ("NFCC_POWER_OFF_SLEEP");
125    default:
126        return ("???? UNKNOWN STATE");
127    }
128}
129
130/*******************************************************************************
131**
132** Function         nfc_hal_event_name
133**
134** Description      This function returns the HAL event name.
135**
136** NOTE             conditionally compiled to save memory.
137**
138** Returns          pointer to the name
139**
140*******************************************************************************/
141static char *nfc_hal_event_name (UINT8 event)
142{
143    switch (event)
144    {
145    case HAL_NFC_OPEN_CPLT_EVT:
146        return ("HAL_NFC_OPEN_CPLT_EVT");
147
148    case HAL_NFC_CLOSE_CPLT_EVT:
149        return ("HAL_NFC_CLOSE_CPLT_EVT");
150
151    case HAL_NFC_POST_INIT_CPLT_EVT:
152        return ("HAL_NFC_POST_INIT_CPLT_EVT");
153
154    case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
155        return ("HAL_NFC_PRE_DISCOVER_CPLT_EVT");
156
157    case HAL_NFC_REQUEST_CONTROL_EVT:
158        return ("HAL_NFC_REQUEST_CONTROL_EVT");
159
160    case HAL_NFC_RELEASE_CONTROL_EVT:
161        return ("HAL_NFC_RELEASE_CONTROL_EVT");
162
163    case HAL_NFC_ERROR_EVT:
164        return ("HAL_NFC_ERROR_EVT");
165
166    default:
167        return ("???? UNKNOWN EVENT");
168    }
169}
170#endif /* BT_TRACE_VERBOSE == TRUE */
171
172/*******************************************************************************
173**
174** Function         nfc_main_notify_enable_status
175**
176** Description      Notify status of Enable/PowerOffSleep/PowerCycle
177**
178*******************************************************************************/
179static void nfc_main_notify_enable_status (tNFC_STATUS nfc_status)
180{
181    tNFC_RESPONSE   evt_data;
182
183    evt_data.status = nfc_status;
184
185    if (nfc_cb.p_resp_cback)
186    {
187        /* if getting out of PowerOffSleep mode or restarting NFCC */
188        if (nfc_cb.flags & (NFC_FL_RESTARTING|NFC_FL_POWER_CYCLE_NFCC))
189        {
190            nfc_cb.flags &= ~(NFC_FL_RESTARTING|NFC_FL_POWER_CYCLE_NFCC);
191            if (nfc_status != NFC_STATUS_OK)
192            {
193                nfc_cb.flags |= NFC_FL_POWER_OFF_SLEEP;
194            }
195            (*nfc_cb.p_resp_cback) (NFC_NFCC_RESTART_REVT, &evt_data);
196        }
197        else
198        {
199            (*nfc_cb.p_resp_cback) (NFC_ENABLE_REVT, &evt_data);
200        }
201    }
202}
203
204
205
206/*******************************************************************************
207**
208** Function         nfc_enabled
209**
210** Description      NFCC enabled, proceed with stack start up.
211**
212** Returns          void
213**
214*******************************************************************************/
215void nfc_enabled (tNFC_STATUS nfc_status, BT_HDR *p_init_rsp_msg)
216{
217    tNFC_RESPONSE evt_data;
218    tNFC_CONN_CB  *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
219    UINT8   *p;
220    UINT8   num_interfaces = 0, xx;
221    int     yy = 0;
222
223    memset (&evt_data, 0, sizeof (tNFC_RESPONSE));
224
225    if (nfc_status == NCI_STATUS_OK)
226    {
227        nfc_set_state (NFC_STATE_IDLE);
228
229        p = (UINT8 *) (p_init_rsp_msg + 1) + p_init_rsp_msg->offset + NCI_MSG_HDR_SIZE + 1;
230        /* we currently only support NCI of the same version.
231        * We may need to change this, when we support multiple version of NFCC */
232        evt_data.enable.nci_version = NCI_VERSION;
233        STREAM_TO_UINT32 (evt_data.enable.nci_features, p);
234        STREAM_TO_UINT8 (num_interfaces, p);
235
236        evt_data.enable.nci_interfaces = 0;
237        for (xx = 0; xx < num_interfaces; xx++)
238        {
239            if ((*p) <= NCI_INTERFACE_MAX)
240                evt_data.enable.nci_interfaces |= (1 << (*p));
241            else if (((*p) >= NCI_INTERFACE_FIRST_VS) && (yy < NFC_NFCC_MAX_NUM_VS_INTERFACE))
242            {
243                /* save the VS RF interface in control block, if there's still room */
244                nfc_cb.vs_interface[yy++] = *p;
245            }
246            p++;
247        }
248        nfc_cb.nci_interfaces    = evt_data.enable.nci_interfaces;
249        memcpy (evt_data.enable.vs_interface, nfc_cb.vs_interface, NFC_NFCC_MAX_NUM_VS_INTERFACE);
250        evt_data.enable.max_conn = *p++;
251        STREAM_TO_UINT16 (evt_data.enable.max_ce_table, p);
252#if (NFC_RW_ONLY == FALSE)
253        nfc_cb.max_ce_table          = evt_data.enable.max_ce_table;
254        nfc_cb.nci_features          = evt_data.enable.nci_features;
255        nfc_cb.max_conn              = evt_data.enable.max_conn;
256#endif
257        nfc_cb.nci_ctrl_size         = *p++; /* Max Control Packet Payload Length */
258        p_cb->init_credits           = p_cb->num_buff = 0;
259        STREAM_TO_UINT16 (evt_data.enable.max_param_size, p);
260        nfc_set_conn_id (p_cb, NFC_RF_CONN_ID);
261        evt_data.enable.manufacture_id   = *p++;
262        STREAM_TO_ARRAY (evt_data.enable.nfcc_info, p, NFC_NFCC_INFO_LEN);
263        NFC_DiscoveryMap (nfc_cb.num_disc_maps, (tNCI_DISCOVER_MAPS *) nfc_cb.p_disc_maps, NULL);
264    }
265    /* else not successful. the buffers will be freed in nfc_free_conn_cb () */
266    else
267    {
268        if (nfc_cb.flags & NFC_FL_RESTARTING)
269        {
270            nfc_set_state (NFC_STATE_NFCC_POWER_OFF_SLEEP);
271        }
272        else
273        {
274            nfc_free_conn_cb (p_cb);
275
276            /* if NFCC didn't respond to CORE_RESET or CORE_INIT */
277            if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT)
278            {
279                /* report status after closing HAL */
280                nfc_cb.p_hal->close ();
281                return;
282            }
283            else
284                nfc_set_state (NFC_STATE_NONE);
285        }
286    }
287
288    nfc_main_notify_enable_status (nfc_status);
289}
290
291/*******************************************************************************
292**
293** Function         nfc_set_state
294**
295** Description      Set the state of NFC stack
296**
297** Returns          void
298**
299*******************************************************************************/
300void nfc_set_state (tNFC_STATE nfc_state)
301{
302#if (BT_TRACE_VERBOSE == TRUE)
303    NFC_TRACE_DEBUG4 ("nfc_set_state %d (%s)->%d (%s)", nfc_cb.nfc_state, nfc_state_name (nfc_cb.nfc_state), nfc_state, nfc_state_name (nfc_state));
304#else
305    NFC_TRACE_DEBUG2 ("nfc_set_state %d->%d", nfc_cb.nfc_state, nfc_state);
306#endif
307    nfc_cb.nfc_state = nfc_state;
308}
309
310/*******************************************************************************
311**
312** Function         nfc_gen_cleanup
313**
314** Description      Clean up for both going into low power mode and disabling NFC
315**
316*******************************************************************************/
317void nfc_gen_cleanup (void)
318{
319    nfc_cb.flags  &= ~NFC_FL_DEACTIVATING;
320
321    /* the HAL pre-discover is still active - clear the pending flag/free the buffer */
322    if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
323    {
324        nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
325        GKI_freebuf (nfc_cb.p_disc_pending);
326        nfc_cb.p_disc_pending = NULL;
327    }
328
329    nfc_cb.flags &= ~(NFC_FL_CONTROL_REQUESTED | NFC_FL_CONTROL_GRANTED | NFC_FL_HAL_REQUESTED);
330
331    nfc_stop_timer (&nfc_cb.deactivate_timer);
332
333    /* Reset the connection control blocks */
334    nfc_reset_all_conn_cbs ();
335
336    if (nfc_cb.p_nci_init_rsp)
337    {
338        GKI_freebuf (nfc_cb.p_nci_init_rsp);
339        nfc_cb.p_nci_init_rsp = NULL;
340    }
341
342    /* clear any pending CMD/RSP */
343    nfc_main_flush_cmd_queue ();
344}
345
346/*******************************************************************************
347**
348** Function         nfc_main_handle_hal_evt
349**
350** Description      Handle BT_EVT_TO_NFC_MSGS
351**
352*******************************************************************************/
353void nfc_main_handle_hal_evt (tNFC_HAL_EVT_MSG *p_msg)
354{
355    UINT8  *ps;
356
357    NFC_TRACE_DEBUG1 ("nfc_main_handle_hal_evt(): HAL event=0x%x", p_msg->hal_evt);
358
359    switch (p_msg->hal_evt)
360    {
361    case HAL_NFC_OPEN_CPLT_EVT: /* only for failure case */
362        nfc_enabled (NFC_STATUS_FAILED, NULL);
363        break;
364
365    case HAL_NFC_CLOSE_CPLT_EVT:
366        if (nfc_cb.p_resp_cback)
367        {
368            if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE)
369            {
370                if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP)
371                {
372                    nfc_cb.flags &= ~NFC_FL_POWER_OFF_SLEEP;
373                    nfc_set_state (NFC_STATE_NFCC_POWER_OFF_SLEEP);
374                    (*nfc_cb.p_resp_cback) (NFC_NFCC_POWER_OFF_REVT, NULL);
375                }
376                else
377                {
378                    nfc_set_state (NFC_STATE_NONE);
379                    (*nfc_cb.p_resp_cback) (NFC_DISABLE_REVT, NULL);
380                    nfc_cb.p_resp_cback = NULL;
381                }
382            }
383            else
384            {
385                /* found error during initialization */
386                nfc_set_state (NFC_STATE_NONE);
387                nfc_main_notify_enable_status (NFC_STATUS_FAILED);
388            }
389        }
390        break;
391
392    case HAL_NFC_POST_INIT_CPLT_EVT:
393        if (nfc_cb.p_nci_init_rsp)
394        {
395            /*
396            ** if NFC_Disable() is called before receiving HAL_NFC_POST_INIT_CPLT_EVT,
397            ** then wait for HAL_NFC_CLOSE_CPLT_EVT.
398            */
399            if (nfc_cb.nfc_state == NFC_STATE_W4_POST_INIT_CPLT)
400            {
401                if (p_msg->status == HAL_NFC_STATUS_OK)
402                {
403                    nfc_enabled (NCI_STATUS_OK, nfc_cb.p_nci_init_rsp);
404                }
405                else /* if post initailization failed */
406                {
407                    nfc_enabled (NCI_STATUS_FAILED, NULL);
408                }
409            }
410
411            GKI_freebuf (nfc_cb.p_nci_init_rsp);
412            nfc_cb.p_nci_init_rsp = NULL;
413        }
414        break;
415
416    case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
417        /* restore the command window, no matter if the discover command is still pending */
418        nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
419        nfc_cb.flags         &= ~NFC_FL_CONTROL_GRANTED;
420        if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
421        {
422            /* issue the discovery command now, if it is still pending */
423            nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
424            ps            = (UINT8 *)nfc_cb.p_disc_pending;
425            nci_snd_discover_cmd (*ps, (tNFC_DISCOVER_PARAMS *)(ps + 1));
426            GKI_freebuf (nfc_cb.p_disc_pending);
427            nfc_cb.p_disc_pending = NULL;
428        }
429        else
430        {
431            /* check if there's other pending commands */
432            nfc_ncif_check_cmd_queue (NULL);
433        }
434
435        if (p_msg->status == HAL_NFC_STATUS_ERR_CMD_TIMEOUT)
436            nfc_ncif_event_status (NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
437        break;
438
439    case HAL_NFC_REQUEST_CONTROL_EVT:
440        nfc_cb.flags    |= NFC_FL_CONTROL_REQUESTED;
441        nfc_cb.flags    |= NFC_FL_HAL_REQUESTED;
442        nfc_ncif_check_cmd_queue (NULL);
443        break;
444
445    case HAL_NFC_RELEASE_CONTROL_EVT:
446        if (nfc_cb.flags & NFC_FL_CONTROL_GRANTED)
447        {
448            nfc_cb.flags &= ~NFC_FL_CONTROL_GRANTED;
449            nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
450            nfc_ncif_check_cmd_queue (NULL);
451
452            if (p_msg->status == HAL_NFC_STATUS_ERR_CMD_TIMEOUT)
453                nfc_ncif_event_status (NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
454        }
455        break;
456
457    case HAL_NFC_ERROR_EVT:
458        switch (p_msg->status)
459        {
460        case HAL_NFC_STATUS_ERR_TRANSPORT:
461            /* Notify app of transport error */
462            if (nfc_cb.p_resp_cback)
463            {
464                (*nfc_cb.p_resp_cback) (NFC_NFCC_TRANSPORT_ERR_REVT, NULL);
465
466                /* if enabling NFC, notify upper layer of failure after closing HAL */
467                if (nfc_cb.nfc_state < NFC_STATE_IDLE)
468                {
469                    nfc_enabled (NFC_STATUS_FAILED, NULL);
470                }
471            }
472            break;
473
474        case HAL_NFC_STATUS_ERR_CMD_TIMEOUT:
475            nfc_ncif_event_status (NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
476
477            /* if enabling NFC, notify upper layer of failure after closing HAL */
478            if (nfc_cb.nfc_state < NFC_STATE_IDLE)
479            {
480                nfc_enabled (NFC_STATUS_FAILED, NULL);
481                return;
482            }
483            break;
484
485        default:
486            break;
487        }
488        break;
489
490    default:
491        NFC_TRACE_ERROR1 ("nfc_main_handle_hal_evt (): unhandled event (0x%x).", p_msg->hal_evt);
492        break;
493    }
494}
495
496
497/*******************************************************************************
498**
499** Function         nfc_main_flush_cmd_queue
500**
501** Description      This function is called when setting power off sleep state.
502**
503** Returns          void
504**
505*******************************************************************************/
506void nfc_main_flush_cmd_queue (void)
507{
508    BT_HDR *p_msg;
509
510    NFC_TRACE_DEBUG0 ("nfc_main_flush_cmd_queue ()");
511
512    /* initialize command window */
513    nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
514
515    /* Stop command-pending timer */
516    nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer);
517
518    /* dequeue and free buffer */
519    while ((p_msg = (BT_HDR *)GKI_dequeue (&nfc_cb.nci_cmd_xmit_q)) != NULL)
520    {
521        GKI_freebuf (p_msg);
522    }
523}
524
525/*******************************************************************************
526**
527** Function         nfc_main_post_hal_evt
528**
529** Description      This function posts HAL event to NFC_TASK
530**
531** Returns          void
532**
533*******************************************************************************/
534void nfc_main_post_hal_evt (UINT8 hal_evt, tHAL_NFC_STATUS status)
535{
536    tNFC_HAL_EVT_MSG *p_msg;
537
538    if ((p_msg = (tNFC_HAL_EVT_MSG *) GKI_getbuf (sizeof(tNFC_HAL_EVT_MSG))) != NULL)
539    {
540        /* Initialize BT_HDR */
541        p_msg->hdr.len    = 0;
542        p_msg->hdr.event  = BT_EVT_TO_NFC_MSGS;
543        p_msg->hdr.offset = 0;
544        p_msg->hdr.layer_specific = 0;
545        p_msg->hal_evt = hal_evt;
546        p_msg->status  = status;
547        GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
548    }
549    else
550    {
551        NFC_TRACE_ERROR0 ("nfc_main_post_hal_evt (): No buffer");
552    }
553}
554
555
556/*******************************************************************************
557**
558** Function         nfc_main_hal_cback
559**
560** Description      HAL event handler
561**
562** Returns          void
563**
564*******************************************************************************/
565static void nfc_main_hal_cback(UINT8 event, tHAL_NFC_STATUS status)
566{
567#if (BT_TRACE_VERBOSE == TRUE)
568    NFC_TRACE_DEBUG3 ("nfc_main_hal_cback event: %s(0x%x), status=%d",
569                       nfc_hal_event_name (event), event, status);
570#else
571    NFC_TRACE_DEBUG2 ("nfc_main_hal_cback event: 0x%x, status=%d", event, status);
572#endif
573
574    switch (event)
575    {
576    case HAL_NFC_OPEN_CPLT_EVT:
577        /*
578        ** if NFC_Disable() is called before receiving HAL_NFC_OPEN_CPLT_EVT,
579        ** then wait for HAL_NFC_CLOSE_CPLT_EVT.
580        */
581        if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_OPEN)
582        {
583            if (status == HAL_NFC_STATUS_OK)
584            {
585                /* Notify NFC_TASK that NCI tranport is initialized */
586                GKI_send_event (NFC_TASK, NFC_TASK_EVT_TRANSPORT_READY);
587            }
588            else
589            {
590                nfc_main_post_hal_evt (event, status);
591            }
592        }
593        break;
594
595    case HAL_NFC_CLOSE_CPLT_EVT:
596    case HAL_NFC_POST_INIT_CPLT_EVT:
597    case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
598    case HAL_NFC_REQUEST_CONTROL_EVT:
599    case HAL_NFC_RELEASE_CONTROL_EVT:
600    case HAL_NFC_ERROR_EVT:
601        nfc_main_post_hal_evt (event, status);
602        break;
603
604    default:
605        NFC_TRACE_DEBUG1 ("nfc_main_hal_cback unhandled event %x", event);
606        break;
607    }
608}
609
610/*******************************************************************************
611**
612** Function         nfc_main_hal_data_cback
613**
614** Description      HAL data event handler
615**
616** Returns          void
617**
618*******************************************************************************/
619static void nfc_main_hal_data_cback(UINT16 data_len, UINT8   *p_data)
620{
621    BT_HDR *p_msg;
622
623    /* ignore all data while shutting down NFCC */
624    if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE)
625    {
626        return;
627    }
628
629    if (p_data)
630    {
631        if ((p_msg = (BT_HDR *) GKI_getpoolbuf (NFC_NCI_POOL_ID)) != NULL)
632        {
633            /* Initialize BT_HDR */
634            p_msg->len    = data_len;
635            p_msg->event  = BT_EVT_TO_NFC_NCI;
636            p_msg->offset = NFC_RECEIVE_MSGS_OFFSET;
637
638            /* no need to check length, it always less than pool size */
639            memcpy ((UINT8 *)(p_msg + 1) + p_msg->offset, p_data, p_msg->len);
640
641            GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
642        }
643        else
644        {
645            NFC_TRACE_ERROR0 ("nfc_main_hal_data_cback (): No buffer");
646        }
647    }
648}
649
650/*******************************************************************************
651**
652** Function         NFC_Enable
653**
654** Description      This function enables NFC. Prior to calling NFC_Enable:
655**                  - the NFCC must be powered up, and ready to receive commands.
656**                  - GKI must be enabled
657**                  - NFC_TASK must be started
658**                  - NCIT_TASK must be started (if using dedicated NCI transport)
659**
660**                  This function opens the NCI transport (if applicable),
661**                  resets the NFC controller, and initializes the NFC subsystems.
662**
663**                  When the NFC startup procedure is completed, an
664**                  NFC_ENABLE_REVT is returned to the application using the
665**                  tNFC_RESPONSE_CBACK.
666**
667** Returns          tNFC_STATUS
668**
669*******************************************************************************/
670tNFC_STATUS NFC_Enable (tNFC_RESPONSE_CBACK *p_cback)
671{
672    NFC_TRACE_API0 ("NFC_Enable ()");
673
674    /* Validate callback */
675    if (!p_cback)
676    {
677        return (NFC_STATUS_INVALID_PARAM);
678    }
679    nfc_cb.p_resp_cback = p_cback;
680
681    /* Open HAL transport. */
682    nfc_set_state (NFC_STATE_W4_HAL_OPEN);
683    nfc_cb.p_hal->open (nfc_main_hal_cback, nfc_main_hal_data_cback);
684
685    return (NFC_STATUS_OK);
686}
687
688/*******************************************************************************
689**
690** Function         NFC_Disable
691**
692** Description      This function performs clean up routines for shutting down
693**                  NFC and closes the NCI transport (if using dedicated NCI
694**                  transport).
695**
696**                  When the NFC shutdown procedure is completed, an
697**                  NFC_DISABLED_REVT is returned to the application using the
698**                  tNFC_RESPONSE_CBACK.
699**
700** Returns          nothing
701**
702*******************************************************************************/
703void NFC_Disable (void)
704{
705    NFC_TRACE_API1 ("NFC_Disable (): nfc_state = %d", nfc_cb.nfc_state);
706
707    if ((nfc_cb.nfc_state == NFC_STATE_NONE) || (nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP))
708    {
709        nfc_set_state (NFC_STATE_NONE);
710        if (nfc_cb.p_resp_cback)
711        {
712            (*nfc_cb.p_resp_cback) (NFC_DISABLE_REVT, NULL);
713            nfc_cb.p_resp_cback = NULL;
714        }
715        return;
716    }
717
718    /* Close transport and clean up */
719    nfc_task_shutdown_nfcc ();
720}
721
722/*******************************************************************************
723**
724** Function         NFC_Init
725**
726** Description      This function initializes control block for NFC
727**
728** Returns          nothing
729**
730*******************************************************************************/
731void NFC_Init (tHAL_NFC_ENTRY *p_hal_entry_tbl)
732{
733    int xx;
734
735    /* Clear nfc control block */
736    memset (&nfc_cb, 0, sizeof (tNFC_CB));
737
738    /* Reset the nfc control block */
739    for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++)
740    {
741        nfc_cb.conn_cb[xx].conn_id = NFC_ILLEGAL_CONN_ID;
742    }
743
744    /* NCI init */
745    nfc_cb.p_hal            = p_hal_entry_tbl;
746    nfc_cb.nfc_state        = NFC_STATE_NONE;
747    nfc_cb.nci_cmd_window   = NCI_MAX_CMD_WINDOW;
748    nfc_cb.nci_wait_rsp_tout= NFC_CMD_CMPL_TIMEOUT;
749    nfc_cb.p_disc_maps      = nfc_interface_mapping;
750    nfc_cb.num_disc_maps    = NFC_NUM_INTERFACE_MAP;
751    nfc_cb.trace_level      = NFC_INITIAL_TRACE_LEVEL;
752    nfc_cb.nci_ctrl_size    = NCI_CTRL_INIT_SIZE;
753    nfc_cb.reassembly       = TRUE;
754
755    rw_init ();
756    ce_init ();
757    llcp_init ();
758    NFC_SET_MAX_CONN_DEFAULT ();
759}
760
761/*******************************************************************************
762**
763** Function         NFC_GetLmrtSize
764**
765** Description      Called by application wto query the Listen Mode Routing
766**                  Table size supported by NFCC
767**
768** Returns          Listen Mode Routing Table size
769**
770*******************************************************************************/
771UINT16 NFC_GetLmrtSize (void)
772{
773    UINT16 size = 0;
774#if (NFC_RW_ONLY == FALSE)
775    size = nfc_cb.max_ce_table;
776#endif
777    return size;
778}
779
780
781/*******************************************************************************
782**
783** Function         NFC_SetConfig
784**
785** Description      This function is called to send the configuration parameter
786**                  TLV to NFCC. The response from NFCC is reported by
787**                  tNFC_RESPONSE_CBACK as NFC_SET_CONFIG_REVT.
788**
789** Parameters       tlv_size - the length of p_param_tlvs.
790**                  p_param_tlvs - the parameter ID/Len/Value list
791**
792** Returns          tNFC_STATUS
793**
794*******************************************************************************/
795tNFC_STATUS NFC_SetConfig (UINT8     tlv_size,
796                           UINT8    *p_param_tlvs)
797{
798    return nci_snd_core_set_config (p_param_tlvs, tlv_size);
799}
800
801/*******************************************************************************
802**
803** Function         NFC_GetConfig
804**
805** Description      This function is called to retrieve the parameter TLV from NFCC.
806**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
807**                  as NFC_GET_CONFIG_REVT.
808**
809** Parameters       num_ids - the number of parameter IDs
810**                  p_param_ids - the parameter ID list.
811**
812** Returns          tNFC_STATUS
813**
814*******************************************************************************/
815tNFC_STATUS NFC_GetConfig (UINT8     num_ids,
816                           UINT8    *p_param_ids)
817{
818    return nci_snd_core_get_config (p_param_ids, num_ids);
819}
820
821/*******************************************************************************
822**
823** Function         NFC_DiscoveryMap
824**
825** Description      This function is called to set the discovery interface mapping.
826**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK as.
827**                  NFC_MAP_DEVT.
828**
829** Parameters       num - the number of items in p_params.
830**                  p_maps - the discovery interface mappings
831**                  p_cback - the discovery callback function
832**
833** Returns          tNFC_STATUS
834**
835*******************************************************************************/
836tNFC_STATUS NFC_DiscoveryMap (UINT8 num, tNFC_DISCOVER_MAPS *p_maps,
837                                        tNFC_DISCOVER_CBACK *p_cback)
838{
839    UINT8   num_disc_maps = num;
840    UINT8   xx, yy, num_intf, intf_mask;
841    tNFC_DISCOVER_MAPS  max_maps[NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX];
842    BOOLEAN is_supported;
843
844    nfc_cb.p_discv_cback = p_cback;
845    num_intf             = 0;
846    NFC_TRACE_DEBUG1 ("nci_interfaces supported by NFCC: 0x%x", nfc_cb.nci_interfaces);
847
848    for (xx = 0; xx < NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX; xx++)
849    {
850        memset (&max_maps[xx], 0x00, sizeof(tNFC_DISCOVER_MAPS));
851    }
852
853    for (xx = 0; xx < num_disc_maps; xx++)
854    {
855        is_supported = FALSE;
856        if (p_maps[xx].intf_type > NCI_INTERFACE_MAX)
857        {
858            for (yy = 0; yy < NFC_NFCC_MAX_NUM_VS_INTERFACE; yy++)
859            {
860                if (nfc_cb.vs_interface[yy] == p_maps[xx].intf_type)
861                    is_supported    = TRUE;
862            }
863            NFC_TRACE_DEBUG3 ("[%d]: vs intf_type:0x%x is_supported:%d", xx, p_maps[xx].intf_type, is_supported);
864        }
865        else
866        {
867            intf_mask = (1 << (p_maps[xx].intf_type));
868            if (intf_mask & nfc_cb.nci_interfaces)
869            {
870                is_supported    = TRUE;
871            }
872            NFC_TRACE_DEBUG4 ("[%d]: intf_type:%d intf_mask: 0x%x is_supported:%d", xx, p_maps[xx].intf_type, intf_mask, is_supported);
873        }
874        if (is_supported)
875            memcpy (&max_maps[num_intf++], &p_maps[xx], sizeof (tNFC_DISCOVER_MAPS));
876        else
877        {
878            NFC_TRACE_WARNING1 ("NFC_DiscoveryMap interface=0x%x is not supported by NFCC", p_maps[xx].intf_type);
879        }
880    }
881
882    return nci_snd_discover_map_cmd (num_intf, (tNCI_DISCOVER_MAPS *) max_maps);
883}
884
885/*******************************************************************************
886**
887** Function         NFC_DiscoveryStart
888**
889** Description      This function is called to start Polling and/or Listening.
890**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK as.
891**                  NFC_START_DEVT. The notification from NFCC is reported by
892**                  tNFC_DISCOVER_CBACK as NFC_RESULT_DEVT.
893**
894** Parameters       num_params - the number of items in p_params.
895**                  p_params - the discovery parameters
896**                  p_cback - the discovery callback function
897**
898** Returns          tNFC_STATUS
899**
900*******************************************************************************/
901tNFC_STATUS NFC_DiscoveryStart (UINT8                 num_params,
902                                tNFC_DISCOVER_PARAMS *p_params,
903                                tNFC_DISCOVER_CBACK  *p_cback)
904{
905    UINT8   *p;
906    int     params_size;
907    tNFC_STATUS status = NFC_STATUS_NO_BUFFERS;
908
909    NFC_TRACE_API0 ("NFC_DiscoveryStart");
910    if (nfc_cb.p_disc_pending)
911    {
912        NFC_TRACE_ERROR0 ("There's pending NFC_DiscoveryStart");
913        status = NFC_STATUS_BUSY;
914    }
915    else
916    {
917        nfc_cb.p_discv_cback = p_cback;
918        nfc_cb.flags        |= NFC_FL_DISCOVER_PENDING;
919        nfc_cb.flags        |= NFC_FL_CONTROL_REQUESTED;
920        params_size          = sizeof (tNFC_DISCOVER_PARAMS) * num_params;
921        nfc_cb.p_disc_pending = GKI_getbuf ((UINT16)(BT_HDR_SIZE + 1 + params_size));
922        if (nfc_cb.p_disc_pending)
923        {
924            p       = (UINT8 *)nfc_cb.p_disc_pending;
925            *p++    = num_params;
926            memcpy (p, p_params, params_size);
927            status = NFC_STATUS_CMD_STARTED;
928            nfc_ncif_check_cmd_queue (NULL);
929        }
930    }
931
932    NFC_TRACE_API1 ("NFC_DiscoveryStart status: 0x%x", status);
933    return status;
934}
935
936/*******************************************************************************
937**
938** Function         NFC_DiscoverySelect
939**
940** Description      If tNFC_DISCOVER_CBACK reports status=NFC_MULTIPLE_PROT,
941**                  the application needs to use this function to select the
942**                  the logical endpoint to continue. The response from NFCC is
943**                  reported by tNFC_DISCOVER_CBACK as NFC_SELECT_DEVT.
944**
945** Parameters       rf_disc_id - The ID identifies the remote device.
946**                  protocol - the logical endpoint on the remote devide
947**                  rf_interface - the RF interface to communicate with NFCC
948**
949** Returns          tNFC_STATUS
950**
951*******************************************************************************/
952tNFC_STATUS NFC_DiscoverySelect (UINT8    rf_disc_id,
953                                 UINT8    protocol,
954                                 UINT8    rf_interface)
955{
956    return nci_snd_discover_select_cmd (rf_disc_id, protocol, rf_interface);
957}
958
959/*******************************************************************************
960**
961** Function         NFC_ConnCreate
962**
963** Description      This function is called to create a logical connection with
964**                  NFCC for data exchange.
965**
966** Parameters       dest_type - the destination type
967**                  id   - the NFCEE ID or RF Discovery ID .
968**                  protocol   - the protocol.
969**                  p_cback - the connection callback function
970**
971** Returns          tNFC_STATUS
972**
973*******************************************************************************/
974tNFC_STATUS NFC_ConnCreate (UINT8            dest_type,
975                            UINT8            id,
976                            UINT8            protocol,
977                            tNFC_CONN_CBACK *p_cback)
978{
979    tNFC_STATUS     status = NFC_STATUS_FAILED;
980    tNFC_CONN_CB    *p_cb;
981    UINT8           num_tlv=0, tlv_size=0;
982    UINT8           param_tlvs[4], *pp;
983
984    p_cb = nfc_alloc_conn_cb (p_cback);
985    if (p_cb)
986    {
987        p_cb->id = id;
988        pp = param_tlvs;
989        if (dest_type == NCI_DEST_TYPE_NFCEE)
990        {
991            num_tlv = 1;
992            UINT8_TO_STREAM (pp, NCI_CON_CREATE_TAG_NFCEE_VAL);
993            UINT8_TO_STREAM (pp, 2);
994            UINT8_TO_STREAM (pp, id);
995            UINT8_TO_STREAM (pp, protocol);
996            tlv_size = 4;
997        }
998        else if (dest_type == NCI_DEST_TYPE_REMOTE)
999        {
1000            num_tlv = 1;
1001            UINT8_TO_STREAM (pp, NCI_CON_CREATE_TAG_RF_DISC_ID);
1002            UINT8_TO_STREAM (pp, 1);
1003            UINT8_TO_STREAM (pp, id);
1004            tlv_size = 3;
1005        }
1006        else if (dest_type == NCI_DEST_TYPE_NFCC)
1007        {
1008            p_cb->id = NFC_TEST_ID;
1009        }
1010        /* Add handling of NCI_DEST_TYPE_REMOTE when more RF interface definitions are added */
1011        p_cb->act_protocol = protocol;
1012        p_cb->p_cback = p_cback;
1013        status = nci_snd_core_conn_create (dest_type, num_tlv, tlv_size, param_tlvs);
1014        if (status == NFC_STATUS_FAILED)
1015            nfc_free_conn_cb (p_cb);
1016    }
1017    return status;
1018}
1019
1020/*******************************************************************************
1021**
1022** Function         NFC_ConnClose
1023**
1024** Description      This function is called to close a logical connection with
1025**                  NFCC.
1026**
1027** Parameters       conn_id - the connection id.
1028**
1029** Returns          tNFC_STATUS
1030**
1031*******************************************************************************/
1032tNFC_STATUS NFC_ConnClose (UINT8 conn_id)
1033{
1034    tNFC_CONN_CB *p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
1035    tNFC_STATUS     status = NFC_STATUS_FAILED;
1036
1037    if (p_cb)
1038    {
1039        status = nci_snd_core_conn_close (conn_id);
1040    }
1041    return status;
1042}
1043
1044/*******************************************************************************
1045**
1046** Function         NFC_SetStaticRfCback
1047**
1048** Description      This function is called to update the data callback function
1049**                  to receive the data for the given connection id.
1050**
1051** Parameters       p_cback - the connection callback function
1052**
1053** Returns          Nothing
1054**
1055*******************************************************************************/
1056void NFC_SetStaticRfCback (tNFC_CONN_CBACK    *p_cback)
1057{
1058    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
1059
1060    p_cb->p_cback = p_cback;
1061    /* just in case DH has received NCI data before the data callback is set
1062     * check if there's any data event to report on this connection id */
1063    nfc_data_event (p_cb);
1064}
1065
1066/*******************************************************************************
1067**
1068** Function         NFC_SetReassemblyFlag
1069**
1070** Description      This function is called to set if nfc will reassemble
1071**                  nci packet as much as its buffer can hold or it should not
1072**                  reassemble but forward the fragmented nci packet to layer above.
1073**                  If nci data pkt is fragmented, nfc may send multiple
1074**                  NFC_DATA_CEVT with status NFC_STATUS_CONTINUE before sending
1075**                  NFC_DATA_CEVT with status NFC_STATUS_OK based on reassembly
1076**                  configuration and reassembly buffer size
1077**
1078** Parameters       reassembly - flag to indicate if nfc may reassemble or not
1079**
1080** Returns          Nothing
1081**
1082*******************************************************************************/
1083void NFC_SetReassemblyFlag (BOOLEAN    reassembly)
1084{
1085    nfc_cb.reassembly = reassembly;
1086}
1087
1088/*******************************************************************************
1089**
1090** Function         NFC_SendData
1091**
1092** Description      This function is called to send the given data packet
1093**                  to the connection identified by the given connection id.
1094**
1095** Parameters       conn_id - the connection id.
1096**                  p_data - the data packet.
1097**                  p_data->offset must be >= NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE
1098**                  The data payload starts at ((UINT8 *) (p_data + 1) + p_data->offset)
1099**
1100** Returns          tNFC_STATUS
1101**
1102*******************************************************************************/
1103tNFC_STATUS NFC_SendData (UINT8       conn_id,
1104                          BT_HDR     *p_data)
1105{
1106    tNFC_STATUS     status = NFC_STATUS_FAILED;
1107    tNFC_CONN_CB *p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
1108
1109    if (p_cb && p_data && p_data->offset >= NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE)
1110    {
1111        status = nfc_ncif_send_data (p_cb, p_data);
1112    }
1113
1114    if (status != NFC_STATUS_OK)
1115        GKI_freebuf (p_data);
1116
1117    return status;
1118}
1119
1120/*******************************************************************************
1121**
1122** Function         NFC_FlushData
1123**
1124** Description      This function is called to discard the tx data queue of
1125**                  the given connection id.
1126**
1127** Parameters       conn_id - the connection id.
1128**
1129** Returns          tNFC_STATUS
1130**
1131*******************************************************************************/
1132tNFC_STATUS NFC_FlushData (UINT8       conn_id)
1133{
1134    tNFC_STATUS     status = NFC_STATUS_FAILED;
1135    tNFC_CONN_CB    *p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
1136    void            *p_buf;
1137
1138    if (p_cb)
1139    {
1140        status  = NFC_STATUS_OK;
1141        while ((p_buf = GKI_dequeue (&p_cb->tx_q)) != NULL)
1142            GKI_freebuf (p_buf);
1143    }
1144
1145    return status;
1146}
1147
1148/*******************************************************************************
1149**
1150** Function         NFC_Deactivate
1151**
1152** Description      This function is called to stop the discovery process or
1153**                  put the listen device in sleep mode or terminate the NFC link.
1154**
1155**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK
1156**                  as NFC_DEACTIVATE_DEVT.
1157**
1158** Parameters       deactivate_type - NFC_DEACTIVATE_TYPE_IDLE, to IDLE mode.
1159**                                    NFC_DEACTIVATE_TYPE_SLEEP to SLEEP mode.
1160**                                    NFC_DEACTIVATE_TYPE_SLEEP_AF to SLEEP_AF mode.
1161**
1162** Returns          tNFC_STATUS
1163**
1164*******************************************************************************/
1165tNFC_STATUS NFC_Deactivate (tNFC_DEACT_TYPE deactivate_type)
1166{
1167    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
1168    tNFC_STATUS  status = NFC_STATUS_OK;
1169
1170#if (BT_TRACE_VERBOSE == TRUE)
1171    NFC_TRACE_API3 ("NFC_Deactivate %d (%s) deactivate_type:%d", nfc_cb.nfc_state, nfc_state_name (nfc_cb.nfc_state), deactivate_type);
1172#else
1173    NFC_TRACE_API2 ("NFC_Deactivate %d deactivate_type:%d", nfc_cb.nfc_state, deactivate_type);
1174#endif
1175
1176    if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
1177    {
1178        /* the HAL pre-discover is still active - clear the pending flag */
1179        nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
1180        if (!(nfc_cb.flags & NFC_FL_HAL_REQUESTED))
1181        {
1182            /* if HAL did not request for control, clear this bit now */
1183            nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED;
1184        }
1185        GKI_freebuf (nfc_cb.p_disc_pending);
1186        nfc_cb.p_disc_pending = NULL;
1187        return NFC_STATUS_OK;
1188    }
1189
1190    if (nfc_cb.nfc_state == NFC_STATE_OPEN)
1191    {
1192        nfc_set_state (NFC_STATE_CLOSING);
1193        NFC_TRACE_DEBUG3 ( "act_protocol %d credits:%d/%d", p_cb->act_protocol, p_cb->init_credits, p_cb->num_buff);
1194        if ((p_cb->act_protocol == NCI_PROTOCOL_NFC_DEP) &&
1195            (p_cb->init_credits != p_cb->num_buff))
1196        {
1197            nfc_cb.flags           |= NFC_FL_DEACTIVATING;
1198            nfc_cb.deactivate_timer.param = (TIMER_PARAM_TYPE) deactivate_type;
1199            nfc_start_timer (&nfc_cb.deactivate_timer , (UINT16) (NFC_TTYPE_WAIT_2_DEACTIVATE), NFC_DEACTIVATE_TIMEOUT);
1200            return status;
1201        }
1202    }
1203
1204    status = nci_snd_deactivate_cmd (deactivate_type);
1205    return status;
1206}
1207
1208/*******************************************************************************
1209**
1210** Function         NFC_UpdateRFCommParams
1211**
1212** Description      This function is called to update RF Communication parameters
1213**                  once the Frame RF Interface has been activated.
1214**
1215**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
1216**                  as NFC_RF_COMM_PARAMS_UPDATE_REVT.
1217**
1218** Returns          tNFC_STATUS
1219**
1220*******************************************************************************/
1221tNFC_STATUS NFC_UpdateRFCommParams (tNFC_RF_COMM_PARAMS *p_params)
1222{
1223    UINT8 tlvs[12];
1224    UINT8 *p = tlvs;
1225    UINT8 data_exch_config;
1226
1227    /* RF Technology and Mode */
1228    if (p_params->include_rf_tech_mode)
1229    {
1230        UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_TECH_N_MODE);
1231        UINT8_TO_STREAM (p, 1);
1232        UINT8_TO_STREAM (p, p_params->rf_tech_n_mode);
1233    }
1234
1235    /* Transmit Bit Rate */
1236    if (p_params->include_tx_bit_rate)
1237    {
1238        UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_TX_BIT_RATE);
1239        UINT8_TO_STREAM (p, 1);
1240        UINT8_TO_STREAM (p, p_params->tx_bit_rate);
1241    }
1242
1243    /* Receive Bit Rate */
1244    if (p_params->include_tx_bit_rate)
1245    {
1246        UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_RX_BIT_RATE);
1247        UINT8_TO_STREAM (p, 1);
1248        UINT8_TO_STREAM (p, p_params->rx_bit_rate);
1249    }
1250
1251    /* NFC-B Data Exchange Configuration */
1252    if (p_params->include_nfc_b_config)
1253    {
1254        UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_B_DATA_EX_PARAM);
1255        UINT8_TO_STREAM (p, 1);
1256
1257        data_exch_config =  (p_params->min_tr0 & 0x03) << 6;          /* b7b6 : Mininum TR0 */
1258        data_exch_config |= (p_params->min_tr1 & 0x03) << 4;          /* b5b4 : Mininum TR1 */
1259        data_exch_config |= (p_params->suppression_eos & 0x01) << 3;  /* b3 :   Suppression of EoS */
1260        data_exch_config |= (p_params->suppression_sos & 0x01) << 2;  /* b2 :   Suppression of SoS */
1261        data_exch_config |= (p_params->min_tr2 & 0x03);               /* b1b0 : Mininum TR2 */
1262
1263        UINT8_TO_STREAM (p, data_exch_config);
1264    }
1265
1266    return nci_snd_parameter_update_cmd (tlvs, (UINT8) (p - tlvs));
1267}
1268
1269/*******************************************************************************
1270**
1271** Function         NFC_SetPowerOffSleep
1272**
1273** Description      This function closes/opens transport and turns off/on NFCC.
1274**
1275** Returns          tNFC_STATUS
1276**
1277*******************************************************************************/
1278tNFC_STATUS NFC_SetPowerOffSleep (BOOLEAN enable)
1279{
1280    NFC_TRACE_API1 ("NFC_SetPowerOffSleep () enable = %d", enable);
1281
1282    if (  (enable == FALSE)
1283        &&(nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP)  )
1284    {
1285        nfc_cb.flags |= NFC_FL_RESTARTING;
1286
1287        /* open transport */
1288        nfc_set_state (NFC_STATE_W4_HAL_OPEN);
1289        nfc_cb.p_hal->open (nfc_main_hal_cback, nfc_main_hal_data_cback);
1290
1291        return NFC_STATUS_OK;
1292    }
1293    else if (  (enable == TRUE)
1294             &&(nfc_cb.nfc_state == NFC_STATE_IDLE)  )
1295    {
1296        /* close transport to turn off NFCC and clean up */
1297        nfc_cb.flags |= NFC_FL_POWER_OFF_SLEEP;
1298        nfc_task_shutdown_nfcc ();
1299
1300        return NFC_STATUS_OK;
1301    }
1302
1303    NFC_TRACE_ERROR1 ("NFC_SetPowerOffSleep () invalid state = %d", nfc_cb.nfc_state);
1304    return NFC_STATUS_FAILED;
1305}
1306
1307/*******************************************************************************
1308**
1309** Function         NFC_PowerCycleNFCC
1310**
1311** Description      This function turns off and then on NFCC.
1312**
1313** Returns          tNFC_STATUS
1314**
1315*******************************************************************************/
1316tNFC_STATUS NFC_PowerCycleNFCC (void)
1317{
1318    NFC_TRACE_API0 ("NFC_PowerCycleNFCC ()");
1319
1320    if (nfc_cb.nfc_state == NFC_STATE_IDLE)
1321    {
1322        /* power cycle NFCC */
1323        nfc_cb.flags |= NFC_FL_POWER_CYCLE_NFCC;
1324        nfc_task_shutdown_nfcc ();
1325
1326        return NFC_STATUS_OK;
1327    }
1328
1329    NFC_TRACE_ERROR1 ("NFC_PowerCycleNFCC () invalid state = %d", nfc_cb.nfc_state);
1330    return NFC_STATUS_FAILED;
1331}
1332
1333
1334/*******************************************************************************
1335**
1336** Function         NFC_SetTraceLevel
1337**
1338** Description      This function sets the trace level for NFC.  If called with
1339**                  a value of 0xFF, it simply returns the current trace level.
1340**
1341** Returns          The new or current trace level
1342**
1343*******************************************************************************/
1344UINT8 NFC_SetTraceLevel (UINT8 new_level)
1345{
1346    NFC_TRACE_API1 ("NFC_SetTraceLevel () new_level = %d", new_level);
1347
1348    if (new_level != 0xFF)
1349        nfc_cb.trace_level = new_level;
1350
1351    return (nfc_cb.trace_level);
1352}
1353
1354#if (BT_TRACE_VERBOSE == TRUE)
1355/*******************************************************************************
1356**
1357** Function         NFC_GetStatusName
1358**
1359** Description      This function returns the status name.
1360**
1361** NOTE             conditionally compiled to save memory.
1362**
1363** Returns          pointer to the name
1364**
1365*******************************************************************************/
1366char *NFC_GetStatusName (tNFC_STATUS status)
1367{
1368    switch (status)
1369    {
1370    case NFC_STATUS_OK:
1371        return "OK";
1372    case NFC_STATUS_REJECTED:
1373        return "REJECTED";
1374    case NFC_STATUS_MSG_CORRUPTED:
1375        return "CORRUPTED";
1376    case NFC_STATUS_BUFFER_FULL:
1377        return "BUFFER_FULL";
1378    case NFC_STATUS_FAILED:
1379        return "FAILED";
1380    case NFC_STATUS_NOT_INITIALIZED:
1381        return "NOT_INITIALIZED";
1382    case NFC_STATUS_SYNTAX_ERROR:
1383        return "SYNTAX_ERROR";
1384    case NFC_STATUS_SEMANTIC_ERROR:
1385        return "SEMANTIC_ERROR";
1386    case NFC_STATUS_UNKNOWN_GID:
1387        return "UNKNOWN_GID";
1388    case NFC_STATUS_UNKNOWN_OID:
1389        return "UNKNOWN_OID";
1390    case NFC_STATUS_INVALID_PARAM:
1391        return "INVALID_PARAM";
1392    case NFC_STATUS_MSG_SIZE_TOO_BIG:
1393        return "MSG_SIZE_TOO_BIG";
1394    case NFC_STATUS_ALREADY_STARTED:
1395        return "ALREADY_STARTED";
1396    case NFC_STATUS_ACTIVATION_FAILED:
1397        return "ACTIVATION_FAILED";
1398    case NFC_STATUS_TEAR_DOWN:
1399        return "TEAR_DOWN";
1400    case NFC_STATUS_RF_TRANSMISSION_ERR:
1401        return "RF_TRANSMISSION_ERR";
1402    case NFC_STATUS_RF_PROTOCOL_ERR:
1403        return "RF_PROTOCOL_ERR";
1404    case NFC_STATUS_TIMEOUT:
1405        return "TIMEOUT";
1406    case NFC_STATUS_EE_INTF_ACTIVE_FAIL:
1407        return "EE_INTF_ACTIVE_FAIL";
1408    case NFC_STATUS_EE_TRANSMISSION_ERR:
1409        return "EE_TRANSMISSION_ERR";
1410    case NFC_STATUS_EE_PROTOCOL_ERR:
1411        return "EE_PROTOCOL_ERR";
1412    case NFC_STATUS_EE_TIMEOUT:
1413        return "EE_TIMEOUT";
1414    case NFC_STATUS_CMD_STARTED:
1415        return "CMD_STARTED";
1416    case NFC_STATUS_HW_TIMEOUT:
1417        return "HW_TIMEOUT";
1418    case NFC_STATUS_CONTINUE:
1419        return "CONTINUE";
1420    case NFC_STATUS_REFUSED:
1421        return "REFUSED";
1422    case NFC_STATUS_BAD_RESP:
1423        return "BAD_RESP";
1424    case NFC_STATUS_CMD_NOT_CMPLTD:
1425        return "CMD_NOT_CMPLTD";
1426    case NFC_STATUS_NO_BUFFERS:
1427        return "NO_BUFFERS";
1428    case NFC_STATUS_WRONG_PROTOCOL:
1429        return "WRONG_PROTOCOL";
1430    case NFC_STATUS_BUSY:
1431        return "BUSY";
1432    case NFC_STATUS_LINK_LOSS:
1433        return "LINK_LOSS";
1434    case NFC_STATUS_BAD_LENGTH:
1435        return "BAD_LENGTH";
1436    case NFC_STATUS_BAD_HANDLE:
1437        return "BAD_HANDLE";
1438    case NFC_STATUS_CONGESTED:
1439        return "CONGESTED";
1440    default:
1441        return"UNKNOWN";
1442    }
1443}
1444#endif
1445
1446#endif /* NFC_INCLUDED == TRUE */
1447