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