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