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