blob: 2a600f146b4bd12691d585adddb0f50ab3d02065 [file] [log] [blame]
nxf24591c1cbeab2018-02-21 17:32:26 +05301/******************************************************************************
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* The original Work has been changed by NXP.
21*
22* Licensed under the Apache License, Version 2.0 (the "License");
23* you may not use this file except in compliance with the License.
24* You may obtain a copy of the License at
25*
26* http://www.apache.org/licenses/LICENSE-2.0
27*
28* Unless required by applicable law or agreed to in writing, software
29* distributed under the License is distributed on an "AS IS" BASIS,
30* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31* See the License for the specific language governing permissions and
32* limitations under the License.
33*
34* Copyright 2018 NXP
35*
36******************************************************************************/
37
38/******************************************************************************
39 *
40 * This is the main implementation file for the NFA HCI.
41 *
42 ******************************************************************************/
43#include <string.h>
44
45#include <android-base/stringprintf.h>
46#include <base/logging.h>
47
48#include "nfa_dm_int.h"
49#include "nfa_ee_api.h"
50#include "nfa_ee_int.h"
51#include "nfa_hci_api.h"
52#include "nfa_hci_defs.h"
53#include "nfa_hci_int.h"
54#include "nfa_nv_co.h"
55#include "trace_api.h"
56
57using android::base::StringPrintf;
58
59extern bool nfc_debug_enabled;
60
61/*****************************************************************************
62** Global Variables
63*****************************************************************************/
64
65tNFA_HCI_CB nfa_hci_cb;
66
67#ifndef NFA_HCI_NV_READ_TIMEOUT_VAL
68#define NFA_HCI_NV_READ_TIMEOUT_VAL 1000
69#endif
70
71#ifndef NFA_HCI_CON_CREATE_TIMEOUT_VAL
72#define NFA_HCI_CON_CREATE_TIMEOUT_VAL 1000
73#endif
74
75/*****************************************************************************
76** Static Functions
77*****************************************************************************/
78
79/* event handler function type */
80static bool nfa_hci_evt_hdlr(NFC_HDR* p_msg);
81
82static void nfa_hci_sys_enable(void);
83static void nfa_hci_sys_disable(void);
84#if(NXP_EXTNS == TRUE)
85void nfa_hci_rsp_timeout(void);
86#else
87static void nfa_hci_rsp_timeout(void);
88#endif
89static void nfa_hci_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
90 tNFC_CONN* p_data);
91#if(NXP_EXTNS == TRUE)
Suraj Uday Kotharkara94976b2018-05-15 16:14:29 +053092static void nfa_hci_timer_cback (TIMER_LIST_ENT *p_tle);
nxf24591c1cbeab2018-02-21 17:32:26 +053093static void nfa_hci_set_receive_buf(tNFA_HCI_PIPE_CMDRSP_INFO *p_pipe_cmdrsp_info);
94static bool nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len);
95#else
96static void nfa_hci_set_receive_buf(uint8_t pipe);
97static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len);
98#endif
99static void nfa_hci_handle_nv_read(uint8_t block, tNFA_STATUS status);
100
101/*****************************************************************************
102** Constants
103*****************************************************************************/
104static const tNFA_SYS_REG nfa_hci_sys_reg = {
105 nfa_hci_sys_enable, nfa_hci_evt_hdlr, nfa_hci_sys_disable,
106 nfa_hci_proc_nfcc_power_mode};
107
108/*******************************************************************************
109**
110** Function nfa_hci_ee_info_cback
111**
112** Description Callback function
113**
114** Returns None
115**
116*******************************************************************************/
117void nfa_hci_ee_info_cback(tNFA_EE_DISC_STS status) {
118 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%d", status);
119
120 switch (status) {
121 case NFA_EE_DISC_STS_ON:
122 if ((!nfa_hci_cb.ee_disc_cmplt) &&
123 ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
124 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))) {
125 /* NFCEE Discovery is in progress */
126 nfa_hci_cb.ee_disc_cmplt = true;
127 nfa_hci_cb.num_ee_dis_req_ntf = 0;
128 nfa_hci_cb.num_hot_plug_evts = 0;
129 nfa_hci_cb.conn_id = 0;
130 nfa_hci_startup();
131#if(NXP_EXTNS == TRUE)
132 } else {
133 int xx;
134 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
135 if(nfa_hci_cb.reset_host[xx].reset_cfg & NFCEE_UNRECOVERABLE_ERRROR) {
136 nfa_hciu_clear_host_resetting(nfa_hci_cb.curr_nfcee, NFCEE_UNRECOVERABLE_ERRROR);
137 /* Discovery operation is complete, retrieve discovery result */
138 nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
139 NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
140 for (int yy = 0; yy < NFA_HCI_MAX_HOST_IN_NETWORK; yy++) {
141 nfa_hci_cb.ee_info[yy].hci_enable_state = NFA_HCI_FL_EE_NONE;
nxf24591c84f9c02018-06-06 14:27:34 +0530142 nfa_hciu_add_host_resetting((nfa_hci_cb.ee_info[yy].ee_handle & ~NFA_HANDLE_GROUP_EE), NFCEE_REINIT);
nxf24591c1cbeab2018-02-21 17:32:26 +0530143 }
144 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
145 " NFCEE_UNRECOVERABLE_ERRROR reset handling");
146 nfa_hci_enable_one_nfcee();
147 break;
148 }
149 }
150#endif
151 }
152 break;
153
154 case NFA_EE_DISC_STS_OFF:
155 if (nfa_hci_cb.ee_disable_disc) break;
156 nfa_hci_cb.ee_disable_disc = true;
157 /* Discovery operation is complete, retrieve discovery result */
158#if(NXP_EXTNS == TRUE)
159 nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
160 NFA_AllEeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
161#endif
162 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
163 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
164 if ((nfa_hci_cb.num_nfcee <= 1) ||
165 (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) ||
166 (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))) {
167 /* No UICC Host is detected or
168 * HOT_PLUG_EVT(s) and or EE DISC REQ Ntf(s) are already received
169 * Get Host list and notify SYS on Initialization complete */
170 nfa_sys_stop_timer(&nfa_hci_cb.timer);
171 if ((nfa_hci_cb.num_nfcee > 1) &&
172 (nfa_hci_cb.num_ee_dis_req_ntf != (nfa_hci_cb.num_nfcee - 1))) {
173 /* Received HOT PLUG EVT, we will also wait for EE DISC REQ Ntf(s)
174 */
175 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
176 p_nfa_hci_cfg->hci_netwk_enable_timeout);
177 } else {
178 nfa_hci_cb.w4_hci_netwk_init = false;
179 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
180 NFA_HCI_HOST_LIST_INDEX);
181 }
182 }
183#if(NXP_EXTNS == TRUE)
184 else {
185 nfa_hci_cb.w4_hci_netwk_init = false;
186 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
187 NFA_HCI_HOST_LIST_INDEX);
188 }
189#endif
190 } else if (nfa_hci_cb.num_nfcee <= 1) {
191 /* No UICC Host is detected, HCI NETWORK is enabled */
192 nfa_hci_cb.w4_hci_netwk_init = false;
193 }
194 break;
195
196 case NFA_EE_DISC_STS_REQ:
197 nfa_hci_cb.num_ee_dis_req_ntf++;
198
199 if (nfa_hci_cb.ee_disable_disc) {
200 /* Already received Discovery Ntf */
201 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
202 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
203 /* Received DISC REQ Ntf while waiting for other Host in the network
204 * to bootup after DH host bootup is complete */
205 if ((nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) &&
206 NFC_GetNCIVersion() != NCI_VERSION_2_0) {
207 /* Received expected number of EE DISC REQ Ntf(s) */
208 nfa_sys_stop_timer(&nfa_hci_cb.timer);
209 nfa_hci_cb.w4_hci_netwk_init = false;
210#if(NXP_EXTNS != TRUE)
211 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
212 NFA_HCI_HOST_LIST_INDEX);
213#endif
214 }
215 } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
216 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
217 /* Received DISC REQ Ntf during DH host bootup */
218 if (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) {
219 /* Received expected number of EE DISC REQ Ntf(s) */
220 nfa_hci_cb.w4_hci_netwk_init = false;
221 }
222 }
223 }
224 break;
225 case NFA_EE_MODE_SET_COMPLETE:
226 /*received mode set Ntf */
227#if(NXP_EXTNS != TRUE)
228 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
229 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
230 /* Discovery operation is complete, retrieve discovery result */
231 NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
232 nfa_hci_enable_one_nfcee();
233 }
234 break;
235#else
236 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
237 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
238
239 if(nfa_hci_cb.next_nfcee_idx < nfa_hci_cb.num_nfcee)
240 {
241 DLOG_IF(INFO, nfc_debug_enabled)
242 << StringPrintf("NFA_EE_MODE_SET_COMPLETE handling 2");
243 if(nfa_hci_cb.ee_info[nfa_hci_cb.next_nfcee_idx].hci_enable_state == NFA_HCI_FL_EE_ENABLING) {
Suraj Uday Kotharkarc6b112a2018-06-08 22:13:00 +0530244 for (uint8_t xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
245 if((nfa_hci_cb.reset_host[xx].reset_cfg & NFCEE_HCI_NOTIFY_ALL_PIPE_CLEARED) && (nfa_hci_cb.reset_host[xx].host_id == nfa_hci_cb.curr_nfcee)) {
246 DLOG_IF(INFO, nfc_debug_enabled)
247 << StringPrintf("NFA_EE_MODE_SET_COMPLETE handling here");
248 nfa_hciu_clear_host_resetting(nfa_hci_cb.curr_nfcee, NFCEE_HCI_NOTIFY_ALL_PIPE_CLEARED);
249 if(nfa_hci_cb.curr_nfcee == NFA_HCI_FIRST_PROP_HOST)
250 {
251 if(nfcFL.eseFL._NCI_NFCEE_PWR_LINK_CMD)
252 NFC_NfceePLConfig(NFA_HCI_FIRST_PROP_HOST, 0x03);
253 status = NFC_NfceeModeSet(NFA_HCI_FIRST_PROP_HOST, NFC_MODE_ACTIVATE);
254 if(status == NFA_STATUS_OK)
255 return;
256 }
257 break;
258 }
259 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530260 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
261 NFA_HCI_HOST_LIST_INDEX);
262 nfa_hci_cb.ee_info[nfa_hci_cb.next_nfcee_idx].hci_enable_state = NFA_HCI_FL_EE_ENABLED;
263 DLOG_IF(INFO, nfc_debug_enabled)
264 << StringPrintf("NFA_EE_MODE_SET_COMPLETE handling 3");
265
266 }
267 else if (!nfa_hci_enable_one_nfcee ())
268 nfa_hci_startup_complete (NFA_STATUS_OK);
269 }
270 } else {
271 int xx;
272 DLOG_IF(INFO, nfc_debug_enabled)
273 << StringPrintf("NFA_EE_MODE_SET_COMPLETE else case");
274 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
275 if(nfa_hci_cb.reset_host[xx].reset_cfg & NFCEE_HCI_NOTIFY_ALL_PIPE_CLEARED) {
276 nfa_hciu_clear_host_resetting(nfa_hci_cb.curr_nfcee, NFCEE_HCI_NOTIFY_ALL_PIPE_CLEARED);
277 if(!nfa_hci_check_set_apdu_pipe_ready_for_next_host ()) {
278 DLOG_IF(INFO, nfc_debug_enabled)
279 << StringPrintf("NFCEE_HCI_NOTIFY_ALL_PIPE_CLEARED () reset handling");
280 nfa_hci_handle_pending_host_reset();
281 }
282 break;
283 } else if (nfa_hci_cb.reset_host[xx].reset_cfg & NFCEE_REINIT) {
284 nfa_hciu_clear_host_resetting(nfa_hci_cb.curr_nfcee, NFCEE_REINIT);
285 nfa_hci_cb.next_nfcee_idx += 1;
286 if(nfa_hci_cb.next_nfcee_idx < nfa_hci_cb.num_nfcee) {
287 DLOG_IF(INFO, nfc_debug_enabled)
288 << StringPrintf("NFCEE_UNRECOVERABLE_ERRROR reset handling");
289 nfa_hci_enable_one_nfcee();
290 }
291 break;
Suraj Uday Kotharkarb43fdb62018-06-08 20:51:09 +0530292 } else if (nfa_hci_cb.reset_host[xx].reset_cfg & NFCEE_INIT_COMPLETED) {
293 if(nfa_hci_cb.next_nfcee_idx < nfa_hci_cb.num_nfcee) {
294 DLOG_IF(INFO, nfc_debug_enabled)
295 << StringPrintf("delayed NFCEE_INIT_COMPLETED handling");
296 nfa_hci_enable_one_nfcee();
297 }
298 break;
nxf24591c1cbeab2018-02-21 17:32:26 +0530299 } else if (nfa_hci_cb.reset_host[xx].reset_cfg & NFCEE_REMOVED_NTF) {
300 DLOG_IF(INFO, nfc_debug_enabled)
301 << StringPrintf("NFCEE_REMOVED_NTF handling");
302 nfa_hciu_clear_host_resetting(nfa_hci_cb.curr_nfcee, NFCEE_REMOVED_NTF);
303 nfa_hci_handle_pending_host_reset();
304 break;
305 }
306 }
307
nxf24591c1cbeab2018-02-21 17:32:26 +0530308 }
309 break;
Suraj Uday Kotharkarc6b112a2018-06-08 22:13:00 +0530310#endif
311#if(NXP_EXTNS == TRUE)
nxf24591c1cbeab2018-02-21 17:32:26 +0530312 case NFA_EE_UNRECOVERABLE_ERROR:
Suraj Uday Kotharkarb43fdb62018-06-08 20:51:09 +0530313 case NFA_EE_STATUS_INIT_COMPLETED:
nxf24591c1cbeab2018-02-21 17:32:26 +0530314 /*NFCEE recovery in progress*/
315 {
316 int ee_entry_index = 0;
317 while (ee_entry_index < nfa_ee_max_ee_cfg) {
Suraj Uday Kotharkarb43fdb62018-06-08 20:51:09 +0530318 if (nfa_ee_cb.ecb[ee_entry_index].nfcee_status == NFC_NFCEE_STS_INIT_COMPLETED) {
319 DLOG_IF(INFO, nfc_debug_enabled)
320 << StringPrintf("NFA_EE_STATUS_NTF received %x",nfa_ee_cb.ecb[ee_entry_index].nfcee_id);
321 if (!((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
322 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE))) {
323 DLOG_IF(INFO, nfc_debug_enabled)
324 << StringPrintf("NFA_EE_STATUS_NTF received %x",nfa_ee_cb.ecb[ee_entry_index].nfcee_id);
325 if (nfa_hciu_find_dyn_apdu_pipe_for_host (nfa_ee_cb.ecb[ee_entry_index].nfcee_id) == NULL)
326 {
327 nfa_hci_cb.curr_nfcee = nfa_ee_cb.ecb[ee_entry_index].nfcee_id;
328 nfa_hci_cb.next_nfcee_idx = 0x00;
329 if(nfa_ee_cb.ecb[ee_entry_index].nfcee_id == NFA_HCI_FIRST_PROP_HOST) {
330 NFC_NfceePLConfig(nfa_ee_cb.ecb[ee_entry_index].nfcee_id, 0x03);
331 nfa_hciu_add_host_resetting(nfa_ee_cb.ecb[ee_entry_index].nfcee_id, NFCEE_INIT_COMPLETED);
332 status = NFC_NfceeModeSet(nfa_ee_cb.ecb[ee_entry_index].nfcee_id, NFC_MODE_ACTIVATE);
333 if(status == NFA_STATUS_OK) {
334 break;
335 }
336 }
337 }
338 }
339 }
340 else if (nfa_ee_cb.ecb[ee_entry_index].nfcee_status == NFC_NFCEE_STS_UNRECOVERABLE_ERROR) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530341 nfa_ee_cb.ecb[ee_entry_index].nfcee_status = NFC_NFCEE_STS_INIT_STARTED;
342 if (!((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
343 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE))) {
344 DLOG_IF(INFO, nfc_debug_enabled)
345 << StringPrintf("NFA_EE_RECOVERY %x",nfa_ee_cb.ecb[ee_entry_index].nfcee_id);
346 if(!nfa_hciu_is_host_reseting(nfa_ee_cb.ecb[ee_entry_index].nfcee_id)) {
nxf24591c84f9c02018-06-06 14:27:34 +0530347 nfa_hciu_add_host_resetting(nfa_ee_cb.ecb[ee_entry_index].nfcee_id, NFCEE_UNRECOVERABLE_ERRROR);
nxf24591c1cbeab2018-02-21 17:32:26 +0530348 nfa_hci_release_transceive(nfa_ee_cb.ecb[ee_entry_index].nfcee_id);
349 nfa_hci_cb.curr_nfcee = nfa_ee_cb.ecb[ee_entry_index].nfcee_id;
350 nfa_hci_cb.next_nfcee_idx = 0x00;
351 if(NFC_NfceeDiscover(true) == NFC_STATUS_FAILED) {
352 DLOG_IF(INFO, nfc_debug_enabled)
353 << StringPrintf("NFA_EE_RECOVERY unable to perform");
354 }
355 }
356 }
357 nfa_hciu_add_host_resetting(nfa_hci_cb.curr_nfcee, NFCEE_UNRECOVERABLE_ERRROR);
358 break;
359 }
360 ee_entry_index++;
361 }
362 break;
363 }
364 case NFA_EE_STATUS_NFCEE_REMOVED:
365 {
366 nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
367 NFA_AllEeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
368 for (int ee_entry_index = 0; ee_entry_index < NFA_HCI_MAX_HOST_IN_NETWORK; ee_entry_index++) {
369 uint8_t nfceeid = nfa_hci_cb.ee_info[ee_entry_index].ee_handle & ~NFA_HANDLE_GROUP_EE;
370 if(nfa_hci_cb.ee_info[ee_entry_index].ee_status == NFA_EE_STATUS_REMOVED &&
371 nfceeid == NFA_HCI_FIRST_PROP_HOST) {
372 if (!(nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE ||
373 nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE ||
374 nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)) {
375 nfa_hciu_add_host_resetting(nfceeid, NFCEE_REMOVED_NTF);
376 nfa_hci_release_transceive(nfceeid);
377 nfa_hci_cb.ee_info[ee_entry_index].hci_enable_state = NFA_HCI_FL_EE_ENABLING;
378 status = NFC_NfceeModeSet(nfceeid, NFC_MODE_ACTIVATE);
379 if(status == NFA_STATUS_OK) {
380 nfa_hci_cb.curr_nfcee = nfceeid;
381 nfa_hci_cb.next_nfcee_idx = ee_entry_index;
382 break;
383 }
384 }
385 }
386 }
387 break;
388 }
389 /*received NFCEE error ntf*/
390#endif
391 }
392}
393
394/*******************************************************************************
395**
396** Function nfa_hci_init
397**
398** Description Initialize NFA HCI
399**
400** Returns None
401**
402*******************************************************************************/
403void nfa_hci_init(void) {
404 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
405#if(NXP_EXTNS == TRUE)
406 uint8_t xx;
407#endif
408 /* initialize control block */
409 memset(&nfa_hci_cb, 0, sizeof(tNFA_HCI_CB));
410
411 nfa_hci_cb.hci_state = NFA_HCI_STATE_STARTUP;
412 nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
413#if(NXP_EXTNS == TRUE)
414 nfa_hci_cb.pipe_in_use = NFA_HCI_INVALID_PIPE;
nxf24591193ee782018-06-06 14:26:10 +0530415 nfa_hci_cb.m_wtx_count = 0;
nxf24591c1cbeab2018-02-21 17:32:26 +0530416 /* initialize timer callback */
417 for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++)
418 {
419 nfa_hci_cb.dyn_pipe_cmdrsp_info[xx].rsp_timer.p_cback = nfa_hci_timer_cback;
420 nfa_hci_cb.dyn_pipe_cmdrsp_info[xx].rsp_timer.param = (uintptr_t) &nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id;
421 }
422 nfa_hci_cb.static_pipe[0] = NFA_HCI_LINK_MANAGEMENT_PIPE;
423 nfa_hci_cb.static_pipe[1] = NFA_HCI_ADMIN_PIPE;
424 for (xx = 0; xx < NFA_HCI_MAX_NUM_STATIC_PIPES; xx++)
425 {
426 nfa_hci_cb.static_pipe_cmdrsp_info[xx].rsp_timer.p_cback = nfa_hci_timer_cback;
427 nfa_hci_cb.static_pipe_cmdrsp_info[xx].rsp_timer.param = (uintptr_t) &nfa_hci_cb.static_pipe[xx];
428 }
429#endif
430 /* register message handler on NFA SYS */
431 nfa_sys_register(NFA_ID_HCI, &nfa_hci_sys_reg);
432}
433
434/*******************************************************************************
435**
436** Function nfa_hci_is_valid_cfg
437**
438** Description Validate hci control block config parameters
439**
440** Returns None
441**
442*******************************************************************************/
443bool nfa_hci_is_valid_cfg(void) {
444 uint8_t xx, yy, zz;
445 tNFA_HANDLE reg_app[NFA_HCI_MAX_APP_CB];
446 uint8_t valid_gate[NFA_HCI_MAX_GATE_CB];
447 uint8_t app_count = 0;
448 uint8_t gate_count = 0;
449 uint32_t pipe_inx_mask = 0;
450
451 /* First, see if valid values are stored in app names, send connectivity
452 * events flag */
453 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
454 /* Check if app name is valid with null terminated string */
455 if (strlen(&nfa_hci_cb.cfg.reg_app_names[xx][0]) > NFA_MAX_HCI_APP_NAME_LEN)
456 return false;
457
458 /* Send Connectivity event flag can be either TRUE or FALSE */
459 if ((nfa_hci_cb.cfg.b_send_conn_evts[xx] != true) &&
460 (nfa_hci_cb.cfg.b_send_conn_evts[xx] != false))
461 return false;
462
463 if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) {
464 /* Check if the app name is present more than one time in the control
465 * block */
466 for (yy = xx + 1; yy < NFA_HCI_MAX_APP_CB; yy++) {
467 if ((nfa_hci_cb.cfg.reg_app_names[yy][0] != 0) &&
468 (!strncmp(&nfa_hci_cb.cfg.reg_app_names[xx][0],
469 &nfa_hci_cb.cfg.reg_app_names[yy][0],
470 strlen(nfa_hci_cb.cfg.reg_app_names[xx])))) {
471 /* Two app cannot have the same name , NVRAM is corrupted */
472 DLOG_IF(INFO, nfc_debug_enabled)
473 << StringPrintf("nfa_hci_is_valid_cfg (%s) Reusing: %u",
474 &nfa_hci_cb.cfg.reg_app_names[xx][0], xx);
475 return false;
476 }
477 }
478 /* Collect list of hci handle */
479 reg_app[app_count++] = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
480 }
481 }
482
483 /* Validate Gate Control block */
484 for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++) {
485 if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != 0) {
486 if (((nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_LOOP_BACK_GATE) &&
487 (nfa_hci_cb.cfg.dyn_gates[xx].gate_id !=
488 NFA_HCI_IDENTITY_MANAGEMENT_GATE) &&
489 (nfa_hci_cb.cfg.dyn_gates[xx].gate_id <
490 NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
491 (nfa_hci_cb.cfg.dyn_gates[xx].gate_id > NFA_HCI_LAST_PROP_GATE))
492 return false;
493
494 /* Check if the same gate id is present more than once in the control
495 * block */
496 for (yy = xx + 1; yy < NFA_HCI_MAX_GATE_CB; yy++) {
497 if ((nfa_hci_cb.cfg.dyn_gates[yy].gate_id != 0) &&
498 (nfa_hci_cb.cfg.dyn_gates[xx].gate_id ==
499 nfa_hci_cb.cfg.dyn_gates[yy].gate_id)) {
500 DLOG_IF(INFO, nfc_debug_enabled)
501 << StringPrintf("nfa_hci_is_valid_cfg Reusing: %u",
502 nfa_hci_cb.cfg.dyn_gates[xx].gate_id);
503 return false;
504 }
505 }
506 if ((nfa_hci_cb.cfg.dyn_gates[xx].gate_owner & (~NFA_HANDLE_GROUP_HCI)) >=
507 NFA_HCI_MAX_APP_CB) {
508 DLOG_IF(INFO, nfc_debug_enabled)
509 << StringPrintf("nfa_hci_is_valid_cfg Invalid Gate owner: %u",
510 nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
511 return false;
512 }
513 if (!((nfa_hci_cb.cfg.dyn_gates[xx].gate_id ==
514 NFA_HCI_CONNECTIVITY_GATE) ||
515 ((nfa_hci_cb.cfg.dyn_gates[xx].gate_id >=
516 NFA_HCI_PROP_GATE_FIRST) ||
517 (nfa_hci_cb.cfg.dyn_gates[xx].gate_id <=
518 NFA_HCI_PROP_GATE_LAST)))) {
519 /* The gate owner should be one of the registered application */
520 for (zz = 0; zz < app_count; zz++) {
521 if (nfa_hci_cb.cfg.dyn_gates[xx].gate_owner == reg_app[zz]) break;
522 }
523 if (zz == app_count) {
524 DLOG_IF(INFO, nfc_debug_enabled)
525 << StringPrintf("nfa_hci_is_valid_cfg Invalid Gate owner: %u",
526 nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
527 return false;
528 }
529 }
530 /* Collect list of allocated gates */
531 valid_gate[gate_count++] = nfa_hci_cb.cfg.dyn_gates[xx].gate_id;
532
533 /* No two gates can own a same pipe */
534 if ((pipe_inx_mask & nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask) != 0)
535 return false;
536 /* Collect the list of pipes on this gate */
537 pipe_inx_mask |= nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask;
538 }
539 }
540
541 for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB));
542 xx++, pipe_inx_mask >>= 1) {
543 /* Every bit set in pipe increment mask indicates a valid pipe */
544 if (pipe_inx_mask & 1) {
545 /* Check if the pipe is valid one */
546 if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
547 return false;
548 }
549 }
550
551 if (xx == NFA_HCI_MAX_PIPE_CB) return false;
552
553 /* Validate Gate Control block */
554 for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++) {
555 if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id != 0) {
556 /* Check if pipe id is valid */
557 if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
558 return false;
559
560 /* Check if pipe state is valid */
561 if ((nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_OPENED) &&
562 (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_CLOSED))
563 return false;
564
565 /* Check if local gate on which the pipe is created is valid */
566 if ((((nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
567 NFA_HCI_LOOP_BACK_GATE) &&
568 (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
569 NFA_HCI_IDENTITY_MANAGEMENT_GATE)) &&
570 (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate <
571 NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
572 (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate > NFA_HCI_LAST_PROP_GATE))
573 return false;
574
575 /* Check if the peer gate on which the pipe is created is valid */
576 if ((((nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate !=
577 NFA_HCI_LOOP_BACK_GATE) &&
578 (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate !=
579 NFA_HCI_IDENTITY_MANAGEMENT_GATE)) &&
580 (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate <
581 NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
582 (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate > NFA_HCI_LAST_PROP_GATE))
583 return false;
584
585 /* Check if the same pipe is present more than once in the control block
586 */
587 for (yy = xx + 1; yy < NFA_HCI_MAX_PIPE_CB; yy++) {
588 if ((nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id != 0) &&
589 (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id ==
590 nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id)) {
591 DLOG_IF(INFO, nfc_debug_enabled)
592 << StringPrintf("nfa_hci_is_valid_cfg Reusing: %u",
593 nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id);
594 return false;
595 }
596 }
597 /* The local gate should be one of the element in gate control block */
598 for (zz = 0; zz < gate_count; zz++) {
599 if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate == valid_gate[zz]) break;
600 }
601 if (zz == gate_count) {
602 DLOG_IF(INFO, nfc_debug_enabled)
603 << StringPrintf("nfa_hci_is_valid_cfg Invalid Gate: %u",
604 nfa_hci_cb.cfg.dyn_pipes[xx].local_gate);
605 return false;
606 }
607 }
608 }
609
610 /* Check if admin pipe state is valid */
611 if ((nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_OPENED) &&
612 (nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_CLOSED))
613 return false;
614
615 /* Check if link management pipe state is valid */
616 if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) &&
617 (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_CLOSED))
618 return false;
619
620 pipe_inx_mask = nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask;
621 for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB));
622 xx++, pipe_inx_mask >>= 1) {
623 /* Every bit set in pipe increment mask indicates a valid pipe */
624 if (pipe_inx_mask & 1) {
625 /* Check if the pipe is valid one */
626 if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
627 return false;
628 /* Check if the pipe is connected to Identity management gate */
629 if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
630 NFA_HCI_IDENTITY_MANAGEMENT_GATE)
631 return false;
632 }
633 }
634 if (xx == NFA_HCI_MAX_PIPE_CB) return false;
635
636 return true;
637}
638
639/*******************************************************************************
640**
641** Function nfa_hci_cfg_default
642**
643** Description Configure default values for hci control block
644**
645** Returns None
646**
647*******************************************************************************/
648void nfa_hci_restore_default_config(uint8_t* p_session_id) {
649 memset(&nfa_hci_cb.cfg, 0, sizeof(nfa_hci_cb.cfg));
650 memcpy(nfa_hci_cb.cfg.admin_gate.session_id, p_session_id,
651 NFA_HCI_SESSION_ID_LEN);
652 nfa_hci_cb.nv_write_needed = true;
653}
654
655/*******************************************************************************
656**
657** Function nfa_hci_proc_nfcc_power_mode
658**
659** Description Restore NFA HCI sub-module
660**
661** Returns None
662**
663*******************************************************************************/
664void nfa_hci_proc_nfcc_power_mode(uint8_t nfcc_power_mode) {
665 DLOG_IF(INFO, nfc_debug_enabled)
666 << StringPrintf("nfcc_power_mode=%d", nfcc_power_mode);
667
668 /* if NFCC power mode is change to full power */
669 if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) {
670 nfa_hci_cb.b_low_power_mode = false;
671 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
672 nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE;
673 nfa_hci_cb.ee_disc_cmplt = false;
674 nfa_hci_cb.ee_disable_disc = true;
675 if (nfa_hci_cb.num_nfcee > 1)
676 nfa_hci_cb.w4_hci_netwk_init = true;
677 else
678 nfa_hci_cb.w4_hci_netwk_init = false;
679 nfa_hci_cb.conn_id = 0;
680 nfa_hci_cb.num_ee_dis_req_ntf = 0;
681 nfa_hci_cb.num_hot_plug_evts = 0;
682 } else {
683 LOG(ERROR) << StringPrintf("Cannot restore now");
684 nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
685 }
686 } else {
687 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
688 nfa_hci_cb.w4_rsp_evt = false;
689 nfa_hci_cb.conn_id = 0;
690 nfa_sys_stop_timer(&nfa_hci_cb.timer);
691 nfa_hci_cb.b_low_power_mode = true;
692 nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
693 }
694}
695
696/*******************************************************************************
697**
698** Function nfa_hci_dh_startup_complete
699**
700** Description Initialization of terminal host in HCI Network is completed
701** Wait for other host in the network to initialize
702**
703** Returns None
704**
705*******************************************************************************/
706void nfa_hci_dh_startup_complete(void) {
707 if (nfa_hci_cb.w4_hci_netwk_init) {
708 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) {
709 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
710 /* Wait for EE Discovery to complete */
711 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
712 NFA_EE_DISCV_TIMEOUT_VAL);
713#if(NXP_EXTNS == TRUE)
714 if(!nfa_ee_cb.num_ee_expecting) {
715 nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
716 NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
717 if(nfa_hci_cb.num_nfcee == nfa_ee_max_ee_cfg)
718 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
719 }
720#endif
721 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) {
722 nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE_NETWK_ENABLE;
723 /* No HCP packet to DH for a specified period of time indicates all host
724 * in the network is initialized */
725 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
726 p_nfa_hci_cfg->hci_netwk_enable_timeout);
727 }
728 } else if ((nfa_hci_cb.num_nfcee > 1) &&
729 (nfa_hci_cb.num_ee_dis_req_ntf != (nfa_hci_cb.num_nfcee - 1))) {
730 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
731 nfa_hci_cb.ee_disable_disc = true;
732 /* Received HOT PLUG EVT, we will also wait for EE DISC REQ Ntf(s) */
733 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
734 p_nfa_hci_cfg->hci_netwk_enable_timeout);
735 } else {
736 /* Received EE DISC REQ Ntf(s) */
737#if(NXP_EXTNS == TRUE)
738 nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
739 NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
740#endif
741 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
742 }
743}
744
745/*******************************************************************************
746**
747** Function nfa_hci_startup_complete
748**
749** Description HCI network initialization is completed
750**
751** Returns None
752**
753*******************************************************************************/
754void nfa_hci_startup_complete(tNFA_STATUS status) {
755 tNFA_HCI_EVT_DATA evt_data;
756
757 nfa_sys_stop_timer(&nfa_hci_cb.timer);
758
759 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ||
760 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
761 nfa_ee_proc_hci_info_cback();
762 nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
763
hariprasad nalacheruvu87d22952018-08-08 01:35:00 +0530764 } else
nxf24591c1cbeab2018-02-21 17:32:26 +0530765#if(NXP_EXTNS == TRUE)
766 if(nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE ||
767 nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
768#endif
769 {
770 evt_data.hci_init.status = status;
771
772 nfa_hciu_send_to_all_apps(NFA_HCI_INIT_EVT, &evt_data);
773 nfa_sys_cback_notify_enable_complete(NFA_ID_HCI);
774 }
775
776 if (status == NFA_STATUS_OK)
777 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
778
779 else
780 nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
781#if(NXP_EXTNS == TRUE)
782 nfa_hci_handle_pending_host_reset();
783#endif
784}
785
786#if(NXP_EXTNS != TRUE)
787/*******************************************************************************
788**
789** Function nfa_hci_enable_one_nfcee
790**
791** Description Enable NFCEE Hosts which are discovered.
792**
793** Returns None
794**
795*******************************************************************************/
796void nfa_hci_enable_one_nfcee(void) {
797 uint8_t xx;
798 uint8_t nfceeid = 0;
799
800 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%d", nfa_hci_cb.num_nfcee);
801
802 for (xx = 0; xx < nfa_hci_cb.num_nfcee; xx++) {
803 nfceeid = nfa_hci_cb.ee_info[xx].ee_handle & ~NFA_HANDLE_GROUP_EE;
804 if (nfa_hci_cb.ee_info[xx].ee_status == NFA_EE_STATUS_INACTIVE) {
805 NFC_NfceeModeSet(nfceeid, NFC_MODE_ACTIVATE);
806 return;
807 }
808 }
809
810 if (xx == nfa_hci_cb.num_nfcee) {
811 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
812 }
813}
814#else
815/*******************************************************************************
816 **
817 ** Function nfa_hci_enable_one_nfcee
818 **
819 ** Description Enable NFCEE Hosts which are discovered.
820 **
821 ** Returns TRUE or FALSE
822 **
823 *******************************************************************************/
824bool nfa_hci_enable_one_nfcee(void) {
825 uint8_t xx;
826 uint8_t nfceeid = 0;
827 bool enable_cmplt = false;
828 DLOG_IF(INFO, nfc_debug_enabled)
829 << StringPrintf("nfa_hci_enable_one_nfcee () enter");
830
831 tNFA_STATUS status = NFA_STATUS_FAILED;
832 for (xx = nfa_hci_cb.next_nfcee_idx; xx < nfa_hci_cb.num_nfcee; xx++) {
833 DLOG_IF(INFO, nfc_debug_enabled)
834 << StringPrintf("nfa_hci_enable_one_nfcee () %d",xx);
835 if (nfa_hci_cb.ee_info[xx].ee_interface[0] != NFA_EE_INTERFACE_HCI_ACCESS) {
836 nfceeid = nfa_hci_cb.ee_info[xx].ee_handle & ~NFA_HANDLE_GROUP_EE;
837 if (nfa_hci_cb.ee_info[xx].ee_status == NFA_EE_STATUS_INACTIVE ||
838 nfa_hci_cb.ee_info[xx].ee_status == NFA_EE_STATUS_ACTIVE ||
839 nfa_hci_cb.ee_info[xx].ee_status == NFA_EE_STATUS_REMOVED) {
840 if(nfceeid != NFA_HCI_FIRST_PROP_HOST &&
841 nfa_hci_cb.ee_info[xx].ee_status == NFA_EE_STATUS_REMOVED) {
842 nfa_hci_cb.next_nfcee_idx = xx + 1;
843 continue;
844 }
845 if(nfa_hci_cb.ee_info[xx].hci_enable_state == NFA_HCI_FL_EE_ENABLED) {
846 if(nfa_hci_check_set_apdu_pipe_ready_for_next_host ()) {
847 nfa_hci_cb.next_nfcee_idx = xx + 1;
848 enable_cmplt = true;
849 break;
850 }
851 nfa_hci_cb.next_nfcee_idx = xx + 1;
852 }
853 else if(nfa_hci_cb.ee_info[xx].hci_enable_state == NFA_HCI_FL_EE_ENABLING ||
854 nfa_hci_cb.ee_info[xx].hci_enable_state == NFA_HCI_FL_EE_NONE)
855 {
856 nfa_hci_cb.ee_info[xx].hci_enable_state = NFA_HCI_FL_EE_ENABLING;
857 if(nfa_hci_cb.ee_info[xx].ee_status == NFA_EE_STATUS_ACTIVE){
858 if(nfa_dm_is_hci_supported()) {
859 nfa_hci_cb.ee_info[xx].hci_enable_state = NFA_HCI_FL_EE_ENABLED;
860 nfa_hciu_clear_host_resetting(nfceeid, NFCEE_REINIT);
861 nfa_hci_cb.next_nfcee_idx = xx + 1;
862 continue;
863 }
864 }
865 if (nfa_hciu_find_dyn_apdu_pipe_for_host (nfceeid) == NULL)
866 {
867 if(nfcFL.eseFL._NCI_NFCEE_PWR_LINK_CMD)
868 {
869 if(nfceeid == NFA_HCI_FIRST_PROP_HOST)
870 status = NFC_NfceePLConfig(nfceeid, 0x03);
871 }
872 }
873 status = NFC_NfceeModeSet(nfceeid, NFC_MODE_ACTIVATE);
874 if(status == NFA_STATUS_OK) {
875 nfa_hci_cb.curr_nfcee = nfceeid;
876 nfa_hci_cb.next_nfcee_idx = xx;
877 enable_cmplt = true;
878 break;
879 }
880 }
881 }
882 }
883 }
884 return enable_cmplt;
885}
886#endif
887/*******************************************************************************
888**
889** Function nfa_hci_startup
890**
891** Description Perform HCI startup
892**
893** Returns None
894**
895*******************************************************************************/
896void nfa_hci_startup(void) {
897 tNFA_STATUS status = NFA_STATUS_FAILED;
898 uint8_t target_handle;
899 uint8_t count = 0;
900 bool found = false;
901
902 if (HCI_LOOPBACK_DEBUG == NFA_HCI_DEBUG_ON) {
903 /* First step in initialization is to open the admin pipe */
904 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
905 return;
906 }
907
908 /* We can only start up if NV Ram is read and EE discovery is complete */
909 if (nfa_hci_cb.nv_read_cmplt && nfa_hci_cb.ee_disc_cmplt &&
910 (nfa_hci_cb.conn_id == 0)) {
911 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
912 NFC_SetStaticHciCback(nfa_hci_conn_cback);
913 } else {
914 NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
915
916 while ((count < nfa_hci_cb.num_nfcee) && (!found)) {
917 target_handle = (uint8_t)nfa_hci_cb.ee_info[count].ee_handle;
918
919 if (nfa_hci_cb.ee_info[count].ee_interface[0] ==
920 NFA_EE_INTERFACE_HCI_ACCESS) {
921 found = true;
922
923#if(NXP_EXTNS != TRUE)
924 if (nfa_hci_cb.ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE) {
925 NFC_NfceeModeSet(target_handle, NFC_MODE_ACTIVATE);
926 }
927#endif
928 if ((status = NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, target_handle,
929 NFA_EE_INTERFACE_HCI_ACCESS,
930 nfa_hci_conn_cback)) == NFA_STATUS_OK)
931 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
932 NFA_HCI_CON_CREATE_TIMEOUT_VAL);
933 else {
934 nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
935 LOG(ERROR) << StringPrintf(
936 "nfa_hci_startup - Failed to Create Logical connection. HCI "
937 "Initialization/Restore failed");
938 nfa_hci_startup_complete(NFA_STATUS_FAILED);
939 }
940#if(NXP_EXTNS == TRUE)
941 if (nfa_hci_cb.ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE) {
942 LOG(ERROR) << StringPrintf(
943 "nfa_hci_startup - Enabling one hci ");
944 NFC_NfceeModeSet(target_handle, NFC_MODE_ACTIVATE);
945 }
946#endif
947 }
948 count++;
949 }
950 if (!found) {
951 LOG(ERROR) << StringPrintf(
952 "nfa_hci_startup - HCI ACCESS Interface not discovered. HCI "
953 "Initialization/Restore failed");
954 nfa_hci_startup_complete(NFA_STATUS_FAILED);
955 }
956 }
957 }
958}
959
960/*******************************************************************************
961**
962** Function nfa_hci_sys_enable
963**
964** Description Enable NFA HCI
965**
966** Returns None
967**
968*******************************************************************************/
969static void nfa_hci_sys_enable(void) {
970 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
971 nfa_ee_reg_cback_enable_done(&nfa_hci_ee_info_cback);
972
973 nfa_nv_co_read((uint8_t*)&nfa_hci_cb.cfg, sizeof(nfa_hci_cb.cfg),
974 DH_NV_BLOCK);
975 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
976 NFA_HCI_NV_READ_TIMEOUT_VAL);
977}
978
979/*******************************************************************************
980**
981** Function nfa_hci_sys_disable
982**
983** Description Disable NFA HCI
984**
985** Returns None
986**
987*******************************************************************************/
988static void nfa_hci_sys_disable(void) {
989 tNFA_HCI_EVT_DATA evt_data;
990
991 nfa_sys_stop_timer(&nfa_hci_cb.timer);
992
993 if (nfa_hci_cb.conn_id) {
994 if (nfa_sys_is_graceful_disable()) {
995 /* Tell all applications stack is down */
996 if (NFC_GetNCIVersion() == NCI_VERSION_1_0) {
997 nfa_hciu_send_to_all_apps(NFA_HCI_EXIT_EVT, &evt_data);
998 NFC_ConnClose(nfa_hci_cb.conn_id);
999 }
1000 return;
1001 }
1002 nfa_hci_cb.conn_id = 0;
1003 }
1004
1005 nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
1006 /* deregister message handler on NFA SYS */
1007 nfa_sys_deregister(NFA_ID_HCI);
1008}
1009
1010/*******************************************************************************
1011**
1012** Function nfa_hci_conn_cback
1013**
1014** Description This function Process event from NCI
1015**
1016** Returns None
1017**
1018*******************************************************************************/
1019static void nfa_hci_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
1020 tNFC_CONN* p_data) {
1021 uint8_t* p;
1022 NFC_HDR* p_pkt = (NFC_HDR*)p_data->data.p_data;
1023 uint8_t chaining_bit;
1024 uint8_t pipe;
1025 uint16_t pkt_len;
1026 char buff[100];
1027 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1028 "%s State: %u Cmd: %u", __func__, nfa_hci_cb.hci_state, event);
1029#if(NXP_EXTNS == TRUE)
1030 tNFA_HCI_DYN_GATE *p_gate;
1031 tNFA_HCI_PIPE_CMDRSP_INFO *p_pipe_cmdrsp_info = NULL;
1032#endif
1033
1034 if (event == NFC_CONN_CREATE_CEVT) {
1035 nfa_hci_cb.conn_id = conn_id;
1036 nfa_hci_cb.buff_size = p_data->conn_create.buff_size;
1037
1038 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) {
1039#if(NXP_EXTNS == TRUE)
1040 nfa_hciu_alloc_gate(NFA_HCI_CONNECTIVITY_GATE, NFA_HCI_APP_HANDLE_NONE);
1041 nfa_hciu_alloc_gate (NFA_HCI_GEN_PURPOSE_APDU_APP_GATE, NFA_HCI_APP_HANDLE_NONE);
1042 nfa_hciu_alloc_gate (NFA_HCI_ID_MNGMNT_APP_GATE, NFA_HCI_APP_HANDLE_NONE);
1043 nfa_hciu_alloc_gate (NFA_HCI_APDU_APP_GATE, NFA_HCI_APP_HANDLE_NONE);
1044 p_gate = nfa_hciu_alloc_gate (NFA_HCI_APDU_GATE, NFA_HCI_APP_HANDLE_NONE);
1045
1046 /* Set flag waiting for EVT_ATR on APDU Pipes connected to different UICC host */
1047 //nfa_hciu_set_server_apdu_host_not_ready (p_gate);
1048#else
1049 nfa_hci_cb.w4_hci_netwk_init = true;
1050 nfa_hciu_alloc_gate(NFA_HCI_CONNECTIVITY_GATE, 0);
1051#endif
1052 }
1053
1054 if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_CLOSED) {
1055 /* First step in initialization/restore is to open the admin pipe */
1056 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1057 } else {
1058 /* Read session id, to know DH session id is correct */
1059 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1060 NFA_HCI_SESSION_IDENTITY_INDEX);
1061 }
1062 } else if (event == NFC_CONN_CLOSE_CEVT) {
1063 nfa_hci_cb.conn_id = 0;
1064 nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
1065 /* deregister message handler on NFA SYS */
1066 nfa_sys_deregister(NFA_ID_HCI);
1067 }
1068
1069 if ((event != NFC_DATA_CEVT) || (p_pkt == NULL)) return;
1070
1071 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
1072 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
1073 /* Received HCP Packet before timeout, Other Host initialization is not
1074 * complete */
1075 nfa_sys_stop_timer(&nfa_hci_cb.timer);
1076 if (nfa_hci_cb.w4_hci_netwk_init)
1077 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1078 p_nfa_hci_cfg->hci_netwk_enable_timeout);
1079 }
1080
1081 p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1082 pkt_len = p_pkt->len;
1083
1084 DispHcp(p, pkt_len, true);
1085
1086 chaining_bit = ((*p) >> 0x07) & 0x01;
1087 pipe = (*p++) & 0x7F;
1088 if (pkt_len != 0) pkt_len--;
1089#if(NXP_EXTNS == TRUE)
hariprasad nalacheruvua9ba2f52018-06-11 17:21:01 +05301090
nxf24591c1cbeab2018-02-21 17:32:26 +05301091 p_pipe_cmdrsp_info = nfa_hciu_get_pipe_cmdrsp_info (pipe);
1092 if (!p_pipe_cmdrsp_info)
1093 {
1094 /* Cannot find the pipe in the control block */
1095 GKI_freebuf (p_pkt);
1096 return;
1097 }
1098 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("nfa_hci_conn_cback () nfa_hci_cb 1");
1099 if (p_pipe_cmdrsp_info->reassembling == false) {
1100#else
1101 if (nfa_hci_cb.assembling == false) {
1102#endif
1103 /* First Segment of a packet */
1104 nfa_hci_cb.type = ((*p) >> 0x06) & 0x03;
1105 nfa_hci_cb.inst = (*p++ & 0x3F);
1106 if (pkt_len != 0) pkt_len--;
1107#if(NXP_EXTNS == TRUE)
1108 nfa_hci_cb.msg_len = 0;
1109
1110 p_pipe_cmdrsp_info->recv_inst_type = nfa_hci_cb.type;
1111 p_pipe_cmdrsp_info->recv_inst = nfa_hci_cb.inst;
1112 p_pipe_cmdrsp_info->reassembly_failed = false;
1113#else
1114 nfa_hci_cb.assembly_failed = false;
1115 nfa_hci_cb.msg_len = 0;
1116#endif
1117#if(NXP_EXTNS == TRUE)
1118 if (chaining_bit == NFA_HCI_MESSAGE_FRAGMENTATION) {
1119 /* Fragmented HCP */
1120 p_pipe_cmdrsp_info->reassembling = true;
1121 nfa_hci_set_receive_buf (p_pipe_cmdrsp_info);
1122 if (!nfa_hci_assemble_msg (p, pkt_len))
1123 p_pipe_cmdrsp_info->reassembly_failed = true;
1124 } else {
1125 /* Non Fragmented HCP */
1126 if ( (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
1127 &&(p_pipe_cmdrsp_info->w4_rsp_apdu_evt) )
1128 {
1129 /* Response APDU: Use buffer provided
1130 ** by layer above for collecting response APDU
1131 */
1132 nfa_hci_set_receive_buf (p_pipe_cmdrsp_info);
1133 if (!nfa_hci_assemble_msg (p, pkt_len))
1134 p_pipe_cmdrsp_info->reassembly_failed = true;
1135 p = nfa_hci_cb.p_msg_data;
1136 nfa_sys_stop_timer (&(p_pipe_cmdrsp_info->rsp_timer));
1137 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
1138 }
1139 }
1140#else
1141 if (chaining_bit == NFA_HCI_MESSAGE_FRAGMENTATION) {
1142 nfa_hci_cb.assembling = true;
1143 nfa_hci_set_receive_buf(pipe);
1144 nfa_hci_assemble_msg(p, pkt_len);
1145 } else {
1146 if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
1147 (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)) {
1148 nfa_hci_set_receive_buf(pipe);
1149 nfa_hci_assemble_msg(p, pkt_len);
1150 p = nfa_hci_cb.p_msg_data;
1151 }
1152 }
1153#endif
1154 } else {
1155#if(NXP_EXTNS == TRUE)
1156 nfa_hci_cb.type = p_pipe_cmdrsp_info->recv_inst_type;
1157 nfa_hci_cb.inst = p_pipe_cmdrsp_info->recv_inst;
1158 nfa_hci_cb.msg_len = p_pipe_cmdrsp_info->msg_rx_len;
1159 nfa_hci_cb.max_msg_len = p_pipe_cmdrsp_info->max_msg_rx_len;
1160 if (p_pipe_cmdrsp_info->reassembly_failed) {
1161#else
1162 if (nfa_hci_cb.assembly_failed) {
1163#endif
1164 /* If Reassembly failed because of insufficient buffer, just drop the new
1165 * segmented packets */
1166 LOG(ERROR) << StringPrintf(
1167 "Insufficient buffer to Reassemble HCP "
1168 "packet! Dropping :%u bytes",
1169 pkt_len);
1170 } else {
1171 /* Reassemble the packet */
1172#if(NXP_EXTNS == TRUE)
1173 if (!nfa_hci_assemble_msg (p, pkt_len))
1174 p_pipe_cmdrsp_info->reassembly_failed = TRUE;
1175#else
1176 nfa_hci_assemble_msg(p, pkt_len);
1177#endif
1178 }
1179
1180 if (chaining_bit == NFA_HCI_NO_MESSAGE_FRAGMENTATION) {
1181 /* Just added the last segment in the chain. Reset pointers */
1182#if(NXP_EXTNS == TRUE)
1183 p_pipe_cmdrsp_info->reassembling = false;
1184#else
1185 nfa_hci_cb.assembling = false;
1186#endif
1187 p = nfa_hci_cb.p_msg_data;
1188 pkt_len = nfa_hci_cb.msg_len;
1189 }
1190 }
1191
1192 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1193 "nfa_hci_conn_cback Recvd data pipe:%d %s chain:%d assmbl:%d len:%d",
1194 (uint8_t)pipe,
1195 nfa_hciu_get_type_inst_names(pipe, nfa_hci_cb.type, nfa_hci_cb.inst,
1196 buff),
1197 (uint8_t)chaining_bit, (uint8_t)nfa_hci_cb.assembling, p_pkt->len);
1198
1199 /* If still reassembling fragments, just return */
1200#if(NXP_EXTNS == TRUE)
1201 if (!p || p_pipe_cmdrsp_info->reassembling) {
1202 /* Either no buffer to hold incoming hcp or the current hcp packet
1203 ** is not the last fragment and will continue to reassemble
1204 */
1205 p_pipe_cmdrsp_info->msg_rx_len = nfa_hci_cb.msg_len;
Suraj Uday Kotharkar32f4f342018-07-18 19:50:25 +05301206 /* if not last packet, release GKI buffer */
1207 nfa_sys_start_timer (&(p_pipe_cmdrsp_info->rsp_timer),
1208 NFA_HCI_RSP_TIMEOUT_EVT, p_pipe_cmdrsp_info->rsp_timeout);
nxf24591c1cbeab2018-02-21 17:32:26 +05301209#else
1210 if (nfa_hci_cb.assembling) {
1211#endif
nxf24591c1cbeab2018-02-21 17:32:26 +05301212 GKI_freebuf(p_pkt);
1213 return;
1214 }
1215#if(NXP_EXTNS == TRUE)
1216 if ((nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
1217 &&(p_pipe_cmdrsp_info->w4_rsp_apdu_evt)) {
1218 /* Response APDU: stop the timers */
1219 nfa_sys_stop_timer (&(p_pipe_cmdrsp_info->rsp_timer));
hariprasad nalacheruvua9ba2f52018-06-11 17:21:01 +05301220 /*Clear chaining resp pending once full resp is received*/
1221 p_pipe_cmdrsp_info->msg_rx_len = 0;
nxf24591c1cbeab2018-02-21 17:32:26 +05301222 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
1223 }
1224#endif
1225 /* If we got a response, cancel the response timer. Also, if waiting for */
1226 /* a single response, we can go back to idle state */
1227#if(NXP_EXTNS != TRUE)
1228 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) &&
1229 ((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) ||
1230 (nfa_hci_cb.w4_rsp_evt && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)))) {
1231#else
1232 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) &&
1233 ((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE))) {
1234#endif
1235 nfa_sys_stop_timer(&nfa_hci_cb.timer);
1236 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
1237 }
1238#if(NXP_EXTNS == TRUE)
1239 else if((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE && p_pipe_cmdrsp_info->w4_cmd_rsp)
1240 || (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE && p_pipe_cmdrsp_info->w4_atr_evt)) {
1241 /* Response received to command sent on generic gate pipe */
1242 nfa_sys_stop_timer (&(p_pipe_cmdrsp_info->rsp_timer));
1243 }
1244 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1245 "nfa_hci_conn_cback Recvd data pipe:%d Type: %u Inst: %u chain:%d ",
1246 pipe, nfa_hci_cb.type, nfa_hci_cb.inst, chaining_bit);
1247#endif
1248 switch (pipe) {
1249 case NFA_HCI_ADMIN_PIPE:
1250 /* Check if data packet is a command, response or event */
1251 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
1252 nfa_hci_handle_admin_gate_cmd(p);
1253 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
1254 nfa_hci_handle_admin_gate_rsp(p, (uint8_t)pkt_len);
1255 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
1256 nfa_hci_handle_admin_gate_evt();
1257 }
1258 break;
1259
1260 case NFA_HCI_LINK_MANAGEMENT_PIPE:
1261 /* We don't send Link Management commands, we only get them */
1262 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1263 nfa_hci_handle_link_mgm_gate_cmd(p);
1264 break;
1265
1266 default:
1267 if (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE)
1268 nfa_hci_handle_dyn_pipe_pkt(pipe, p, pkt_len);
1269 break;
1270 }
1271#if(NXP_EXTNS != TRUE)
1272 if ((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) ||
1273 (nfa_hci_cb.w4_rsp_evt && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE))) {
1274 nfa_hci_cb.w4_rsp_evt = false;
1275 }
1276#endif
1277 /* Send a message to ouselves to check for anything to do */
1278 p_pkt->event = NFA_HCI_CHECK_QUEUE_EVT;
1279 p_pkt->len = 0;
1280 nfa_sys_sendmsg(p_pkt);
1281}
1282
1283/*******************************************************************************
1284**
1285** Function nfa_hci_handle_nv_read
1286**
1287** Description handler function for nv read complete event
1288**
1289** Returns None
1290**
1291*******************************************************************************/
1292void nfa_hci_handle_nv_read(uint8_t block, tNFA_STATUS status) {
1293 uint8_t session_id[NFA_HCI_SESSION_ID_LEN];
1294 uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
1295 0xFF, 0xFF, 0xFF, 0xFF};
1296 uint8_t reset_session[NFA_HCI_SESSION_ID_LEN] = {0x00, 0x00, 0x00, 0x00,
1297 0x00, 0x00, 0x00, 0x00};
1298 uint32_t os_tick;
1299
1300 if (block == DH_NV_BLOCK) {
1301 /* Stop timer as NVDATA Read Completed */
1302 nfa_sys_stop_timer(&nfa_hci_cb.timer);
1303 nfa_hci_cb.nv_read_cmplt = true;
1304 if ((status != NFA_STATUS_OK) || (!nfa_hci_is_valid_cfg()) ||
1305 (!(memcmp(nfa_hci_cb.cfg.admin_gate.session_id, default_session,
1306 NFA_HCI_SESSION_ID_LEN))) ||
1307 (!(memcmp(nfa_hci_cb.cfg.admin_gate.session_id, reset_session,
1308 NFA_HCI_SESSION_ID_LEN)))) {
1309 nfa_hci_cb.b_hci_netwk_reset = true;
1310 /* Set a new session id so that we clear all pipes later after seeing a
1311 * difference with the HC Session ID */
1312 memcpy(&session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
1313 nfa_hci_cb.cfg.admin_gate.session_id,
1314 (NFA_HCI_SESSION_ID_LEN / 2));
1315 os_tick = GKI_get_os_tick_count();
1316 memcpy(session_id, (uint8_t*)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
1317 nfa_hci_restore_default_config(session_id);
1318 }
1319 nfa_hci_startup();
1320 }
1321}
1322
1323/*******************************************************************************
1324**
1325** Function nfa_hci_rsp_timeout
1326**
1327** Description action function to process timeout
1328**
1329** Returns None
1330**
1331*******************************************************************************/
1332void nfa_hci_rsp_timeout() {
1333 tNFA_HCI_EVT evt = 0;
1334 tNFA_HCI_EVT_DATA evt_data;
1335 uint8_t delete_pipe;
nxf24591193ee782018-06-06 14:26:10 +05301336#if(NXP_EXTNS == TRUE)
1337 uint8_t ee_entry_index = 0;
1338#endif
nxf24591c1cbeab2018-02-21 17:32:26 +05301339 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1340 "State: %u Cmd: %u", nfa_hci_cb.hci_state, nfa_hci_cb.cmd_sent);
1341
1342 evt_data.status = NFA_STATUS_FAILED;
1343
1344 switch (nfa_hci_cb.hci_state) {
1345 case NFA_HCI_STATE_STARTUP:
1346 case NFA_HCI_STATE_RESTORE:
1347 LOG(ERROR) << StringPrintf(
1348 "nfa_hci_rsp_timeout - Initialization failed!");
1349 nfa_hci_startup_complete(NFA_STATUS_TIMEOUT);
1350 break;
1351
1352 case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
1353 case NFA_HCI_STATE_RESTORE_NETWK_ENABLE:
1354
1355 if (nfa_hci_cb.w4_hci_netwk_init) {
1356 /* HCI Network is enabled */
1357 nfa_hci_cb.w4_hci_netwk_init = false;
1358#if(NXP_EXTNS == TRUE)
1359 nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
1360 NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
1361#endif
1362 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1363 NFA_HCI_HOST_LIST_INDEX);
1364 } else {
1365#if(NXP_EXTNS == TRUE)
1366 if (!nfa_hci_enable_one_nfcee ())
1367#endif
1368 nfa_hci_startup_complete(NFA_STATUS_FAILED);
1369 }
1370 break;
1371
1372 case NFA_HCI_STATE_REMOVE_GATE:
1373 /* Something wrong, NVRAM data could be corrupt */
1374 if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) {
1375 nfa_hciu_send_clear_all_pipe_cmd();
1376 } else {
1377 nfa_hciu_remove_all_pipes_from_host(0);
1378 nfa_hci_api_dealloc_gate(NULL);
1379 }
1380 break;
1381
1382 case NFA_HCI_STATE_APP_DEREGISTER:
1383 /* Something wrong, NVRAM data could be corrupt */
1384 if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) {
1385 nfa_hciu_send_clear_all_pipe_cmd();
1386 } else {
1387 nfa_hciu_remove_all_pipes_from_host(0);
1388 nfa_hci_api_deregister(NULL);
1389 }
1390 break;
1391
1392 case NFA_HCI_STATE_WAIT_RSP:
1393 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
nxf24591193ee782018-06-06 14:26:10 +05301394#if(NXP_EXTNS == TRUE)
1395 while (ee_entry_index < nfa_ee_max_ee_cfg) {
1396 nfa_hci_release_transceive(nfa_ee_cb.ecb[ee_entry_index].nfcee_id);
1397 ee_entry_index++;
1398 }
1399#endif
nxf24591c1cbeab2018-02-21 17:32:26 +05301400 if (nfa_hci_cb.w4_rsp_evt) {
1401 nfa_hci_cb.w4_rsp_evt = false;
1402 evt = NFA_HCI_EVENT_RCVD_EVT;
1403 evt_data.rcvd_evt.pipe = nfa_hci_cb.pipe_in_use;
1404 evt_data.rcvd_evt.evt_code = 0;
1405 evt_data.rcvd_evt.evt_len = 0;
1406 evt_data.rcvd_evt.p_evt_buf = NULL;
1407 nfa_hci_cb.rsp_buf_size = 0;
1408 nfa_hci_cb.p_rsp_buf = NULL;
1409#if(NXP_EXTNS != TRUE)
1410 break;
1411 }
1412#endif
1413 delete_pipe = 0;
1414 switch (nfa_hci_cb.cmd_sent) {
1415 case NFA_HCI_ANY_SET_PARAMETER:
1416 /*
1417 * As no response to the command sent on this pipe, we may assume the
1418 * pipe is
1419 * deleted already and release the pipe. But still send delete pipe
1420 * command to be safe.
1421 */
1422 delete_pipe = nfa_hci_cb.pipe_in_use;
1423 evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
1424 evt_data.registry.data_len = 0;
1425 evt_data.registry.index = nfa_hci_cb.param_in_use;
1426 evt = NFA_HCI_SET_REG_RSP_EVT;
1427 break;
1428
1429 case NFA_HCI_ANY_GET_PARAMETER:
1430 /*
1431 * As no response to the command sent on this pipe, we may assume the
1432 * pipe is
1433 * deleted already and release the pipe. But still send delete pipe
1434 * command to be safe.
1435 */
1436 delete_pipe = nfa_hci_cb.pipe_in_use;
1437 evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
1438 evt_data.registry.data_len = 0;
1439 evt_data.registry.index = nfa_hci_cb.param_in_use;
1440 evt = NFA_HCI_GET_REG_RSP_EVT;
1441 break;
1442
1443 case NFA_HCI_ANY_OPEN_PIPE:
1444 /*
1445 * As no response to the command sent on this pipe, we may assume the
1446 * pipe is
1447 * deleted already and release the pipe. But still send delete pipe
1448 * command to be safe.
1449 */
1450 delete_pipe = nfa_hci_cb.pipe_in_use;
1451 evt_data.opened.pipe = nfa_hci_cb.pipe_in_use;
1452 evt = NFA_HCI_OPEN_PIPE_EVT;
1453 break;
1454
1455 case NFA_HCI_ANY_CLOSE_PIPE:
1456 /*
1457 * As no response to the command sent on this pipe, we may assume the
1458 * pipe is
1459 * deleted already and release the pipe. But still send delete pipe
1460 * command to be safe.
1461 */
1462 delete_pipe = nfa_hci_cb.pipe_in_use;
1463 evt_data.closed.pipe = nfa_hci_cb.pipe_in_use;
1464 evt = NFA_HCI_CLOSE_PIPE_EVT;
1465 break;
1466
1467 case NFA_HCI_ADM_CREATE_PIPE:
1468 evt_data.created.pipe = nfa_hci_cb.pipe_in_use;
1469 evt_data.created.source_gate = nfa_hci_cb.local_gate_in_use;
1470 evt_data.created.dest_host = nfa_hci_cb.remote_host_in_use;
1471 evt_data.created.dest_gate = nfa_hci_cb.remote_gate_in_use;
1472 evt = NFA_HCI_CREATE_PIPE_EVT;
1473 break;
1474
1475 case NFA_HCI_ADM_DELETE_PIPE:
1476 /*
1477 * As no response to the command sent on this pipe, we may assume the
1478 * pipe is
1479 * deleted already. Just release the pipe.
1480 */
1481 if (nfa_hci_cb.pipe_in_use <= NFA_HCI_LAST_DYNAMIC_PIPE)
1482 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1483 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1484 evt = NFA_HCI_DELETE_PIPE_EVT;
1485 break;
1486
1487 default:
1488 /*
1489 * As no response to the command sent on this pipe, we may assume the
1490 * pipe is
1491 * deleted already and release the pipe. But still send delete pipe
1492 * command to be safe.
1493 */
1494#if(NXP_EXTNS != TRUE)
1495 /*dont delete the pipe incase of no response*/
1496 delete_pipe = nfa_hci_cb.pipe_in_use;
1497#endif
1498 break;
1499 }
1500#if(NXP_EXTNS == TRUE)
1501 if(nfa_hci_cb.evt_sent.evt_type == NFA_HCI_EVT_ABORT) {
1502 evt = NFA_HCI_APDU_ABORTED_EVT;
1503 evt_data.apdu_aborted.status = NFA_STATUS_TIMEOUT;
1504 evt_data.apdu_aborted.atr_len = 0;
1505 evt_data.apdu_aborted.host_id = nfa_hci_cb.remote_host_in_use;
1506 }
1507#endif
1508 if (delete_pipe && (delete_pipe <= NFA_HCI_LAST_DYNAMIC_PIPE)) {
1509 nfa_hciu_send_delete_pipe_cmd(delete_pipe);
1510 nfa_hciu_release_pipe(delete_pipe);
1511#if(NXP_EXTNS == TRUE)
1512 }
1513#endif
1514 }
1515 break;
1516 case NFA_HCI_STATE_DISABLED:
1517 default:
1518 DLOG_IF(INFO, nfc_debug_enabled)
1519 << StringPrintf("Timeout in DISABLED/ Invalid state");
1520 break;
1521 }
1522 if (evt != 0) nfa_hciu_send_to_app(evt, &evt_data, nfa_hci_cb.app_in_use);
1523}
1524
1525/*******************************************************************************
1526**
1527** Function nfa_hci_set_receive_buf
1528**
1529** Description Set reassembly buffer for incoming message
1530**
1531** Returns status
1532**
1533*******************************************************************************/
1534#if(NXP_EXTNS == TRUE)
1535static void nfa_hci_set_receive_buf(tNFA_HCI_PIPE_CMDRSP_INFO *p_pipe_cmdrsp_info) {
1536#else
1537static void nfa_hci_set_receive_buf(uint8_t pipe) {
1538#endif
1539#if(NXP_EXTNS == TRUE)
1540 if ( (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
1541 &&(p_pipe_cmdrsp_info->w4_rsp_apdu_evt) )
1542 {
1543 /* Response APDU */
1544 if ( (p_pipe_cmdrsp_info->rsp_buf_size)
1545 &&(p_pipe_cmdrsp_info->p_rsp_buf != NULL) )
1546 {
1547 /* Buffer provided by layer above for Response APDU */
1548 nfa_hci_cb.p_msg_data = p_pipe_cmdrsp_info->p_rsp_buf;
1549 nfa_hci_cb.max_msg_len = p_pipe_cmdrsp_info->rsp_buf_size;
1550 p_pipe_cmdrsp_info->max_msg_rx_len = nfa_hci_cb.max_msg_len;
1551 }
1552 else
1553 {
1554 nfa_hci_cb.p_msg_data = NULL;
1555 nfa_hci_cb.max_msg_len = 0;
1556 p_pipe_cmdrsp_info->max_msg_rx_len = 0;
1557 }
1558 }
1559 else
1560 {
1561 nfa_hci_cb.p_msg_data = nfa_hci_cb.msg_data;
1562 nfa_hci_cb.max_msg_len = NFA_MAX_HCI_EVENT_LEN;
1563 p_pipe_cmdrsp_info->max_msg_rx_len = nfa_hci_cb.max_msg_len;
1564 }
1565#else
1566 if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
1567 (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)) {
1568 if ((nfa_hci_cb.rsp_buf_size) && (nfa_hci_cb.p_rsp_buf != NULL)) {
1569 nfa_hci_cb.p_msg_data = nfa_hci_cb.p_rsp_buf;
1570 nfa_hci_cb.max_msg_len = nfa_hci_cb.rsp_buf_size;
1571 return;
1572 }
1573 }
1574 nfa_hci_cb.p_msg_data = nfa_hci_cb.msg_data;
1575 nfa_hci_cb.max_msg_len = NFA_MAX_HCI_EVENT_LEN;
1576#endif
1577}
1578
1579/*******************************************************************************
1580 **
1581 ** Function nfa_hci_assemble_msg
1582 **
1583 ** Description Reassemble the incoming message
1584 **
1585 ** Returns None
1586 **
1587 *******************************************************************************/
1588#if(NXP_EXTNS == TRUE)
1589static bool nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len) {
1590 if (nfa_hci_cb.p_msg_data == NULL)
1591 {
1592 LOG(ERROR) << StringPrintf ("nfa_hci_assemble_msg (): No buffer! Dropping :%u bytes",
1593 data_len);
1594 return false;
1595 }
1596 if ((nfa_hci_cb.msg_len + data_len) > nfa_hci_cb.max_msg_len) {
1597 /* Fill the buffer as much it can hold */
1598 memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data,
1599 (nfa_hci_cb.max_msg_len - nfa_hci_cb.msg_len));
1600 nfa_hci_cb.msg_len = nfa_hci_cb.max_msg_len;
1601 LOG(ERROR) << StringPrintf(
1602 "nfa_hci_assemble_msg (): Insufficient buffer to Reassemble HCP "
1603 "packet! Dropping :%u bytes",
1604 ((nfa_hci_cb.msg_len + data_len) - nfa_hci_cb.max_msg_len));
1605 /* Not enaough buffer to reassemble the incoming hcp */
1606 return false;
1607 }
1608 memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, data_len);
1609 nfa_hci_cb.msg_len += data_len;
1610 return true;
1611}
1612#else
1613static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len) {
1614 if ((nfa_hci_cb.msg_len + data_len) > nfa_hci_cb.max_msg_len) {
1615 /* Fill the buffer as much it can hold */
1616 memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data,
1617 (nfa_hci_cb.max_msg_len - nfa_hci_cb.msg_len));
1618 nfa_hci_cb.msg_len = nfa_hci_cb.max_msg_len;
1619 /* Set Reassembly failed */
1620 nfa_hci_cb.assembly_failed = true;
1621 LOG(ERROR) << StringPrintf(
1622 "Insufficient buffer to Reassemble HCP "
1623 "packet! Dropping :%u bytes",
1624 ((nfa_hci_cb.msg_len + data_len) - nfa_hci_cb.max_msg_len));
1625 } else {
1626 memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, data_len);
1627 nfa_hci_cb.msg_len += data_len;
1628 }
1629}
1630#endif
1631
1632/*******************************************************************************
1633**
1634** Function nfa_hci_evt_hdlr
1635**
1636** Description Processing all event for NFA HCI
1637**
1638** Returns TRUE if p_msg needs to be deallocated
1639**
1640*******************************************************************************/
1641static bool nfa_hci_evt_hdlr(NFC_HDR* p_msg) {
1642 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1643 "nfa_hci_evt_hdlr state: %s (%d) event: %s (0x%04x)",
1644 nfa_hciu_get_state_name(nfa_hci_cb.hci_state).c_str(),
1645 nfa_hci_cb.hci_state, nfa_hciu_get_event_name(p_msg->event).c_str(),
1646 p_msg->event);
1647
1648 /* If this is an API request, queue it up */
1649 if ((p_msg->event >= NFA_HCI_FIRST_API_EVENT) &&
1650 (p_msg->event <= NFA_HCI_LAST_API_EVENT)) {
1651 GKI_enqueue(&nfa_hci_cb.hci_api_q, p_msg);
1652 } else {
1653 tNFA_HCI_EVENT_DATA* p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
1654 switch (p_msg->event) {
1655 case NFA_HCI_RSP_NV_READ_EVT:
1656 nfa_hci_handle_nv_read(p_evt_data->nv_read.block,
1657 p_evt_data->nv_read.status);
1658 break;
1659
1660 case NFA_HCI_RSP_NV_WRITE_EVT:
1661 /* NV Ram write completed - nothing to do... */
1662 break;
1663
1664 case NFA_HCI_RSP_TIMEOUT_EVT:
1665 nfa_hci_rsp_timeout();
1666 break;
1667
1668 case NFA_HCI_CHECK_QUEUE_EVT:
1669 if (HCI_LOOPBACK_DEBUG == NFA_HCI_DEBUG_ON) {
1670 if (p_msg->len != 0) {
1671 tNFC_CONN nfc_conn;
1672 nfc_conn.data.p_data = p_msg;
1673 nfa_hci_conn_cback(0, NFC_DATA_CEVT, &nfc_conn);
1674 return false;
1675 }
1676 }
1677 break;
1678 }
1679 }
1680
1681 if ((p_msg->event > NFA_HCI_LAST_API_EVENT)) GKI_freebuf(p_msg);
1682
1683 nfa_hci_check_api_requests();
1684
1685 if (nfa_hciu_is_no_host_resetting()) nfa_hci_check_pending_api_requests();
1686
1687 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) &&
1688 (nfa_hci_cb.nv_write_needed)) {
1689 nfa_hci_cb.nv_write_needed = false;
1690 nfa_nv_co_write((uint8_t*)&nfa_hci_cb.cfg, sizeof(nfa_hci_cb.cfg),
1691 DH_NV_BLOCK);
1692 }
1693 return false;
1694}
1695
1696#if(NXP_EXTNS == TRUE)
1697void nfa_hci_release_transceive(uint8_t host_id) {
1698 DLOG_IF(INFO, nfc_debug_enabled)
1699 << StringPrintf("nfa_hci_release_transcieve ()");
1700 tNFA_HCI_DYN_PIPE *p_pipe;
1701 tNFA_HCI_PIPE_CMDRSP_INFO *p_pipe_cmdrsp_info = NULL;
1702 tNFA_HCI_EVT_DATA evt_data;
1703 uint8_t cmd_inst;
1704 uint8_t cmd_inst_param;
1705 tNFA_HCI_DYN_GATE *p_gate;
1706
1707 p_pipe = nfa_hciu_find_dyn_apdu_pipe_for_host (host_id);
nxf24591193ee782018-06-06 14:26:10 +05301708 if ((p_pipe == NULL) || (p_pipe->pipe_id != NFA_HCI_INVALID_PIPE))
nxf24591c1cbeab2018-02-21 17:32:26 +05301709 {
1710 p_pipe_cmdrsp_info = nfa_hciu_get_pipe_cmdrsp_info (p_pipe->pipe_id);
1711 }
nxf24591193ee782018-06-06 14:26:10 +05301712 else
1713 {
1714 DLOG_IF(INFO, nfc_debug_enabled)
1715 << StringPrintf("nfa_hci_release_transcieve ():pipe is not valid or NULL ");
1716 }
nxf24591c1cbeab2018-02-21 17:32:26 +05301717 if(p_pipe_cmdrsp_info == NULL) return;
1718
1719 if (p_pipe_cmdrsp_info->w4_cmd_rsp)
1720 {
1721 /* Timeout to command response on host specific generic pipe */
1722 p_pipe_cmdrsp_info->w4_cmd_rsp = false;
1723
1724 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
1725
1726 if (p_gate == NULL)
1727 {
1728 LOG(ERROR) << StringPrintf ("nfa_hci_release_transceive ():Invalid Gate[0x%02x] for pipe[0x%02x] ",
1729 p_pipe->local_gate, p_pipe->pipe_id);
1730 return;
1731 }
1732
1733 cmd_inst = p_pipe_cmdrsp_info->cmd_inst_sent;
1734 cmd_inst_param = p_pipe_cmdrsp_info->cmd_inst_param_sent;
1735
1736 if (cmd_inst == NFA_HCI_ANY_OPEN_PIPE)
1737 {
1738 /* Tell application */
1739 evt_data.opened.status = NFA_STATUS_TIMEOUT;
1740 evt_data.opened.pipe = p_pipe->pipe_id;
1741
1742 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_gate->gate_owner);
1743 }
1744 else if (cmd_inst == NFA_HCI_ANY_CLOSE_PIPE)
1745 {
1746 /* Tell application */
1747 evt_data.closed.status = NFA_STATUS_TIMEOUT;
1748 evt_data.closed.pipe = p_pipe->pipe_id;
1749
1750 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_gate->gate_owner);
1751 }
1752 else if (cmd_inst == NFA_HCI_ANY_GET_PARAMETER)
1753 {
1754 /* Tell application */
1755 evt_data.registry.status = NFA_STATUS_TIMEOUT;
1756 evt_data.registry.pipe = p_pipe->pipe_id;
1757 evt_data.registry.index = cmd_inst_param;
1758
1759 nfa_hciu_send_to_app (NFA_HCI_GET_REG_RSP_EVT, &evt_data, p_gate->gate_owner);
1760 }
1761 else if (cmd_inst == NFA_HCI_ANY_SET_PARAMETER)
1762 {
1763 /* Tell application */
1764 evt_data.registry.status = NFA_STATUS_TIMEOUT;
1765 evt_data.registry.pipe = p_pipe->pipe_id;
1766 evt_data.registry.index = cmd_inst_param;
1767
1768 nfa_hciu_send_to_app (NFA_HCI_SET_REG_RSP_EVT, &evt_data, p_gate->gate_owner);
1769 }
1770 else
1771 {
1772 /* Could be a response to application specific command sent, pass it on */
1773 evt_data.rsp_rcvd.status = NFA_STATUS_TIMEOUT;
1774 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
1775
1776 nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, p_gate->gate_owner);
1777 }
1778 }
1779 else
1780 {
1781 /* Timeout in APDU Pipe */
1782 DLOG_IF(INFO, nfc_debug_enabled)
1783 << StringPrintf ("nfa_hci_timer_cback () Timeout on APDU Pipe");
1784
1785 p_pipe_cmdrsp_info->p_rsp_buf = NULL;
1786 p_pipe_cmdrsp_info->rsp_buf_size = 0;
1787
1788 if (p_pipe_cmdrsp_info->w4_atr_evt)
1789 {
1790 /* Timeout to ETSI_HCI_EVT_ATR after ETSI_HCI_EVT_ABORT is sent on the APDU pipe
1791 ** and so cannot send next command APDU on the pipe till APDU server initialize
1792 ** and sends ETSI_HCI_EVT_ATR on the pipe
1793 */
1794 p_pipe_cmdrsp_info->w4_rsp_apdu_evt = false;
1795
1796 evt_data.apdu_aborted.status = NFA_STATUS_TIMEOUT;
1797 evt_data.apdu_aborted.host_id = p_pipe->dest_host;
1798
1799 /* Send NFA_HCI_APDU_ABORTED_EVT to notify status */
1800 nfa_hciu_send_to_app (NFA_HCI_APDU_ABORTED_EVT, &evt_data,
1801 p_pipe_cmdrsp_info->pipe_user);
1802 }
1803 else if (p_pipe_cmdrsp_info->w4_rsp_apdu_evt)
1804 {
1805 /* Timeout to Response APDU (ETSI_HCI_EVT_R_APDU) */
1806 p_pipe_cmdrsp_info->w4_rsp_apdu_evt = false;
1807
1808 evt_data.apdu_rcvd.status = NFA_STATUS_TIMEOUT;
1809 evt_data.apdu_rcvd.p_apdu = NULL;
1810 evt_data.apdu_rcvd.host_id = p_pipe->dest_host;
1811
1812 /* notify NFA_HCI_RSP_APDU_RCVD_EVT to the application */
1813 nfa_hciu_send_to_app (NFA_HCI_RSP_APDU_RCVD_EVT, &evt_data,
1814 p_pipe_cmdrsp_info->pipe_user);
1815
1816 /* Release the temporary ownership for APDU Pipe given to the App */
1817 p_pipe_cmdrsp_info->pipe_user = NFA_HCI_APP_HANDLE_NONE;
1818 }
1819 }
1820 p_pipe_cmdrsp_info->cmd_inst_sent = 0;
1821 p_pipe_cmdrsp_info->cmd_inst_param_sent = 0;
1822}
1823
1824/*******************************************************************************
1825**
1826** Function nfa_hci_timer_cback
1827**
1828** Description Process timeout event when timer expires
1829**
1830** Returns None
1831**
1832*******************************************************************************/
Suraj Uday Kotharkara94976b2018-05-15 16:14:29 +05301833static void nfa_hci_timer_cback (TIMER_LIST_ENT *p_tle)
nxf24591c1cbeab2018-02-21 17:32:26 +05301834{
1835 uint8_t *p_pipe_id;
1836 uint8_t cmd_inst;
1837 uint8_t cmd_inst_param;
1838 TIMER_LIST_ENT *p_timer;
1839 tNFA_HCI_DYN_PIPE *p_pipe;
1840 tNFA_HCI_DYN_GATE *p_gate;
1841 tNFA_HCI_EVT_DATA evt_data;
1842 tNFA_HCI_PIPE_CMDRSP_INFO *p_pipe_cmdrsp_info = NULL;
1843
1844 DLOG_IF(INFO, nfc_debug_enabled)
1845 << StringPrintf ("nfa_hci_timer_cback () Timeout on pipe connected to Generic gate");
1846
1847 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
1848 {
1849 LOG(ERROR) << StringPrintf ("nfa_hci_timer_cback - Initialization failed!");
1850 /* Timeout to Read Registry from APDU gate pipe */
1851 nfa_hci_startup_complete (NFA_STATUS_FAILED);
1852 }
1853 else
1854 {
Suraj Uday Kotharkara94976b2018-05-15 16:14:29 +05301855 p_timer = p_tle;
nxf24591c1cbeab2018-02-21 17:32:26 +05301856 p_pipe_id = (uint8_t *) p_timer->param;
1857
1858 p_pipe = nfa_hciu_find_pipe_by_pid (*p_pipe_id);
1859 p_pipe_cmdrsp_info = nfa_hciu_get_pipe_cmdrsp_info (*p_pipe_id);
1860
1861 memset (&evt_data, 0, sizeof (evt_data));
1862
1863 if (p_pipe_cmdrsp_info->w4_cmd_rsp)
1864 {
1865 /* Timeout to command response on host specific generic pipe */
1866 p_pipe_cmdrsp_info->w4_cmd_rsp = false;
1867
1868 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
1869
1870 if (p_gate == NULL)
1871 {
1872 LOG(ERROR) << StringPrintf("nfa_hci_timer_cback ():Invalid Gate[0x%02x] for pipe[0x%02x] ",
1873 p_pipe->local_gate, p_pipe->pipe_id);
1874 return;
1875 }
1876
1877 cmd_inst = p_pipe_cmdrsp_info->cmd_inst_sent;
1878 cmd_inst_param = p_pipe_cmdrsp_info->cmd_inst_param_sent;
1879
1880 if (cmd_inst == NFA_HCI_ANY_OPEN_PIPE)
1881 {
1882 /* Tell application */
1883 evt_data.opened.status = NFA_STATUS_TIMEOUT;
1884 evt_data.opened.pipe = p_pipe->pipe_id;
1885
1886 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_gate->gate_owner);
1887 }
1888 else if (cmd_inst == NFA_HCI_ANY_CLOSE_PIPE)
1889 {
1890 /* Tell application */
1891 evt_data.closed.status = NFA_STATUS_TIMEOUT;
1892 evt_data.closed.pipe = p_pipe->pipe_id;
1893
1894 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_gate->gate_owner);
1895 }
1896 else if (cmd_inst == NFA_HCI_ANY_GET_PARAMETER)
1897 {
1898 /* Tell application */
1899 evt_data.registry.status = NFA_STATUS_TIMEOUT;
1900 evt_data.registry.pipe = p_pipe->pipe_id;
1901 evt_data.registry.index = cmd_inst_param;
1902
1903 nfa_hciu_send_to_app (NFA_HCI_GET_REG_RSP_EVT, &evt_data, p_gate->gate_owner);
1904 }
1905 else if (cmd_inst == NFA_HCI_ANY_SET_PARAMETER)
1906 {
1907 /* Tell application */
1908 evt_data.registry.status = NFA_STATUS_TIMEOUT;
1909 evt_data.registry.pipe = p_pipe->pipe_id;
1910 evt_data.registry.index = cmd_inst_param;
1911
1912 nfa_hciu_send_to_app (NFA_HCI_SET_REG_RSP_EVT, &evt_data, p_gate->gate_owner);
1913 }
1914 else
1915 {
1916 /* Could be a response to application specific command sent, pass it on */
1917 evt_data.rsp_rcvd.status = NFA_STATUS_TIMEOUT;
1918 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
1919
1920 nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, p_gate->gate_owner);
1921 }
1922 }
1923 else
1924 {
1925 /* Timeout in APDU Pipe */
1926 DLOG_IF(INFO, nfc_debug_enabled)
1927 << StringPrintf ("nfa_hci_timer_cback () Timeout on APDU Pipe");
1928
1929 p_pipe_cmdrsp_info->p_rsp_buf = NULL;
1930 p_pipe_cmdrsp_info->rsp_buf_size = 0;
hariprasad nalacheruvua9ba2f52018-06-11 17:21:01 +05301931 /*In case of chaining Rx timeout clear resp len*/
1932 p_pipe_cmdrsp_info->msg_rx_len = 0;
nxf24591c1cbeab2018-02-21 17:32:26 +05301933 if (p_pipe_cmdrsp_info->w4_atr_evt)
1934 {
1935 /* Timeout to ETSI_HCI_EVT_ATR after ETSI_HCI_EVT_ABORT is sent on the APDU pipe
1936 ** and so cannot send next command APDU on the pipe till APDU server initialize
1937 ** and sends ETSI_HCI_EVT_ATR on the pipe
1938 */
Suraj Uday Kotharkar32f4f342018-07-18 19:50:25 +05301939 p_pipe_cmdrsp_info->w4_atr_evt = false;
nxf24591c1cbeab2018-02-21 17:32:26 +05301940 p_pipe_cmdrsp_info->w4_rsp_apdu_evt = false;
1941
1942 evt_data.apdu_aborted.status = NFA_STATUS_TIMEOUT;
1943 evt_data.apdu_aborted.host_id = p_pipe->dest_host;
1944
1945 /* Send NFA_HCI_APDU_ABORTED_EVT to notify status */
1946 nfa_hciu_send_to_app (NFA_HCI_APDU_ABORTED_EVT, &evt_data,
1947 p_pipe_cmdrsp_info->pipe_user);
1948 }
1949 else if (p_pipe_cmdrsp_info->w4_rsp_apdu_evt)
1950 {
1951 /* Timeout to Response APDU (ETSI_HCI_EVT_R_APDU) */
1952 p_pipe_cmdrsp_info->w4_rsp_apdu_evt = false;
1953
1954 evt_data.apdu_rcvd.status = NFA_STATUS_TIMEOUT;
1955 evt_data.apdu_rcvd.p_apdu = NULL;
1956 evt_data.apdu_rcvd.host_id = p_pipe->dest_host;
Suraj Uday Kotharkar32f4f342018-07-18 19:50:25 +05301957 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
nxf24591c1cbeab2018-02-21 17:32:26 +05301958 /* notify NFA_HCI_RSP_APDU_RCVD_EVT to the application */
1959 nfa_hciu_send_to_app (NFA_HCI_RSP_APDU_RCVD_EVT, &evt_data,
1960 p_pipe_cmdrsp_info->pipe_user);
1961
1962 /* Release the temporary ownership for APDU Pipe given to the App */
1963 p_pipe_cmdrsp_info->pipe_user = NFA_HCI_APP_HANDLE_NONE;
1964 }
1965 }
1966 p_pipe_cmdrsp_info->cmd_inst_sent = 0;
1967 p_pipe_cmdrsp_info->cmd_inst_param_sent = 0;
1968 }
1969}
1970#endif