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