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