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