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