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