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