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