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 *
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 else if (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE && pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE && pp->pipe_id && pp->local_gate >= NFA_HCI_FIRST_PROP_GATE && pp->local_gate <= NFA_HCI_LAST_PROP_GATE)
454 {
455 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
456 {
457 if (pp->local_gate == pg->gate_id)
458 {
459 if (!pg->gate_owner)
460 memcpy (&evt_data.gates_pipes.uicc_created_pipe [evt_data.gates_pipes.num_uicc_created_pipes++], pp, sizeof (tNFA_HCI_PIPE_INFO));
461 break;
462 }
463 }
464 }
465 }
466
467 evt_data.gates_pipes.status = NFA_STATUS_OK;
468
469 /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */
470 nfa_hciu_send_to_app (NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data, p_evt_data->get_gate_pipe_list.hci_handle);
471 }
472
473 /*******************************************************************************
474 **
475 ** Function nfa_hci_api_alloc_gate
476 **
477 ** Description action function to allocate gate
478 **
479 ** Returns None
480 **
481 *******************************************************************************/
nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA * p_evt_data)482 static void nfa_hci_api_alloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data)
483 {
484 tNFA_HANDLE app_handle = p_evt_data->comm.hci_handle;
485 tNFA_HCI_EVT_DATA evt_data;
486 tNFA_HCI_DYN_GATE *p_gate;
487
488 p_gate = nfa_hciu_alloc_gate (p_evt_data->gate_info.gate, app_handle);
489
490 if (p_gate)
491 {
492 if (!p_gate->gate_owner)
493 {
494 /* No app owns the gate yet */
495 p_gate->gate_owner = app_handle;
496 }
497 else if (p_gate->gate_owner != app_handle)
498 {
499 /* Some other app owns the gate */
500 p_gate = NULL;
501 NFA_TRACE_ERROR1 ("nfa_hci_api_alloc_gate (): The Gate (0X%02x) already taken!", p_evt_data->gate_info.gate);
502 }
503 }
504
505 evt_data.allocated.gate = p_gate ? p_gate->gate_id : 0;
506 evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED;
507
508 /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */
509 nfa_hciu_send_to_app (NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle);
510 }
511
512 /*******************************************************************************
513 **
514 ** Function nfa_hci_api_dealloc_gate
515 **
516 ** Description action function to deallocate the given generic gate
517 **
518 ** Returns None
519 **
520 *******************************************************************************/
nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA * p_evt_data)521 void nfa_hci_api_dealloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data)
522 {
523 tNFA_HCI_EVT_DATA evt_data;
524 UINT8 gate_id;
525 tNFA_HCI_DYN_GATE *p_gate;
526 tNFA_HCI_DYN_PIPE *p_pipe;
527 tNFA_HANDLE app_handle;
528
529 /* p_evt_data may be NULL if we are recursively deleting pipes */
530 if (p_evt_data)
531 {
532 gate_id = p_evt_data->gate_dealloc.gate;
533 app_handle = p_evt_data->gate_dealloc.hci_handle;
534
535 }
536 else
537 {
538 nfa_sys_stop_timer (&nfa_hci_cb.timer);
539 gate_id = nfa_hci_cb.local_gate_in_use;
540 app_handle = nfa_hci_cb.app_in_use;
541 }
542
543 evt_data.deallocated.gate = gate_id;;
544
545 p_gate = nfa_hciu_find_gate_by_gid (gate_id);
546
547 if (p_gate == NULL)
548 {
549 evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID;
550 }
551 else if (p_gate->gate_owner != app_handle)
552 {
553 evt_data.deallocated.status = NFA_STATUS_FAILED;
554 }
555 else
556 {
557 /* See if any pipe is owned by this app */
558 if (nfa_hciu_find_pipe_on_gate (p_gate->gate_id) == NULL)
559 {
560 nfa_hciu_release_gate (p_gate->gate_id);
561
562 nfa_hci_cb.nv_write_needed = TRUE;
563 evt_data.deallocated.status = NFA_STATUS_OK;
564
565 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
566 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
567 }
568 else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate (p_gate->gate_id)) == NULL)
569 {
570 /* UICC is not active at the moment and cannot delete the pipe */
571 nfa_hci_cb.nv_write_needed = TRUE;
572 evt_data.deallocated.status = NFA_STATUS_FAILED;
573
574 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
575 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
576 }
577 else
578 {
579 /* Delete pipes on the gate */
580 nfa_hci_cb.local_gate_in_use = gate_id;
581 nfa_hci_cb.app_in_use = app_handle;
582 nfa_hci_cb.hci_state = NFA_HCI_STATE_REMOVE_GATE;
583
584 nfa_hciu_send_delete_pipe_cmd (p_pipe->pipe_id);
585 return;
586 }
587 }
588
589 nfa_hciu_send_to_app (NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle);
590 }
591
592 /*******************************************************************************
593 **
594 ** Function nfa_hci_api_get_host_list
595 **
596 ** Description action function to get the host list from HCI network
597 **
598 ** Returns None
599 **
600 *******************************************************************************/
nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA * p_evt_data)601 static void nfa_hci_api_get_host_list (tNFA_HCI_EVENT_DATA *p_evt_data)
602 {
603 UINT8 app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
604
605 nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
606
607 /* Send Get Host List command on "Internal request" or requested by registered application with valid handle and callback function */
608 if ( (nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID)
609 ||((app_inx < NFA_HCI_MAX_APP_CB) && (nfa_hci_cb.p_app_cback[app_inx] != NULL)) )
610 {
611 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
612 }
613 }
614
615 /*******************************************************************************
616 **
617 ** Function nfa_hci_api_create_pipe
618 **
619 ** Description action function to create a pipe
620 **
621 ** Returns TRUE, if the command is processed
622 ** FALSE, if command is queued for processing later
623 **
624 *******************************************************************************/
nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)625 static BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
626 {
627 tNFA_HCI_DYN_GATE *p_gate = nfa_hciu_find_gate_by_gid (p_evt_data->create_pipe.source_gate);
628 tNFA_HCI_EVT_DATA evt_data;
629 BOOLEAN report_failed = FALSE;
630
631 /* Verify that the app owns the gate that the pipe is being created on */
632 if ( (p_gate == NULL)
633 ||(p_gate->gate_owner != p_evt_data->create_pipe.hci_handle) )
634 {
635 report_failed = TRUE;
636 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);
637 }
638 else if (nfa_hciu_check_pipe_between_gates (p_evt_data->create_pipe.source_gate, p_evt_data->create_pipe.dest_host, p_evt_data->create_pipe.dest_gate))
639 {
640 report_failed = TRUE;
641 NFA_TRACE_ERROR0 ("nfa_hci_api_create_pipe : Cannot create multiple pipe between the same two gates!");
642 }
643
644 if (report_failed)
645 {
646 evt_data.created.source_gate = p_evt_data->create_pipe.source_gate;
647 evt_data.created.status = NFA_STATUS_FAILED;
648
649 nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
650 }
651 else
652 {
653 if (nfa_hciu_is_host_reseting (p_evt_data->create_pipe.dest_gate))
654 {
655 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
656 return FALSE;
657 }
658
659 nfa_hci_cb.local_gate_in_use = p_evt_data->create_pipe.source_gate;
660 nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
661 nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
662 nfa_hci_cb.app_in_use = p_evt_data->create_pipe.hci_handle;
663
664 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);
665 }
666 return TRUE;
667 }
668
669 /*******************************************************************************
670 **
671 ** Function nfa_hci_api_open_pipe
672 **
673 ** Description action function to open a pipe
674 **
675 ** Returns None
676 **
677 *******************************************************************************/
nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)678 static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
679 {
680 tNFA_HCI_EVT_DATA evt_data;
681 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->open_pipe.pipe);
682 tNFA_HCI_DYN_GATE *p_gate = NULL;
683
684 if (p_pipe != NULL)
685 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
686
687 if ( (p_pipe != NULL)
688 &&(p_gate != NULL)
689 &&(nfa_hciu_is_active_host (p_pipe->dest_host))
690 &&(p_gate->gate_owner == p_evt_data->open_pipe.hci_handle))
691 {
692 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
693 {
694 nfa_hciu_send_open_pipe_cmd (p_evt_data->open_pipe.pipe);
695 }
696 else
697 {
698 evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
699 evt_data.opened.status = NFA_STATUS_OK;
700
701 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
702 }
703 }
704 else
705 {
706 evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
707 evt_data.opened.status = NFA_STATUS_FAILED;
708
709 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
710 }
711 }
712
713 /*******************************************************************************
714 **
715 ** Function nfa_hci_api_get_reg_value
716 **
717 ** Description action function to get the reg value of the specified index
718 **
719 ** Returns TRUE, if the command is processed
720 ** FALSE, if command is queued for processing later
721 **
722 *******************************************************************************/
nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA * p_evt_data)723 static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
724 {
725 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->get_registry.pipe);
726 tNFA_HCI_DYN_GATE *p_gate;
727 tNFA_STATUS status = NFA_STATUS_FAILED;
728 tNFA_HCI_EVT_DATA evt_data;
729
730 if (p_pipe != NULL)
731 {
732 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
733
734 if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->get_registry.hci_handle))
735 {
736 nfa_hci_cb.app_in_use = p_evt_data->get_registry.hci_handle;
737
738 if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
739 {
740 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
741 return FALSE;
742 }
743
744 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
745 {
746 NFA_TRACE_WARNING1 ("nfa_hci_api_get_reg_value pipe:%d not open", p_evt_data->get_registry.pipe);
747 }
748 else
749 {
750 if ((status = nfa_hciu_send_get_param_cmd (p_evt_data->get_registry.pipe, p_evt_data->get_registry.reg_inx)) == NFA_STATUS_OK)
751 return TRUE;
752 }
753 }
754 }
755
756 evt_data.cmd_sent.status = status;
757
758 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
759 nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->get_registry.hci_handle);
760 return TRUE;
761 }
762
763 /*******************************************************************************
764 **
765 ** Function nfa_hci_api_set_reg_value
766 **
767 ** Description action function to set the reg value at specified index
768 **
769 ** Returns TRUE, if the command is processed
770 ** FALSE, if command is queued for processing later
771 **
772 *******************************************************************************/
nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA * p_evt_data)773 static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
774 {
775 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->set_registry.pipe);
776 tNFA_HCI_DYN_GATE *p_gate;
777 tNFA_STATUS status = NFA_STATUS_FAILED;
778 tNFA_HCI_EVT_DATA evt_data;
779
780 if (p_pipe != NULL)
781 {
782 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
783
784 if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->set_registry.hci_handle))
785 {
786 nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle;
787
788 if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
789 {
790 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
791 return FALSE;
792 }
793
794 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
795 {
796 NFA_TRACE_WARNING1 ("nfa_hci_api_set_reg_value pipe:%d not open", p_evt_data->set_registry.pipe);
797 }
798 else
799 {
800 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)
801 return TRUE;
802 }
803 }
804 }
805 evt_data.cmd_sent.status = status;
806
807 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
808 nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->set_registry.hci_handle);
809 return TRUE;
810
811 }
812
813 /*******************************************************************************
814 **
815 ** Function nfa_hci_api_close_pipe
816 **
817 ** Description action function to close a pipe
818 **
819 ** Returns None
820 **
821 *******************************************************************************/
nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)822 static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
823 {
824 tNFA_HCI_EVT_DATA evt_data;
825 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->close_pipe.pipe);
826 tNFA_HCI_DYN_GATE *p_gate = NULL;
827
828 if (p_pipe != NULL)
829 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
830
831 if ( (p_pipe != NULL)
832 &&(p_gate != NULL)
833 &&(nfa_hciu_is_active_host (p_pipe->dest_host))
834 &&(p_gate->gate_owner == p_evt_data->close_pipe.hci_handle) )
835 {
836 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
837 {
838 nfa_hciu_send_close_pipe_cmd (p_evt_data->close_pipe.pipe);
839 }
840 else
841 {
842 evt_data.closed.status = NFA_STATUS_OK;
843 evt_data.closed.pipe = p_evt_data->close_pipe.pipe;
844
845 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
846 }
847 }
848 else
849 {
850 evt_data.closed.status = NFA_STATUS_FAILED;
851 evt_data.closed.pipe = 0x00;
852
853 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
854 }
855 }
856
857 /*******************************************************************************
858 **
859 ** Function nfa_hci_api_delete_pipe
860 **
861 ** Description action function to delete a pipe
862 **
863 ** Returns None
864 **
865 *******************************************************************************/
nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)866 static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
867 {
868 tNFA_HCI_EVT_DATA evt_data;
869 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->delete_pipe.pipe);
870 tNFA_HCI_DYN_GATE *p_gate = NULL;
871
872 if (p_pipe != NULL)
873 {
874 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
875 if ( (p_gate != NULL)
876 &&(p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle)
877 &&(nfa_hciu_is_active_host (p_pipe->dest_host)) )
878 {
879 nfa_hciu_send_delete_pipe_cmd (p_evt_data->delete_pipe.pipe);
880 return;
881 }
882 }
883
884 evt_data.deleted.status = NFA_STATUS_FAILED;
885 evt_data.deleted.pipe = 0x00;
886 nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
887 }
888
889 /*******************************************************************************
890 **
891 ** Function nfa_hci_api_send_cmd
892 **
893 ** Description action function to send command on the given pipe
894 **
895 ** Returns TRUE, if the command is processed
896 ** FALSE, if command is queued for processing later
897 **
898 *******************************************************************************/
nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA * p_evt_data)899 static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data)
900 {
901 tNFA_STATUS status = NFA_STATUS_FAILED;
902 tNFA_HCI_DYN_PIPE *p_pipe;
903 tNFA_HCI_EVT_DATA evt_data;
904 tNFA_HANDLE app_handle;
905
906 if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_cmd.pipe)) != NULL)
907 {
908 app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_cmd.pipe);
909
910 if ( (nfa_hciu_is_active_host (p_pipe->dest_host))
911 &&((app_handle == p_evt_data->send_cmd.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)) )
912 {
913 if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
914 {
915 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
916 return FALSE;
917 }
918
919 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
920 {
921 nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
922 if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE, p_evt_data->send_cmd.cmd_code,
923 p_evt_data->send_cmd.cmd_len, p_evt_data->send_cmd.data)) == NFA_STATUS_OK)
924 return TRUE;
925 }
926 else
927 {
928 NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not open", p_pipe->pipe_id);
929 }
930 }
931 else
932 {
933 NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d Owned by different application or Destination host is not active",
934 p_pipe->pipe_id);
935 }
936 }
937 else
938 {
939 NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not found", p_evt_data->send_cmd.pipe);
940 }
941
942 evt_data.cmd_sent.status = status;
943
944 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
945 nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->send_cmd.hci_handle);
946 return TRUE;
947 }
948
949 /*******************************************************************************
950 **
951 ** Function nfa_hci_api_send_rsp
952 **
953 ** Description action function to send response on the given pipe
954 **
955 ** Returns None
956 **
957 *******************************************************************************/
nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA * p_evt_data)958 static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data)
959 {
960 tNFA_STATUS status = NFA_STATUS_FAILED;
961 tNFA_HCI_DYN_PIPE *p_pipe;
962 tNFA_HCI_EVT_DATA evt_data;
963 tNFA_HANDLE app_handle;
964
965 if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_rsp.pipe)) != NULL)
966 {
967 app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_rsp.pipe);
968
969 if ( (nfa_hciu_is_active_host (p_pipe->dest_host))
970 &&((app_handle == p_evt_data->send_rsp.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)) )
971 {
972 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
973 {
974 if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, p_evt_data->send_rsp.response,
975 p_evt_data->send_rsp.size, p_evt_data->send_rsp.data)) == NFA_STATUS_OK)
976 return;
977 }
978 else
979 {
980 NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not open", p_pipe->pipe_id);
981 }
982 }
983 else
984 {
985 NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d Owned by different application or Destination host is not active",
986 p_pipe->pipe_id);
987 }
988 }
989 else
990 {
991 NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not found", p_evt_data->send_rsp.pipe);
992 }
993
994 evt_data.rsp_sent.status = status;
995
996 /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
997 nfa_hciu_send_to_app (NFA_HCI_RSP_SENT_EVT, &evt_data, p_evt_data->send_rsp.hci_handle);
998 }
999
1000 /*******************************************************************************
1001 **
1002 ** Function nfa_hci_api_send_event
1003 **
1004 ** Description action function to send an event to the given pipe
1005 **
1006 ** Returns TRUE, if the event is processed
1007 ** FALSE, if event is queued for processing later
1008 **
1009 *******************************************************************************/
nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA * p_evt_data)1010 static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data)
1011 {
1012 tNFA_STATUS status = NFA_STATUS_FAILED;
1013 tNFA_HCI_DYN_PIPE *p_pipe;
1014 tNFA_HCI_EVT_DATA evt_data;
1015 tNFA_HANDLE app_handle;
1016
1017 if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_evt.pipe)) != NULL)
1018 {
1019 app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_evt.pipe);
1020
1021 if ( (nfa_hciu_is_active_host (p_pipe->dest_host))
1022 &&((app_handle == p_evt_data->send_evt.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)) )
1023 {
1024 if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
1025 {
1026 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
1027 return FALSE;
1028 }
1029
1030 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
1031 {
1032 status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code,
1033 p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf);
1034
1035 if (status == NFA_STATUS_OK)
1036 {
1037 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
1038 {
1039 nfa_hci_cb.w4_rsp_evt = TRUE;
1040 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
1041 }
1042
1043 if (p_evt_data->send_evt.rsp_len)
1044 {
1045 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
1046 nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len;
1047 nfa_hci_cb.p_rsp_buf = p_evt_data->send_evt.p_rsp_buf;
1048 if (p_evt_data->send_evt.rsp_timeout)
1049 {
1050 nfa_hci_cb.w4_rsp_evt = TRUE;
1051 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
1052 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_evt_data->send_evt.rsp_timeout);
1053 }
1054 else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
1055 {
1056 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout);
1057 }
1058 }
1059 else
1060 {
1061 if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
1062 {
1063 nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
1064 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout);
1065 }
1066 nfa_hci_cb.rsp_buf_size = 0;
1067 nfa_hci_cb.p_rsp_buf = NULL;
1068 }
1069 }
1070 }
1071 else
1072 {
1073 NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not open", p_pipe->pipe_id);
1074 }
1075 }
1076 else
1077 {
1078 NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d Owned by different application or Destination host is not active",
1079 p_pipe->pipe_id);
1080 }
1081 }
1082 else
1083 {
1084 NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not found", p_evt_data->send_evt.pipe);
1085 }
1086
1087 evt_data.evt_sent.status = status;
1088
1089 /* Send NFC_HCI_EVENT_SENT_EVT to notify status */
1090 nfa_hciu_send_to_app (NFA_HCI_EVENT_SENT_EVT, &evt_data, p_evt_data->send_evt.hci_handle);
1091 return TRUE;
1092 }
1093
1094 /*******************************************************************************
1095 **
1096 ** Function nfa_hci_api_add_static_pipe
1097 **
1098 ** Description action function to add static pipe
1099 **
1100 ** Returns None
1101 **
1102 *******************************************************************************/
nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)1103 static void nfa_hci_api_add_static_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
1104 {
1105 tNFA_HCI_DYN_GATE *pg;
1106 tNFA_HCI_DYN_PIPE *pp;
1107 tNFA_HCI_EVT_DATA evt_data;
1108
1109 /* Allocate a proprietary gate */
1110 if ((pg = nfa_hciu_alloc_gate (p_evt_data->add_static_pipe.gate, p_evt_data->add_static_pipe.hci_handle)) != NULL)
1111 {
1112 /* Assign new owner to the gate */
1113 pg->gate_owner = p_evt_data->add_static_pipe.hci_handle;
1114
1115 /* Add the dynamic pipe to the proprietary gate */
1116 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)
1117 {
1118 /* Unable to add the dynamic pipe, so release the gate */
1119 nfa_hciu_release_gate (pg->gate_id);
1120 evt_data.pipe_added.status = NFA_STATUS_FAILED;
1121 nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
1122 return;
1123 }
1124 if ((pp = nfa_hciu_find_pipe_by_pid (p_evt_data->add_static_pipe.pipe)) != NULL)
1125 {
1126 /* This pipe is always opened */
1127 pp->pipe_state = NFA_HCI_PIPE_OPENED;
1128 evt_data.pipe_added.status = NFA_STATUS_OK;
1129 nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
1130 return;
1131 }
1132 }
1133 /* Unable to add static pipe */
1134 evt_data.pipe_added.status = NFA_STATUS_FAILED;
1135 nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
1136
1137 }
1138
1139 /*******************************************************************************
1140 **
1141 ** Function nfa_hci_handle_link_mgm_gate_cmd
1142 **
1143 ** Description This function handles incoming link management gate hci
1144 ** commands
1145 **
1146 ** Returns none
1147 **
1148 *******************************************************************************/
nfa_hci_handle_link_mgm_gate_cmd(UINT8 * p_data)1149 void nfa_hci_handle_link_mgm_gate_cmd (UINT8 *p_data)
1150 {
1151 UINT8 index;
1152 UINT8 data[2];
1153 UINT8 rsp_len = 0;
1154 UINT8 response = NFA_HCI_ANY_OK;
1155
1156 if ( (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED)
1157 &&(nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE) )
1158 {
1159 nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL);
1160 return;
1161 }
1162
1163 switch (nfa_hci_cb.inst)
1164 {
1165 case NFA_HCI_ANY_SET_PARAMETER:
1166 STREAM_TO_UINT8 (index, p_data);
1167
1168 if (index == 1)
1169 {
1170 STREAM_TO_UINT16 (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
1171 }
1172 else
1173 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
1174 break;
1175
1176 case NFA_HCI_ANY_GET_PARAMETER:
1177 STREAM_TO_UINT8 (index, p_data);
1178 if (index == 1)
1179 {
1180 data[0] = (UINT8) ((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF);
1181 data[1] = (UINT8) (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F);
1182 rsp_len = 2;
1183 }
1184 else
1185 response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
1186 break;
1187
1188 case NFA_HCI_ANY_OPEN_PIPE:
1189 data[0] = 0;
1190 rsp_len = 1;
1191 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED;
1192 break;
1193
1194 case NFA_HCI_ANY_CLOSE_PIPE:
1195 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1196 break;
1197
1198 default:
1199 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1200 break;
1201 }
1202
1203 nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
1204 }
1205
1206
1207
1208 /*******************************************************************************
1209 **
1210 ** Function nfa_hci_handle_pipe_open_close_cmd
1211 **
1212 ** Description This function handles all generic gates (excluding
1213 ** connectivity gate) commands
1214 **
1215 ** Returns none
1216 **
1217 *******************************************************************************/
nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE * p_pipe)1218 void nfa_hci_handle_pipe_open_close_cmd (tNFA_HCI_DYN_PIPE *p_pipe)
1219 {
1220 UINT8 data[1];
1221 UINT8 rsp_len = 0;
1222 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1223 tNFA_HCI_DYN_GATE *p_gate;
1224
1225 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE)
1226 {
1227 if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL)
1228 data[0] = nfa_hciu_count_open_pipes_on_gate (p_gate);
1229 else
1230 data[0] = 0;
1231
1232 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1233 rsp_len = 1;
1234 }
1235 else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE)
1236 {
1237 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1238 }
1239
1240 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
1241 }
1242
1243 /*******************************************************************************
1244 **
1245 ** Function nfa_hci_handle_admin_gate_cmd
1246 **
1247 ** Description This function handles incoming commands on ADMIN gate
1248 **
1249 ** Returns none
1250 **
1251 *******************************************************************************/
nfa_hci_handle_admin_gate_cmd(UINT8 * p_data)1252 void nfa_hci_handle_admin_gate_cmd (UINT8 *p_data)
1253 {
1254 UINT8 source_host, source_gate, dest_host, dest_gate, pipe;
1255 UINT8 data = 0;
1256 UINT8 rsp_len = 0;
1257 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1258 tNFA_HCI_DYN_GATE *pgate;
1259 tNFA_HCI_EVT_DATA evt_data;
1260
1261 switch (nfa_hci_cb.inst)
1262 {
1263 case NFA_HCI_ANY_OPEN_PIPE:
1264 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
1265 data = 0;
1266 rsp_len = 1;
1267 break;
1268
1269 case NFA_HCI_ANY_CLOSE_PIPE:
1270 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1271 /* Reopen the pipe immediately */
1272 nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
1273 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
1274 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
1275 return;
1276 break;
1277
1278 case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
1279 STREAM_TO_UINT8 (source_host, p_data);
1280 STREAM_TO_UINT8 (source_gate, p_data);
1281 STREAM_TO_UINT8 (dest_host, p_data);
1282 STREAM_TO_UINT8 (dest_gate, p_data);
1283 STREAM_TO_UINT8 (pipe, p_data);
1284
1285 if ( (dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
1286 ||(dest_gate == NFA_HCI_LOOP_BACK_GATE) )
1287 {
1288 response = nfa_hciu_add_pipe_to_static_gate (dest_gate, pipe, source_host, source_gate);
1289 }
1290 else
1291 {
1292 if ((pgate = nfa_hciu_find_gate_by_gid (dest_gate)) != NULL)
1293 {
1294 /* If the gate is valid, add the pipe to it */
1295 if (nfa_hciu_check_pipe_between_gates (dest_gate, source_host, source_gate))
1296 {
1297 /* Already, there is a pipe between these two gates, so will reject */
1298 response = NFA_HCI_ANY_E_NOK;
1299 }
1300 else if ((response = nfa_hciu_add_pipe_to_gate (pipe, dest_gate, source_host, source_gate)) == NFA_HCI_ANY_OK)
1301 {
1302 /* Tell the application a pipe was created with its gate */
1303
1304 evt_data.created.status = NFA_STATUS_OK;
1305 evt_data.created.pipe = pipe;
1306 evt_data.created.source_gate = dest_gate;
1307 evt_data.created.dest_host = source_host;
1308 evt_data.created.dest_gate = source_gate;
1309
1310 nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, pgate->gate_owner);
1311 }
1312 }
1313 else
1314 {
1315 response = NFA_HCI_ANY_E_NOK;
1316 if ((dest_gate >= NFA_HCI_FIRST_PROP_GATE) && (dest_gate <= NFA_HCI_LAST_PROP_GATE))
1317 {
1318 if (nfa_hciu_alloc_gate (dest_gate, 0))
1319 response = nfa_hciu_add_pipe_to_gate (pipe, dest_gate, source_host, source_gate);
1320 }
1321 }
1322 }
1323 break;
1324
1325 case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
1326 STREAM_TO_UINT8 (pipe, p_data);
1327 response = nfa_hciu_release_pipe (pipe);
1328 break;
1329
1330 case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
1331 STREAM_TO_UINT8 (source_host, p_data);
1332
1333 nfa_hciu_remove_all_pipes_from_host (source_host);
1334
1335 if (source_host == NFA_HCI_HOST_CONTROLLER)
1336 {
1337 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1338 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1339
1340 /* Reopen the admin pipe immediately */
1341 nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
1342 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
1343 return;
1344 }
1345 else
1346 {
1347 if ( (source_host >= NFA_HCI_HOST_ID_UICC0)
1348 &&(source_host < (NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)) )
1349 {
1350 nfa_hci_cb.reset_host[source_host - NFA_HCI_HOST_ID_UICC0] = source_host;
1351 }
1352 }
1353 break;
1354
1355 default:
1356 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1357 break;
1358 }
1359
1360 nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
1361 }
1362
1363 /*******************************************************************************
1364 **
1365 ** Function nfa_hci_handle_admin_gate_rsp
1366 **
1367 ** Description This function handles response received on admin gate
1368 **
1369 ** Returns none
1370 **
1371 *******************************************************************************/
nfa_hci_handle_admin_gate_rsp(UINT8 * p_data,UINT8 data_len)1372 void nfa_hci_handle_admin_gate_rsp (UINT8 *p_data, UINT8 data_len)
1373 {
1374 UINT8 source_host;
1375 UINT8 source_gate = nfa_hci_cb.local_gate_in_use;
1376 UINT8 dest_host = nfa_hci_cb.remote_host_in_use;
1377 UINT8 dest_gate = nfa_hci_cb.remote_gate_in_use;
1378 UINT8 pipe = 0;
1379 tNFA_STATUS status;
1380 tNFA_HCI_EVT_DATA evt_data;
1381 UINT8 default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1382 UINT8 host_count = 0;
1383 UINT8 host_id = 0;
1384 UINT32 os_tick;
1385
1386 #if (BT_TRACE_VERBOSE == TRUE)
1387 NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s App: 0x%04x Gate: 0x%02x Pipe: 0x%02x",
1388 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);
1389 #else
1390 NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp LastCmdSent: %u App: 0x%04x Gate: 0x%02x Pipe: 0x%02x",
1391 nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
1392 #endif
1393
1394 /* If starting up, handle events here */
1395 if ( (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
1396 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
1397 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)
1398 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE))
1399 {
1400 if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED)
1401 {
1402 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
1403 return;
1404 }
1405
1406 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK)
1407 {
1408 NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_rsp - Initialization failed");
1409 nfa_hci_startup_complete (NFA_STATUS_FAILED);
1410 return;
1411 }
1412
1413 switch (nfa_hci_cb.cmd_sent)
1414 {
1415 case NFA_HCI_ANY_SET_PARAMETER:
1416 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
1417 {
1418 /* Set WHITELIST */
1419 nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
1420 }
1421 else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX)
1422 {
1423 if ( (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
1424 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) )
1425 nfa_hci_dh_startup_complete ();
1426 }
1427 break;
1428
1429 case NFA_HCI_ANY_GET_PARAMETER:
1430 if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX)
1431 {
1432 host_count = 0;
1433 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)
1434 {
1435 nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count;
1436 host_count++;
1437 }
1438
1439 host_count = 0;
1440 /* Collect active host in the Host Network */
1441 while (host_count < data_len)
1442 {
1443 host_id = (UINT8) *p_data++;
1444
1445 if ( (host_id >= NFA_HCI_HOST_ID_UICC0)
1446 &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK) )
1447 {
1448 nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
1449 nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
1450 }
1451
1452 host_count++;
1453 }
1454 nfa_hci_startup_complete (NFA_STATUS_OK);
1455 }
1456 else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
1457 {
1458 /* The only parameter we get when initializing is the session ID. Check for match. */
1459 if (!memcmp ((UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, p_data, NFA_HCI_SESSION_ID_LEN) )
1460 {
1461 /* Session has not changed, Set WHITELIST */
1462 nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
1463 }
1464 else
1465 {
1466 /* Something wrong, NVRAM data could be corrupt or first start with default session id */
1467 nfa_hciu_send_clear_all_pipe_cmd ();
1468 nfa_hci_cb.b_hci_netwk_reset = TRUE;
1469 }
1470 }
1471 break;
1472
1473 case NFA_HCI_ANY_OPEN_PIPE:
1474 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
1475
1476 if (nfa_hci_cb.b_hci_netwk_reset)
1477 {
1478 nfa_hci_cb.b_hci_netwk_reset = FALSE;
1479 /* Session ID is reset, Set New session id */
1480 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));
1481 os_tick = GKI_get_os_tick_count ();
1482 memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
1483 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);
1484 }
1485 else
1486 {
1487 /* First thing is to get the session ID */
1488 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
1489 }
1490 break;
1491
1492 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1493 nfa_hciu_remove_all_pipes_from_host (0);
1494 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1495 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1496 nfa_hci_cb.nv_write_needed = TRUE;
1497
1498 /* Open admin */
1499 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
1500 break;
1501 }
1502 }
1503 else
1504 {
1505 status = (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
1506
1507 switch (nfa_hci_cb.cmd_sent)
1508 {
1509 case NFA_HCI_ANY_SET_PARAMETER:
1510 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1511 nfa_hci_api_deregister (NULL);
1512 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1513 nfa_hci_api_dealloc_gate (NULL);
1514 break;
1515
1516 case NFA_HCI_ANY_GET_PARAMETER:
1517 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
1518 {
1519 if (!memcmp ((UINT8 *) default_session, p_data , NFA_HCI_SESSION_ID_LEN))
1520 {
1521 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));
1522 os_tick = GKI_get_os_tick_count ();
1523 memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *) &os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
1524 nfa_hci_cb.nv_write_needed = TRUE;
1525 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);
1526 }
1527 else
1528 {
1529 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1530 nfa_hci_api_deregister (NULL);
1531 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1532 nfa_hci_api_dealloc_gate (NULL);
1533 }
1534 }
1535 else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX)
1536 {
1537 evt_data.hosts.status = status;
1538 evt_data.hosts.num_hosts = data_len;
1539 memcpy (evt_data.hosts.host, p_data, data_len);
1540
1541 host_count = 0;
1542 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)
1543 {
1544 nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count;
1545 host_count++;
1546 }
1547
1548 host_count = 0;
1549 /* Collect active host in the Host Network */
1550 while (host_count < data_len)
1551 {
1552 host_id = (UINT8) *p_data++;
1553
1554 if ( (host_id >= NFA_HCI_HOST_ID_UICC0)
1555 &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK) )
1556 {
1557 nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
1558 nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
1559 }
1560 host_count++;
1561 }
1562 if (nfa_hciu_is_no_host_resetting ())
1563 nfa_hci_check_pending_api_requests ();
1564 nfa_hciu_send_to_app (NFA_HCI_HOST_LIST_EVT, &evt_data, nfa_hci_cb.app_in_use);
1565 }
1566 break;
1567
1568 case NFA_HCI_ADM_CREATE_PIPE:
1569 if (status == NFA_STATUS_OK)
1570 {
1571 STREAM_TO_UINT8 (source_host, p_data);
1572 STREAM_TO_UINT8 (source_gate, p_data);
1573 STREAM_TO_UINT8 (dest_host, p_data);
1574 STREAM_TO_UINT8 (dest_gate, p_data);
1575 STREAM_TO_UINT8 (pipe, p_data);
1576
1577 /* Sanity check */
1578 if (source_gate != nfa_hci_cb.local_gate_in_use)
1579 {
1580 NFA_TRACE_WARNING2 ("nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u got back: %u",
1581 nfa_hci_cb.local_gate_in_use, source_gate);
1582 break;
1583 }
1584
1585 nfa_hciu_add_pipe_to_gate (pipe, source_gate, dest_host, dest_gate);
1586
1587 }
1588
1589 /* Tell the application his pipe was created or not */
1590 evt_data.created.status = status;
1591 evt_data.created.pipe = pipe;
1592 evt_data.created.source_gate = source_gate;
1593 evt_data.created.dest_host = dest_host;
1594 evt_data.created.dest_gate = dest_gate;
1595
1596 nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
1597 break;
1598
1599 case NFA_HCI_ADM_DELETE_PIPE:
1600 if (status == NFA_STATUS_OK)
1601 {
1602 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
1603
1604 /* If only deleting one pipe, tell the app we are done */
1605 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
1606 {
1607 evt_data.deleted.status = status;
1608 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1609
1610 nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
1611 }
1612 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1613 nfa_hci_api_deregister (NULL);
1614 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1615 nfa_hci_api_dealloc_gate (NULL);
1616 }
1617 else
1618 {
1619 /* If only deleting one pipe, tell the app we are done */
1620 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
1621 {
1622 evt_data.deleted.status = status;
1623 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1624
1625 nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
1626 }
1627 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1628 {
1629 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
1630 nfa_hci_api_deregister (NULL);
1631 }
1632 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1633 {
1634 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
1635 nfa_hci_api_dealloc_gate (NULL);
1636 }
1637 }
1638 break;
1639
1640 case NFA_HCI_ANY_OPEN_PIPE:
1641 nfa_hci_cb.cfg.admin_gate.pipe01_state = status ? NFA_HCI_PIPE_CLOSED:NFA_HCI_PIPE_OPENED;
1642 nfa_hci_cb.nv_write_needed = TRUE;
1643 if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED)
1644 {
1645 /* First thing is to get the session ID */
1646 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
1647 }
1648 break;
1649
1650 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1651 nfa_hciu_remove_all_pipes_from_host (0);
1652 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1653 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1654 nfa_hci_cb.nv_write_needed = TRUE;
1655 /* Open admin */
1656 nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
1657 break;
1658
1659 }
1660 }
1661 }
1662
1663 /*******************************************************************************
1664 **
1665 ** Function nfa_hci_handle_admin_gate_evt
1666 **
1667 ** Description This function handles events received on admin gate
1668 **
1669 ** Returns none
1670 **
1671 *******************************************************************************/
nfa_hci_handle_admin_gate_evt(UINT8 * p_data)1672 void nfa_hci_handle_admin_gate_evt (UINT8 *p_data)
1673 {
1674 tNFA_HCI_EVT_DATA evt_data;
1675 tNFA_HCI_API_GET_HOST_LIST *p_msg;
1676
1677 if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG)
1678 {
1679 NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
1680 return;
1681 }
1682
1683 NFA_TRACE_DEBUG0 ("nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe");
1684 nfa_hci_cb.num_hot_plug_evts++;
1685
1686 if ( (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)
1687 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE) )
1688 {
1689 /* Received Hot Plug evt while waiting for other Host in the network to bootup after DH host bootup is complete */
1690 if ( (nfa_hci_cb.ee_disable_disc)
1691 &&(nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))
1692 &&(nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1)) )
1693 {
1694 /* Received expected number of Hot Plug event(s) before as many number of EE DISC REQ Ntf(s) are received */
1695 nfa_sys_stop_timer (&nfa_hci_cb.timer);
1696 /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ Ntf(s) */
1697 nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hci_netwk_enable_timeout);
1698 }
1699 }
1700 else if ( (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
1701 ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) )
1702 {
1703 /* Received Hot Plug evt during DH host bootup */
1704 if ( (nfa_hci_cb.ee_disable_disc)
1705 &&(nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))
1706 &&(nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1)) )
1707 {
1708 /* Received expected number of Hot Plug event(s) before as many number of EE DISC REQ Ntf(s) are received */
1709 nfa_hci_cb.w4_hci_netwk_init = FALSE;
1710 }
1711 }
1712 else
1713 {
1714 /* Received Hot Plug evt on UICC self reset */
1715 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
1716 /* Notify all registered application with the HOT_PLUG_EVT */
1717 nfa_hciu_send_to_all_apps (NFA_HCI_EVENT_RCVD_EVT, &evt_data);
1718
1719 /* Send Get Host List after receiving any pending response */
1720 if ((p_msg = (tNFA_HCI_API_GET_HOST_LIST *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_HOST_LIST))) != NULL)
1721 {
1722 p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT;
1723 /* Set Invalid handle to identify this Get Host List command is internal */
1724 p_msg->hci_handle = NFA_HANDLE_INVALID;
1725
1726 nfa_sys_sendmsg (p_msg);
1727 }
1728 }
1729 }
1730
1731 /*******************************************************************************
1732 **
1733 ** Function nfa_hci_handle_dyn_pipe_pkt
1734 **
1735 ** Description This function handles data received via dynamic pipe
1736 **
1737 ** Returns none
1738 **
1739 *******************************************************************************/
nfa_hci_handle_dyn_pipe_pkt(UINT8 pipe_id,UINT8 * p_data,UINT16 data_len)1740 void nfa_hci_handle_dyn_pipe_pkt (UINT8 pipe_id, UINT8 *p_data, UINT16 data_len)
1741 {
1742 tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id);
1743 tNFA_HCI_DYN_GATE *p_gate;
1744
1745 if (p_pipe == NULL)
1746 {
1747 /* Invalid pipe ID */
1748 NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",pipe_id);
1749 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1750 nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL);
1751 return;
1752 }
1753
1754 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
1755 {
1756 nfa_hci_handle_identity_mgmt_gate_pkt (p_data, p_pipe);
1757 }
1758 else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
1759 {
1760 nfa_hci_handle_loopback_gate_pkt (p_data, data_len, p_pipe);
1761 }
1762 else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)
1763 {
1764 nfa_hci_handle_connectivity_gate_pkt (p_data, data_len, p_pipe);
1765 }
1766 else
1767 {
1768 p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
1769 if (p_gate == NULL)
1770 {
1771 NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",p_pipe->local_gate);
1772 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1773 nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL);
1774 return;
1775 }
1776
1777 /* Check if data packet is a command, response or event */
1778 switch (nfa_hci_cb.type)
1779 {
1780 case NFA_HCI_COMMAND_TYPE:
1781 nfa_hci_handle_generic_gate_cmd (p_data, (UINT8) data_len, p_gate, p_pipe);
1782 break;
1783
1784 case NFA_HCI_RESPONSE_TYPE:
1785 nfa_hci_handle_generic_gate_rsp (p_data, (UINT8) data_len, p_gate, p_pipe);
1786 break;
1787
1788 case NFA_HCI_EVENT_TYPE:
1789 nfa_hci_handle_generic_gate_evt (p_data, data_len, p_gate, p_pipe);
1790 break;
1791 }
1792 }
1793 }
1794
1795 /*******************************************************************************
1796 **
1797 ** Function nfa_hci_handle_identity_mgmt_gate_pkt
1798 **
1799 ** Description This function handles incoming Identity Management gate hci
1800 ** commands
1801 **
1802 ** Returns none
1803 **
1804 *******************************************************************************/
nfa_hci_handle_identity_mgmt_gate_pkt(UINT8 * p_data,tNFA_HCI_DYN_PIPE * p_pipe)1805 static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe)
1806 {
1807 UINT8 data[20];
1808 UINT8 index;
1809 UINT8 gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
1810 UINT16 rsp_len = 0;
1811 UINT8 *p_rsp = data;
1812 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1813
1814 /* We never send commands on a pipe where the local gate is the identity management
1815 * gate, so only commands should be processed.
1816 */
1817 if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE)
1818 return;
1819
1820 switch (nfa_hci_cb.inst)
1821 {
1822 case NFA_HCI_ANY_GET_PARAMETER:
1823 index = *(p_data++);
1824 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
1825 {
1826 switch (index)
1827 {
1828 case NFA_HCI_VERSION_SW_INDEX:
1829 data[0] = (UINT8) ((NFA_HCI_VERSION_SW >> 16 ) & 0xFF);
1830 data[1] = (UINT8) ((NFA_HCI_VERSION_SW >> 8 ) & 0xFF);
1831 data[2] = (UINT8) ((NFA_HCI_VERSION_SW ) & 0xFF);
1832 rsp_len = 3;
1833 break;
1834
1835 case NFA_HCI_HCI_VERSION_INDEX:
1836 data[0] = NFA_HCI_VERSION;
1837 rsp_len = 1;
1838 break;
1839
1840 case NFA_HCI_VERSION_HW_INDEX:
1841 data[0] = (UINT8) ((NFA_HCI_VERSION_HW >> 16 ) & 0xFF);
1842 data[1] = (UINT8) ((NFA_HCI_VERSION_HW >> 8 ) & 0xFF);
1843 data[2] = (UINT8) ((NFA_HCI_VERSION_HW ) & 0xFF);
1844 rsp_len = 3;
1845 break;
1846
1847 case NFA_HCI_VENDOR_NAME_INDEX:
1848 memcpy (data,NFA_HCI_VENDOR_NAME,strlen (NFA_HCI_VENDOR_NAME));
1849 rsp_len = (UINT8) strlen (NFA_HCI_VENDOR_NAME);
1850 break;
1851
1852 case NFA_HCI_MODEL_ID_INDEX:
1853 data[0] = NFA_HCI_MODEL_ID;
1854 rsp_len = 1;
1855 break;
1856
1857 case NFA_HCI_GATES_LIST_INDEX:
1858 gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
1859 gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
1860 gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
1861 num_gates = nfa_hciu_get_allocated_gate_list (&gate_rsp[3]);
1862 rsp_len = num_gates + 3;
1863 p_rsp = gate_rsp;
1864 break;
1865
1866 default:
1867 response = NFA_HCI_ANY_E_NOK;
1868 break;
1869 }
1870 }
1871 else
1872 {
1873 response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
1874 }
1875 break;
1876
1877 case NFA_HCI_ANY_OPEN_PIPE:
1878 data[0] = 0;
1879 rsp_len = 1;
1880 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1881 break;
1882
1883 case NFA_HCI_ANY_CLOSE_PIPE:
1884 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1885 break;
1886
1887 default:
1888 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1889 break;
1890 }
1891
1892 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, p_rsp);
1893 }
1894
1895 /*******************************************************************************
1896 **
1897 ** Function nfa_hci_handle_generic_gate_cmd
1898 **
1899 ** Description This function handles all generic gates (excluding
1900 ** connectivity gate) commands
1901 **
1902 ** Returns none
1903 **
1904 *******************************************************************************/
nfa_hci_handle_generic_gate_cmd(UINT8 * p_data,UINT8 data_len,tNFA_HCI_DYN_GATE * p_gate,tNFA_HCI_DYN_PIPE * p_pipe)1905 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)
1906 {
1907 tNFA_HCI_EVT_DATA evt_data;
1908 tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner (p_pipe->pipe_id);
1909
1910 switch (nfa_hci_cb.inst)
1911 {
1912 case NFA_HCI_ANY_SET_PARAMETER:
1913 evt_data.registry.pipe = p_pipe->pipe_id;
1914 evt_data.registry.index = *p_data++;
1915 if (data_len > 0)
1916 data_len--;
1917 evt_data.registry.data_len = data_len;
1918
1919 memcpy (evt_data.registry.reg_data, p_data, data_len);
1920
1921 nfa_hciu_send_to_app (NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
1922 break;
1923
1924 case NFA_HCI_ANY_GET_PARAMETER:
1925 evt_data.registry.pipe = p_pipe->pipe_id;
1926 evt_data.registry.index = *p_data;
1927 evt_data.registry.data_len = 0;
1928
1929 nfa_hciu_send_to_app (NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
1930 break;
1931
1932 case NFA_HCI_ANY_OPEN_PIPE:
1933 nfa_hci_handle_pipe_open_close_cmd (p_pipe);
1934
1935 evt_data.opened.pipe = p_pipe->pipe_id;
1936 evt_data.opened.status = NFA_STATUS_OK;
1937
1938 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
1939 break;
1940
1941 case NFA_HCI_ANY_CLOSE_PIPE:
1942 nfa_hci_handle_pipe_open_close_cmd (p_pipe);
1943
1944 evt_data.closed.pipe = p_pipe->pipe_id;
1945 evt_data.opened.status = NFA_STATUS_OK;
1946
1947 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
1948 break;
1949
1950 default:
1951 /* Could be application specific command, pass it on */
1952 evt_data.cmd_rcvd.status = NFA_STATUS_OK;
1953 evt_data.cmd_rcvd.pipe = p_pipe->pipe_id;;
1954 evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
1955 evt_data.cmd_rcvd.cmd_len = data_len;
1956
1957 if (data_len <= NFA_MAX_HCI_CMD_LEN)
1958 memcpy (evt_data.cmd_rcvd.cmd_data, p_data, data_len);
1959
1960 nfa_hciu_send_to_app (NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
1961 break;
1962 }
1963 }
1964
1965 /*******************************************************************************
1966 **
1967 ** Function nfa_hci_handle_generic_gate_rsp
1968 **
1969 ** Description This function handles all generic gates (excluding
1970 ** connectivity) response
1971 **
1972 ** Returns none
1973 **
1974 *******************************************************************************/
nfa_hci_handle_generic_gate_rsp(UINT8 * p_data,UINT8 data_len,tNFA_HCI_DYN_GATE * p_gate,tNFA_HCI_DYN_PIPE * p_pipe)1975 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)
1976 {
1977 tNFA_HCI_EVT_DATA evt_data;
1978 tNFA_STATUS status = NFA_STATUS_OK;
1979
1980 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK)
1981 status = NFA_STATUS_FAILED;
1982
1983 if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE)
1984 {
1985 if (status == NFA_STATUS_OK)
1986 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1987
1988 nfa_hci_cb.nv_write_needed = TRUE;
1989 /* Tell application */
1990 evt_data.opened.status = status;
1991 evt_data.opened.pipe = p_pipe->pipe_id;
1992
1993 nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
1994 }
1995 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
1996 {
1997 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1998
1999 nfa_hci_cb.nv_write_needed = TRUE;
2000 /* Tell application */
2001 evt_data.opened.status = status;;
2002 evt_data.opened.pipe = p_pipe->pipe_id;
2003
2004 nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
2005 }
2006 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER)
2007 {
2008 /* Tell application */
2009 evt_data.registry.status = status;
2010 evt_data.registry.pipe = p_pipe->pipe_id;
2011 evt_data.registry.data_len = data_len;
2012 evt_data.registry.index = nfa_hci_cb.param_in_use;
2013
2014 memcpy (evt_data.registry.reg_data, p_data, data_len);
2015
2016 nfa_hciu_send_to_app (NFA_HCI_GET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
2017 }
2018 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER)
2019 {
2020 /* Tell application */
2021 evt_data.registry.status = status;;
2022 evt_data.registry.pipe = p_pipe->pipe_id;
2023
2024 nfa_hciu_send_to_app (NFA_HCI_SET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
2025 }
2026 else
2027 {
2028 /* Could be a response to application specific command sent, pass it on */
2029 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2030 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;;
2031 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2032 evt_data.rsp_rcvd.rsp_len = data_len;
2033
2034 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2035 memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2036
2037 nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
2038 }
2039
2040 }
2041
2042 /*******************************************************************************
2043 **
2044 ** Function nfa_hci_handle_connectivity_gate_pkt
2045 **
2046 ** Description This function handles incoming connectivity gate packets
2047 **
2048 ** Returns none
2049 **
2050 *******************************************************************************/
nfa_hci_handle_connectivity_gate_pkt(UINT8 * p_data,UINT16 data_len,tNFA_HCI_DYN_PIPE * p_pipe)2051 static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
2052 {
2053 tNFA_HCI_EVT_DATA evt_data;
2054
2055 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
2056 {
2057 switch (nfa_hci_cb.inst)
2058 {
2059 case NFA_HCI_ANY_OPEN_PIPE:
2060 case NFA_HCI_ANY_CLOSE_PIPE:
2061 nfa_hci_handle_pipe_open_close_cmd (p_pipe);
2062 break;
2063
2064 case NFA_HCI_CON_PRO_HOST_REQUEST:
2065 /* A request to the DH to activate another host. This is not supported for */
2066 /* now, we will implement it when the spec is clearer and UICCs need it. */
2067 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
2068 break;
2069
2070 default:
2071 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
2072 break;
2073 }
2074 }
2075 else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
2076 {
2077 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2078 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2079 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2080 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2081
2082 /* Could be a response to application specific command sent, pass it on */
2083 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2084 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;;
2085 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2086 evt_data.rsp_rcvd.rsp_len = data_len;
2087
2088 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2089 memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2090
2091 nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
2092 }
2093 else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
2094 {
2095 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2096 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2097 evt_data.rcvd_evt.evt_len = data_len;
2098 evt_data.rcvd_evt.p_evt_buf = p_data;
2099
2100 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2101 nfa_hciu_send_to_apps_handling_connectivity_evts (NFA_HCI_EVENT_RCVD_EVT, &evt_data);
2102 }
2103 }
2104
2105 /*******************************************************************************
2106 **
2107 ** Function nfa_hci_handle_loopback_gate_pkt
2108 **
2109 ** Description This function handles incoming loopback gate hci events
2110 **
2111 ** Returns none
2112 **
2113 *******************************************************************************/
nfa_hci_handle_loopback_gate_pkt(UINT8 * p_data,UINT16 data_len,tNFA_HCI_DYN_PIPE * p_pipe)2114 static void nfa_hci_handle_loopback_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
2115 {
2116 UINT8 data[1];
2117 UINT8 rsp_len = 0;
2118 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
2119 tNFA_HCI_EVT_DATA evt_data;
2120
2121 /* Check if data packet is a command, response or event */
2122 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
2123 {
2124 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE)
2125 {
2126 data[0] = 0;
2127 rsp_len = 1;
2128 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2129 }
2130 else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE)
2131 {
2132 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2133 }
2134 else
2135 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
2136
2137 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
2138 }
2139 else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
2140 {
2141 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2142 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2143 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2144 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2145
2146 /* Could be a response to application specific command sent, pass it on */
2147 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2148 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;;
2149 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2150 evt_data.rsp_rcvd.rsp_len = data_len;
2151
2152 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2153 memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2154
2155 nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
2156 }
2157 else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
2158 {
2159 if (nfa_hci_cb.w4_rsp_evt)
2160 {
2161 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2162 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2163 evt_data.rcvd_evt.evt_len = data_len;
2164 evt_data.rcvd_evt.p_evt_buf = p_data;
2165
2166 nfa_hciu_send_to_app (NFA_HCI_EVENT_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
2167 }
2168 else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA)
2169 {
2170 /* Send back the same data we got */
2171 nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, NFA_HCI_EVT_POST_DATA, data_len, p_data);
2172 }
2173 }
2174 }
2175
2176 /*******************************************************************************
2177 **
2178 ** Function nfa_hci_handle_generic_gate_evt
2179 **
2180 ** Description This function handles incoming Generic gate hci events
2181 **
2182 ** Returns none
2183 **
2184 *******************************************************************************/
nfa_hci_handle_generic_gate_evt(UINT8 * p_data,UINT16 data_len,tNFA_HCI_DYN_GATE * p_gate,tNFA_HCI_DYN_PIPE * p_pipe)2185 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)
2186 {
2187 tNFA_HCI_EVT_DATA evt_data;
2188
2189 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2190 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2191 evt_data.rcvd_evt.evt_len = data_len;
2192
2193 if (nfa_hci_cb.assembly_failed)
2194 evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL;
2195 else
2196 evt_data.rcvd_evt.status = NFA_STATUS_OK;
2197
2198 evt_data.rcvd_evt.p_evt_buf = p_data;
2199 nfa_hci_cb.rsp_buf_size = 0;
2200 nfa_hci_cb.p_rsp_buf = NULL;
2201
2202 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2203 nfa_hciu_send_to_app (NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
2204 }
2205
2206