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