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