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