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