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