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