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