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