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