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