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