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