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