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