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