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 is the main implementation file for the NFA HCI.
22 *
23 ******************************************************************************/
24#include <string.h>
25#include "nfa_dm_int.h"
26#include "nfa_ee_api.h"
27#include "nfa_ee_int.h"
28#include "nfa_hci_api.h"
29#include "nfa_hci_defs.h"
30#include "nfa_hci_int.h"
31#include "nfa_mem_co.h"
32#include "nfa_nv_co.h"
33#include "nfa_sys.h"
34#include "nfa_sys_int.h"
35#include "nfc_api.h"
36#include "trace_api.h"
37
38/*****************************************************************************
39**  Global Variables
40*****************************************************************************/
41
42tNFA_HCI_CB nfa_hci_cb;
43
44#ifndef NFA_HCI_NV_READ_TIMEOUT_VAL
45#define NFA_HCI_NV_READ_TIMEOUT_VAL 1000
46#endif
47
48#ifndef NFA_HCI_CON_CREATE_TIMEOUT_VAL
49#define NFA_HCI_CON_CREATE_TIMEOUT_VAL 1000
50#endif
51
52/*****************************************************************************
53**  Static Functions
54*****************************************************************************/
55
56/* event handler function type */
57static bool nfa_hci_evt_hdlr(NFC_HDR* p_msg);
58
59static void nfa_hci_sys_enable(void);
60static void nfa_hci_sys_disable(void);
61static void nfa_hci_rsp_timeout(tNFA_HCI_EVENT_DATA* p_evt_data);
62static void nfa_hci_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
63                               tNFC_CONN* p_data);
64static void nfa_hci_set_receive_buf(uint8_t pipe);
65static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len);
66static void nfa_hci_handle_nv_read(uint8_t block, tNFA_STATUS status);
67
68/*****************************************************************************
69**  Constants
70*****************************************************************************/
71static const tNFA_SYS_REG nfa_hci_sys_reg = {
72    nfa_hci_sys_enable, nfa_hci_evt_hdlr, nfa_hci_sys_disable,
73    nfa_hci_proc_nfcc_power_mode};
74
75/*******************************************************************************
76**
77** Function         nfa_hci_ee_info_cback
78**
79** Description      Callback function
80**
81** Returns          None
82**
83*******************************************************************************/
84void nfa_hci_ee_info_cback(tNFA_EE_DISC_STS status) {
85  uint8_t num_nfcee = 3;
86  tNFA_EE_INFO ee_info[3];
87
88  NFA_TRACE_DEBUG1("nfa_hci_ee_info_cback (): %d", status);
89
90  switch (status) {
91    case NFA_EE_DISC_STS_ON:
92      if ((!nfa_hci_cb.ee_disc_cmplt) &&
93          ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
94           (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))) {
95        /* NFCEE Discovery is in progress */
96        nfa_hci_cb.ee_disc_cmplt = true;
97        nfa_hci_cb.num_ee_dis_req_ntf = 0;
98        nfa_hci_cb.num_hot_plug_evts = 0;
99        nfa_hci_cb.conn_id = 0;
100        nfa_hci_startup();
101      }
102      break;
103
104    case NFA_EE_DISC_STS_OFF:
105      if (nfa_hci_cb.ee_disable_disc) break;
106      nfa_hci_cb.ee_disable_disc = true;
107      /* Discovery operation is complete, retrieve discovery result */
108      NFA_EeGetInfo(&num_nfcee, ee_info);
109      nfa_hci_cb.num_nfcee = num_nfcee;
110
111      if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
112          (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
113        if ((nfa_hci_cb.num_nfcee <= 1) ||
114            (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) ||
115            (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))) {
116          /* No UICC Host is detected or
117           * HOT_PLUG_EVT(s) and or EE DISC REQ Ntf(s) are already received
118           * Get Host list and notify SYS on Initialization complete */
119          nfa_sys_stop_timer(&nfa_hci_cb.timer);
120          if ((nfa_hci_cb.num_nfcee > 1) &&
121              (nfa_hci_cb.num_ee_dis_req_ntf != (nfa_hci_cb.num_nfcee - 1))) {
122            /* Received HOT PLUG EVT, we will also wait for EE DISC REQ Ntf(s)
123             */
124            nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
125                                p_nfa_hci_cfg->hci_netwk_enable_timeout);
126          } else {
127            nfa_hci_cb.w4_hci_netwk_init = false;
128            nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
129                                        NFA_HCI_HOST_LIST_INDEX);
130          }
131        }
132      } else if (nfa_hci_cb.num_nfcee <= 1) {
133        /* No UICC Host is detected, HCI NETWORK is enabled */
134        nfa_hci_cb.w4_hci_netwk_init = false;
135      }
136      break;
137
138    case NFA_EE_DISC_STS_REQ:
139      nfa_hci_cb.num_ee_dis_req_ntf++;
140
141      if (nfa_hci_cb.ee_disable_disc) {
142        /* Already received Discovery Ntf */
143        if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
144            (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
145          /* Received DISC REQ Ntf while waiting for other Host in the network
146           * to bootup after DH host bootup is complete */
147          if (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) {
148            /* Received expected number of EE DISC REQ Ntf(s) */
149            nfa_sys_stop_timer(&nfa_hci_cb.timer);
150            nfa_hci_cb.w4_hci_netwk_init = false;
151            nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
152                                        NFA_HCI_HOST_LIST_INDEX);
153          }
154        } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
155                   (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
156          /* Received DISC REQ Ntf during DH host bootup */
157          if (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) {
158            /* Received expected number of EE DISC REQ Ntf(s) */
159            nfa_hci_cb.w4_hci_netwk_init = false;
160          }
161        }
162      }
163      break;
164  }
165}
166
167/*******************************************************************************
168**
169** Function         nfa_hci_init
170**
171** Description      Initialize NFA HCI
172**
173** Returns          None
174**
175*******************************************************************************/
176void nfa_hci_init(void) {
177  NFA_TRACE_DEBUG0("nfa_hci_init ()");
178
179  /* initialize control block */
180  memset(&nfa_hci_cb, 0, sizeof(tNFA_HCI_CB));
181
182  nfa_hci_cb.hci_state = NFA_HCI_STATE_STARTUP;
183
184  /* register message handler on NFA SYS */
185  nfa_sys_register(NFA_ID_HCI, &nfa_hci_sys_reg);
186}
187
188/*******************************************************************************
189**
190** Function         nfa_hci_is_valid_cfg
191**
192** Description      Validate hci control block config parameters
193**
194** Returns          None
195**
196*******************************************************************************/
197bool nfa_hci_is_valid_cfg(void) {
198  uint8_t xx, yy, zz;
199  tNFA_HANDLE reg_app[NFA_HCI_MAX_APP_CB];
200  uint8_t valid_gate[NFA_HCI_MAX_GATE_CB];
201  uint8_t app_count = 0;
202  uint8_t gate_count = 0;
203  uint32_t pipe_inx_mask = 0;
204
205  /* First, see if valid values are stored in app names, send connectivity
206   * events flag */
207  for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
208    /* Check if app name is valid with null terminated string */
209    if (strlen(&nfa_hci_cb.cfg.reg_app_names[xx][0]) > NFA_MAX_HCI_APP_NAME_LEN)
210      return false;
211
212    /* Send Connectivity event flag can be either TRUE or FALSE */
213    if ((nfa_hci_cb.cfg.b_send_conn_evts[xx] != true) &&
214        (nfa_hci_cb.cfg.b_send_conn_evts[xx] != false))
215      return false;
216
217    if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) {
218      /* Check if the app name is present more than one time in the control
219       * block */
220      for (yy = xx + 1; yy < NFA_HCI_MAX_APP_CB; yy++) {
221        if ((nfa_hci_cb.cfg.reg_app_names[yy][0] != 0) &&
222            (!strncmp(&nfa_hci_cb.cfg.reg_app_names[xx][0],
223                      &nfa_hci_cb.cfg.reg_app_names[yy][0],
224                      strlen(nfa_hci_cb.cfg.reg_app_names[xx])))) {
225          /* Two app cannot have the same name , NVRAM is corrupted */
226          NFA_TRACE_EVENT2("nfa_hci_is_valid_cfg (%s)  Reusing: %u",
227                           &nfa_hci_cb.cfg.reg_app_names[xx][0], xx);
228          return false;
229        }
230      }
231      /* Collect list of hci handle */
232      reg_app[app_count++] = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
233    }
234  }
235
236  /* Validate Gate Control block */
237  for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++) {
238    if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != 0) {
239      if (((nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_LOOP_BACK_GATE) &&
240           (nfa_hci_cb.cfg.dyn_gates[xx].gate_id !=
241            NFA_HCI_IDENTITY_MANAGEMENT_GATE) &&
242           (nfa_hci_cb.cfg.dyn_gates[xx].gate_id <
243            NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
244          (nfa_hci_cb.cfg.dyn_gates[xx].gate_id > NFA_HCI_LAST_PROP_GATE))
245        return false;
246
247      /* Check if the same gate id is present more than once in the control
248       * block */
249      for (yy = xx + 1; yy < NFA_HCI_MAX_GATE_CB; yy++) {
250        if ((nfa_hci_cb.cfg.dyn_gates[yy].gate_id != 0) &&
251            (nfa_hci_cb.cfg.dyn_gates[xx].gate_id ==
252             nfa_hci_cb.cfg.dyn_gates[yy].gate_id)) {
253          NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Reusing: %u",
254                           nfa_hci_cb.cfg.dyn_gates[xx].gate_id);
255          return false;
256        }
257      }
258      if ((nfa_hci_cb.cfg.dyn_gates[xx].gate_owner & (~NFA_HANDLE_GROUP_HCI)) >=
259          NFA_HCI_MAX_APP_CB) {
260        NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate owner: %u",
261                         nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
262        return false;
263      }
264      if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_CONNECTIVITY_GATE) {
265        /* The gate owner should be one of the registered application */
266        for (zz = 0; zz < app_count; zz++) {
267          if (nfa_hci_cb.cfg.dyn_gates[xx].gate_owner == reg_app[zz]) break;
268        }
269        if (zz == app_count) {
270          NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate owner: %u",
271                           nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
272          return false;
273        }
274      }
275      /* Collect list of allocated gates */
276      valid_gate[gate_count++] = nfa_hci_cb.cfg.dyn_gates[xx].gate_id;
277
278      /* No two gates can own a same pipe */
279      if ((pipe_inx_mask & nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask) != 0)
280        return false;
281      /* Collect the list of pipes on this gate */
282      pipe_inx_mask |= nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask;
283    }
284  }
285
286  for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB));
287       xx++, pipe_inx_mask >>= 1) {
288    /* Every bit set in pipe increment mask indicates a valid pipe */
289    if (pipe_inx_mask & 1) {
290      /* Check if the pipe is valid one */
291      if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
292        return false;
293    }
294  }
295
296  if (xx == NFA_HCI_MAX_PIPE_CB) return false;
297
298  /* Validate Gate Control block */
299  for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++) {
300    if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id != 0) {
301      /* Check if pipe id is valid */
302      if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
303        return false;
304
305      /* Check if pipe state is valid */
306      if ((nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_OPENED) &&
307          (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_CLOSED))
308        return false;
309
310      /* Check if local gate on which the pipe is created is valid */
311      if ((((nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
312             NFA_HCI_LOOP_BACK_GATE) &&
313            (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
314             NFA_HCI_IDENTITY_MANAGEMENT_GATE)) &&
315           (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate <
316            NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
317          (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate > NFA_HCI_LAST_PROP_GATE))
318        return false;
319
320      /* Check if the peer gate on which the pipe is created is valid */
321      if ((((nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate !=
322             NFA_HCI_LOOP_BACK_GATE) &&
323            (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate !=
324             NFA_HCI_IDENTITY_MANAGEMENT_GATE)) &&
325           (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate <
326            NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
327          (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate > NFA_HCI_LAST_PROP_GATE))
328        return false;
329
330      /* Check if the same pipe is present more than once in the control block
331       */
332      for (yy = xx + 1; yy < NFA_HCI_MAX_PIPE_CB; yy++) {
333        if ((nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id != 0) &&
334            (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id ==
335             nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id)) {
336          NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Reusing: %u",
337                           nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id);
338          return false;
339        }
340      }
341      /* The local gate should be one of the element in gate control block */
342      for (zz = 0; zz < gate_count; zz++) {
343        if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate == valid_gate[zz]) break;
344      }
345      if (zz == gate_count) {
346        NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate: %u",
347                         nfa_hci_cb.cfg.dyn_pipes[xx].local_gate);
348        return false;
349      }
350    }
351  }
352
353  /* Check if admin pipe state is valid */
354  if ((nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_OPENED) &&
355      (nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_CLOSED))
356    return false;
357
358  /* Check if link management pipe state is valid */
359  if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) &&
360      (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_CLOSED))
361    return false;
362
363  pipe_inx_mask = nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask;
364  for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB));
365       xx++, pipe_inx_mask >>= 1) {
366    /* Every bit set in pipe increment mask indicates a valid pipe */
367    if (pipe_inx_mask & 1) {
368      /* Check if the pipe is valid one */
369      if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
370        return false;
371      /* Check if the pipe is connected to Identity management gate */
372      if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
373          NFA_HCI_IDENTITY_MANAGEMENT_GATE)
374        return false;
375    }
376  }
377  if (xx == NFA_HCI_MAX_PIPE_CB) return false;
378
379  return true;
380}
381
382/*******************************************************************************
383**
384** Function         nfa_hci_cfg_default
385**
386** Description      Configure default values for hci control block
387**
388** Returns          None
389**
390*******************************************************************************/
391void nfa_hci_restore_default_config(uint8_t* p_session_id) {
392  memset(&nfa_hci_cb.cfg, 0, sizeof(nfa_hci_cb.cfg));
393  memcpy(nfa_hci_cb.cfg.admin_gate.session_id, p_session_id,
394         NFA_HCI_SESSION_ID_LEN);
395  nfa_hci_cb.nv_write_needed = true;
396}
397
398/*******************************************************************************
399**
400** Function         nfa_hci_proc_nfcc_power_mode
401**
402** Description      Restore NFA HCI sub-module
403**
404** Returns          None
405**
406*******************************************************************************/
407void nfa_hci_proc_nfcc_power_mode(uint8_t nfcc_power_mode) {
408  NFA_TRACE_DEBUG1("nfa_hci_proc_nfcc_power_mode () nfcc_power_mode=%d",
409                   nfcc_power_mode);
410
411  /* if NFCC power mode is change to full power */
412  if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) {
413    nfa_hci_cb.b_low_power_mode = false;
414    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
415      nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE;
416      nfa_hci_cb.ee_disc_cmplt = false;
417      nfa_hci_cb.ee_disable_disc = true;
418      if (nfa_hci_cb.num_nfcee > 1)
419        nfa_hci_cb.w4_hci_netwk_init = true;
420      else
421        nfa_hci_cb.w4_hci_netwk_init = false;
422      nfa_hci_cb.conn_id = 0;
423      nfa_hci_cb.num_ee_dis_req_ntf = 0;
424      nfa_hci_cb.num_hot_plug_evts = 0;
425    } else {
426      NFA_TRACE_ERROR0("nfa_hci_proc_nfcc_power_mode (): Cannot restore now");
427      nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
428    }
429  } else {
430    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
431    nfa_hci_cb.w4_rsp_evt = false;
432    nfa_hci_cb.conn_id = 0;
433    nfa_sys_stop_timer(&nfa_hci_cb.timer);
434    nfa_hci_cb.b_low_power_mode = true;
435    nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
436  }
437}
438
439/*******************************************************************************
440**
441** Function         nfa_hci_dh_startup_complete
442**
443** Description      Initialization of terminal host in HCI Network is completed
444**                  Wait for other host in the network to initialize
445**
446** Returns          None
447**
448*******************************************************************************/
449void nfa_hci_dh_startup_complete(void) {
450  if (nfa_hci_cb.w4_hci_netwk_init) {
451    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) {
452      nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
453      /* Wait for EE Discovery to complete */
454      nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
455                          NFA_EE_DISCV_TIMEOUT_VAL);
456    } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) {
457      nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE_NETWK_ENABLE;
458      /* No HCP packet to DH for a specified period of time indicates all host
459       * in the network is initialized */
460      nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
461                          p_nfa_hci_cfg->hci_netwk_enable_timeout);
462    }
463  } else if ((nfa_hci_cb.num_nfcee > 1) &&
464             (nfa_hci_cb.num_ee_dis_req_ntf != (nfa_hci_cb.num_nfcee - 1))) {
465    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
466      nfa_hci_cb.ee_disable_disc = true;
467    /* Received HOT PLUG EVT, we will also wait for EE DISC REQ Ntf(s) */
468    nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
469                        p_nfa_hci_cfg->hci_netwk_enable_timeout);
470  } else {
471    /* Received EE DISC REQ Ntf(s) */
472    nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
473  }
474}
475
476/*******************************************************************************
477**
478** Function         nfa_hci_startup_complete
479**
480** Description      HCI network initialization is completed
481**
482** Returns          None
483**
484*******************************************************************************/
485void nfa_hci_startup_complete(tNFA_STATUS status) {
486  tNFA_HCI_EVT_DATA evt_data;
487
488  NFA_TRACE_EVENT1("nfa_hci_startup_complete (): Status: %u", status);
489
490  nfa_sys_stop_timer(&nfa_hci_cb.timer);
491
492  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ||
493      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
494    nfa_ee_proc_hci_info_cback();
495    nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
496  } else {
497    evt_data.hci_init.status = status;
498
499    nfa_hciu_send_to_all_apps(NFA_HCI_INIT_EVT, &evt_data);
500    nfa_sys_cback_notify_enable_complete(NFA_ID_HCI);
501  }
502
503  if (status == NFA_STATUS_OK)
504    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
505
506  else
507    nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
508}
509
510/*******************************************************************************
511**
512** Function         nfa_hci_startup
513**
514** Description      Perform HCI startup
515**
516** Returns          None
517**
518*******************************************************************************/
519void nfa_hci_startup(void) {
520  tNFA_STATUS status = NFA_STATUS_FAILED;
521  tNFA_EE_INFO ee_info[2];
522  uint8_t num_nfcee = 2;
523  uint8_t target_handle;
524  uint8_t count = 0;
525  bool found = false;
526
527  if (HCI_LOOPBACK_DEBUG) {
528    /* First step in initialization is to open the admin pipe */
529    nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
530    return;
531  }
532
533  /* We can only start up if NV Ram is read and EE discovery is complete */
534  if (nfa_hci_cb.nv_read_cmplt && nfa_hci_cb.ee_disc_cmplt &&
535      (nfa_hci_cb.conn_id == 0)) {
536    NFA_EeGetInfo(&num_nfcee, ee_info);
537
538    while ((count < num_nfcee) && (!found)) {
539      target_handle = (uint8_t)ee_info[count].ee_handle;
540
541      if (ee_info[count].ee_interface[0] == NFA_EE_INTERFACE_HCI_ACCESS) {
542        found = true;
543
544        if (ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE) {
545          NFC_NfceeModeSet(target_handle, NFC_MODE_ACTIVATE);
546        }
547        status =
548            NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, target_handle,
549                           NFA_EE_INTERFACE_HCI_ACCESS, nfa_hci_conn_cback);
550        if (status == NFA_STATUS_OK)
551          nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
552                              NFA_HCI_CON_CREATE_TIMEOUT_VAL);
553        else {
554          nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
555          NFA_TRACE_ERROR0(
556              "nfa_hci_startup - Failed to Create Logical connection. HCI "
557              "Initialization/Restore failed");
558          nfa_hci_startup_complete(NFA_STATUS_FAILED);
559        }
560      }
561      count++;
562    }
563    if (!found) {
564      NFA_TRACE_ERROR0(
565          "nfa_hci_startup - HCI ACCESS Interface not discovered. HCI "
566          "Initialization/Restore failed");
567      nfa_hci_startup_complete(NFA_STATUS_FAILED);
568    }
569  }
570}
571
572/*******************************************************************************
573**
574** Function         nfa_hci_sys_enable
575**
576** Description      Enable NFA HCI
577**
578** Returns          None
579**
580*******************************************************************************/
581static void nfa_hci_sys_enable(void) {
582  NFA_TRACE_DEBUG0("nfa_hci_sys_enable ()");
583  nfa_ee_reg_cback_enable_done(&nfa_hci_ee_info_cback);
584
585  nfa_nv_co_read((uint8_t*)&nfa_hci_cb.cfg, sizeof(nfa_hci_cb.cfg),
586                 DH_NV_BLOCK);
587  nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
588                      NFA_HCI_NV_READ_TIMEOUT_VAL);
589}
590
591/*******************************************************************************
592**
593** Function         nfa_hci_sys_disable
594**
595** Description      Disable NFA HCI
596**
597** Returns          None
598**
599*******************************************************************************/
600static void nfa_hci_sys_disable(void) {
601  tNFA_HCI_EVT_DATA evt_data;
602
603  nfa_sys_stop_timer(&nfa_hci_cb.timer);
604
605  if (nfa_hci_cb.conn_id) {
606    if (nfa_sys_is_graceful_disable()) {
607      /* Tell all applications stack is down */
608      nfa_hciu_send_to_all_apps(NFA_HCI_EXIT_EVT, &evt_data);
609      NFC_ConnClose(nfa_hci_cb.conn_id);
610      return;
611    }
612    nfa_hci_cb.conn_id = 0;
613  }
614
615  nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
616  /* deregister message handler on NFA SYS */
617  nfa_sys_deregister(NFA_ID_HCI);
618}
619
620/*******************************************************************************
621**
622** Function         nfa_hci_conn_cback
623**
624** Description      This function Process event from NCI
625**
626** Returns          None
627**
628*******************************************************************************/
629static void nfa_hci_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
630                               tNFC_CONN* p_data) {
631  uint8_t* p;
632  NFC_HDR* p_pkt = (NFC_HDR*)p_data->data.p_data;
633  uint8_t chaining_bit;
634  uint8_t pipe;
635  uint16_t pkt_len;
636#if (BT_TRACE_VERBOSE == TRUE)
637  char buff[100];
638#endif
639
640  if (event == NFC_CONN_CREATE_CEVT) {
641    nfa_hci_cb.conn_id = conn_id;
642    nfa_hci_cb.buff_size = p_data->conn_create.buff_size;
643
644    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) {
645      nfa_hci_cb.w4_hci_netwk_init = true;
646      nfa_hciu_alloc_gate(NFA_HCI_CONNECTIVITY_GATE, 0);
647    }
648
649    if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_CLOSED) {
650      /* First step in initialization/restore is to open the admin pipe */
651      nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
652    } else {
653      /* Read session id, to know DH session id is correct */
654      nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
655                                  NFA_HCI_SESSION_IDENTITY_INDEX);
656    }
657  } else if (event == NFC_CONN_CLOSE_CEVT) {
658    nfa_hci_cb.conn_id = 0;
659    nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
660    /* deregister message handler on NFA SYS */
661    nfa_sys_deregister(NFA_ID_HCI);
662  }
663
664  if ((event != NFC_DATA_CEVT) || (p_pkt == NULL)) return;
665
666  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
667      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
668    /* Received HCP Packet before timeout, Other Host initialization is not
669     * complete */
670    nfa_sys_stop_timer(&nfa_hci_cb.timer);
671    if (nfa_hci_cb.w4_hci_netwk_init)
672      nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
673                          p_nfa_hci_cfg->hci_netwk_enable_timeout);
674  }
675
676  p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
677  pkt_len = p_pkt->len;
678
679#if (BT_TRACE_PROTOCOL == TRUE)
680  DispHcp(p, pkt_len, true, (bool)!nfa_hci_cb.assembling);
681#endif
682
683  chaining_bit = ((*p) >> 0x07) & 0x01;
684  pipe = (*p++) & 0x7F;
685  if (pkt_len != 0) pkt_len--;
686
687  if (nfa_hci_cb.assembling == false) {
688    /* First Segment of a packet */
689    nfa_hci_cb.type = ((*p) >> 0x06) & 0x03;
690    nfa_hci_cb.inst = (*p++ & 0x3F);
691    if (pkt_len != 0) pkt_len--;
692    nfa_hci_cb.assembly_failed = false;
693    nfa_hci_cb.msg_len = 0;
694
695    if (chaining_bit == NFA_HCI_MESSAGE_FRAGMENTATION) {
696      nfa_hci_cb.assembling = true;
697      nfa_hci_set_receive_buf(pipe);
698      nfa_hci_assemble_msg(p, pkt_len);
699    } else {
700      if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
701          (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)) {
702        nfa_hci_set_receive_buf(pipe);
703        nfa_hci_assemble_msg(p, pkt_len);
704        p = nfa_hci_cb.p_msg_data;
705      }
706    }
707  } else {
708    if (nfa_hci_cb.assembly_failed) {
709      /* If Reassembly failed because of insufficient buffer, just drop the new
710       * segmented packets */
711      NFA_TRACE_ERROR1(
712          "nfa_hci_conn_cback (): Insufficient buffer to Reassemble HCP "
713          "packet! Dropping :%u bytes",
714          pkt_len);
715    } else {
716      /* Reassemble the packet */
717      nfa_hci_assemble_msg(p, pkt_len);
718    }
719
720    if (chaining_bit == NFA_HCI_NO_MESSAGE_FRAGMENTATION) {
721      /* Just added the last segment in the chain. Reset pointers */
722      nfa_hci_cb.assembling = false;
723      p = nfa_hci_cb.p_msg_data;
724      pkt_len = nfa_hci_cb.msg_len;
725    }
726  }
727
728#if (BT_TRACE_VERBOSE == TRUE)
729  NFA_TRACE_EVENT5(
730      "nfa_hci_conn_cback Recvd data pipe:%d  %s  chain:%d  assmbl:%d  len:%d",
731      (uint8_t)pipe, nfa_hciu_get_type_inst_names(pipe, nfa_hci_cb.type,
732                                                  nfa_hci_cb.inst, buff),
733      (uint8_t)chaining_bit, (uint8_t)nfa_hci_cb.assembling, p_pkt->len);
734#else
735  NFA_TRACE_EVENT6(
736      "nfa_hci_conn_cback Recvd data pipe:%d  Type: %u  Inst: %u  chain:%d "
737      "reassm:%d len:%d",
738      pipe, nfa_hci_cb.type, nfa_hci_cb.inst, chaining_bit,
739      nfa_hci_cb.assembling, p_pkt->len);
740#endif
741
742  /* If still reassembling fragments, just return */
743  if (nfa_hci_cb.assembling) {
744    /* if not last packet, release GKI buffer */
745    GKI_freebuf(p_pkt);
746    return;
747  }
748
749  /* If we got a response, cancel the response timer. Also, if waiting for */
750  /* a single response, we can go back to idle state                       */
751  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) &&
752      ((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) ||
753       (nfa_hci_cb.w4_rsp_evt && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)))) {
754    nfa_sys_stop_timer(&nfa_hci_cb.timer);
755    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
756  }
757
758  switch (pipe) {
759    case NFA_HCI_ADMIN_PIPE:
760      /* Check if data packet is a command, response or event */
761      if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
762        nfa_hci_handle_admin_gate_cmd(p);
763      } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
764        nfa_hci_handle_admin_gate_rsp(p, (uint8_t)pkt_len);
765      } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
766        nfa_hci_handle_admin_gate_evt(p);
767      }
768      break;
769
770    case NFA_HCI_LINK_MANAGEMENT_PIPE:
771      /* We don't send Link Management commands, we only get them */
772      if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
773        nfa_hci_handle_link_mgm_gate_cmd(p);
774      break;
775
776    default:
777      if (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE)
778        nfa_hci_handle_dyn_pipe_pkt(pipe, p, pkt_len);
779      break;
780  }
781
782  if ((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) ||
783      (nfa_hci_cb.w4_rsp_evt && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE))) {
784    nfa_hci_cb.w4_rsp_evt = false;
785  }
786
787  /* Send a message to ouselves to check for anything to do */
788  p_pkt->event = NFA_HCI_CHECK_QUEUE_EVT;
789  p_pkt->len = 0;
790  nfa_sys_sendmsg(p_pkt);
791}
792
793/*******************************************************************************
794**
795** Function         nfa_hci_handle_nv_read
796**
797** Description      handler function for nv read complete event
798**
799** Returns          None
800**
801*******************************************************************************/
802void nfa_hci_handle_nv_read(uint8_t block, tNFA_STATUS status) {
803  uint8_t session_id[NFA_HCI_SESSION_ID_LEN];
804  uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
805                                                     0xFF, 0xFF, 0xFF, 0xFF};
806  uint8_t reset_session[NFA_HCI_SESSION_ID_LEN] = {0x00, 0x00, 0x00, 0x00,
807                                                   0x00, 0x00, 0x00, 0x00};
808  uint32_t os_tick;
809
810  if (block == DH_NV_BLOCK) {
811    /* Stop timer as NVDATA Read Completed */
812    nfa_sys_stop_timer(&nfa_hci_cb.timer);
813    nfa_hci_cb.nv_read_cmplt = true;
814    if ((status != NFA_STATUS_OK) || (!nfa_hci_is_valid_cfg()) ||
815        (!(memcmp(nfa_hci_cb.cfg.admin_gate.session_id, default_session,
816                  NFA_HCI_SESSION_ID_LEN))) ||
817        (!(memcmp(nfa_hci_cb.cfg.admin_gate.session_id, reset_session,
818                  NFA_HCI_SESSION_ID_LEN)))) {
819      nfa_hci_cb.b_hci_netwk_reset = true;
820      /* Set a new session id so that we clear all pipes later after seeing a
821       * difference with the HC Session ID */
822      memcpy(&session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
823             nfa_hci_cb.cfg.admin_gate.session_id,
824             (NFA_HCI_SESSION_ID_LEN / 2));
825      os_tick = GKI_get_os_tick_count();
826      memcpy(session_id, (uint8_t*)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
827      nfa_hci_restore_default_config(session_id);
828    }
829    nfa_hci_startup();
830  }
831}
832
833/*******************************************************************************
834**
835** Function         nfa_hci_rsp_timeout
836**
837** Description      action function to process timeout
838**
839** Returns          None
840**
841*******************************************************************************/
842void nfa_hci_rsp_timeout(tNFA_HCI_EVENT_DATA* p_evt_data) {
843  tNFA_HCI_EVT evt = 0;
844  tNFA_HCI_EVT_DATA evt_data;
845  uint8_t delete_pipe;
846
847  NFA_TRACE_EVENT2("nfa_hci_rsp_timeout () State: %u  Cmd: %u",
848                   nfa_hci_cb.hci_state, nfa_hci_cb.cmd_sent);
849
850  evt_data.status = NFA_STATUS_FAILED;
851
852  switch (nfa_hci_cb.hci_state) {
853    case NFA_HCI_STATE_STARTUP:
854    case NFA_HCI_STATE_RESTORE:
855      NFA_TRACE_ERROR0("nfa_hci_rsp_timeout - Initialization failed!");
856      nfa_hci_startup_complete(NFA_STATUS_TIMEOUT);
857      break;
858
859    case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
860    case NFA_HCI_STATE_RESTORE_NETWK_ENABLE:
861
862      if (nfa_hci_cb.w4_hci_netwk_init) {
863        /* HCI Network is enabled */
864        nfa_hci_cb.w4_hci_netwk_init = false;
865        nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
866                                    NFA_HCI_HOST_LIST_INDEX);
867      } else {
868        nfa_hci_startup_complete(NFA_STATUS_FAILED);
869      }
870      break;
871
872    case NFA_HCI_STATE_REMOVE_GATE:
873      /* Something wrong, NVRAM data could be corrupt */
874      if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) {
875        nfa_hciu_send_clear_all_pipe_cmd();
876      } else {
877        nfa_hciu_remove_all_pipes_from_host(0);
878        nfa_hci_api_dealloc_gate(NULL);
879      }
880      break;
881
882    case NFA_HCI_STATE_APP_DEREGISTER:
883      /* Something wrong, NVRAM data could be corrupt */
884      if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) {
885        nfa_hciu_send_clear_all_pipe_cmd();
886      } else {
887        nfa_hciu_remove_all_pipes_from_host(0);
888        nfa_hci_api_deregister(NULL);
889      }
890      break;
891
892    case NFA_HCI_STATE_WAIT_RSP:
893      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
894
895      if (nfa_hci_cb.w4_rsp_evt) {
896        nfa_hci_cb.w4_rsp_evt = false;
897        evt = NFA_HCI_EVENT_RCVD_EVT;
898        evt_data.rcvd_evt.pipe = nfa_hci_cb.pipe_in_use;
899        evt_data.rcvd_evt.evt_code = 0;
900        evt_data.rcvd_evt.evt_len = 0;
901        evt_data.rcvd_evt.p_evt_buf = NULL;
902        nfa_hci_cb.rsp_buf_size = 0;
903        nfa_hci_cb.p_rsp_buf = NULL;
904
905        break;
906      }
907
908      delete_pipe = 0;
909      switch (nfa_hci_cb.cmd_sent) {
910        case NFA_HCI_ANY_SET_PARAMETER:
911          /*
912           * As no response to the command sent on this pipe, we may assume the
913           * pipe is
914           * deleted already and release the pipe. But still send delete pipe
915           * command to be safe.
916           */
917          delete_pipe = nfa_hci_cb.pipe_in_use;
918          evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
919          evt_data.registry.data_len = 0;
920          evt_data.registry.index = nfa_hci_cb.param_in_use;
921          evt = NFA_HCI_SET_REG_RSP_EVT;
922          break;
923
924        case NFA_HCI_ANY_GET_PARAMETER:
925          /*
926           * As no response to the command sent on this pipe, we may assume the
927           * pipe is
928           * deleted already and release the pipe. But still send delete pipe
929           * command to be safe.
930           */
931          delete_pipe = nfa_hci_cb.pipe_in_use;
932          evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
933          evt_data.registry.data_len = 0;
934          evt_data.registry.index = nfa_hci_cb.param_in_use;
935          evt = NFA_HCI_GET_REG_RSP_EVT;
936          break;
937
938        case NFA_HCI_ANY_OPEN_PIPE:
939          /*
940           * As no response to the command sent on this pipe, we may assume the
941           * pipe is
942           * deleted already and release the pipe. But still send delete pipe
943           * command to be safe.
944           */
945          delete_pipe = nfa_hci_cb.pipe_in_use;
946          evt_data.opened.pipe = nfa_hci_cb.pipe_in_use;
947          evt = NFA_HCI_OPEN_PIPE_EVT;
948          break;
949
950        case NFA_HCI_ANY_CLOSE_PIPE:
951          /*
952           * As no response to the command sent on this pipe, we may assume the
953           * pipe is
954           * deleted already and release the pipe. But still send delete pipe
955           * command to be safe.
956           */
957          delete_pipe = nfa_hci_cb.pipe_in_use;
958          evt_data.closed.pipe = nfa_hci_cb.pipe_in_use;
959          evt = NFA_HCI_CLOSE_PIPE_EVT;
960          break;
961
962        case NFA_HCI_ADM_CREATE_PIPE:
963          evt_data.created.pipe = nfa_hci_cb.pipe_in_use;
964          evt_data.created.source_gate = nfa_hci_cb.local_gate_in_use;
965          evt_data.created.dest_host = nfa_hci_cb.remote_host_in_use;
966          evt_data.created.dest_gate = nfa_hci_cb.remote_gate_in_use;
967          evt = NFA_HCI_CREATE_PIPE_EVT;
968          break;
969
970        case NFA_HCI_ADM_DELETE_PIPE:
971          /*
972           * As no response to the command sent on this pipe, we may assume the
973           * pipe is
974           * deleted already. Just release the pipe.
975           */
976          if (nfa_hci_cb.pipe_in_use <= NFA_HCI_LAST_DYNAMIC_PIPE)
977            nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
978          evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
979          evt = NFA_HCI_DELETE_PIPE_EVT;
980          break;
981
982        default:
983          /*
984           * As no response to the command sent on this pipe, we may assume the
985           * pipe is
986           * deleted already and release the pipe. But still send delete pipe
987           * command to be safe.
988           */
989          delete_pipe = nfa_hci_cb.pipe_in_use;
990          break;
991      }
992      if (delete_pipe && (delete_pipe <= NFA_HCI_LAST_DYNAMIC_PIPE)) {
993        nfa_hciu_send_delete_pipe_cmd(delete_pipe);
994        nfa_hciu_release_pipe(delete_pipe);
995      }
996      break;
997    case NFA_HCI_STATE_DISABLED:
998    default:
999      NFA_TRACE_DEBUG0(
1000          "nfa_hci_rsp_timeout () Timeout in DISABLED/ Invalid state");
1001      break;
1002  }
1003  if (evt != 0) nfa_hciu_send_to_app(evt, &evt_data, nfa_hci_cb.app_in_use);
1004}
1005
1006/*******************************************************************************
1007**
1008** Function         nfa_hci_set_receive_buf
1009**
1010** Description      Set reassembly buffer for incoming message
1011**
1012** Returns          status
1013**
1014*******************************************************************************/
1015static void nfa_hci_set_receive_buf(uint8_t pipe) {
1016  if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
1017      (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)) {
1018    if ((nfa_hci_cb.rsp_buf_size) && (nfa_hci_cb.p_rsp_buf != NULL)) {
1019      nfa_hci_cb.p_msg_data = nfa_hci_cb.p_rsp_buf;
1020      nfa_hci_cb.max_msg_len = nfa_hci_cb.rsp_buf_size;
1021      return;
1022    }
1023  }
1024  nfa_hci_cb.p_msg_data = nfa_hci_cb.msg_data;
1025  nfa_hci_cb.max_msg_len = NFA_MAX_HCI_EVENT_LEN;
1026}
1027
1028/*******************************************************************************
1029**
1030** Function         nfa_hci_assemble_msg
1031**
1032** Description      Reassemble the incoming message
1033**
1034** Returns          None
1035**
1036*******************************************************************************/
1037static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len) {
1038  if ((nfa_hci_cb.msg_len + data_len) > nfa_hci_cb.max_msg_len) {
1039    /* Fill the buffer as much it can hold */
1040    memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data,
1041           (nfa_hci_cb.max_msg_len - nfa_hci_cb.msg_len));
1042    nfa_hci_cb.msg_len = nfa_hci_cb.max_msg_len;
1043    /* Set Reassembly failed */
1044    nfa_hci_cb.assembly_failed = true;
1045    NFA_TRACE_ERROR1(
1046        "nfa_hci_assemble_msg (): Insufficient buffer to Reassemble HCP "
1047        "packet! Dropping :%u bytes",
1048        ((nfa_hci_cb.msg_len + data_len) - nfa_hci_cb.max_msg_len));
1049  } else {
1050    memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, data_len);
1051    nfa_hci_cb.msg_len += data_len;
1052  }
1053}
1054
1055/*******************************************************************************
1056**
1057** Function         nfa_hci_evt_hdlr
1058**
1059** Description      Processing all event for NFA HCI
1060**
1061** Returns          TRUE if p_msg needs to be deallocated
1062**
1063*******************************************************************************/
1064static bool nfa_hci_evt_hdlr(NFC_HDR* p_msg) {
1065  tNFA_HCI_EVENT_DATA* p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
1066
1067#if (BT_TRACE_VERBOSE == TRUE)
1068  NFA_TRACE_EVENT4(
1069      "nfa_hci_evt_hdlr state: %s (%d) event: %s (0x%04x)",
1070      nfa_hciu_get_state_name(nfa_hci_cb.hci_state), nfa_hci_cb.hci_state,
1071      nfa_hciu_get_event_name(p_evt_data->hdr.event), p_evt_data->hdr.event);
1072#else
1073  NFA_TRACE_EVENT2("nfa_hci_evt_hdlr state: %d event: 0x%04x",
1074                   nfa_hci_cb.hci_state, p_evt_data->hdr.event);
1075#endif
1076
1077  /* If this is an API request, queue it up */
1078  if ((p_msg->event >= NFA_HCI_FIRST_API_EVENT) &&
1079      (p_msg->event <= NFA_HCI_LAST_API_EVENT)) {
1080    GKI_enqueue(&nfa_hci_cb.hci_api_q, p_msg);
1081  } else {
1082    switch (p_msg->event) {
1083      case NFA_HCI_RSP_NV_READ_EVT:
1084        nfa_hci_handle_nv_read(p_evt_data->nv_read.block,
1085                               p_evt_data->nv_read.status);
1086        break;
1087
1088      case NFA_HCI_RSP_NV_WRITE_EVT:
1089        /* NV Ram write completed - nothing to do... */
1090        break;
1091
1092      case NFA_HCI_RSP_TIMEOUT_EVT:
1093        nfa_hci_rsp_timeout((tNFA_HCI_EVENT_DATA*)p_msg);
1094        break;
1095
1096      case NFA_HCI_CHECK_QUEUE_EVT:
1097        if (HCI_LOOPBACK_DEBUG) {
1098          if (p_msg->len != 0) {
1099            tNFC_DATA_CEVT xx;
1100            xx.p_data = p_msg;
1101            nfa_hci_conn_cback(0, NFC_DATA_CEVT, (tNFC_CONN*)&xx);
1102            return false;
1103          }
1104        }
1105        break;
1106    }
1107  }
1108
1109  if ((p_msg->event > NFA_HCI_LAST_API_EVENT)) GKI_freebuf(p_msg);
1110
1111  nfa_hci_check_api_requests();
1112
1113  if (nfa_hciu_is_no_host_resetting()) nfa_hci_check_pending_api_requests();
1114
1115  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) &&
1116      (nfa_hci_cb.nv_write_needed)) {
1117    nfa_hci_cb.nv_write_needed = false;
1118    nfa_nv_co_write((uint8_t*)&nfa_hci_cb.cfg, sizeof(nfa_hci_cb.cfg),
1119                    DH_NV_BLOCK);
1120  }
1121
1122  return false;
1123}
1124