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 file contains the action functions for the NFA HCI.
22 *
23 ******************************************************************************/
24 #include <string.h>
25 #include "nfa_dm_int.h"
26 #include "nfa_hci_api.h"
27 #include "nfa_hci_defs.h"
28 #include "nfa_hci_int.h"
29 #include "nfa_mem_co.h"
30 #include "nfa_nv_co.h"
31 #include "nfa_sys.h"
32 #include "nfa_sys_int.h"
33 #include "nfc_api.h"
34 #include "trace_api.h"
35
36 /* Static local functions */
37 static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data);
38 static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data);
39 static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data);
40 static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data);
41 static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
42 static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
43 static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
44 static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
45 static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
46 static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
47 static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data);
48 static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data);
49 static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data);
50 static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
51
52 static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
53 tNFA_HCI_DYN_PIPE* p_pipe);
54 static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
55 tNFA_HCI_DYN_PIPE* p_pipe);
56 static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
57 uint16_t data_len,
58 tNFA_HCI_DYN_PIPE* p_pipe);
59 static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
60 tNFA_HCI_DYN_GATE* p_gate,
61 tNFA_HCI_DYN_PIPE* p_pipe);
62 static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
63 tNFA_HCI_DYN_GATE* p_gate,
64 tNFA_HCI_DYN_PIPE* p_pipe);
65 static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
66 tNFA_HCI_DYN_GATE* p_gate,
67 tNFA_HCI_DYN_PIPE* p_pipe);
68
69 /*******************************************************************************
70 **
71 ** Function nfa_hci_check_pending_api_requests
72 **
73 ** Description This function handles pending API requests
74 **
75 ** Returns none
76 **
77 *******************************************************************************/
nfa_hci_check_pending_api_requests(void)78 void nfa_hci_check_pending_api_requests(void) {
79 NFC_HDR* p_msg;
80 tNFA_HCI_EVENT_DATA* p_evt_data;
81 bool b_free;
82
83 /* If busy, or API queue is empty, then exit */
84 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
85 ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_host_reset_api_q)) ==
86 NULL))
87 return;
88
89 /* Process API request */
90 p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
91
92 /* Save the application handle */
93 nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
94
95 b_free = true;
96 switch (p_msg->event) {
97 case NFA_HCI_API_CREATE_PIPE_EVT:
98 if (nfa_hci_api_create_pipe(p_evt_data) == false) b_free = false;
99 break;
100
101 case NFA_HCI_API_GET_REGISTRY_EVT:
102 if (nfa_hci_api_get_reg_value(p_evt_data) == false) b_free = false;
103 break;
104
105 case NFA_HCI_API_SET_REGISTRY_EVT:
106 if (nfa_hci_api_set_reg_value(p_evt_data) == false) b_free = false;
107 break;
108
109 case NFA_HCI_API_SEND_CMD_EVT:
110 if (nfa_hci_api_send_cmd(p_evt_data) == false) b_free = false;
111 break;
112 case NFA_HCI_API_SEND_EVENT_EVT:
113 if (nfa_hci_api_send_event(p_evt_data) == false) b_free = false;
114 break;
115 }
116
117 if (b_free) GKI_freebuf(p_msg);
118 }
119
120 /*******************************************************************************
121 **
122 ** Function nfa_hci_check_api_requests
123 **
124 ** Description This function handles API requests
125 **
126 ** Returns none
127 **
128 *******************************************************************************/
nfa_hci_check_api_requests(void)129 void nfa_hci_check_api_requests(void) {
130 NFC_HDR* p_msg;
131 tNFA_HCI_EVENT_DATA* p_evt_data;
132
133 for (;;) {
134 /* If busy, or API queue is empty, then exit */
135 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
136 ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_api_q)) == NULL))
137 break;
138
139 /* Process API request */
140 p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
141
142 /* Save the application handle */
143 nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
144
145 switch (p_msg->event) {
146 case NFA_HCI_API_REGISTER_APP_EVT:
147 nfa_hci_api_register(p_evt_data);
148 break;
149
150 case NFA_HCI_API_DEREGISTER_APP_EVT:
151 nfa_hci_api_deregister(p_evt_data);
152 break;
153
154 case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
155 nfa_hci_api_get_gate_pipe_list(p_evt_data);
156 break;
157
158 case NFA_HCI_API_ALLOC_GATE_EVT:
159 nfa_hci_api_alloc_gate(p_evt_data);
160 break;
161
162 case NFA_HCI_API_DEALLOC_GATE_EVT:
163 nfa_hci_api_dealloc_gate(p_evt_data);
164 break;
165
166 case NFA_HCI_API_GET_HOST_LIST_EVT:
167 nfa_hci_api_get_host_list(p_evt_data);
168 break;
169
170 case NFA_HCI_API_GET_REGISTRY_EVT:
171 if (nfa_hci_api_get_reg_value(p_evt_data) == false) continue;
172 break;
173
174 case NFA_HCI_API_SET_REGISTRY_EVT:
175 if (nfa_hci_api_set_reg_value(p_evt_data) == false) continue;
176 break;
177
178 case NFA_HCI_API_CREATE_PIPE_EVT:
179 if (nfa_hci_api_create_pipe(p_evt_data) == false) continue;
180 break;
181
182 case NFA_HCI_API_OPEN_PIPE_EVT:
183 nfa_hci_api_open_pipe(p_evt_data);
184 break;
185
186 case NFA_HCI_API_CLOSE_PIPE_EVT:
187 nfa_hci_api_close_pipe(p_evt_data);
188 break;
189
190 case NFA_HCI_API_DELETE_PIPE_EVT:
191 nfa_hci_api_delete_pipe(p_evt_data);
192 break;
193
194 case NFA_HCI_API_SEND_CMD_EVT:
195 if (nfa_hci_api_send_cmd(p_evt_data) == false) continue;
196 break;
197
198 case NFA_HCI_API_SEND_RSP_EVT:
199 nfa_hci_api_send_rsp(p_evt_data);
200 break;
201
202 case NFA_HCI_API_SEND_EVENT_EVT:
203 if (nfa_hci_api_send_event(p_evt_data) == false) continue;
204 break;
205
206 case NFA_HCI_API_ADD_STATIC_PIPE_EVT:
207 nfa_hci_api_add_static_pipe(p_evt_data);
208 break;
209
210 default:
211 NFA_TRACE_ERROR1("nfa_hci_check_api_requests () Unknown event: 0x%04x",
212 p_msg->event);
213 break;
214 }
215
216 GKI_freebuf(p_msg);
217 }
218 }
219
220 /*******************************************************************************
221 **
222 ** Function nfa_hci_api_register
223 **
224 ** Description action function to register the events for the given AID
225 **
226 ** Returns None
227 **
228 *******************************************************************************/
nfa_hci_api_register(tNFA_HCI_EVENT_DATA * p_evt_data)229 static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data) {
230 tNFA_HCI_EVT_DATA evt_data;
231 char* p_app_name = p_evt_data->app_info.app_name;
232 tNFA_HCI_CBACK* p_cback = p_evt_data->app_info.p_cback;
233 int xx, yy;
234 uint8_t num_gates = 0, num_pipes = 0;
235 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
236
237 /* First, see if the application was already registered */
238 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
239 if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
240 !strncmp(p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0],
241 strlen(p_app_name))) {
242 NFA_TRACE_EVENT2("nfa_hci_api_register (%s) Reusing: %u", p_app_name,
243 xx);
244 break;
245 }
246 }
247
248 if (xx != NFA_HCI_MAX_APP_CB) {
249 nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
250 /* The app was registered, find the number of gates and pipes associated to
251 * the app */
252
253 for (yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++) {
254 if (pg->gate_owner == nfa_hci_cb.app_in_use) {
255 num_gates++;
256 num_pipes += nfa_hciu_count_pipes_on_gate(pg);
257 }
258 }
259 } else {
260 /* Not registered, look for a free entry */
261 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
262 if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0) {
263 memset(&nfa_hci_cb.cfg.reg_app_names[xx][0], 0,
264 sizeof(nfa_hci_cb.cfg.reg_app_names[xx]));
265 strncpy(&nfa_hci_cb.cfg.reg_app_names[xx][0], p_app_name,
266 NFA_MAX_HCI_APP_NAME_LEN);
267 nfa_hci_cb.nv_write_needed = true;
268 NFA_TRACE_EVENT2("nfa_hci_api_register (%s) Allocated: %u", p_app_name,
269 xx);
270 break;
271 }
272 }
273
274 if (xx == NFA_HCI_MAX_APP_CB) {
275 NFA_TRACE_ERROR1("nfa_hci_api_register (%s) NO ENTRIES", p_app_name);
276
277 evt_data.hci_register.status = NFA_STATUS_FAILED;
278 p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
279 return;
280 }
281 }
282
283 evt_data.hci_register.num_pipes = num_pipes;
284 evt_data.hci_register.num_gates = num_gates;
285 nfa_hci_cb.p_app_cback[xx] = p_cback;
286
287 nfa_hci_cb.cfg.b_send_conn_evts[xx] = p_evt_data->app_info.b_send_conn_evts;
288
289 evt_data.hci_register.hci_handle = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
290
291 evt_data.hci_register.status = NFA_STATUS_OK;
292
293 /* notify NFA_HCI_REGISTER_EVT to the application */
294 p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
295 }
296
297 /*******************************************************************************
298 **
299 ** Function nfa_hci_api_deregister
300 **
301 ** Description action function to deregister the given application
302 **
303 ** Returns None
304 **
305 *******************************************************************************/
nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA * p_evt_data)306 void nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA* p_evt_data) {
307 tNFA_HCI_EVT_DATA evt_data;
308 tNFA_HCI_CBACK* p_cback = NULL;
309 int xx;
310 tNFA_HCI_DYN_PIPE* p_pipe;
311 tNFA_HCI_DYN_GATE* p_gate;
312
313 /* If needed, find the application registration handle */
314 if (p_evt_data != NULL) {
315 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
316 if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
317 !strncmp(p_evt_data->app_info.app_name,
318 &nfa_hci_cb.cfg.reg_app_names[xx][0],
319 strlen(p_evt_data->app_info.app_name))) {
320 NFA_TRACE_EVENT2("nfa_hci_api_deregister (%s) inx: %u",
321 p_evt_data->app_info.app_name, xx);
322 break;
323 }
324 }
325
326 if (xx == NFA_HCI_MAX_APP_CB) {
327 NFA_TRACE_WARNING1("nfa_hci_api_deregister () Unknown app: %s",
328 p_evt_data->app_info.app_name);
329 return;
330 }
331 nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
332 p_cback = nfa_hci_cb.p_app_cback[xx];
333 } else {
334 nfa_sys_stop_timer(&nfa_hci_cb.timer);
335 /* We are recursing through deleting all the app's pipes and gates */
336 p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK];
337 }
338
339 /* See if any pipe is owned by this app */
340 if (nfa_hciu_find_pipe_by_owner(nfa_hci_cb.app_in_use) == NULL) {
341 /* No pipes, release all gates owned by this app */
342 while ((p_gate = nfa_hciu_find_gate_by_owner(nfa_hci_cb.app_in_use)) !=
343 NULL)
344 nfa_hciu_release_gate(p_gate->gate_id);
345
346 memset(&nfa_hci_cb.cfg
347 .reg_app_names[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK][0],
348 0, NFA_MAX_HCI_APP_NAME_LEN + 1);
349 nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = NULL;
350
351 nfa_hci_cb.nv_write_needed = true;
352
353 evt_data.hci_deregister.status = NFC_STATUS_OK;
354
355 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
356 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
357
358 /* notify NFA_HCI_DEREGISTER_EVT to the application */
359 if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
360 } else if ((p_pipe = nfa_hciu_find_active_pipe_by_owner(
361 nfa_hci_cb.app_in_use)) == NULL) {
362 /* No pipes, release all gates owned by this app */
363 while ((p_gate = nfa_hciu_find_gate_with_nopipes_by_owner(
364 nfa_hci_cb.app_in_use)) != NULL)
365 nfa_hciu_release_gate(p_gate->gate_id);
366
367 nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = NULL;
368
369 nfa_hci_cb.nv_write_needed = true;
370
371 evt_data.hci_deregister.status = NFC_STATUS_FAILED;
372
373 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
374 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
375
376 /* notify NFA_HCI_DEREGISTER_EVT to the application */
377 if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
378 } else {
379 /* Delete all active pipes created for the application before de registering
380 **/
381 nfa_hci_cb.hci_state = NFA_HCI_STATE_APP_DEREGISTER;
382
383 nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
384 }
385 }
386
387 /*******************************************************************************
388 **
389 ** Function nfa_hci_api_get_gate_pipe_list
390 **
391 ** Description action function to get application allocated gates and
392 ** application created pipes
393 **
394 ** Returns None
395 **
396 *******************************************************************************/
nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA * p_evt_data)397 static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
398 tNFA_HCI_EVT_DATA evt_data;
399 int xx, yy;
400 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
401 tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
402
403 evt_data.gates_pipes.num_gates = 0;
404 evt_data.gates_pipes.num_pipes = 0;
405
406 for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
407 if (pg->gate_owner == p_evt_data->get_gate_pipe_list.hci_handle) {
408 evt_data.gates_pipes.gate[evt_data.gates_pipes.num_gates++] = pg->gate_id;
409
410 pp = nfa_hci_cb.cfg.dyn_pipes;
411
412 /* Loop through looking for a match */
413 for (yy = 0; yy < NFA_HCI_MAX_PIPE_CB; yy++, pp++) {
414 if (pp->local_gate == pg->gate_id)
415 evt_data.gates_pipes.pipe[evt_data.gates_pipes.num_pipes++] =
416 *(tNFA_HCI_PIPE_INFO*)pp;
417 }
418 }
419 }
420
421 evt_data.gates_pipes.num_uicc_created_pipes = 0;
422 /* Loop through all pipes that are connected to connectivity gate */
423 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
424 xx++, pp++) {
425 if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
426 memcpy(&evt_data.gates_pipes.uicc_created_pipe
427 [evt_data.gates_pipes.num_uicc_created_pipes++],
428 pp, sizeof(tNFA_HCI_PIPE_INFO));
429 } else if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_LOOP_BACK_GATE) {
430 memcpy(&evt_data.gates_pipes.uicc_created_pipe
431 [evt_data.gates_pipes.num_uicc_created_pipes++],
432 pp, sizeof(tNFA_HCI_PIPE_INFO));
433 } else if (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE &&
434 pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE && pp->pipe_id &&
435 pp->local_gate >= NFA_HCI_FIRST_PROP_GATE &&
436 pp->local_gate <= NFA_HCI_LAST_PROP_GATE) {
437 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
438 xx++, pg++) {
439 if (pp->local_gate == pg->gate_id) {
440 if (!pg->gate_owner)
441 memcpy(&evt_data.gates_pipes.uicc_created_pipe
442 [evt_data.gates_pipes.num_uicc_created_pipes++],
443 pp, sizeof(tNFA_HCI_PIPE_INFO));
444 break;
445 }
446 }
447 }
448 }
449
450 evt_data.gates_pipes.status = NFA_STATUS_OK;
451
452 /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */
453 nfa_hciu_send_to_app(NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data,
454 p_evt_data->get_gate_pipe_list.hci_handle);
455 }
456
457 /*******************************************************************************
458 **
459 ** Function nfa_hci_api_alloc_gate
460 **
461 ** Description action function to allocate gate
462 **
463 ** Returns None
464 **
465 *******************************************************************************/
nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA * p_evt_data)466 static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
467 tNFA_HANDLE app_handle = p_evt_data->comm.hci_handle;
468 tNFA_HCI_EVT_DATA evt_data;
469 tNFA_HCI_DYN_GATE* p_gate;
470
471 p_gate = nfa_hciu_alloc_gate(p_evt_data->gate_info.gate, app_handle);
472
473 if (p_gate) {
474 if (!p_gate->gate_owner) {
475 /* No app owns the gate yet */
476 p_gate->gate_owner = app_handle;
477 } else if (p_gate->gate_owner != app_handle) {
478 /* Some other app owns the gate */
479 p_gate = NULL;
480 NFA_TRACE_ERROR1(
481 "nfa_hci_api_alloc_gate (): The Gate (0X%02x) already taken!",
482 p_evt_data->gate_info.gate);
483 }
484 }
485
486 evt_data.allocated.gate = p_gate ? p_gate->gate_id : 0;
487 evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED;
488
489 /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */
490 nfa_hciu_send_to_app(NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle);
491 }
492
493 /*******************************************************************************
494 **
495 ** Function nfa_hci_api_dealloc_gate
496 **
497 ** Description action function to deallocate the given generic gate
498 **
499 ** Returns None
500 **
501 *******************************************************************************/
nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA * p_evt_data)502 void nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
503 tNFA_HCI_EVT_DATA evt_data;
504 uint8_t gate_id;
505 tNFA_HCI_DYN_GATE* p_gate;
506 tNFA_HCI_DYN_PIPE* p_pipe;
507 tNFA_HANDLE app_handle;
508
509 /* p_evt_data may be NULL if we are recursively deleting pipes */
510 if (p_evt_data) {
511 gate_id = p_evt_data->gate_dealloc.gate;
512 app_handle = p_evt_data->gate_dealloc.hci_handle;
513
514 } else {
515 nfa_sys_stop_timer(&nfa_hci_cb.timer);
516 gate_id = nfa_hci_cb.local_gate_in_use;
517 app_handle = nfa_hci_cb.app_in_use;
518 }
519
520 evt_data.deallocated.gate = gate_id;
521 ;
522
523 p_gate = nfa_hciu_find_gate_by_gid(gate_id);
524
525 if (p_gate == NULL) {
526 evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID;
527 } else if (p_gate->gate_owner != app_handle) {
528 evt_data.deallocated.status = NFA_STATUS_FAILED;
529 } else {
530 /* See if any pipe is owned by this app */
531 if (nfa_hciu_find_pipe_on_gate(p_gate->gate_id) == NULL) {
532 nfa_hciu_release_gate(p_gate->gate_id);
533
534 nfa_hci_cb.nv_write_needed = true;
535 evt_data.deallocated.status = NFA_STATUS_OK;
536
537 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
538 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
539 } else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate(p_gate->gate_id)) ==
540 NULL) {
541 /* UICC is not active at the moment and cannot delete the pipe */
542 nfa_hci_cb.nv_write_needed = true;
543 evt_data.deallocated.status = NFA_STATUS_FAILED;
544
545 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
546 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
547 } else {
548 /* Delete pipes on the gate */
549 nfa_hci_cb.local_gate_in_use = gate_id;
550 nfa_hci_cb.app_in_use = app_handle;
551 nfa_hci_cb.hci_state = NFA_HCI_STATE_REMOVE_GATE;
552
553 nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
554 return;
555 }
556 }
557
558 nfa_hciu_send_to_app(NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle);
559 }
560
561 /*******************************************************************************
562 **
563 ** Function nfa_hci_api_get_host_list
564 **
565 ** Description action function to get the host list from HCI network
566 **
567 ** Returns None
568 **
569 *******************************************************************************/
nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA * p_evt_data)570 static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
571 uint8_t app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
572
573 nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
574
575 /* Send Get Host List command on "Internal request" or requested by registered
576 * application with valid handle and callback function */
577 if ((nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID) ||
578 ((app_inx < NFA_HCI_MAX_APP_CB) &&
579 (nfa_hci_cb.p_app_cback[app_inx] != NULL))) {
580 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
581 }
582 }
583
584 /*******************************************************************************
585 **
586 ** Function nfa_hci_api_create_pipe
587 **
588 ** Description action function to create a pipe
589 **
590 ** Returns TRUE, if the command is processed
591 ** FALSE, if command is queued for processing later
592 **
593 *******************************************************************************/
nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)594 static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
595 tNFA_HCI_DYN_GATE* p_gate =
596 nfa_hciu_find_gate_by_gid(p_evt_data->create_pipe.source_gate);
597 tNFA_HCI_EVT_DATA evt_data;
598 bool report_failed = false;
599
600 /* Verify that the app owns the gate that the pipe is being created on */
601 if ((p_gate == NULL) ||
602 (p_gate->gate_owner != p_evt_data->create_pipe.hci_handle)) {
603 report_failed = true;
604 NFA_TRACE_ERROR2(
605 "nfa_hci_api_create_pipe Cannot create pipe! APP: 0x%02x does not own "
606 "the gate:0x%x",
607 p_evt_data->create_pipe.hci_handle,
608 p_evt_data->create_pipe.source_gate);
609 } else if (nfa_hciu_check_pipe_between_gates(
610 p_evt_data->create_pipe.source_gate,
611 p_evt_data->create_pipe.dest_host,
612 p_evt_data->create_pipe.dest_gate)) {
613 report_failed = true;
614 NFA_TRACE_ERROR0(
615 "nfa_hci_api_create_pipe : Cannot create multiple pipe between the "
616 "same two gates!");
617 }
618
619 if (report_failed) {
620 evt_data.created.source_gate = p_evt_data->create_pipe.source_gate;
621 evt_data.created.status = NFA_STATUS_FAILED;
622
623 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
624 p_evt_data->open_pipe.hci_handle);
625 } else {
626 if (nfa_hciu_is_host_reseting(p_evt_data->create_pipe.dest_gate)) {
627 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
628 return false;
629 }
630
631 nfa_hci_cb.local_gate_in_use = p_evt_data->create_pipe.source_gate;
632 nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
633 nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
634 nfa_hci_cb.app_in_use = p_evt_data->create_pipe.hci_handle;
635
636 nfa_hciu_send_create_pipe_cmd(p_evt_data->create_pipe.source_gate,
637 p_evt_data->create_pipe.dest_host,
638 p_evt_data->create_pipe.dest_gate);
639 }
640 return true;
641 }
642
643 /*******************************************************************************
644 **
645 ** Function nfa_hci_api_open_pipe
646 **
647 ** Description action function to open a pipe
648 **
649 ** Returns None
650 **
651 *******************************************************************************/
nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)652 static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
653 tNFA_HCI_EVT_DATA evt_data;
654 tNFA_HCI_DYN_PIPE* p_pipe =
655 nfa_hciu_find_pipe_by_pid(p_evt_data->open_pipe.pipe);
656 tNFA_HCI_DYN_GATE* p_gate = NULL;
657
658 if (p_pipe != NULL) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
659
660 if ((p_pipe != NULL) && (p_gate != NULL) &&
661 (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
662 (p_gate->gate_owner == p_evt_data->open_pipe.hci_handle)) {
663 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
664 nfa_hciu_send_open_pipe_cmd(p_evt_data->open_pipe.pipe);
665 } else {
666 evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
667 evt_data.opened.status = NFA_STATUS_OK;
668
669 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
670 p_evt_data->open_pipe.hci_handle);
671 }
672 } else {
673 evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
674 evt_data.opened.status = NFA_STATUS_FAILED;
675
676 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
677 p_evt_data->open_pipe.hci_handle);
678 }
679 }
680
681 /*******************************************************************************
682 **
683 ** Function nfa_hci_api_get_reg_value
684 **
685 ** Description action function to get the reg value of the specified index
686 **
687 ** Returns TRUE, if the command is processed
688 ** FALSE, if command is queued for processing later
689 **
690 *******************************************************************************/
nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA * p_evt_data)691 static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
692 tNFA_HCI_DYN_PIPE* p_pipe =
693 nfa_hciu_find_pipe_by_pid(p_evt_data->get_registry.pipe);
694 tNFA_HCI_DYN_GATE* p_gate;
695 tNFA_STATUS status = NFA_STATUS_FAILED;
696 tNFA_HCI_EVT_DATA evt_data;
697
698 if (p_pipe != NULL) {
699 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
700
701 if ((p_gate != NULL) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
702 (p_gate->gate_owner == p_evt_data->get_registry.hci_handle)) {
703 nfa_hci_cb.app_in_use = p_evt_data->get_registry.hci_handle;
704
705 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
706 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
707 return false;
708 }
709
710 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
711 NFA_TRACE_WARNING1("nfa_hci_api_get_reg_value pipe:%d not open",
712 p_evt_data->get_registry.pipe);
713 } else {
714 status = nfa_hciu_send_get_param_cmd(p_evt_data->get_registry.pipe,
715 p_evt_data->get_registry.reg_inx);
716 if (status == NFA_STATUS_OK) return true;
717 }
718 }
719 }
720
721 evt_data.cmd_sent.status = status;
722
723 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
724 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
725 p_evt_data->get_registry.hci_handle);
726 return true;
727 }
728
729 /*******************************************************************************
730 **
731 ** Function nfa_hci_api_set_reg_value
732 **
733 ** Description action function to set the reg value at specified index
734 **
735 ** Returns TRUE, if the command is processed
736 ** FALSE, if command is queued for processing later
737 **
738 *******************************************************************************/
nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA * p_evt_data)739 static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
740 tNFA_HCI_DYN_PIPE* p_pipe =
741 nfa_hciu_find_pipe_by_pid(p_evt_data->set_registry.pipe);
742 tNFA_HCI_DYN_GATE* p_gate;
743 tNFA_STATUS status = NFA_STATUS_FAILED;
744 tNFA_HCI_EVT_DATA evt_data;
745
746 if (p_pipe != NULL) {
747 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
748
749 if ((p_gate != NULL) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
750 (p_gate->gate_owner == p_evt_data->set_registry.hci_handle)) {
751 nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle;
752
753 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
754 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
755 return false;
756 }
757
758 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
759 NFA_TRACE_WARNING1("nfa_hci_api_set_reg_value pipe:%d not open",
760 p_evt_data->set_registry.pipe);
761 } else {
762 status = nfa_hciu_send_set_param_cmd(
763 p_evt_data->set_registry.pipe, p_evt_data->set_registry.reg_inx,
764 p_evt_data->set_registry.size, p_evt_data->set_registry.data);
765 if (status == NFA_STATUS_OK) return true;
766 }
767 }
768 }
769 evt_data.cmd_sent.status = status;
770
771 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
772 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
773 p_evt_data->set_registry.hci_handle);
774 return true;
775 }
776
777 /*******************************************************************************
778 **
779 ** Function nfa_hci_api_close_pipe
780 **
781 ** Description action function to close a pipe
782 **
783 ** Returns None
784 **
785 *******************************************************************************/
nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)786 static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
787 tNFA_HCI_EVT_DATA evt_data;
788 tNFA_HCI_DYN_PIPE* p_pipe =
789 nfa_hciu_find_pipe_by_pid(p_evt_data->close_pipe.pipe);
790 tNFA_HCI_DYN_GATE* p_gate = NULL;
791
792 if (p_pipe != NULL) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
793
794 if ((p_pipe != NULL) && (p_gate != NULL) &&
795 (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
796 (p_gate->gate_owner == p_evt_data->close_pipe.hci_handle)) {
797 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
798 nfa_hciu_send_close_pipe_cmd(p_evt_data->close_pipe.pipe);
799 } else {
800 evt_data.closed.status = NFA_STATUS_OK;
801 evt_data.closed.pipe = p_evt_data->close_pipe.pipe;
802
803 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
804 p_evt_data->close_pipe.hci_handle);
805 }
806 } else {
807 evt_data.closed.status = NFA_STATUS_FAILED;
808 evt_data.closed.pipe = 0x00;
809
810 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
811 p_evt_data->close_pipe.hci_handle);
812 }
813 }
814
815 /*******************************************************************************
816 **
817 ** Function nfa_hci_api_delete_pipe
818 **
819 ** Description action function to delete a pipe
820 **
821 ** Returns None
822 **
823 *******************************************************************************/
nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)824 static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
825 tNFA_HCI_EVT_DATA evt_data;
826 tNFA_HCI_DYN_PIPE* p_pipe =
827 nfa_hciu_find_pipe_by_pid(p_evt_data->delete_pipe.pipe);
828 tNFA_HCI_DYN_GATE* p_gate = NULL;
829
830 if (p_pipe != NULL) {
831 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
832 if ((p_gate != NULL) &&
833 (p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle) &&
834 (nfa_hciu_is_active_host(p_pipe->dest_host))) {
835 nfa_hciu_send_delete_pipe_cmd(p_evt_data->delete_pipe.pipe);
836 return;
837 }
838 }
839
840 evt_data.deleted.status = NFA_STATUS_FAILED;
841 evt_data.deleted.pipe = 0x00;
842 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
843 p_evt_data->close_pipe.hci_handle);
844 }
845
846 /*******************************************************************************
847 **
848 ** Function nfa_hci_api_send_cmd
849 **
850 ** Description action function to send command on the given pipe
851 **
852 ** Returns TRUE, if the command is processed
853 ** FALSE, if command is queued for processing later
854 **
855 *******************************************************************************/
nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA * p_evt_data)856 static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data) {
857 tNFA_STATUS status = NFA_STATUS_FAILED;
858 tNFA_HCI_DYN_PIPE* p_pipe;
859 tNFA_HCI_EVT_DATA evt_data;
860 tNFA_HANDLE app_handle;
861
862 if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_cmd.pipe)) != NULL) {
863 app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_cmd.pipe);
864
865 if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
866 ((app_handle == p_evt_data->send_cmd.hci_handle ||
867 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
868 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
869 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
870 return false;
871 }
872
873 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
874 nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
875 status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE,
876 p_evt_data->send_cmd.cmd_code,
877 p_evt_data->send_cmd.cmd_len,
878 p_evt_data->send_cmd.data);
879 if (status == NFA_STATUS_OK) return true;
880 } else {
881 NFA_TRACE_WARNING1("nfa_hci_api_send_cmd pipe:%d not open",
882 p_pipe->pipe_id);
883 }
884 } else {
885 NFA_TRACE_WARNING1(
886 "nfa_hci_api_send_cmd pipe:%d Owned by different application or "
887 "Destination host is not active",
888 p_pipe->pipe_id);
889 }
890 } else {
891 NFA_TRACE_WARNING1("nfa_hci_api_send_cmd pipe:%d not found",
892 p_evt_data->send_cmd.pipe);
893 }
894
895 evt_data.cmd_sent.status = status;
896
897 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
898 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
899 p_evt_data->send_cmd.hci_handle);
900 return true;
901 }
902
903 /*******************************************************************************
904 **
905 ** Function nfa_hci_api_send_rsp
906 **
907 ** Description action function to send response on the given pipe
908 **
909 ** Returns None
910 **
911 *******************************************************************************/
nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA * p_evt_data)912 static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data) {
913 tNFA_STATUS status = NFA_STATUS_FAILED;
914 tNFA_HCI_DYN_PIPE* p_pipe;
915 tNFA_HCI_EVT_DATA evt_data;
916 tNFA_HANDLE app_handle;
917
918 if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_rsp.pipe)) != NULL) {
919 app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_rsp.pipe);
920
921 if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
922 ((app_handle == p_evt_data->send_rsp.hci_handle ||
923 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
924 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
925 status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
926 p_evt_data->send_rsp.response,
927 p_evt_data->send_rsp.size,
928 p_evt_data->send_rsp.data);
929 if (status == NFA_STATUS_OK) return;
930 } else {
931 NFA_TRACE_WARNING1("nfa_hci_api_send_rsp pipe:%d not open",
932 p_pipe->pipe_id);
933 }
934 } else {
935 NFA_TRACE_WARNING1(
936 "nfa_hci_api_send_rsp pipe:%d Owned by different application or "
937 "Destination host is not active",
938 p_pipe->pipe_id);
939 }
940 } else {
941 NFA_TRACE_WARNING1("nfa_hci_api_send_rsp pipe:%d not found",
942 p_evt_data->send_rsp.pipe);
943 }
944
945 evt_data.rsp_sent.status = status;
946
947 /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
948 nfa_hciu_send_to_app(NFA_HCI_RSP_SENT_EVT, &evt_data,
949 p_evt_data->send_rsp.hci_handle);
950 }
951
952 /*******************************************************************************
953 **
954 ** Function nfa_hci_api_send_event
955 **
956 ** Description action function to send an event to the given pipe
957 **
958 ** Returns TRUE, if the event is processed
959 ** FALSE, if event is queued for processing later
960 **
961 *******************************************************************************/
nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA * p_evt_data)962 static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data) {
963 tNFA_STATUS status = NFA_STATUS_FAILED;
964 tNFA_HCI_DYN_PIPE* p_pipe;
965 tNFA_HCI_EVT_DATA evt_data;
966 tNFA_HANDLE app_handle;
967
968 if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_evt.pipe)) != NULL) {
969 app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_evt.pipe);
970
971 if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
972 ((app_handle == p_evt_data->send_evt.hci_handle ||
973 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
974 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
975 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
976 return false;
977 }
978
979 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
980 status = nfa_hciu_send_msg(
981 p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code,
982 p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf);
983
984 if (status == NFA_STATUS_OK) {
985 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
986 nfa_hci_cb.w4_rsp_evt = true;
987 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
988 }
989
990 if (p_evt_data->send_evt.rsp_len) {
991 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
992 nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len;
993 nfa_hci_cb.p_rsp_buf = p_evt_data->send_evt.p_rsp_buf;
994 if (p_evt_data->send_evt.rsp_timeout) {
995 nfa_hci_cb.w4_rsp_evt = true;
996 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
997 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
998 p_evt_data->send_evt.rsp_timeout);
999 } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
1000 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1001 p_nfa_hci_cfg->hcp_response_timeout);
1002 }
1003 } else {
1004 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
1005 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
1006 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1007 p_nfa_hci_cfg->hcp_response_timeout);
1008 }
1009 nfa_hci_cb.rsp_buf_size = 0;
1010 nfa_hci_cb.p_rsp_buf = NULL;
1011 }
1012 }
1013 } else {
1014 NFA_TRACE_WARNING1("nfa_hci_api_send_event pipe:%d not open",
1015 p_pipe->pipe_id);
1016 }
1017 } else {
1018 NFA_TRACE_WARNING1(
1019 "nfa_hci_api_send_event pipe:%d Owned by different application or "
1020 "Destination host is not active",
1021 p_pipe->pipe_id);
1022 }
1023 } else {
1024 NFA_TRACE_WARNING1("nfa_hci_api_send_event pipe:%d not found",
1025 p_evt_data->send_evt.pipe);
1026 }
1027
1028 evt_data.evt_sent.status = status;
1029
1030 /* Send NFC_HCI_EVENT_SENT_EVT to notify status */
1031 nfa_hciu_send_to_app(NFA_HCI_EVENT_SENT_EVT, &evt_data,
1032 p_evt_data->send_evt.hci_handle);
1033 return true;
1034 }
1035
1036 /*******************************************************************************
1037 **
1038 ** Function nfa_hci_api_add_static_pipe
1039 **
1040 ** Description action function to add static pipe
1041 **
1042 ** Returns None
1043 **
1044 *******************************************************************************/
nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)1045 static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
1046 tNFA_HCI_DYN_GATE* pg;
1047 tNFA_HCI_DYN_PIPE* pp;
1048 tNFA_HCI_EVT_DATA evt_data;
1049
1050 /* Allocate a proprietary gate */
1051 pg = nfa_hciu_alloc_gate(p_evt_data->add_static_pipe.gate,
1052 p_evt_data->add_static_pipe.hci_handle);
1053 if (pg != NULL) {
1054 /* Assign new owner to the gate */
1055 pg->gate_owner = p_evt_data->add_static_pipe.hci_handle;
1056
1057 /* Add the dynamic pipe to the proprietary gate */
1058 if (nfa_hciu_add_pipe_to_gate(p_evt_data->add_static_pipe.pipe, pg->gate_id,
1059 p_evt_data->add_static_pipe.host,
1060 p_evt_data->add_static_pipe.gate) !=
1061 NFA_HCI_ANY_OK) {
1062 /* Unable to add the dynamic pipe, so release the gate */
1063 nfa_hciu_release_gate(pg->gate_id);
1064 evt_data.pipe_added.status = NFA_STATUS_FAILED;
1065 nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
1066 p_evt_data->add_static_pipe.hci_handle);
1067 return;
1068 }
1069 pp = nfa_hciu_find_pipe_by_pid(p_evt_data->add_static_pipe.pipe);
1070 if (pp != NULL) {
1071 /* This pipe is always opened */
1072 pp->pipe_state = NFA_HCI_PIPE_OPENED;
1073 evt_data.pipe_added.status = NFA_STATUS_OK;
1074 nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
1075 p_evt_data->add_static_pipe.hci_handle);
1076 return;
1077 }
1078 }
1079 /* Unable to add static pipe */
1080 evt_data.pipe_added.status = NFA_STATUS_FAILED;
1081 nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
1082 p_evt_data->add_static_pipe.hci_handle);
1083 }
1084
1085 /*******************************************************************************
1086 **
1087 ** Function nfa_hci_handle_link_mgm_gate_cmd
1088 **
1089 ** Description This function handles incoming link management gate hci
1090 ** commands
1091 **
1092 ** Returns none
1093 **
1094 *******************************************************************************/
nfa_hci_handle_link_mgm_gate_cmd(uint8_t * p_data)1095 void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data) {
1096 uint8_t index;
1097 uint8_t data[2];
1098 uint8_t rsp_len = 0;
1099 uint8_t response = NFA_HCI_ANY_OK;
1100
1101 if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) &&
1102 (nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE)) {
1103 nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE,
1104 NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL);
1105 return;
1106 }
1107
1108 switch (nfa_hci_cb.inst) {
1109 case NFA_HCI_ANY_SET_PARAMETER:
1110 STREAM_TO_UINT8(index, p_data);
1111
1112 if (index == 1) {
1113 STREAM_TO_UINT16(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
1114 } else
1115 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
1116 break;
1117
1118 case NFA_HCI_ANY_GET_PARAMETER:
1119 STREAM_TO_UINT8(index, p_data);
1120 if (index == 1) {
1121 data[0] =
1122 (uint8_t)((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF);
1123 data[1] = (uint8_t)(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F);
1124 rsp_len = 2;
1125 } else
1126 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
1127 break;
1128
1129 case NFA_HCI_ANY_OPEN_PIPE:
1130 data[0] = 0;
1131 rsp_len = 1;
1132 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED;
1133 break;
1134
1135 case NFA_HCI_ANY_CLOSE_PIPE:
1136 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1137 break;
1138
1139 default:
1140 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1141 break;
1142 }
1143
1144 nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE,
1145 response, rsp_len, data);
1146 }
1147
1148 /*******************************************************************************
1149 **
1150 ** Function nfa_hci_handle_pipe_open_close_cmd
1151 **
1152 ** Description This function handles all generic gates (excluding
1153 ** connectivity gate) commands
1154 **
1155 ** Returns none
1156 **
1157 *******************************************************************************/
nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE * p_pipe)1158 void nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE* p_pipe) {
1159 uint8_t data[1];
1160 uint8_t rsp_len = 0;
1161 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1162 tNFA_HCI_DYN_GATE* p_gate;
1163
1164 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
1165 if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL)
1166 data[0] = nfa_hciu_count_open_pipes_on_gate(p_gate);
1167 else
1168 data[0] = 0;
1169
1170 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1171 rsp_len = 1;
1172 } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
1173 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1174 }
1175
1176 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
1177 data);
1178 }
1179
1180 /*******************************************************************************
1181 **
1182 ** Function nfa_hci_handle_admin_gate_cmd
1183 **
1184 ** Description This function handles incoming commands on ADMIN gate
1185 **
1186 ** Returns none
1187 **
1188 *******************************************************************************/
nfa_hci_handle_admin_gate_cmd(uint8_t * p_data)1189 void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data) {
1190 uint8_t source_host, source_gate, dest_host, dest_gate, pipe;
1191 uint8_t data = 0;
1192 uint8_t rsp_len = 0;
1193 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1194 tNFA_HCI_DYN_GATE* pgate;
1195 tNFA_HCI_EVT_DATA evt_data;
1196
1197 switch (nfa_hci_cb.inst) {
1198 case NFA_HCI_ANY_OPEN_PIPE:
1199 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
1200 data = 0;
1201 rsp_len = 1;
1202 break;
1203
1204 case NFA_HCI_ANY_CLOSE_PIPE:
1205 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1206 /* Reopen the pipe immediately */
1207 nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response,
1208 rsp_len, &data);
1209 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
1210 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1211 return;
1212 break;
1213
1214 case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
1215 STREAM_TO_UINT8(source_host, p_data);
1216 STREAM_TO_UINT8(source_gate, p_data);
1217 STREAM_TO_UINT8(dest_host, p_data);
1218 STREAM_TO_UINT8(dest_gate, p_data);
1219 STREAM_TO_UINT8(pipe, p_data);
1220
1221 if ((dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) ||
1222 (dest_gate == NFA_HCI_LOOP_BACK_GATE)) {
1223 response = nfa_hciu_add_pipe_to_static_gate(dest_gate, pipe,
1224 source_host, source_gate);
1225 } else {
1226 if ((pgate = nfa_hciu_find_gate_by_gid(dest_gate)) != NULL) {
1227 /* If the gate is valid, add the pipe to it */
1228 if (nfa_hciu_check_pipe_between_gates(dest_gate, source_host,
1229 source_gate)) {
1230 /* Already, there is a pipe between these two gates, so will reject
1231 */
1232 response = NFA_HCI_ANY_E_NOK;
1233 } else {
1234 response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host,
1235 source_gate);
1236 if (response == NFA_HCI_ANY_OK) {
1237 /* Tell the application a pipe was created with its gate */
1238
1239 evt_data.created.status = NFA_STATUS_OK;
1240 evt_data.created.pipe = pipe;
1241 evt_data.created.source_gate = dest_gate;
1242 evt_data.created.dest_host = source_host;
1243 evt_data.created.dest_gate = source_gate;
1244
1245 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
1246 pgate->gate_owner);
1247 }
1248 }
1249 } else {
1250 response = NFA_HCI_ANY_E_NOK;
1251 if ((dest_gate >= NFA_HCI_FIRST_PROP_GATE) &&
1252 (dest_gate <= NFA_HCI_LAST_PROP_GATE)) {
1253 if (nfa_hciu_alloc_gate(dest_gate, 0))
1254 response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host,
1255 source_gate);
1256 }
1257 }
1258 }
1259 break;
1260
1261 case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
1262 STREAM_TO_UINT8(pipe, p_data);
1263 response = nfa_hciu_release_pipe(pipe);
1264 break;
1265
1266 case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
1267 STREAM_TO_UINT8(source_host, p_data);
1268
1269 nfa_hciu_remove_all_pipes_from_host(source_host);
1270
1271 if (source_host == NFA_HCI_HOST_CONTROLLER) {
1272 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1273 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1274
1275 /* Reopen the admin pipe immediately */
1276 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
1277 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1278 return;
1279 } else {
1280 if ((source_host >= NFA_HCI_HOST_ID_UICC0) &&
1281 (source_host <
1282 (NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK))) {
1283 nfa_hci_cb.reset_host[source_host - NFA_HCI_HOST_ID_UICC0] =
1284 source_host;
1285 }
1286 }
1287 break;
1288
1289 default:
1290 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1291 break;
1292 }
1293
1294 nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response,
1295 rsp_len, &data);
1296 }
1297
1298 /*******************************************************************************
1299 **
1300 ** Function nfa_hci_handle_admin_gate_rsp
1301 **
1302 ** Description This function handles response received on admin gate
1303 **
1304 ** Returns none
1305 **
1306 *******************************************************************************/
nfa_hci_handle_admin_gate_rsp(uint8_t * p_data,uint8_t data_len)1307 void nfa_hci_handle_admin_gate_rsp(uint8_t* p_data, uint8_t data_len) {
1308 uint8_t source_host;
1309 uint8_t source_gate = nfa_hci_cb.local_gate_in_use;
1310 uint8_t dest_host = nfa_hci_cb.remote_host_in_use;
1311 uint8_t dest_gate = nfa_hci_cb.remote_gate_in_use;
1312 uint8_t pipe = 0;
1313 tNFA_STATUS status;
1314 tNFA_HCI_EVT_DATA evt_data;
1315 uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
1316 0xFF, 0xFF, 0xFF, 0xFF};
1317 uint8_t host_count = 0;
1318 uint8_t host_id = 0;
1319 uint32_t os_tick;
1320
1321 #if (BT_TRACE_VERBOSE == TRUE)
1322 NFA_TRACE_DEBUG4(
1323 "nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s App: 0x%04x Gate: "
1324 "0x%02x Pipe: 0x%02x",
1325 nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent), nfa_hci_cb.app_in_use,
1326 nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
1327 #else
1328 NFA_TRACE_DEBUG4(
1329 "nfa_hci_handle_admin_gate_rsp LastCmdSent: %u App: 0x%04x Gate: "
1330 "0x%02x Pipe: 0x%02x",
1331 nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use,
1332 nfa_hci_cb.pipe_in_use);
1333 #endif
1334
1335 /* If starting up, handle events here */
1336 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1337 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ||
1338 (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
1339 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
1340 if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED) {
1341 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1342 return;
1343 }
1344
1345 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) {
1346 NFA_TRACE_ERROR0("nfa_hci_handle_admin_gate_rsp - Initialization failed");
1347 nfa_hci_startup_complete(NFA_STATUS_FAILED);
1348 return;
1349 }
1350
1351 switch (nfa_hci_cb.cmd_sent) {
1352 case NFA_HCI_ANY_SET_PARAMETER:
1353 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1354 /* Set WHITELIST */
1355 nfa_hciu_send_set_param_cmd(
1356 NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
1357 p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
1358 } else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX) {
1359 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1360 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))
1361 nfa_hci_dh_startup_complete();
1362 }
1363 break;
1364
1365 case NFA_HCI_ANY_GET_PARAMETER:
1366 if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
1367 host_count = 0;
1368 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK) {
1369 nfa_hci_cb.inactive_host[host_count] =
1370 NFA_HCI_HOST_ID_UICC0 + host_count;
1371 host_count++;
1372 }
1373
1374 host_count = 0;
1375 /* Collect active host in the Host Network */
1376 while (host_count < data_len) {
1377 host_id = (uint8_t)*p_data++;
1378
1379 if ((host_id >= NFA_HCI_HOST_ID_UICC0) &&
1380 (host_id <
1381 NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)) {
1382 nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
1383 nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
1384 }
1385
1386 host_count++;
1387 }
1388 nfa_hci_startup_complete(NFA_STATUS_OK);
1389 } else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1390 /* The only parameter we get when initializing is the session ID.
1391 * Check for match. */
1392 if (!memcmp((uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id, p_data,
1393 NFA_HCI_SESSION_ID_LEN)) {
1394 /* Session has not changed, Set WHITELIST */
1395 nfa_hciu_send_set_param_cmd(
1396 NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
1397 p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
1398 } else {
1399 /* Something wrong, NVRAM data could be corrupt or first start with
1400 * default session id */
1401 nfa_hciu_send_clear_all_pipe_cmd();
1402 nfa_hci_cb.b_hci_netwk_reset = true;
1403 }
1404 }
1405 break;
1406
1407 case NFA_HCI_ANY_OPEN_PIPE:
1408 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
1409
1410 if (nfa_hci_cb.b_hci_netwk_reset) {
1411 nfa_hci_cb.b_hci_netwk_reset = false;
1412 /* Session ID is reset, Set New session id */
1413 memcpy(
1414 &nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2],
1415 nfa_hci_cb.cfg.admin_gate.session_id,
1416 (NFA_HCI_SESSION_ID_LEN / 2));
1417 os_tick = GKI_get_os_tick_count();
1418 memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
1419 (NFA_HCI_SESSION_ID_LEN / 2));
1420 nfa_hciu_send_set_param_cmd(
1421 NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
1422 NFA_HCI_SESSION_ID_LEN,
1423 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
1424 } else {
1425 /* First thing is to get the session ID */
1426 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1427 NFA_HCI_SESSION_IDENTITY_INDEX);
1428 }
1429 break;
1430
1431 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1432 nfa_hciu_remove_all_pipes_from_host(0);
1433 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1434 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1435 nfa_hci_cb.nv_write_needed = true;
1436
1437 /* Open admin */
1438 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1439 break;
1440 }
1441 } else {
1442 status =
1443 (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
1444
1445 switch (nfa_hci_cb.cmd_sent) {
1446 case NFA_HCI_ANY_SET_PARAMETER:
1447 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1448 nfa_hci_api_deregister(NULL);
1449 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1450 nfa_hci_api_dealloc_gate(NULL);
1451 break;
1452
1453 case NFA_HCI_ANY_GET_PARAMETER:
1454 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1455 if (!memcmp((uint8_t*)default_session, p_data,
1456 NFA_HCI_SESSION_ID_LEN)) {
1457 memcpy(&nfa_hci_cb.cfg.admin_gate
1458 .session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
1459 nfa_hci_cb.cfg.admin_gate.session_id,
1460 (NFA_HCI_SESSION_ID_LEN / 2));
1461 os_tick = GKI_get_os_tick_count();
1462 memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
1463 (NFA_HCI_SESSION_ID_LEN / 2));
1464 nfa_hci_cb.nv_write_needed = true;
1465 nfa_hciu_send_set_param_cmd(
1466 NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
1467 NFA_HCI_SESSION_ID_LEN,
1468 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
1469 } else {
1470 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1471 nfa_hci_api_deregister(NULL);
1472 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1473 nfa_hci_api_dealloc_gate(NULL);
1474 }
1475 } else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
1476 evt_data.hosts.status = status;
1477 evt_data.hosts.num_hosts = data_len;
1478 memcpy(evt_data.hosts.host, p_data, data_len);
1479
1480 host_count = 0;
1481 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK) {
1482 nfa_hci_cb.inactive_host[host_count] =
1483 NFA_HCI_HOST_ID_UICC0 + host_count;
1484 host_count++;
1485 }
1486
1487 host_count = 0;
1488 /* Collect active host in the Host Network */
1489 while (host_count < data_len) {
1490 host_id = (uint8_t)*p_data++;
1491
1492 if ((host_id >= NFA_HCI_HOST_ID_UICC0) &&
1493 (host_id <
1494 NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)) {
1495 nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
1496 nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
1497 }
1498 host_count++;
1499 }
1500 if (nfa_hciu_is_no_host_resetting())
1501 nfa_hci_check_pending_api_requests();
1502 nfa_hciu_send_to_app(NFA_HCI_HOST_LIST_EVT, &evt_data,
1503 nfa_hci_cb.app_in_use);
1504 }
1505 break;
1506
1507 case NFA_HCI_ADM_CREATE_PIPE:
1508 if (status == NFA_STATUS_OK) {
1509 STREAM_TO_UINT8(source_host, p_data);
1510 STREAM_TO_UINT8(source_gate, p_data);
1511 STREAM_TO_UINT8(dest_host, p_data);
1512 STREAM_TO_UINT8(dest_gate, p_data);
1513 STREAM_TO_UINT8(pipe, p_data);
1514
1515 /* Sanity check */
1516 if (source_gate != nfa_hci_cb.local_gate_in_use) {
1517 NFA_TRACE_WARNING2(
1518 "nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u "
1519 "got back: %u",
1520 nfa_hci_cb.local_gate_in_use, source_gate);
1521 break;
1522 }
1523
1524 nfa_hciu_add_pipe_to_gate(pipe, source_gate, dest_host, dest_gate);
1525 }
1526
1527 /* Tell the application his pipe was created or not */
1528 evt_data.created.status = status;
1529 evt_data.created.pipe = pipe;
1530 evt_data.created.source_gate = source_gate;
1531 evt_data.created.dest_host = dest_host;
1532 evt_data.created.dest_gate = dest_gate;
1533
1534 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
1535 nfa_hci_cb.app_in_use);
1536 break;
1537
1538 case NFA_HCI_ADM_DELETE_PIPE:
1539 if (status == NFA_STATUS_OK) {
1540 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1541
1542 /* If only deleting one pipe, tell the app we are done */
1543 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
1544 evt_data.deleted.status = status;
1545 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1546
1547 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
1548 nfa_hci_cb.app_in_use);
1549 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1550 nfa_hci_api_deregister(NULL);
1551 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1552 nfa_hci_api_dealloc_gate(NULL);
1553 } else {
1554 /* If only deleting one pipe, tell the app we are done */
1555 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
1556 evt_data.deleted.status = status;
1557 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1558
1559 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
1560 nfa_hci_cb.app_in_use);
1561 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) {
1562 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1563 nfa_hci_api_deregister(NULL);
1564 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) {
1565 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1566 nfa_hci_api_dealloc_gate(NULL);
1567 }
1568 }
1569 break;
1570
1571 case NFA_HCI_ANY_OPEN_PIPE:
1572 nfa_hci_cb.cfg.admin_gate.pipe01_state =
1573 status ? NFA_HCI_PIPE_CLOSED : NFA_HCI_PIPE_OPENED;
1574 nfa_hci_cb.nv_write_needed = true;
1575 if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED) {
1576 /* First thing is to get the session ID */
1577 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1578 NFA_HCI_SESSION_IDENTITY_INDEX);
1579 }
1580 break;
1581
1582 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1583 nfa_hciu_remove_all_pipes_from_host(0);
1584 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1585 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1586 nfa_hci_cb.nv_write_needed = true;
1587 /* Open admin */
1588 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1589 break;
1590 }
1591 }
1592 }
1593
1594 /*******************************************************************************
1595 **
1596 ** Function nfa_hci_handle_admin_gate_evt
1597 **
1598 ** Description This function handles events received on admin gate
1599 **
1600 ** Returns none
1601 **
1602 *******************************************************************************/
nfa_hci_handle_admin_gate_evt(uint8_t * p_data)1603 void nfa_hci_handle_admin_gate_evt(uint8_t* p_data) {
1604 tNFA_HCI_EVT_DATA evt_data;
1605 tNFA_HCI_API_GET_HOST_LIST* p_msg;
1606
1607 if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG) {
1608 NFA_TRACE_ERROR0(
1609 "nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
1610 return;
1611 }
1612
1613 NFA_TRACE_DEBUG0(
1614 "nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe");
1615 nfa_hci_cb.num_hot_plug_evts++;
1616
1617 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
1618 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
1619 /* Received Hot Plug evt while waiting for other Host in the network to
1620 * bootup after DH host bootup is complete */
1621 if ((nfa_hci_cb.ee_disable_disc) &&
1622 (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
1623 (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
1624 /* Received expected number of Hot Plug event(s) before as many number of
1625 * EE DISC REQ Ntf(s) are received */
1626 nfa_sys_stop_timer(&nfa_hci_cb.timer);
1627 /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ
1628 * Ntf(s) */
1629 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1630 p_nfa_hci_cfg->hci_netwk_enable_timeout);
1631 }
1632 } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1633 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
1634 /* Received Hot Plug evt during DH host bootup */
1635 if ((nfa_hci_cb.ee_disable_disc) &&
1636 (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
1637 (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
1638 /* Received expected number of Hot Plug event(s) before as many number of
1639 * EE DISC REQ Ntf(s) are received */
1640 nfa_hci_cb.w4_hci_netwk_init = false;
1641 }
1642 } else {
1643 /* Received Hot Plug evt on UICC self reset */
1644 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
1645 /* Notify all registered application with the HOT_PLUG_EVT */
1646 nfa_hciu_send_to_all_apps(NFA_HCI_EVENT_RCVD_EVT, &evt_data);
1647
1648 /* Send Get Host List after receiving any pending response */
1649 p_msg = (tNFA_HCI_API_GET_HOST_LIST*)GKI_getbuf(
1650 sizeof(tNFA_HCI_API_GET_HOST_LIST));
1651 if (p_msg != NULL) {
1652 p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT;
1653 /* Set Invalid handle to identify this Get Host List command is internal
1654 */
1655 p_msg->hci_handle = NFA_HANDLE_INVALID;
1656
1657 nfa_sys_sendmsg(p_msg);
1658 }
1659 }
1660 }
1661
1662 /*******************************************************************************
1663 **
1664 ** Function nfa_hci_handle_dyn_pipe_pkt
1665 **
1666 ** Description This function handles data received via dynamic pipe
1667 **
1668 ** Returns none
1669 **
1670 *******************************************************************************/
nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id,uint8_t * p_data,uint16_t data_len)1671 void nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id, uint8_t* p_data,
1672 uint16_t data_len) {
1673 tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
1674 tNFA_HCI_DYN_GATE* p_gate;
1675
1676 if (p_pipe == NULL) {
1677 /* Invalid pipe ID */
1678 NFA_TRACE_ERROR1("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d", pipe_id);
1679 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1680 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
1681 NULL);
1682 return;
1683 }
1684
1685 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
1686 nfa_hci_handle_identity_mgmt_gate_pkt(p_data, p_pipe);
1687 } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
1688 nfa_hci_handle_loopback_gate_pkt(p_data, data_len, p_pipe);
1689 } else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
1690 nfa_hci_handle_connectivity_gate_pkt(p_data, data_len, p_pipe);
1691 } else {
1692 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
1693 if (p_gate == NULL) {
1694 NFA_TRACE_ERROR1(
1695 "nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",
1696 p_pipe->local_gate);
1697 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1698 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
1699 NULL);
1700 return;
1701 }
1702
1703 /* Check if data packet is a command, response or event */
1704 switch (nfa_hci_cb.type) {
1705 case NFA_HCI_COMMAND_TYPE:
1706 nfa_hci_handle_generic_gate_cmd(p_data, (uint8_t)data_len, p_gate,
1707 p_pipe);
1708 break;
1709
1710 case NFA_HCI_RESPONSE_TYPE:
1711 nfa_hci_handle_generic_gate_rsp(p_data, (uint8_t)data_len, p_gate,
1712 p_pipe);
1713 break;
1714
1715 case NFA_HCI_EVENT_TYPE:
1716 nfa_hci_handle_generic_gate_evt(p_data, data_len, p_gate, p_pipe);
1717 break;
1718 }
1719 }
1720 }
1721
1722 /*******************************************************************************
1723 **
1724 ** Function nfa_hci_handle_identity_mgmt_gate_pkt
1725 **
1726 ** Description This function handles incoming Identity Management gate hci
1727 ** commands
1728 **
1729 ** Returns none
1730 **
1731 *******************************************************************************/
nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t * p_data,tNFA_HCI_DYN_PIPE * p_pipe)1732 static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
1733 tNFA_HCI_DYN_PIPE* p_pipe) {
1734 uint8_t data[20];
1735 uint8_t index;
1736 uint8_t gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
1737 uint16_t rsp_len = 0;
1738 uint8_t* p_rsp = data;
1739 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1740
1741 /* We never send commands on a pipe where the local gate is the identity
1742 * management
1743 * gate, so only commands should be processed.
1744 */
1745 if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE) return;
1746
1747 switch (nfa_hci_cb.inst) {
1748 case NFA_HCI_ANY_GET_PARAMETER:
1749 index = *(p_data++);
1750 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
1751 switch (index) {
1752 case NFA_HCI_VERSION_SW_INDEX:
1753 data[0] = (uint8_t)((NFA_HCI_VERSION_SW >> 16) & 0xFF);
1754 data[1] = (uint8_t)((NFA_HCI_VERSION_SW >> 8) & 0xFF);
1755 data[2] = (uint8_t)((NFA_HCI_VERSION_SW)&0xFF);
1756 rsp_len = 3;
1757 break;
1758
1759 case NFA_HCI_HCI_VERSION_INDEX:
1760 data[0] = NFA_HCI_VERSION;
1761 rsp_len = 1;
1762 break;
1763
1764 case NFA_HCI_VERSION_HW_INDEX:
1765 data[0] = (uint8_t)((NFA_HCI_VERSION_HW >> 16) & 0xFF);
1766 data[1] = (uint8_t)((NFA_HCI_VERSION_HW >> 8) & 0xFF);
1767 data[2] = (uint8_t)((NFA_HCI_VERSION_HW)&0xFF);
1768 rsp_len = 3;
1769 break;
1770
1771 case NFA_HCI_VENDOR_NAME_INDEX:
1772 memcpy(data, NFA_HCI_VENDOR_NAME, strlen(NFA_HCI_VENDOR_NAME));
1773 rsp_len = (uint8_t)strlen(NFA_HCI_VENDOR_NAME);
1774 break;
1775
1776 case NFA_HCI_MODEL_ID_INDEX:
1777 data[0] = NFA_HCI_MODEL_ID;
1778 rsp_len = 1;
1779 break;
1780
1781 case NFA_HCI_GATES_LIST_INDEX:
1782 gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
1783 gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
1784 gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
1785 num_gates = nfa_hciu_get_allocated_gate_list(&gate_rsp[3]);
1786 rsp_len = num_gates + 3;
1787 p_rsp = gate_rsp;
1788 break;
1789
1790 default:
1791 response = NFA_HCI_ANY_E_NOK;
1792 break;
1793 }
1794 } else {
1795 response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
1796 }
1797 break;
1798
1799 case NFA_HCI_ANY_OPEN_PIPE:
1800 data[0] = 0;
1801 rsp_len = 1;
1802 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1803 break;
1804
1805 case NFA_HCI_ANY_CLOSE_PIPE:
1806 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1807 break;
1808
1809 default:
1810 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1811 break;
1812 }
1813
1814 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
1815 p_rsp);
1816 }
1817
1818 /*******************************************************************************
1819 **
1820 ** Function nfa_hci_handle_generic_gate_cmd
1821 **
1822 ** Description This function handles all generic gates (excluding
1823 ** connectivity gate) commands
1824 **
1825 ** Returns none
1826 **
1827 *******************************************************************************/
nfa_hci_handle_generic_gate_cmd(uint8_t * p_data,uint8_t data_len,tNFA_HCI_DYN_GATE * p_gate,tNFA_HCI_DYN_PIPE * p_pipe)1828 static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
1829 tNFA_HCI_DYN_GATE* p_gate,
1830 tNFA_HCI_DYN_PIPE* p_pipe) {
1831 tNFA_HCI_EVT_DATA evt_data;
1832 tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner(p_pipe->pipe_id);
1833
1834 switch (nfa_hci_cb.inst) {
1835 case NFA_HCI_ANY_SET_PARAMETER:
1836 evt_data.registry.pipe = p_pipe->pipe_id;
1837 evt_data.registry.index = *p_data++;
1838 if (data_len > 0) data_len--;
1839 evt_data.registry.data_len = data_len;
1840
1841 memcpy(evt_data.registry.reg_data, p_data, data_len);
1842
1843 nfa_hciu_send_to_app(NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
1844 break;
1845
1846 case NFA_HCI_ANY_GET_PARAMETER:
1847 evt_data.registry.pipe = p_pipe->pipe_id;
1848 evt_data.registry.index = *p_data;
1849 evt_data.registry.data_len = 0;
1850
1851 nfa_hciu_send_to_app(NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
1852 break;
1853
1854 case NFA_HCI_ANY_OPEN_PIPE:
1855 nfa_hci_handle_pipe_open_close_cmd(p_pipe);
1856
1857 evt_data.opened.pipe = p_pipe->pipe_id;
1858 evt_data.opened.status = NFA_STATUS_OK;
1859
1860 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
1861 break;
1862
1863 case NFA_HCI_ANY_CLOSE_PIPE:
1864 nfa_hci_handle_pipe_open_close_cmd(p_pipe);
1865
1866 evt_data.closed.pipe = p_pipe->pipe_id;
1867 evt_data.opened.status = NFA_STATUS_OK;
1868
1869 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
1870 break;
1871
1872 default:
1873 /* Could be application specific command, pass it on */
1874 evt_data.cmd_rcvd.status = NFA_STATUS_OK;
1875 evt_data.cmd_rcvd.pipe = p_pipe->pipe_id;
1876 ;
1877 evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
1878 evt_data.cmd_rcvd.cmd_len = data_len;
1879
1880 if (data_len <= NFA_MAX_HCI_CMD_LEN)
1881 memcpy(evt_data.cmd_rcvd.cmd_data, p_data, data_len);
1882
1883 nfa_hciu_send_to_app(NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
1884 break;
1885 }
1886 }
1887
1888 /*******************************************************************************
1889 **
1890 ** Function nfa_hci_handle_generic_gate_rsp
1891 **
1892 ** Description This function handles all generic gates (excluding
1893 ** connectivity) response
1894 **
1895 ** Returns none
1896 **
1897 *******************************************************************************/
nfa_hci_handle_generic_gate_rsp(uint8_t * p_data,uint8_t data_len,tNFA_HCI_DYN_GATE * p_gate,tNFA_HCI_DYN_PIPE * p_pipe)1898 static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
1899 tNFA_HCI_DYN_GATE* p_gate,
1900 tNFA_HCI_DYN_PIPE* p_pipe) {
1901 tNFA_HCI_EVT_DATA evt_data;
1902 tNFA_STATUS status = NFA_STATUS_OK;
1903
1904 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) status = NFA_STATUS_FAILED;
1905
1906 if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) {
1907 if (status == NFA_STATUS_OK) p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1908
1909 nfa_hci_cb.nv_write_needed = true;
1910 /* Tell application */
1911 evt_data.opened.status = status;
1912 evt_data.opened.pipe = p_pipe->pipe_id;
1913
1914 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
1915 nfa_hci_cb.app_in_use);
1916 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) {
1917 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1918
1919 nfa_hci_cb.nv_write_needed = true;
1920 /* Tell application */
1921 evt_data.opened.status = status;
1922 ;
1923 evt_data.opened.pipe = p_pipe->pipe_id;
1924
1925 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
1926 nfa_hci_cb.app_in_use);
1927 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) {
1928 /* Tell application */
1929 evt_data.registry.status = status;
1930 evt_data.registry.pipe = p_pipe->pipe_id;
1931 evt_data.registry.data_len = data_len;
1932 evt_data.registry.index = nfa_hci_cb.param_in_use;
1933
1934 memcpy(evt_data.registry.reg_data, p_data, data_len);
1935
1936 nfa_hciu_send_to_app(NFA_HCI_GET_REG_RSP_EVT, &evt_data,
1937 nfa_hci_cb.app_in_use);
1938 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER) {
1939 /* Tell application */
1940 evt_data.registry.status = status;
1941 ;
1942 evt_data.registry.pipe = p_pipe->pipe_id;
1943
1944 nfa_hciu_send_to_app(NFA_HCI_SET_REG_RSP_EVT, &evt_data,
1945 nfa_hci_cb.app_in_use);
1946 } else {
1947 /* Could be a response to application specific command sent, pass it on */
1948 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
1949 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
1950 ;
1951 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
1952 evt_data.rsp_rcvd.rsp_len = data_len;
1953
1954 if (data_len <= NFA_MAX_HCI_RSP_LEN)
1955 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
1956
1957 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
1958 nfa_hci_cb.app_in_use);
1959 }
1960 }
1961
1962 /*******************************************************************************
1963 **
1964 ** Function nfa_hci_handle_connectivity_gate_pkt
1965 **
1966 ** Description This function handles incoming connectivity gate packets
1967 **
1968 ** Returns none
1969 **
1970 *******************************************************************************/
nfa_hci_handle_connectivity_gate_pkt(uint8_t * p_data,uint16_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)1971 static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
1972 uint16_t data_len,
1973 tNFA_HCI_DYN_PIPE* p_pipe) {
1974 tNFA_HCI_EVT_DATA evt_data;
1975
1976 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
1977 switch (nfa_hci_cb.inst) {
1978 case NFA_HCI_ANY_OPEN_PIPE:
1979 case NFA_HCI_ANY_CLOSE_PIPE:
1980 nfa_hci_handle_pipe_open_close_cmd(p_pipe);
1981 break;
1982
1983 case NFA_HCI_CON_PRO_HOST_REQUEST:
1984 /* A request to the DH to activate another host. This is not supported
1985 * for */
1986 /* now, we will implement it when the spec is clearer and UICCs need it.
1987 */
1988 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
1989 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
1990 break;
1991
1992 default:
1993 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
1994 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
1995 break;
1996 }
1997 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
1998 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
1999 (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2000 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2001 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2002 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2003
2004 /* Could be a response to application specific command sent, pass it on */
2005 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2006 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2007 ;
2008 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2009 evt_data.rsp_rcvd.rsp_len = data_len;
2010
2011 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2012 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2013
2014 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2015 nfa_hci_cb.app_in_use);
2016 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
2017 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2018 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2019 evt_data.rcvd_evt.evt_len = data_len;
2020 evt_data.rcvd_evt.p_evt_buf = p_data;
2021
2022 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2023 nfa_hciu_send_to_apps_handling_connectivity_evts(NFA_HCI_EVENT_RCVD_EVT,
2024 &evt_data);
2025 }
2026 }
2027
2028 /*******************************************************************************
2029 **
2030 ** Function nfa_hci_handle_loopback_gate_pkt
2031 **
2032 ** Description This function handles incoming loopback gate hci events
2033 **
2034 ** Returns none
2035 **
2036 *******************************************************************************/
nfa_hci_handle_loopback_gate_pkt(uint8_t * p_data,uint16_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)2037 static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
2038 tNFA_HCI_DYN_PIPE* p_pipe) {
2039 uint8_t data[1];
2040 uint8_t rsp_len = 0;
2041 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
2042 tNFA_HCI_EVT_DATA evt_data;
2043
2044 /* Check if data packet is a command, response or event */
2045 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
2046 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
2047 data[0] = 0;
2048 rsp_len = 1;
2049 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2050 } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
2051 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2052 } else
2053 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
2054
2055 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
2056 data);
2057 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
2058 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
2059 (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2060 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2061 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2062 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2063
2064 /* Could be a response to application specific command sent, pass it on */
2065 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2066 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2067 ;
2068 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2069 evt_data.rsp_rcvd.rsp_len = data_len;
2070
2071 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2072 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2073
2074 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2075 nfa_hci_cb.app_in_use);
2076 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
2077 if (nfa_hci_cb.w4_rsp_evt) {
2078 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2079 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2080 evt_data.rcvd_evt.evt_len = data_len;
2081 evt_data.rcvd_evt.p_evt_buf = p_data;
2082
2083 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data,
2084 nfa_hci_cb.app_in_use);
2085 } else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA) {
2086 /* Send back the same data we got */
2087 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_EVENT_TYPE,
2088 NFA_HCI_EVT_POST_DATA, data_len, p_data);
2089 }
2090 }
2091 }
2092
2093 /*******************************************************************************
2094 **
2095 ** Function nfa_hci_handle_generic_gate_evt
2096 **
2097 ** Description This function handles incoming Generic gate hci events
2098 **
2099 ** Returns none
2100 **
2101 *******************************************************************************/
nfa_hci_handle_generic_gate_evt(uint8_t * p_data,uint16_t data_len,tNFA_HCI_DYN_GATE * p_gate,tNFA_HCI_DYN_PIPE * p_pipe)2102 static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
2103 tNFA_HCI_DYN_GATE* p_gate,
2104 tNFA_HCI_DYN_PIPE* p_pipe) {
2105 tNFA_HCI_EVT_DATA evt_data;
2106
2107 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2108 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2109 evt_data.rcvd_evt.evt_len = data_len;
2110
2111 if (nfa_hci_cb.assembly_failed)
2112 evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL;
2113 else
2114 evt_data.rcvd_evt.status = NFA_STATUS_OK;
2115
2116 evt_data.rcvd_evt.p_evt_buf = p_data;
2117 nfa_hci_cb.rsp_buf_size = 0;
2118 nfa_hci_cb.p_rsp_buf = NULL;
2119
2120 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2121 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
2122 }
2123