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