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 *******************************************************************************/
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 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 *******************************************************************************/
NFA_HciAllocGate(tNFA_HANDLE hci_handle)212 tNFA_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 *******************************************************************************/
NFA_HciDeallocGate(tNFA_HANDLE hci_handle,UINT8 gate)250 tNFA_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 *******************************************************************************/
NFA_HciGetHostList(tNFA_HANDLE hci_handle)295 tNFA_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 *******************************************************************************/
NFA_HciCreatePipe(tNFA_HANDLE hci_handle,UINT8 source_gate_id,UINT8 dest_host,UINT8 dest_gate)342 tNFA_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 *******************************************************************************/
NFA_HciOpenPipe(tNFA_HANDLE hci_handle,UINT8 pipe)412 tNFA_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 *******************************************************************************/
NFA_HciGetRegistry(tNFA_HANDLE hci_handle,UINT8 pipe,UINT8 reg_inx)462 tNFA_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 *******************************************************************************/
NFA_HciSetRegistry(tNFA_HANDLE hci_handle,UINT8 pipe,UINT8 reg_inx,UINT8 data_size,UINT8 * p_data)512 NFC_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 *******************************************************************************/
NFA_HciSendCommand(tNFA_HANDLE hci_handle,UINT8 pipe,UINT8 cmd_code,UINT16 cmd_size,UINT8 * p_data)574 tNFA_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 *******************************************************************************/
NFA_HciSendResponse(tNFA_HANDLE hci_handle,UINT8 pipe,UINT8 response,UINT8 data_size,UINT8 * p_data)635 NFC_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 *******************************************************************************/
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)713 tNFA_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 *******************************************************************************/
NFA_HciClosePipe(tNFA_HANDLE hci_handle,UINT8 pipe)785 tNFA_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 *******************************************************************************/
NFA_HciDeletePipe(tNFA_HANDLE hci_handle,UINT8 pipe)834 tNFA_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 *******************************************************************************/
NFA_HciAddStaticPipe(tNFA_HANDLE hci_handle,UINT8 host,UINT8 gate,UINT8 pipe)880 tNFA_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 *******************************************************************************/
NFA_HciDebug(UINT8 action,UINT8 size,UINT8 * p_data)939 void 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