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 *******************************************************************************/
NFA_HciRegister(char * p_app_name,tNFA_HCI_CBACK * p_cback,BOOLEAN b_send_conn_evts)49 tNFA_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 *******************************************************************************/
NFA_HciGetGateAndPipeList(tNFA_HANDLE hci_handle)107 tNFA_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 *******************************************************************************/
NFA_HciDeregister(char * p_app_name)148 tNFA_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 *******************************************************************************/
NFA_HciAllocGate(tNFA_HANDLE hci_handle,UINT8 gate)212 tNFA_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 *******************************************************************************/
NFA_HciDeallocGate(tNFA_HANDLE hci_handle,UINT8 gate)258 tNFA_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 *******************************************************************************/
NFA_HciGetHostList(tNFA_HANDLE hci_handle)303 tNFA_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 *******************************************************************************/
NFA_HciCreatePipe(tNFA_HANDLE hci_handle,UINT8 source_gate_id,UINT8 dest_host,UINT8 dest_gate)350 tNFA_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 *******************************************************************************/
NFA_HciOpenPipe(tNFA_HANDLE hci_handle,UINT8 pipe)420 tNFA_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 *******************************************************************************/
NFA_HciGetRegistry(tNFA_HANDLE hci_handle,UINT8 pipe,UINT8 reg_inx)470 tNFA_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 *******************************************************************************/
NFA_HciSetRegistry(tNFA_HANDLE hci_handle,UINT8 pipe,UINT8 reg_inx,UINT8 data_size,UINT8 * p_data)520 NFC_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 *******************************************************************************/
NFA_HciSendCommand(tNFA_HANDLE hci_handle,UINT8 pipe,UINT8 cmd_code,UINT16 cmd_size,UINT8 * p_data)582 tNFA_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 *******************************************************************************/
NFA_HciSendResponse(tNFA_HANDLE hci_handle,UINT8 pipe,UINT8 response,UINT8 data_size,UINT8 * p_data)643 NFC_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 *******************************************************************************/
NFA_HciSendEvent(tNFA_HANDLE hci_handle,UINT8 pipe,UINT8 evt_code,UINT16 evt_size,UINT8 * p_data,UINT16 rsp_size,UINT8 * p_rsp_buf,UINT16 rsp_timeout)721 tNFA_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 *******************************************************************************/
NFA_HciClosePipe(tNFA_HANDLE hci_handle,UINT8 pipe)793 tNFA_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 *******************************************************************************/
NFA_HciDeletePipe(tNFA_HANDLE hci_handle,UINT8 pipe)842 tNFA_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 *******************************************************************************/
NFA_HciAddStaticPipe(tNFA_HANDLE hci_handle,UINT8 host,UINT8 gate,UINT8 pipe)888 tNFA_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 *******************************************************************************/
NFA_HciDebug(UINT8 action,UINT8 size,UINT8 * p_data)947 void 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