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