nfa_hci_api.c revision 993437a401849447dfaabc2edf53e682e056a5a4
1/*****************************************************************************
2**
3**  Name:           nfa_hci_api.c
4**
5**  Description:    NFA interface to HCI
6**
7**  Copyright (c) 2010, Broadcom Corp., All Rights Reserved.
8**  Broadcom Bluetooth Core. Proprietary and confidential.
9**
10*****************************************************************************/
11#include <string.h>
12#include "nfc_api.h"
13#include "nfa_sys.h"
14#include "nfa_sys_int.h"
15#include "nfa_hci_api.h"
16#include "nfa_hci_int.h"
17#include "nfa_hci_defs.h"
18
19/*******************************************************************************
20**
21** Function         NFA_HciRegister
22**
23** Description      This function will register an application with hci and
24**                  returns an application handle and provides a mechanism to
25**                  register a callback with HCI to receive NFA HCI event notification.
26**                  When the application is registered (or if an error occurs),
27**                  the app will be notified with NFA_HCI_REGISTER_EVT. Previous
28**                  session information including allocated gates, created pipes
29**                  and pipes states will be returned as part of tNFA_HCI_REGISTER data.
30**
31** Returns          NFA_STATUS_OK if successfully initiated
32**                  NFA_STATUS_FAILED otherwise
33**
34*******************************************************************************/
35tNFA_STATUS NFA_HciRegister (char *p_app_name, tNFA_HCI_CBACK *p_cback, BOOLEAN b_send_conn_evts)
36{
37    tNFA_HCI_API_REGISTER_APP *p_msg;
38    UINT8                     app_name_len;
39
40    if (p_app_name == NULL)
41    {
42        NFA_TRACE_API0 ("NFA_HciRegister (): Invalid Application name");
43        return (NFA_STATUS_FAILED);
44    }
45
46    if (p_cback == NULL)
47    {
48        NFA_TRACE_API0 ("NFA_HciRegister (): Application should provide callback function to register!");
49        return (NFA_STATUS_FAILED);
50    }
51
52    NFA_TRACE_API1 ("NFA_HciRegister (): Application Name: %s", p_app_name);
53
54    app_name_len = (UINT8) strlen (p_app_name);
55
56    /* Register the application with HCI */
57    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
58        &&(p_app_name != NULL)
59        &&(app_name_len <= NFA_MAX_HCI_APP_NAME_LEN)
60        &&((p_msg = (tNFA_HCI_API_REGISTER_APP *) GKI_getbuf (sizeof (tNFA_HCI_API_REGISTER_APP))) != NULL))
61    {
62        p_msg->hdr.event  = NFA_HCI_API_REGISTER_APP_EVT;
63
64        /* Save application name and callback */
65        memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
66        BCM_STRNCPY_S (p_msg->app_name, sizeof (p_msg->app_name), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
67        p_msg->p_cback          = p_cback;
68        p_msg->b_send_conn_evts = b_send_conn_evts;
69
70        nfa_sys_sendmsg (p_msg);
71        return (NFA_STATUS_OK);
72    }
73
74    return (NFA_STATUS_FAILED);
75}
76
77/*******************************************************************************
78**
79** Function         NFA_HciGetGateAndPipeList
80**
81** Description      This function will get the list of gates allocated to the
82**                  application and list of dynamic pipes created by the
83**                  application. The app will be notified with
84**                  NFA_HCI_GET_GATE_PIPE_LIST_EVT. List of allocated dynamic
85**                  gates to the application and list of pipes created by the
86**                  application will be returned as part of
87**                  tNFA_HCI_GET_GATE_PIPE_LIST data.
88**
89** Returns          NFA_STATUS_OK if successfully initiated
90**                  NFA_STATUS_FAILED otherwise
91**
92*******************************************************************************/
93tNFA_STATUS NFA_HciGetGateAndPipeList (tNFA_HANDLE hci_handle)
94{
95    tNFA_HCI_API_GET_APP_GATE_PIPE *p_msg;
96
97    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
98    {
99        NFA_TRACE_API1 ("NFA_HciGetGateAndPipeList (): Invalid hci_handle:0x%04x", hci_handle);
100        return (NFA_STATUS_FAILED);
101    }
102
103    NFA_TRACE_API1 ("NFA_HciGetGateAndPipeList (): hci_handle:0x%04x", hci_handle);
104
105    /* Register the application with HCI */
106    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
107        &&((p_msg = (tNFA_HCI_API_GET_APP_GATE_PIPE *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_APP_GATE_PIPE))) != NULL))
108    {
109        p_msg->hdr.event  = NFA_HCI_API_GET_APP_GATE_PIPE_EVT;
110        p_msg->hci_handle = hci_handle;
111
112        nfa_sys_sendmsg (p_msg);
113        return (NFA_STATUS_OK);
114    }
115
116    return (NFA_STATUS_FAILED);
117}
118
119/*******************************************************************************
120**
121** Function         NFA_HciDeregister
122**
123** Description      This function is called to deregister an application
124**                  from HCI. The app will be notified by NFA_HCI_DEREGISTER_EVT
125**                  after deleting all the pipes owned by the app and deallocating
126**                  all the gates allocated to the app or if an error occurs.
127**                  Even if deregistration fails, the app has to register again
128**                  to provide a new cback function.
129**
130** Returns          NFA_STATUS_OK if the application is deregistered successfully
131**                  NFA_STATUS_FAILED otherwise
132
133*******************************************************************************/
134tNFA_STATUS NFA_HciDeregister (char *p_app_name)
135{
136    tNFA_HCI_API_DEREGISTER_APP *p_msg;
137    int                         xx;
138    UINT8                       app_name_len;
139
140    if (p_app_name == NULL)
141    {
142        NFA_TRACE_API0 ("NFA_HciDeregister (): Invalid Application");
143        return (NFA_STATUS_FAILED);
144    }
145
146    NFA_TRACE_API1 ("NFA_HciDeregister (): Application Name: %s", p_app_name);
147    app_name_len = (UINT8) strlen (p_app_name);
148
149    if (app_name_len > NFA_MAX_HCI_APP_NAME_LEN)
150        return (NFA_STATUS_FAILED);
151
152    /* Find the application registration */
153    for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
154    {
155        if (  (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
156            &&(!strncmp (p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], app_name_len)) )
157            break;
158    }
159
160    if (xx == NFA_HCI_MAX_APP_CB)
161    {
162        NFA_TRACE_ERROR1 ("NFA_HciDeregister (): Application Name: %s  NOT FOUND", p_app_name);
163        return (NFA_STATUS_FAILED);
164    }
165
166    /* Deregister the application with HCI */
167    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
168        &&((p_msg = (tNFA_HCI_API_DEREGISTER_APP *) GKI_getbuf (sizeof (tNFA_HCI_API_DEREGISTER_APP))) != NULL) )
169    {
170        p_msg->hdr.event  = NFA_HCI_API_DEREGISTER_APP_EVT;
171
172        memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
173        BCM_STRNCPY_S (p_msg->app_name, sizeof (p_msg->app_name), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
174
175        nfa_sys_sendmsg (p_msg);
176        return (NFA_STATUS_OK);
177    }
178
179    return (NFA_STATUS_FAILED);
180}
181
182/*******************************************************************************
183**
184** Function         NFA_HciAllocGate
185**
186** Description      This function will allocate an available generic gate for
187**                  the app to provide an entry point for a particular service
188**                  to other host or to establish communication with other host.
189**                  When the generic gate is allocated (or if an error occurs),
190**                  the app will be notified with NFA_HCI_ALLOCATE_GATE_EVT with
191**                  the gate id. The allocated Gate information will be stored in
192**                  non volatile memory.
193**
194** Returns          NFA_STATUS_OK if this API started
195**                  NFA_STATUS_FAILED if no generic gate is available
196**
197*******************************************************************************/
198tNFA_STATUS NFA_HciAllocGate (tNFA_HANDLE hci_handle)
199{
200    tNFA_HCI_API_ALLOC_GATE *p_msg;
201
202    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
203    {
204        NFA_TRACE_API1 ("NFA_HciAllocGate (): Invalid hci_handle:0x%04x", hci_handle);
205        return (NFA_STATUS_FAILED);
206    }
207
208    NFA_TRACE_API1 ("NFA_HciAllocGate (): hci_handle:0x%04x", hci_handle);
209
210    /* Request HCI to allocate a gate to the application */
211    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
212        &&((p_msg = (tNFA_HCI_API_ALLOC_GATE *) GKI_getbuf (sizeof (tNFA_HCI_API_ALLOC_GATE))) != NULL) )
213    {
214        p_msg->hdr.event  = NFA_HCI_API_ALLOC_GATE_EVT;
215        p_msg->hci_handle = hci_handle;
216
217        nfa_sys_sendmsg (p_msg);
218        return (NFA_STATUS_OK);
219    }
220    return (NFA_STATUS_FAILED);
221}
222
223/*******************************************************************************
224**
225** Function         NFA_HciDeallocGate
226**
227** Description      This function will release the specified gate that was
228**                  previously allocated to the application. When the generic
229**                  gate is released (or if an error occurs), the app will be
230**                  notified with NFA_HCI_DEALLOCATE_GATE_EVT with the gate id.
231**
232** Returns          NFA_STATUS_OK if successfully initiated
233**                  NFA_STATUS_FAILED otherwise
234**
235*******************************************************************************/
236tNFA_STATUS NFA_HciDeallocGate (tNFA_HANDLE hci_handle, UINT8 gate)
237{
238    tNFA_HCI_API_DEALLOC_GATE *p_msg;
239
240    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
241    {
242        NFA_TRACE_API1 ("NFA_HciDeallocGate (): Invalid hci_handle:0x%04x", hci_handle);
243        return (NFA_STATUS_FAILED);
244    }
245
246    if ((gate < NFA_HCI_FIRST_DYNAMIC_GATE) || (gate > NFA_HCI_LAST_DYNAMIC_GATE) || (gate == NFA_HCI_CONNECTIVITY_GATE))
247    {
248        NFA_TRACE_API1 ("NFA_HciDeallocGate (): Cannot deallocate the gate:0x%02x", gate);
249        return (NFA_STATUS_FAILED);
250    }
251
252    NFA_TRACE_API2 ("NFA_HciDeallocGate (): hci_handle:0x%04x, gate:0x%02X", hci_handle, gate);
253
254    /* Request HCI to deallocate the gate that was previously allocated to the application */
255    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
256        &&((p_msg = (tNFA_HCI_API_DEALLOC_GATE *) GKI_getbuf (sizeof (tNFA_HCI_API_DEALLOC_GATE))) != NULL) )
257    {
258        p_msg->hdr.event  = NFA_HCI_API_DEALLOC_GATE_EVT;
259        p_msg->hci_handle = hci_handle;
260        p_msg->gate       = gate;
261
262        nfa_sys_sendmsg (p_msg);
263        return (NFA_STATUS_OK);
264    }
265    return (NFA_STATUS_FAILED);
266}
267
268/*******************************************************************************
269**
270** Function         NFA_HciGetHostList
271**
272** Description      This function will request the host controller to return the
273**                  list of hosts that are present in the host network. When
274**                  host controller responds with the host list (or if an error
275**                  occurs), the app will be notified with NFA_HCI_HOST_LIST_EVT
276**
277** Returns          NFA_STATUS_OK if successfully initiated
278**                  NFA_STATUS_FAILED otherwise
279**
280*******************************************************************************/
281tNFA_STATUS NFA_HciGetHostList (tNFA_HANDLE hci_handle)
282{
283    tNFA_HCI_API_GET_HOST_LIST *p_msg;
284
285
286    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
287    {
288        NFA_TRACE_API1 ("NFA_HciGetHostList (): Invalid hci_handle:0x%04x", hci_handle);
289        return (NFA_STATUS_FAILED);
290    }
291
292    NFA_TRACE_API1 ("NFA_HciGetHostList (): hci_handle:0x%04x",hci_handle);
293
294    /* Request HCI to get list of host in the hci network */
295    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
296        &&((p_msg = (tNFA_HCI_API_GET_HOST_LIST *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_HOST_LIST))) != NULL) )
297    {
298        p_msg->hdr.event    = NFA_HCI_API_GET_HOST_LIST_EVT;
299        p_msg->hci_handle   = hci_handle;
300
301        nfa_sys_sendmsg (p_msg);
302        return (NFA_STATUS_OK);
303    }
304
305    return (NFA_STATUS_FAILED);
306}
307
308/*******************************************************************************
309**
310** Function         NFA_HciCreatePipe
311**
312** Description      This function is called to create a dynamic pipe with the
313**                  specified host. When the dynamic pipe is created (or
314**                  if an error occurs), the app will be notified with
315**                  NFA_HCI_CREATE_PIPE_EVT with the pipe id. If a pipe exists
316**                  between the two gates passed as argument and if it was
317**                  created earlier by the calling application then the pipe
318**                  id of the existing pipe will be returned and a new pipe
319**                  will not be created. After successful creation of pipe,
320**                  registry entry will be created for the dynamic pipe and
321**                  all information related to the pipe will be stored in non
322**                  volatile memory.
323**
324** Returns          NFA_STATUS_OK if successfully initiated
325**                  NFA_STATUS_FAILED otherwise
326**
327*******************************************************************************/
328tNFA_STATUS NFA_HciCreatePipe (tNFA_HANDLE  hci_handle,
329                               UINT8        source_gate_id,
330                               UINT8        dest_host,
331                               UINT8        dest_gate)
332{
333    tNFA_HCI_API_CREATE_PIPE_EVT *p_msg;
334    UINT8                        xx;
335
336    NFA_TRACE_API4 ("NFA_HciCreatePipe (): hci_handle:0x%04x, source gate:0x%02X, destination host:0x%02X , destination gate:0x%02X",
337                                         hci_handle, source_gate_id, dest_host, dest_gate);
338
339    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
340    {
341        NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid hci_handle:0x%04x", hci_handle);
342        return (NFA_STATUS_FAILED);
343    }
344
345    if ((source_gate_id < NFA_HCI_FIRST_DYNAMIC_GATE) || (source_gate_id > NFA_HCI_LAST_DYNAMIC_GATE))
346    {
347        NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid local Gate:0x%02x", source_gate_id);
348        return (NFA_STATUS_FAILED);
349    }
350
351    if (  ((dest_gate < NFA_HCI_FIRST_DYNAMIC_GATE) && (dest_gate != NFA_HCI_LOOP_BACK_GATE) && (dest_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE))
352        ||(dest_gate > NFA_HCI_LAST_DYNAMIC_GATE))
353    {
354        NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid Destination Gate:0x%02x", dest_gate);
355        return (NFA_STATUS_FAILED);
356    }
357
358    for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
359        if (nfa_hci_cb.inactive_host[xx] == dest_host)
360            break;
361
362    if (xx != NFA_HCI_MAX_HOST_IN_NETWORK)
363    {
364        NFA_TRACE_API1 ("NFA_HciCreatePipe (): Host not active:0x%02x", dest_host);
365        return (NFA_STATUS_FAILED);
366    }
367
368    /* Request HCI to create a pipe between two specified gates */
369    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
370        &&(!nfa_hci_cb.b_low_power_mode)
371        &&((p_msg = (tNFA_HCI_API_CREATE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_CREATE_PIPE_EVT))) != NULL) )
372    {
373        p_msg->hdr.event    = NFA_HCI_API_CREATE_PIPE_EVT;
374        p_msg->hci_handle   = hci_handle;
375        p_msg->source_gate  = source_gate_id;
376        p_msg->dest_host    = dest_host;        /* Host id of the destination host */
377        p_msg->dest_gate    = dest_gate;        /* Gate id of the destination gate */
378
379        nfa_sys_sendmsg (p_msg);
380        return (NFA_STATUS_OK);
381    }
382    return (NFA_STATUS_FAILED);
383}
384
385/*******************************************************************************
386**
387** Function         NFA_HciOpenPipe
388**
389** Description      This function is called to open a dynamic pipe.
390**                  When the dynamic pipe is opened (or
391**                  if an error occurs), the app will be notified with
392**                  NFA_HCI_OPEN_PIPE_EVT with the pipe id.
393**
394** Returns          NFA_STATUS_OK if successfully initiated
395**                  NFA_STATUS_FAILED otherwise
396**
397*******************************************************************************/
398tNFA_STATUS NFA_HciOpenPipe (tNFA_HANDLE hci_handle, UINT8 pipe)
399{
400    tNFA_HCI_API_OPEN_PIPE_EVT *p_msg;
401
402    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
403    {
404        NFA_TRACE_API1 ("NFA_HciOpenPipe (): Invalid hci_handle:0x%04x", hci_handle);
405        return (NFA_STATUS_FAILED);
406    }
407
408    if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
409    {
410        NFA_TRACE_API1 ("NFA_HciOpenPipe (): Invalid Pipe:0x%02x", pipe);
411        return (NFA_STATUS_FAILED);
412    }
413
414
415    NFA_TRACE_API2 ("NFA_HciOpenPipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
416
417    /* Request HCI to open a pipe if it is in closed state */
418    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
419        &&(!nfa_hci_cb.b_low_power_mode)
420        &&((p_msg = (tNFA_HCI_API_OPEN_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_OPEN_PIPE_EVT))) != NULL) )
421    {
422        p_msg->hdr.event    = NFA_HCI_API_OPEN_PIPE_EVT;
423        p_msg->hci_handle   = hci_handle;
424        p_msg->pipe         = pipe;                     /* Pipe ID of the pipe to open */
425
426        nfa_sys_sendmsg (p_msg);
427        return (NFA_STATUS_OK);
428    }
429    return (NFA_STATUS_FAILED);
430}
431
432/*******************************************************************************
433**
434** Function         NFA_HciGetRegistry
435**
436** Description      This function requests a peer host to return the desired
437**                  registry field value for the gate that the pipe is on.
438**
439**                  When the peer host responds,the app is notified with
440**                  NFA_HCI_GET_REG_RSP_EVT or
441**                  if an error occurs in sending the command the app will be
442**                  notified by NFA_HCI_CMD_SENT_EVT
443**
444** Returns          NFA_STATUS_OK if successfully initiated
445**                  NFA_STATUS_FAILED otherwise
446**
447*******************************************************************************/
448tNFA_STATUS NFA_HciGetRegistry (tNFA_HANDLE hci_handle, UINT8 pipe, UINT8 reg_inx)
449{
450    tNFA_HCI_API_GET_REGISTRY *p_msg;
451
452    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
453    {
454        NFA_TRACE_API1 ("NFA_HciGetRegistry (): Invalid hci_handle:0x%04x", hci_handle);
455        return (NFA_STATUS_FAILED);
456    }
457
458    if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
459    {
460        NFA_TRACE_API1 ("NFA_HciGetRegistry (): Invalid Pipe:0x%02x", pipe);
461        return (NFA_STATUS_FAILED);
462    }
463
464    NFA_TRACE_API2 ("NFA_HciGetRegistry (): hci_handle:0x%04x  Pipe: 0x%02x", hci_handle, pipe);
465
466    /* Request HCI to get list of gates supported by the specified host */
467    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
468        &&((p_msg = (tNFA_HCI_API_GET_REGISTRY *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_REGISTRY))) != NULL) )
469    {
470        p_msg->hdr.event    = NFA_HCI_API_GET_REGISTRY_EVT;
471        p_msg->hci_handle   = hci_handle;
472        p_msg->pipe         = pipe;
473        p_msg->reg_inx      = reg_inx;
474
475        nfa_sys_sendmsg (p_msg);
476        return (NFA_STATUS_OK);
477    }
478
479    return (NFA_STATUS_FAILED);
480}
481
482/*******************************************************************************
483**
484** Function         NFA_HciSetRegistry
485**
486** Description      This function requests a peer host to set the desired
487**                  registry field value for the gate that the pipe is on.
488**
489**                  When the peer host responds,the app is notified with
490**                  NFA_HCI_SET_REG_RSP_EVT or
491**                  if an error occurs in sending the command the app will be
492**                  notified by NFA_HCI_CMD_SENT_EVT
493**
494** Returns          NFA_STATUS_OK if successfully initiated
495**                  NFA_STATUS_FAILED otherwise
496**
497*******************************************************************************/
498NFC_API extern tNFA_STATUS NFA_HciSetRegistry (tNFA_HANDLE   hci_handle,
499                                               UINT8         pipe,
500                                               UINT8         reg_inx,
501                                               UINT8         data_size,
502                                               UINT8         *p_data)
503{
504    tNFA_HCI_API_SET_REGISTRY *p_msg;
505
506
507    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
508    {
509        NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid hci_handle:0x%04x", hci_handle);
510        return (NFA_STATUS_FAILED);
511    }
512
513    if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
514    {
515        NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid Pipe:0x%02x", pipe);
516        return (NFA_STATUS_FAILED);
517    }
518
519    if ((data_size == 0) || (p_data == NULL) || (data_size > NFA_MAX_HCI_CMD_LEN))
520    {
521        NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid data size:0x%02x", data_size);
522        return (NFA_STATUS_FAILED);
523    }
524
525    NFA_TRACE_API2 ("NFA_HciSetRegistry (): hci_handle:0x%04x  Pipe: 0x%02x", hci_handle, pipe);
526
527    /* Request HCI to get list of gates supported by the specified host */
528    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
529        &&((p_msg = (tNFA_HCI_API_SET_REGISTRY *) GKI_getbuf (sizeof (tNFA_HCI_API_SET_REGISTRY))) != NULL) )
530    {
531        p_msg->hdr.event    = NFA_HCI_API_SET_REGISTRY_EVT;
532        p_msg->hci_handle   = hci_handle;
533        p_msg->pipe         = pipe;
534        p_msg->reg_inx      = reg_inx;
535        p_msg->size         = data_size;
536
537        memcpy (p_msg->data, p_data, data_size);
538        nfa_sys_sendmsg (p_msg);
539        return (NFA_STATUS_OK);
540    }
541
542    return (NFA_STATUS_FAILED);
543}
544
545/*******************************************************************************
546**
547** Function         NFA_HciSendCommand
548**
549** Description      This function is called to send a command on a pipe created
550**                  by the application.
551**                  The app will be notified by NFA_HCI_CMD_SENT_EVT if an error
552**                  occurs.
553**                  When the peer host responds,the app is notified with
554**                  NFA_HCI_RSP_RCVD_EVT
555**
556** Returns          NFA_STATUS_OK if successfully initiated
557**                  NFA_STATUS_FAILED otherwise
558**
559*******************************************************************************/
560tNFA_STATUS NFA_HciSendCommand (tNFA_HANDLE  hci_handle,
561                              UINT8        pipe,
562                              UINT8        cmd_code,
563                              UINT16       cmd_size,
564                              UINT8        *p_data)
565{
566    tNFA_HCI_API_SEND_CMD_EVT *p_msg;
567
568    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
569    {
570        NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid hci_handle:0x%04x", hci_handle);
571        return (NFA_STATUS_FAILED);
572    }
573
574    if ((cmd_size && (p_data == NULL)) || (cmd_size > NFA_MAX_HCI_CMD_LEN))
575    {
576        NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid cmd size:0x%02x", cmd_size);
577        return (NFA_STATUS_FAILED);
578    }
579
580    NFA_TRACE_API3 ("NFA_HciSendCommand (): hci_handle:0x%04x, pipe:0x%02x  Code: %0x%02x", hci_handle, pipe, cmd_code);
581
582    /* Request HCI to post event data on a particular pipe */
583    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
584        &&((p_msg = (tNFA_HCI_API_SEND_CMD_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_CMD_EVT))) != NULL) )
585    {
586        p_msg->hdr.event    = NFA_HCI_API_SEND_CMD_EVT;
587        p_msg->hci_handle   = hci_handle;
588        p_msg->pipe         = pipe;
589        p_msg->cmd_code     = cmd_code;
590        p_msg->cmd_len      = cmd_size;
591
592        if (cmd_size)
593            memcpy (p_msg->data, p_data, cmd_size);
594
595        nfa_sys_sendmsg (p_msg);
596        return (NFA_STATUS_OK);
597    }
598
599    return (NFA_STATUS_FAILED);
600}
601
602/*******************************************************************************
603**
604** Function         NFA_HciSendResponse
605**
606** Description      This function is called to send a response on a pipe created
607**                  by the application.
608**                  The app will be notified by NFA_HCI_RSP_SENT_EVT if an error
609**                  occurs.
610**
611** Returns          NFA_STATUS_OK if successfully initiated
612**                  NFA_STATUS_FAILED otherwise
613**
614*******************************************************************************/
615NFC_API extern tNFA_STATUS NFA_HciSendResponse (tNFA_HANDLE   hci_handle,
616                                                UINT8         pipe,
617                                                UINT8         response,
618                                                UINT8         data_size,
619                                                UINT8         *p_data)
620{
621    tNFA_HCI_API_SEND_RSP_EVT *p_msg;
622
623    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
624    {
625        NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid hci_handle:0x%04x", hci_handle);
626        return (NFA_STATUS_FAILED);
627    }
628
629    if ((data_size && (p_data == NULL)) || (data_size > NFA_MAX_HCI_RSP_LEN))
630    {
631        NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid data size:0x%02x", data_size);
632        return (NFA_STATUS_FAILED);
633    }
634
635    NFA_TRACE_API3 ("NFA_HciSendResponse (): hci_handle:0x%04x  Pipe: 0x%02x  Response: 0x%02x", hci_handle, pipe, response);
636
637    /* Request HCI to get list of gates supported by the specified host */
638    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
639        &&((p_msg = (tNFA_HCI_API_SEND_RSP_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_RSP_EVT))) != NULL) )
640    {
641        p_msg->hdr.event    = NFA_HCI_API_SEND_RSP_EVT;
642        p_msg->hci_handle   = hci_handle;
643        p_msg->response     = response;
644        p_msg->size         = data_size;
645
646        if (data_size)
647            memcpy (p_msg->data, p_data, data_size);
648
649        nfa_sys_sendmsg (p_msg);
650        return (NFA_STATUS_OK);
651    }
652
653    return (NFA_STATUS_FAILED);
654}
655
656
657/*******************************************************************************
658**
659** Function         NFA_HciSendEvent
660**
661** Description      This function is called to send any event on a pipe created
662**                  by the application.
663**                  The app will be notified by NFA_HCI_EVENT_SENT_EVT
664**                  after successfully sending the event on the specified pipe
665**                  or if an error occurs. The application should wait for this
666**                  event before releasing event buffer passed as argument.
667**                  If the app is expecting a response to the event then it can
668**                  provide response buffer for collecting the response.
669**                  Maximum of NFA_MAX_HCI_EVENT_LEN bytes APDU can be received
670**                  using internal buffer if no response buffer is provided by
671**                  the application. The app will be notified by
672**                  NFA_HCI_EVENT_RCVD_EVT after receiving the response event
673**                  or if an error occurs. If response buffer if provided by the
674**                  application, it should wait for this event before releasing
675**                  the buffer.
676**
677** Returns          NFA_STATUS_OK if successfully initiated
678**                  NFA_STATUS_FAILED otherwise
679**
680*******************************************************************************/
681tNFA_STATUS NFA_HciSendEvent (tNFA_HANDLE  hci_handle,
682                              UINT8        pipe,
683                              UINT8        evt_code,
684                              UINT16       evt_size,
685                              UINT8        *p_data,
686                              UINT16       rsp_size,
687                              UINT8        *p_rsp_buf)
688{
689    tNFA_HCI_API_SEND_EVENT_EVT *p_msg;
690
691    NFA_TRACE_API3 ("NFA_HciSendEvent(): hci_handle:0x%04x, pipe:0x%02x  Code: %0x%02x", hci_handle, pipe, evt_code);
692
693
694    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
695    {
696        NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid hci_handle:0x%04x", hci_handle);
697        return (NFA_STATUS_FAILED);
698    }
699
700    if (evt_size && (p_data == NULL))
701    {
702        NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid Event size:0x%02x", evt_size);
703        return (NFA_STATUS_FAILED);
704    }
705
706    if (rsp_size && (p_rsp_buf == NULL))
707    {
708        NFA_TRACE_API1 ("NFA_HciSendEvent (): No Event buffer, but invalid event buffer size :%u", rsp_size);
709        return (NFA_STATUS_FAILED);
710    }
711
712    /* Request HCI to post event data on a particular pipe */
713    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
714        &&((p_msg = (tNFA_HCI_API_SEND_EVENT_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_EVENT_EVT))) != NULL) )
715    {
716        p_msg->hdr.event    = NFA_HCI_API_SEND_EVENT_EVT;
717        p_msg->hci_handle   = hci_handle;
718        p_msg->pipe         = pipe;
719        p_msg->evt_code     = evt_code;
720        p_msg->evt_len      = evt_size;
721        p_msg->p_evt_buf    = p_data;
722        p_msg->rsp_len      = rsp_size;
723        p_msg->p_rsp_buf    = p_rsp_buf;
724
725        nfa_sys_sendmsg (p_msg);
726        return (NFA_STATUS_OK);
727    }
728
729    return (NFA_STATUS_FAILED);
730}
731
732/*******************************************************************************
733**
734** Function         NFA_HciClosePipe
735**
736** Description      This function is called to close a dynamic pipe.
737**                  When the dynamic pipe is closed (or
738**                  if an error occurs), the app will be notified with
739**                  NFA_HCI_CLOSE_PIPE_EVT with the pipe id.
740**
741** Returns          NFA_STATUS_OK if successfully initiated
742**                  NFA_STATUS_FAILED otherwise
743**
744*******************************************************************************/
745tNFA_STATUS NFA_HciClosePipe (tNFA_HANDLE hci_handle, UINT8 pipe)
746{
747    tNFA_HCI_API_CLOSE_PIPE_EVT *p_msg;
748
749    NFA_TRACE_API2 ("NFA_HciClosePipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
750
751    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
752    {
753        NFA_TRACE_API1 ("NFA_HciClosePipe (): Invalid hci_handle:0x%04x", hci_handle);
754        return (NFA_STATUS_FAILED);
755    }
756
757    if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
758    {
759        NFA_TRACE_API1 ("NFA_HciClosePipe (): Invalid Pipe:0x%02x", pipe);
760        return (NFA_STATUS_FAILED);
761    }
762
763    /* Request HCI to close a pipe if it is in opened state */
764    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
765        &&(!nfa_hci_cb.b_low_power_mode)
766        &&((p_msg = (tNFA_HCI_API_CLOSE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_CLOSE_PIPE_EVT))) != NULL) )
767    {
768        p_msg->hdr.event    = NFA_HCI_API_CLOSE_PIPE_EVT;
769        p_msg->hci_handle   = hci_handle;
770        p_msg->pipe         = pipe;
771
772        nfa_sys_sendmsg (p_msg);
773        return (NFA_STATUS_OK);
774    }
775    return (NFA_STATUS_FAILED);
776}
777
778/*******************************************************************************
779**
780** Function         NFA_HciDeletePipe
781**
782** Description      This function is called to delete a particular dynamic pipe.
783**                  When the dynamic pipe is deleted (or if an error occurs),
784**                  the app will be notified with NFA_HCI_DELETE_PIPE_EVT with
785**                  the pipe id. After successful deletion of pipe, registry
786**                  entry will be deleted for the dynamic pipe and all
787**                  information related to the pipe will be deleted from non
788**                  volatile memory.
789**
790** Returns          NFA_STATUS_OK if successfully initiated
791**                  NFA_STATUS_FAILED otherwise
792**
793*******************************************************************************/
794tNFA_STATUS NFA_HciDeletePipe (tNFA_HANDLE  hci_handle, UINT8 pipe)
795{
796    tNFA_HCI_API_DELETE_PIPE_EVT *p_msg;
797
798    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
799    {
800        NFA_TRACE_API1 ("NFA_HciDeletePipe (): Invalid hci_handle:0x%04x", hci_handle);
801        return (NFA_STATUS_FAILED);
802    }
803
804    if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
805    {
806        NFA_TRACE_API1 ("NFA_HciDeletePipe (): Invalid Pipe:0x%02x", pipe);
807        return (NFA_STATUS_FAILED);
808    }
809
810    NFA_TRACE_API2 ("NFA_HciDeletePipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
811
812    /* Request HCI to delete a pipe created by the application identified by hci handle */
813    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
814        &&(!nfa_hci_cb.b_low_power_mode)
815        &&((p_msg = (tNFA_HCI_API_DELETE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_DELETE_PIPE_EVT))) != NULL) )
816    {
817        p_msg->hdr.event    = NFA_HCI_API_DELETE_PIPE_EVT;
818        p_msg->hci_handle   = hci_handle;
819        p_msg->pipe         = pipe;
820
821        nfa_sys_sendmsg (p_msg);
822        return (NFA_STATUS_OK);
823    }
824    return (NFA_STATUS_FAILED);
825}
826
827/*******************************************************************************
828**
829** Function         NFA_HciDebug
830**
831** Description      Debug function.
832**
833*******************************************************************************/
834void NFA_HciDebug (UINT8 action, UINT8 size, UINT8 *p_data)
835{
836    int                 xx;
837    tNFA_HCI_DYN_GATE   *pg = nfa_hci_cb.cfg.dyn_gates;
838    tNFA_HCI_DYN_PIPE   *pp = nfa_hci_cb.cfg.dyn_pipes;
839    BT_HDR              *p_msg;
840    UINT8               *p;
841
842    switch (action)
843    {
844    case NFA_HCI_DEBUG_DISPLAY_CB:
845        NFA_TRACE_API0 ("NFA_HciDebug  Host List:");
846        for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
847        {
848            if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
849            {
850                NFA_TRACE_API2 ("              Host Inx:  %u   Name: %s", xx, &nfa_hci_cb.cfg.reg_app_names[xx][0]);
851            }
852        }
853
854        NFA_TRACE_API0 ("NFA_HciDebug  Gate List:");
855        for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
856        {
857            if (pg->gate_id != 0)
858            {
859                NFA_TRACE_API4 ("              Gate Inx: %x  ID: 0x%02x  Owner: 0x%04x  PipeInxMask: 0x%08x",
860                                xx, pg->gate_id, pg->gate_owner, pg->pipe_inx_mask);
861            }
862        }
863
864        NFA_TRACE_API0 ("NFA_HciDebug  Pipe List:");
865        for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
866        {
867            if (pp->pipe_id != 0)
868            {
869                NFA_TRACE_API6 ("              Pipe Inx: %x  ID: 0x%02x  State: %u  LocalGate: 0x%02x  Dest Gate: 0x%02x  Host: 0x%02x",
870                    xx, pp->pipe_id, pp->pipe_state, pp->local_gate, pp->dest_gate, pp->dest_host);
871            }
872        }
873        break;
874
875    case NFA_HCI_DEBUG_SIM_HCI_EVENT:
876        if ((p_msg = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
877        {
878            p = (UINT8 *) (p_msg + 1);
879
880            p_msg->event  = NFA_HCI_CHECK_QUEUE_EVT;
881            p_msg->len    = size;
882            p_msg->offset = 0;
883
884            memcpy (p, p_data, size);
885
886            nfa_sys_sendmsg (p_msg);
887        }
888        break;
889
890    case NFA_HCI_DEBUG_ENABLE_LOOPBACK:
891        NFA_TRACE_API0 ("NFA_HciDebug  HCI_LOOPBACK_DEBUG = TRUE");
892        HCI_LOOPBACK_DEBUG = TRUE;
893        break;
894
895    case NFA_HCI_DEBUG_DISABLE_LOOPBACK:
896        NFA_TRACE_API0 ("NFA_HciDebug  HCI_LOOPBACK_DEBUG = FALSE");
897        HCI_LOOPBACK_DEBUG = FALSE;
898        break;
899    }
900}
901