• 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  *  This file contains the utility functions for the NFA HCI.
22  *
23  ******************************************************************************/
24 #include <string>
25 
26 #include <android-base/stringprintf.h>
27 #include <base/logging.h>
28 
29 #include "nfa_dm_int.h"
30 #include "nfa_hci_api.h"
31 #include "nfa_hci_defs.h"
32 #include "nfa_hci_int.h"
33 
34 using android::base::StringPrintf;
35 
36 extern bool nfc_debug_enabled;
37 
38 static void handle_debug_loopback(NFC_HDR* p_buf, uint8_t type,
39                                   uint8_t instruction);
40 uint8_t HCI_LOOPBACK_DEBUG = NFA_HCI_DEBUG_OFF;
41 
42 /*******************************************************************************
43 **
44 ** Function         nfa_hciu_find_pipe_by_pid
45 **
46 ** Description      look for the pipe control block based on pipe id
47 **
48 ** Returns          pointer to the pipe control block, or NULL if not found
49 **
50 *******************************************************************************/
nfa_hciu_find_pipe_by_pid(uint8_t pipe_id)51 tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_by_pid(uint8_t pipe_id) {
52   tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
53   int xx = 0;
54 
55   /* Loop through looking for a match */
56   for (; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) {
57     if (pp->pipe_id == pipe_id) return (pp);
58   }
59 
60   /* If here, not found */
61   return (nullptr);
62 }
63 
64 /*******************************************************************************
65 **
66 ** Function         nfa_hciu_find_gate_by_gid
67 **
68 ** Description      Find the gate control block for the given gate id
69 **
70 ** Returns          pointer to the gate control block, or NULL if not found
71 **
72 *******************************************************************************/
nfa_hciu_find_gate_by_gid(uint8_t gate_id)73 tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_by_gid(uint8_t gate_id) {
74   tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
75   int xx = 0;
76 
77   for (; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
78     if (pg->gate_id == gate_id) return (pg);
79   }
80 
81   return (nullptr);
82 }
83 
84 /*******************************************************************************
85 **
86 ** Function         nfa_hciu_find_gate_by_owner
87 **
88 ** Description      Find the the first gate control block for the given owner
89 **
90 ** Returns          pointer to the gate control block, or NULL if not found
91 **
92 *******************************************************************************/
nfa_hciu_find_gate_by_owner(tNFA_HANDLE app_handle)93 tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_by_owner(tNFA_HANDLE app_handle) {
94   tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
95   int xx = 0;
96 
97   for (; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
98     if (pg->gate_owner == app_handle) return (pg);
99   }
100 
101   return (nullptr);
102 }
103 
104 /*******************************************************************************
105 **
106 ** Function         nfa_hciu_find_gate_with_nopipes_by_owner
107 **
108 ** Description      Find the the first gate control block with no pipes
109 **                  for the given owner
110 **
111 ** Returns          pointer to the gate control block, or NULL if not found
112 **
113 *******************************************************************************/
nfa_hciu_find_gate_with_nopipes_by_owner(tNFA_HANDLE app_handle)114 tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_with_nopipes_by_owner(
115     tNFA_HANDLE app_handle) {
116   tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
117   int xx = 0;
118 
119   for (; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
120     if ((pg->gate_owner == app_handle) && (pg->pipe_inx_mask == 0)) return (pg);
121   }
122 
123   return (nullptr);
124 }
125 
126 /*******************************************************************************
127 **
128 ** Function         nfa_hciu_count_pipes_on_gate
129 **
130 ** Description      Count the number of pipes on the given gate
131 **
132 ** Returns          the number of pipes on the gate
133 **
134 *******************************************************************************/
nfa_hciu_count_pipes_on_gate(tNFA_HCI_DYN_GATE * p_gate)135 uint8_t nfa_hciu_count_pipes_on_gate(tNFA_HCI_DYN_GATE* p_gate) {
136   int xx = 0;
137   uint32_t mask = 1;
138   uint8_t count = 0;
139 
140   for (; xx < NFA_HCI_MAX_PIPE_CB; xx++) {
141     if (p_gate->pipe_inx_mask & mask) count++;
142 
143     mask = mask << 1;
144   }
145 
146   return (count);
147 }
148 
149 /*******************************************************************************
150 **
151 ** Function         nfa_hciu_count_open_pipes_on_gate
152 **
153 ** Description      Count the number of opened pipes on the given gate
154 **
155 ** Returns          the number of pipes in OPENED state on the gate
156 **
157 *******************************************************************************/
nfa_hciu_count_open_pipes_on_gate(tNFA_HCI_DYN_GATE * p_gate)158 uint8_t nfa_hciu_count_open_pipes_on_gate(tNFA_HCI_DYN_GATE* p_gate) {
159   tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
160   int xx = 0;
161   uint32_t mask = 1;
162   uint8_t count = 0;
163 
164   for (; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) {
165     /* For each pipe on this gate, check if it is open */
166     if ((p_gate->pipe_inx_mask & mask) &&
167         (pp->pipe_state == NFA_HCI_PIPE_OPENED))
168       count++;
169 
170     mask = mask << 1;
171   }
172 
173   return (count);
174 }
175 
176 /*******************************************************************************
177 **
178 ** Function         nfa_hciu_get_gate_owner
179 **
180 ** Description      Find the application that owns a gate
181 **
182 ** Returns          application handle
183 **
184 *******************************************************************************/
nfa_hciu_get_gate_owner(uint8_t gate_id)185 tNFA_HANDLE nfa_hciu_get_gate_owner(uint8_t gate_id) {
186   tNFA_HCI_DYN_GATE* pg;
187 
188   pg = nfa_hciu_find_gate_by_gid(gate_id);
189   if (pg == nullptr) return (NFA_HANDLE_INVALID);
190 
191   return (pg->gate_owner);
192 }
193 
194 /*******************************************************************************
195 **
196 ** Function         nfa_hciu_get_pipe_owner
197 **
198 ** Description      Find the application that owns a pipe
199 **
200 ** Returns          application handle
201 **
202 *******************************************************************************/
nfa_hciu_get_pipe_owner(uint8_t pipe_id)203 tNFA_HANDLE nfa_hciu_get_pipe_owner(uint8_t pipe_id) {
204   tNFA_HCI_DYN_PIPE* pp;
205   tNFA_HCI_DYN_GATE* pg;
206 
207   pp = nfa_hciu_find_pipe_by_pid(pipe_id);
208   if (pp == nullptr) return (NFA_HANDLE_INVALID);
209 
210   pg = nfa_hciu_find_gate_by_gid(pp->local_gate);
211   if (pg == nullptr) return (NFA_HANDLE_INVALID);
212 
213   return (pg->gate_owner);
214 }
215 
216 /*******************************************************************************
217 **
218 ** Function         nfa_hciu_alloc_gate
219 **
220 ** Description      Allocate an gate control block
221 **
222 ** Returns          pointer to the allocated gate, or NULL if cannot allocate
223 **
224 *******************************************************************************/
nfa_hciu_alloc_gate(uint8_t gate_id,tNFA_HANDLE app_handle)225 tNFA_HCI_DYN_GATE* nfa_hciu_alloc_gate(uint8_t gate_id,
226                                        tNFA_HANDLE app_handle) {
227   tNFA_HCI_DYN_GATE* pg;
228   int xx;
229   uint8_t app_inx = app_handle & NFA_HANDLE_MASK;
230 
231   /* First, check if the application handle is valid */
232   if ((gate_id != NFA_HCI_CONNECTIVITY_GATE) &&
233       (gate_id < NFA_HCI_FIRST_PROP_GATE) &&
234       (((app_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI) ||
235        (app_inx >= NFA_HCI_MAX_APP_CB) ||
236        (nfa_hci_cb.p_app_cback[app_inx] == nullptr))) {
237     return (nullptr);
238   }
239 
240   if (gate_id != 0) {
241     pg = nfa_hciu_find_gate_by_gid(gate_id);
242     if (pg != nullptr) return (pg);
243   } else {
244     /* If gate_id is 0, we need to assign a free one */
245     /* Loop through all possible gate IDs checking if they are already used */
246     uint32_t gate_id_index;
247     for (gate_id_index = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE;
248          gate_id_index <= NFA_HCI_LAST_PROP_GATE; gate_id_index++) {
249       /* Skip connectivity gate */
250       if (gate_id_index == NFA_HCI_CONNECTIVITY_GATE) continue;
251 
252       /* Check if the gate is already allocated */
253       if (nfa_hciu_find_gate_by_gid(gate_id_index) == nullptr) {
254         gate_id = gate_id_index & 0xFF;
255         break;
256       }
257     }
258     if (gate_id_index > NFA_HCI_LAST_PROP_GATE) {
259       LOG(ERROR) << StringPrintf(
260           "nfa_hci_alloc_gate - no free Gate ID: %u  App Handle: 0x%04x",
261           gate_id_index, app_handle);
262       return (nullptr);
263     }
264   }
265 
266   /* Now look for a free control block */
267   for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
268        xx++, pg++) {
269     if (pg->gate_id == 0) {
270       /* Found a free gate control block */
271       pg->gate_id = gate_id;
272       pg->gate_owner = app_handle;
273       pg->pipe_inx_mask = 0;
274 
275       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
276           "nfa_hciu_alloc_gate id:%d  app_handle: 0x%04x", gate_id, app_handle);
277 
278       nfa_hci_cb.nv_write_needed = true;
279       return (pg);
280     }
281   }
282 
283   /* If here, no free gate control block */
284   LOG(ERROR) << StringPrintf(
285       "nfa_hci_alloc_gate - no CB  Gate ID: %u  App Handle: 0x%04x", gate_id,
286       app_handle);
287   return (nullptr);
288 }
289 
290 /*******************************************************************************
291 **
292 ** Function         nfa_hciu_send_msg
293 **
294 ** Description      This function will fragment the given packet, if necessary
295 **                  and send it on the given pipe.
296 **
297 ** Returns          status
298 **
299 *******************************************************************************/
nfa_hciu_send_msg(uint8_t pipe_id,uint8_t type,uint8_t instruction,uint16_t msg_len,uint8_t * p_msg)300 tNFA_STATUS nfa_hciu_send_msg(uint8_t pipe_id, uint8_t type,
301                               uint8_t instruction, uint16_t msg_len,
302                               uint8_t* p_msg) {
303   NFC_HDR* p_buf;
304   uint8_t* p_data;
305   bool first_pkt = true;
306   uint16_t data_len;
307   tNFA_STATUS status = NFA_STATUS_OK;
308   uint16_t max_seg_hcp_pkt_size = nfa_hci_cb.buff_size - NCI_DATA_HDR_SIZE;
309 
310   char buff[100];
311 
312   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
313       "nfa_hciu_send_msg pipe_id:%d   %s  len:%d", pipe_id,
314       nfa_hciu_get_type_inst_names(pipe_id, type, instruction, buff), msg_len);
315 
316   if (instruction == NFA_HCI_ANY_GET_PARAMETER)
317     nfa_hci_cb.param_in_use = *p_msg;
318 
319   while ((first_pkt == true) || (msg_len != 0)) {
320     p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
321     if (p_buf != nullptr) {
322       p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
323 
324       /* First packet has a 2-byte header, subsequent fragments have a 1-byte
325        * header */
326       data_len =
327           first_pkt ? (max_seg_hcp_pkt_size - 2) : (max_seg_hcp_pkt_size - 1);
328 
329       p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
330 
331       /* Last or only segment has "no fragmentation" bit set */
332       if (msg_len > data_len) {
333         *p_data++ = (NFA_HCI_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
334       } else {
335         data_len = msg_len;
336         *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
337       }
338 
339       p_buf->len = 1;
340 
341       /* Message header only goes in the first segment */
342       if (first_pkt) {
343         first_pkt = false;
344         *p_data++ = (type << 6) | instruction;
345         p_buf->len++;
346       }
347 
348       if (data_len != 0) {
349         memcpy(p_data, p_msg, data_len);
350 
351         p_buf->len += data_len;
352         msg_len -= data_len;
353         if (msg_len > 0) p_msg += data_len;
354       }
355 
356       if (HCI_LOOPBACK_DEBUG == NFA_HCI_DEBUG_ON)
357         handle_debug_loopback(p_buf, type, instruction);
358       else
359         status = NFC_SendData(nfa_hci_cb.conn_id, p_buf);
360     } else {
361       LOG(ERROR) << StringPrintf("nfa_hciu_send_data_packet no buffers");
362       status = NFA_STATUS_NO_BUFFERS;
363       break;
364     }
365   }
366 
367   /* Start timer if response to wait for a particular time for the response  */
368   if (type == NFA_HCI_COMMAND_TYPE) {
369     nfa_hci_cb.cmd_sent = instruction;
370 
371     if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
372       nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
373 
374     nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
375                         p_nfa_hci_cfg->hcp_response_timeout);
376   }
377 
378   return status;
379 }
380 
381 /*******************************************************************************
382 **
383 ** Function         nfa_hciu_get_allocated_gate_list
384 **
385 ** Description      fills in a list of allocated gates
386 **
387 ** Returns          the number of gates
388 **
389 *******************************************************************************/
nfa_hciu_get_allocated_gate_list(uint8_t * p_gate_list)390 uint8_t nfa_hciu_get_allocated_gate_list(uint8_t* p_gate_list) {
391   tNFA_HCI_DYN_GATE* p_cb;
392   int xx;
393   uint8_t count = 0;
394 
395   for (xx = 0, p_cb = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
396        xx++, p_cb++) {
397     if (p_cb->gate_id != 0) {
398       *p_gate_list++ = p_cb->gate_id;
399       count++;
400     }
401   }
402 
403   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("returns: %u", count);
404 
405   return (count);
406 }
407 
408 /*******************************************************************************
409 **
410 ** Function         nfa_hciu_alloc_pipe
411 **
412 ** Description      Allocate a pipe control block
413 **
414 ** Returns          pointer to the pipe control block, or NULL if
415 **                  cannot allocate
416 **
417 *******************************************************************************/
nfa_hciu_alloc_pipe(uint8_t pipe_id)418 tNFA_HCI_DYN_PIPE* nfa_hciu_alloc_pipe(uint8_t pipe_id) {
419   uint8_t xx;
420   tNFA_HCI_DYN_PIPE* pp;
421 
422   /* If we already have a pipe of the same ID, release it first it */
423   pp = nfa_hciu_find_pipe_by_pid(pipe_id);
424   if (pp != nullptr) {
425     if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) return pp;
426     nfa_hciu_release_pipe(pipe_id);
427   }
428 
429   /* Look for a free pipe control block */
430   for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
431        xx++, pp++) {
432     if (pp->pipe_id == 0) {
433       DLOG_IF(INFO, nfc_debug_enabled)
434           << StringPrintf("nfa_hciu_alloc_pipe:%d, index:%d", pipe_id, xx);
435       pp->pipe_id = pipe_id;
436 
437       nfa_hci_cb.nv_write_needed = true;
438       return (pp);
439     }
440   }
441 
442   DLOG_IF(INFO, nfc_debug_enabled)
443       << StringPrintf("nfa_hciu_alloc_pipe:%d, NO free entries !!", pipe_id);
444   return (nullptr);
445 }
446 
447 /*******************************************************************************
448 **
449 ** Function         nfa_hciu_release_gate
450 **
451 ** Description      Remove a generic gate from gate list
452 **
453 ** Returns          none
454 **
455 *******************************************************************************/
nfa_hciu_release_gate(uint8_t gate_id)456 void nfa_hciu_release_gate(uint8_t gate_id) {
457   tNFA_HCI_DYN_GATE* p_gate = nfa_hciu_find_gate_by_gid(gate_id);
458 
459   if (p_gate != nullptr) {
460     DLOG_IF(INFO, nfc_debug_enabled)
461         << StringPrintf("ID: %d  owner: 0x%04x  pipe_inx_mask: 0x%04x", gate_id,
462                         p_gate->gate_owner, p_gate->pipe_inx_mask);
463 
464     p_gate->gate_id = 0;
465     p_gate->gate_owner = 0;
466     p_gate->pipe_inx_mask = 0;
467 
468     nfa_hci_cb.nv_write_needed = true;
469   } else {
470     LOG(WARNING) << StringPrintf("ID: %d  NOT FOUND", gate_id);
471   }
472 }
473 
474 /*******************************************************************************
475 **
476 ** Function         nfa_hciu_add_pipe_to_gate
477 **
478 ** Description      Add pipe to generic gate
479 **
480 ** Returns          NFA_STATUS_OK, if successfully add the pipe on to the gate
481 **                  NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
482 **
483 *******************************************************************************/
nfa_hciu_add_pipe_to_gate(uint8_t pipe_id,uint8_t local_gate,uint8_t dest_host,uint8_t dest_gate)484 tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_gate(uint8_t pipe_id, uint8_t local_gate,
485                                             uint8_t dest_host,
486                                             uint8_t dest_gate) {
487   tNFA_HCI_DYN_GATE* p_gate;
488   tNFA_HCI_DYN_PIPE* p_pipe;
489   uint8_t pipe_index;
490 
491   p_gate = nfa_hciu_find_gate_by_gid(local_gate);
492 
493   if (p_gate != nullptr) {
494     /* Allocate a pipe control block */
495     p_pipe = nfa_hciu_alloc_pipe(pipe_id);
496     if (p_pipe != nullptr) {
497       p_pipe->pipe_id = pipe_id;
498       p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
499       p_pipe->dest_host = dest_host;
500       p_pipe->dest_gate = dest_gate;
501       p_pipe->local_gate = local_gate;
502 
503       /* Save the pipe in the gate that it belongs to */
504       pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
505       p_gate->pipe_inx_mask |= (uint32_t)(1 << pipe_index);
506 
507       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
508           "nfa_hciu_add_pipe_to_gate  Gate ID: 0x%02x  Pipe ID: 0x%02x  "
509           "pipe_index: %u  App Handle: 0x%08x",
510           local_gate, pipe_id, pipe_index, p_gate->gate_owner);
511       return (NFA_HCI_ANY_OK);
512     }
513   }
514 
515   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
516       "nfa_hciu_add_pipe_to_gate: 0x%02x  NOT FOUND", local_gate);
517 
518   return (NFA_HCI_ADM_E_NO_PIPES_AVAILABLE);
519 }
520 
521 /*******************************************************************************
522 **
523 ** Function         nfa_hciu_add_pipe_to_static_gate
524 **
525 ** Description      Add pipe to identity management gate
526 **
527 ** Returns          NFA_HCI_ANY_OK, if successfully add the pipe on to the gate
528 **                  NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
529 **
530 *******************************************************************************/
nfa_hciu_add_pipe_to_static_gate(uint8_t local_gate,uint8_t pipe_id,uint8_t dest_host,uint8_t dest_gate)531 tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_static_gate(uint8_t local_gate,
532                                                    uint8_t pipe_id,
533                                                    uint8_t dest_host,
534                                                    uint8_t dest_gate) {
535   tNFA_HCI_DYN_PIPE* p_pipe;
536   uint8_t pipe_index;
537 
538   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
539       "nfa_hciu_add_pipe_to_static_gate (%u)  Pipe: 0x%02x  Dest Host: 0x%02x  "
540       "Dest Gate: 0x%02x)",
541       local_gate, pipe_id, dest_host, dest_gate);
542 
543   /* Allocate a pipe control block */
544   p_pipe = nfa_hciu_alloc_pipe(pipe_id);
545   if (p_pipe != nullptr) {
546     p_pipe->pipe_id = pipe_id;
547     p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
548     p_pipe->dest_host = dest_host;
549     p_pipe->dest_gate = dest_gate;
550     p_pipe->local_gate = local_gate;
551 
552     /* If this is the ID gate, save the pipe index in the ID gate info     */
553     /* block. Note that for loopback, it is enough to just create the pipe */
554     if (local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
555       pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
556       nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask |= (uint32_t)(1 << pipe_index);
557     }
558     return NFA_HCI_ANY_OK;
559   }
560 
561   return NFA_HCI_ADM_E_NO_PIPES_AVAILABLE;
562 }
563 
564 /*******************************************************************************
565 **
566 ** Function         nfa_hciu_find_active_pipe_by_owner
567 **
568 ** Description      Find the first pipe associated with the given app
569 **
570 ** Returns          pointer to pipe, or NULL if none found
571 **
572 *******************************************************************************/
nfa_hciu_find_active_pipe_by_owner(tNFA_HANDLE app_handle)573 tNFA_HCI_DYN_PIPE* nfa_hciu_find_active_pipe_by_owner(tNFA_HANDLE app_handle) {
574   tNFA_HCI_DYN_GATE* pg;
575   tNFA_HCI_DYN_PIPE* pp;
576   int xx;
577 
578   DLOG_IF(INFO, nfc_debug_enabled)
579       << StringPrintf("app_handle:0x%x", app_handle);
580 
581   /* Loop through all pipes looking for the owner */
582   for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
583        xx++, pp++) {
584     if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
585         (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
586         (nfa_hciu_is_active_host(pp->dest_host))) {
587       if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != nullptr) &&
588           (pg->gate_owner == app_handle))
589         return (pp);
590     }
591   }
592 
593   /* If here, not found */
594   return (nullptr);
595 }
596 
597 /*******************************************************************************
598 **
599 ** Function         nfa_hciu_check_pipe_between_gates
600 **
601 ** Description      Check if there is a pipe between specified Terminal host
602 **                  gate and and the specified UICC gate
603 **
604 ** Returns          TRUE, if there exists a pipe between the two specified gated
605 **                  FALSE, otherwise
606 **
607 *******************************************************************************/
nfa_hciu_check_pipe_between_gates(uint8_t local_gate,uint8_t dest_host,uint8_t dest_gate)608 bool nfa_hciu_check_pipe_between_gates(uint8_t local_gate, uint8_t dest_host,
609                                        uint8_t dest_gate) {
610   tNFA_HCI_DYN_PIPE* pp;
611   int xx;
612 
613   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
614       "Local gate: 0x%02X, Host[0x%02X] "
615       "gate: 0x%02X",
616       local_gate, dest_host, dest_gate);
617 
618   /* Loop through all pipes looking for the owner */
619   for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
620        xx++, pp++) {
621     if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
622         (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
623         (pp->local_gate == local_gate) && (pp->dest_host == dest_host) &&
624         (pp->dest_gate == dest_gate)) {
625       return true;
626     }
627   }
628 
629   /* If here, not found */
630   return false;
631 }
632 
633 /*******************************************************************************
634 **
635 ** Function         nfa_hciu_find_pipe_by_owner
636 **
637 ** Description      Find the first pipe associated with the given app
638 **
639 ** Returns          pointer to pipe, or NULL if none found
640 **
641 *******************************************************************************/
nfa_hciu_find_pipe_by_owner(tNFA_HANDLE app_handle)642 tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_by_owner(tNFA_HANDLE app_handle) {
643   tNFA_HCI_DYN_GATE* pg;
644   tNFA_HCI_DYN_PIPE* pp;
645   int xx;
646 
647   DLOG_IF(INFO, nfc_debug_enabled)
648       << StringPrintf("app_handle:0x%x", app_handle);
649 
650   /* Loop through all pipes looking for the owner */
651   for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
652        xx++, pp++) {
653     if (pp->pipe_id != 0) {
654       if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != nullptr) &&
655           (pg->gate_owner == app_handle))
656         return (pp);
657     }
658   }
659 
660   /* If here, not found */
661   return (nullptr);
662 }
663 
664 /*******************************************************************************
665 **
666 ** Function         nfa_hciu_find_pipe_on_gate
667 **
668 ** Description      Find the first pipe associated with the given gate
669 **
670 ** Returns          pointer to pipe, or NULL if none found
671 **
672 *******************************************************************************/
nfa_hciu_find_pipe_on_gate(uint8_t gate_id)673 tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_on_gate(uint8_t gate_id) {
674   tNFA_HCI_DYN_GATE* pg;
675   tNFA_HCI_DYN_PIPE* pp;
676   int xx;
677 
678   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Gate:0x%x", gate_id);
679 
680   /* Loop through all pipes looking for the owner */
681   for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
682        xx++, pp++) {
683     if (pp->pipe_id != 0) {
684       if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != nullptr) &&
685           (pg->gate_id == gate_id))
686         return (pp);
687     }
688   }
689 
690   /* If here, not found */
691   return (nullptr);
692 }
693 
694 /*******************************************************************************
695 **
696 ** Function         nfa_hciu_is_active_host
697 **
698 ** Description      Check if the host is currently active
699 **
700 ** Returns          TRUE, if the host is active in the host network
701 **                  FALSE, if the host is not active in the host network
702 **
703 *******************************************************************************/
nfa_hciu_is_active_host(uint8_t host_id)704 bool nfa_hciu_is_active_host(uint8_t host_id) {
705   uint8_t xx;
706 
707   if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
708       (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
709     for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
710       if (nfa_hci_cb.active_host[xx] == host_id) return true;
711     }
712   }
713 
714   return false;
715 }
716 
717 /*******************************************************************************
718 **
719 ** Function         nfa_hciu_is_host_reseting
720 **
721 ** Description      Check if the host is currently reseting
722 **
723 ** Returns          TRUE, if the host is reseting
724 **                  FALSE, if the host is not reseting
725 **
726 *******************************************************************************/
nfa_hciu_is_host_reseting(uint8_t host_id)727 bool nfa_hciu_is_host_reseting(uint8_t host_id) {
728   uint8_t xx;
729 
730   if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
731       (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
732     for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
733       if (nfa_hci_cb.reset_host[xx] == host_id) return true;
734     }
735   }
736 
737   return false;
738 }
739 
740 /*******************************************************************************
741 **
742 ** Function         nfa_hciu_is_no_host_resetting
743 **
744 ** Description      Check if no host is reseting
745 **
746 ** Returns          TRUE, if no host is resetting at this time
747 **                  FALSE, if one or more host is resetting
748 **
749 *******************************************************************************/
nfa_hciu_is_no_host_resetting(void)750 bool nfa_hciu_is_no_host_resetting(void) {
751   uint8_t xx;
752 
753   for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
754     if (nfa_hci_cb.reset_host[xx] != 0) return false;
755   }
756 
757   return true;
758 }
759 
760 /*******************************************************************************
761 **
762 ** Function         nfa_hciu_find_active_pipe_on_gate
763 **
764 ** Description      Find the first active pipe associated with the given gate
765 **
766 ** Returns          pointer to pipe, or NULL if none found
767 **
768 *******************************************************************************/
nfa_hciu_find_active_pipe_on_gate(uint8_t gate_id)769 tNFA_HCI_DYN_PIPE* nfa_hciu_find_active_pipe_on_gate(uint8_t gate_id) {
770   tNFA_HCI_DYN_GATE* pg;
771   tNFA_HCI_DYN_PIPE* pp;
772   int xx;
773 
774   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Gate:0x%x", gate_id);
775 
776   /* Loop through all pipes looking for the owner */
777   for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
778        xx++, pp++) {
779     if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
780         (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
781         (nfa_hciu_is_active_host(pp->dest_host))) {
782       if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != nullptr) &&
783           (pg->gate_id == gate_id))
784         return (pp);
785     }
786   }
787 
788   /* If here, not found */
789   return (nullptr);
790 }
791 
792 /*******************************************************************************
793 **
794 ** Function         nfa_hciu_release_pipe
795 **
796 ** Description      remove the specified pipe
797 **
798 ** Returns          NFA_HCI_ANY_OK, if removed
799 **                  NFA_HCI_ANY_E_NOK, if otherwise
800 **
801 *******************************************************************************/
nfa_hciu_release_pipe(uint8_t pipe_id)802 tNFA_HCI_RESPONSE nfa_hciu_release_pipe(uint8_t pipe_id) {
803   tNFA_HCI_DYN_GATE* p_gate;
804   tNFA_HCI_DYN_PIPE* p_pipe;
805   uint8_t pipe_index;
806 
807   DLOG_IF(INFO, nfc_debug_enabled)
808       << StringPrintf("nfa_hciu_release_pipe: %u", pipe_id);
809 
810   p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
811   if (p_pipe == nullptr) return (NFA_HCI_ANY_E_NOK);
812 
813   if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) {
814     DLOG_IF(INFO, nfc_debug_enabled)
815         << StringPrintf("ignore pipe: %d", pipe_id);
816     return (NFA_HCI_ANY_E_NOK);
817   }
818 
819   pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
820 
821   if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
822     /* Remove pipe from ID management gate */
823     nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask &= ~(uint32_t)(1 << pipe_index);
824   } else {
825     p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
826     if (p_gate == nullptr) {
827       /* Mark the pipe control block as free */
828       p_pipe->pipe_id = 0;
829       return (NFA_HCI_ANY_E_NOK);
830     }
831 
832     /* Remove pipe from gate */
833     p_gate->pipe_inx_mask &= ~(uint32_t)(1 << pipe_index);
834   }
835 
836   /* Reset pipe control block */
837   memset(p_pipe, 0, sizeof(tNFA_HCI_DYN_PIPE));
838   nfa_hci_cb.nv_write_needed = true;
839   return NFA_HCI_ANY_OK;
840 }
841 
842 /*******************************************************************************
843 **
844 ** Function         nfa_hciu_remove_all_pipes_from_host
845 **
846 ** Description      remove all the pipes that are connected to a specific host
847 **
848 ** Returns          None
849 **
850 *******************************************************************************/
nfa_hciu_remove_all_pipes_from_host(uint8_t host)851 void nfa_hciu_remove_all_pipes_from_host(uint8_t host) {
852   tNFA_HCI_DYN_GATE* pg;
853   tNFA_HCI_DYN_PIPE* pp;
854   int xx;
855   tNFA_HCI_EVT_DATA evt_data;
856 
857   DLOG_IF(INFO, nfc_debug_enabled)
858       << StringPrintf("nfa_hciu_remove_all_pipes_from_host (0x%02x)", host);
859 
860   /* Remove all pipes from the specified host connected to all generic gates */
861   for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
862        xx++, pp++) {
863     if ((pp->pipe_id == 0) ||
864         ((host != 0) && ((pp->dest_host != host) ||
865                          (pp->pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE))))
866       continue;
867 
868     pg = nfa_hciu_find_gate_by_gid(pp->local_gate);
869     if (pg != nullptr) {
870       evt_data.deleted.status = NFA_STATUS_OK;
871       evt_data.deleted.pipe = pp->pipe_id;
872 
873       nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data, pg->gate_owner);
874     }
875     nfa_hciu_release_pipe(pp->pipe_id);
876   }
877 }
878 
879 /*******************************************************************************
880 **
881 ** Function         nfa_hciu_send_create_pipe_cmd
882 **
883 ** Description      Create dynamic pipe between the specified gates
884 **
885 ** Returns          status
886 **
887 *******************************************************************************/
nfa_hciu_send_create_pipe_cmd(uint8_t source_gate,uint8_t dest_host,uint8_t dest_gate)888 tNFA_STATUS nfa_hciu_send_create_pipe_cmd(uint8_t source_gate,
889                                           uint8_t dest_host,
890                                           uint8_t dest_gate) {
891   tNFA_STATUS status;
892   uint8_t data[3];
893 
894   data[0] = source_gate;
895   data[1] = dest_host;
896   data[2] = dest_gate;
897 
898   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
899       "nfa_hciu_send_create_pipe_cmd source_gate:%d, dest_host:%d, "
900       "dest_gate:%d",
901       source_gate, dest_host, dest_gate);
902 
903   status = nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
904                              NFA_HCI_ADM_CREATE_PIPE, 3, data);
905 
906   return status;
907 }
908 
909 /*******************************************************************************
910 **
911 ** Function         nfa_hciu_send_delete_pipe_cmd
912 **
913 ** Description      Delete the dynamic pipe
914 **
915 ** Returns          None
916 **
917 *******************************************************************************/
nfa_hciu_send_delete_pipe_cmd(uint8_t pipe)918 tNFA_STATUS nfa_hciu_send_delete_pipe_cmd(uint8_t pipe) {
919   tNFA_STATUS status;
920 
921   DLOG_IF(INFO, nfc_debug_enabled)
922       << StringPrintf("nfa_hciu_send_delete_pipe_cmd: %d", pipe);
923 
924   if (pipe > NFA_HCI_LAST_DYNAMIC_PIPE) {
925     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("ignore pipe: %d", pipe);
926     return (NFA_HCI_ANY_E_NOK);
927   }
928   nfa_hci_cb.pipe_in_use = pipe;
929 
930   status = nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
931                              NFA_HCI_ADM_DELETE_PIPE, 1, &pipe);
932 
933   return status;
934 }
935 
936 /*******************************************************************************
937 **
938 ** Function         nfa_hciu_send_clear_all_pipe_cmd
939 **
940 ** Description      delete all the dynamic pipe connected to device host,
941 **                  to close all static pipes connected to device host,
942 **                  and to set registry values related to static pipes to
943 **                  theri default values.
944 **
945 ** Returns          None
946 **
947 *******************************************************************************/
nfa_hciu_send_clear_all_pipe_cmd(void)948 tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd(void) {
949   tNFA_STATUS status;
950   uint16_t id_ref_data = 0x0102;
951 
952   DLOG_IF(INFO, nfc_debug_enabled)
953       << StringPrintf("nfa_hciu_send_clear_all_pipe_cmd");
954 
955   status =
956       nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
957                         NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (uint8_t*)&id_ref_data);
958 
959   return status;
960 }
961 
962 /*******************************************************************************
963 **
964 ** Function         nfa_hciu_send_open_pipe_cmd
965 **
966 ** Description      Open a closed pipe
967 **
968 ** Returns          status
969 **
970 *******************************************************************************/
nfa_hciu_send_open_pipe_cmd(uint8_t pipe)971 tNFA_STATUS nfa_hciu_send_open_pipe_cmd(uint8_t pipe) {
972   tNFA_STATUS status;
973 
974   nfa_hci_cb.pipe_in_use = pipe;
975 
976   status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_OPEN_PIPE,
977                              0, nullptr);
978 
979   return status;
980 }
981 
982 /*******************************************************************************
983 **
984 ** Function         nfa_hciu_send_close_pipe_cmd
985 **
986 ** Description      Close an opened pipe
987 **
988 ** Returns          status
989 **
990 *******************************************************************************/
nfa_hciu_send_close_pipe_cmd(uint8_t pipe)991 tNFA_STATUS nfa_hciu_send_close_pipe_cmd(uint8_t pipe) {
992   tNFA_STATUS status;
993 
994   nfa_hci_cb.pipe_in_use = pipe;
995 
996   status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_CLOSE_PIPE,
997                              0, nullptr);
998 
999   return status;
1000 }
1001 
1002 /*******************************************************************************
1003 **
1004 ** Function         nfa_hciu_send_get_param_cmd
1005 **
1006 ** Description      Read a parameter value from gate registry
1007 **
1008 ** Returns          None
1009 **
1010 *******************************************************************************/
nfa_hciu_send_get_param_cmd(uint8_t pipe,uint8_t index)1011 tNFA_STATUS nfa_hciu_send_get_param_cmd(uint8_t pipe, uint8_t index) {
1012   tNFA_STATUS status;
1013 
1014   status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE,
1015                              NFA_HCI_ANY_GET_PARAMETER, 1, &index);
1016   if (status == NFC_STATUS_OK) nfa_hci_cb.param_in_use = index;
1017 
1018   return status;
1019 }
1020 
1021 /*******************************************************************************
1022 **
1023 ** Function         nfa_hciu_send_set_param_cmd
1024 **
1025 ** Description      Set a parameter value in a gate registry
1026 **
1027 ** Returns          None
1028 **
1029 *******************************************************************************/
nfa_hciu_send_set_param_cmd(uint8_t pipe,uint8_t index,uint8_t length,uint8_t * p_data)1030 tNFA_STATUS nfa_hciu_send_set_param_cmd(uint8_t pipe, uint8_t index,
1031                                         uint8_t length, uint8_t* p_data) {
1032   tNFA_STATUS status;
1033   uint8_t data[255];
1034 
1035   data[0] = index;
1036 
1037   memcpy(&data[1], p_data, length);
1038 
1039   status =
1040       nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_SET_PARAMETER,
1041                         (uint16_t)(length + 1), data);
1042   if (status == NFC_STATUS_OK) nfa_hci_cb.param_in_use = index;
1043 
1044   return status;
1045 }
1046 
1047 /*******************************************************************************
1048 **
1049 ** Function         nfa_hciu_send_to_app
1050 **
1051 ** Description      Send an event back to an application
1052 **
1053 ** Returns          none
1054 **
1055 *******************************************************************************/
nfa_hciu_send_to_app(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt,tNFA_HANDLE app_handle)1056 void nfa_hciu_send_to_app(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt,
1057                           tNFA_HANDLE app_handle) {
1058   uint8_t app_inx = app_handle & NFA_HANDLE_MASK;
1059 
1060   /* First, check if the application handle is valid */
1061   if (((app_handle & NFA_HANDLE_GROUP_MASK) == NFA_HANDLE_GROUP_HCI) &&
1062       (app_inx < NFA_HCI_MAX_APP_CB)) {
1063     if (nfa_hci_cb.p_app_cback[app_inx] != nullptr) {
1064       nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
1065       return;
1066     }
1067   }
1068 
1069   if (app_handle != NFA_HANDLE_INVALID) {
1070     LOG(WARNING) << StringPrintf(
1071         "nfa_hciu_send_to_app no callback,  event: 0x%04x  app_handle: 0x%04x",
1072         event, app_handle);
1073   }
1074 }
1075 
1076 /*******************************************************************************
1077 **
1078 ** Function         nfa_hciu_send_to_all_apps
1079 **
1080 ** Description      Send an event back to all applications
1081 **
1082 ** Returns          none
1083 **
1084 *******************************************************************************/
nfa_hciu_send_to_all_apps(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt)1085 void nfa_hciu_send_to_all_apps(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt) {
1086   uint8_t app_inx;
1087 
1088   for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) {
1089     if (nfa_hci_cb.p_app_cback[app_inx] != nullptr)
1090       nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
1091   }
1092 }
1093 
1094 /*******************************************************************************
1095 **
1096 ** Function         nfa_hciu_send_to_apps_handling_connectivity_evts
1097 **
1098 ** Description      Send a connectivity event to all the application interested
1099 **                  in connectivity events
1100 **
1101 ** Returns          none
1102 **
1103 *******************************************************************************/
nfa_hciu_send_to_apps_handling_connectivity_evts(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt)1104 void nfa_hciu_send_to_apps_handling_connectivity_evts(
1105     tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt) {
1106   uint8_t app_inx;
1107 
1108   for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) {
1109     if ((nfa_hci_cb.p_app_cback[app_inx] != nullptr) &&
1110         (nfa_hci_cb.cfg.b_send_conn_evts[app_inx]))
1111 
1112       nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
1113   }
1114 }
1115 
1116 /*******************************************************************************
1117 **
1118 ** Function         nfa_hciu_get_response_name
1119 **
1120 ** Description      This function returns the error code name.
1121 **
1122 ** NOTE             conditionally compiled to save memory.
1123 **
1124 ** Returns          pointer to the name
1125 **
1126 *******************************************************************************/
nfa_hciu_get_response_name(uint8_t rsp_code)1127 static std::string nfa_hciu_get_response_name(uint8_t rsp_code) {
1128   switch (rsp_code) {
1129     case NFA_HCI_ANY_OK:
1130       return "ANY_OK";
1131     case NFA_HCI_ANY_E_NOT_CONNECTED:
1132       return "ANY_E_NOT_CONNECTED";
1133     case NFA_HCI_ANY_E_CMD_PAR_UNKNOWN:
1134       return "ANY_E_CMD_PAR_UNKNOWN";
1135     case NFA_HCI_ANY_E_NOK:
1136       return "ANY_E_NOK";
1137     case NFA_HCI_ADM_E_NO_PIPES_AVAILABLE:
1138       return "ADM_E_NO_PIPES_AVAILABLE";
1139     case NFA_HCI_ANY_E_REG_PAR_UNKNOWN:
1140       return "ANY_E_REG_PAR_UNKNOWN";
1141     case NFA_HCI_ANY_E_PIPE_NOT_OPENED:
1142       return "ANY_E_PIPE_NOT_OPENED";
1143     case NFA_HCI_ANY_E_CMD_NOT_SUPPORTED:
1144       return "ANY_E_CMD_NOT_SUPPORTED";
1145     case NFA_HCI_ANY_E_INHIBITED:
1146       return "ANY_E_INHIBITED";
1147     case NFA_HCI_ANY_E_TIMEOUT:
1148       return "ANY_E_TIMEOUT";
1149     case NFA_HCI_ANY_E_REG_ACCESS_DENIED:
1150       return "ANY_E_REG_ACCESS_DENIED";
1151     case NFA_HCI_ANY_E_PIPE_ACCESS_DENIED:
1152       return "ANY_E_PIPE_ACCESS_DENIED";
1153     default:
1154       return "UNKNOWN";
1155   }
1156 }
1157 
1158 /*******************************************************************************
1159 **
1160 ** Function         nfa_hciu_type_2_str
1161 **
1162 ** Description      This function returns the type name.
1163 **
1164 ** Returns          pointer to the name
1165 **
1166 *******************************************************************************/
nfa_hciu_type_2_str(uint8_t type)1167 static std::string nfa_hciu_type_2_str(uint8_t type) {
1168   switch (type) {
1169     case NFA_HCI_COMMAND_TYPE:
1170       return "COMMAND";
1171     case NFA_HCI_EVENT_TYPE:
1172       return "EVENT";
1173     case NFA_HCI_RESPONSE_TYPE:
1174       return "RESPONSE";
1175     default:
1176       return "UNKNOWN";
1177   }
1178 }
1179 
1180 /*******************************************************************************
1181 **
1182 ** Function         nfa_hciu_instr_2_str
1183 **
1184 ** Description      This function returns the instruction name.
1185 **
1186 ** Returns          pointer to the name
1187 **
1188 *******************************************************************************/
nfa_hciu_instr_2_str(uint8_t instruction)1189 std::string nfa_hciu_instr_2_str(uint8_t instruction) {
1190   switch (instruction) {
1191     case NFA_HCI_ANY_SET_PARAMETER:
1192       return "ANY_SET_PARAMETER";
1193     case NFA_HCI_ANY_GET_PARAMETER:
1194       return "ANY_GET_PARAMETER";
1195     case NFA_HCI_ANY_OPEN_PIPE:
1196       return "ANY_OPEN_PIPE";
1197     case NFA_HCI_ANY_CLOSE_PIPE:
1198       return "ANY_CLOSE_PIPE";
1199     case NFA_HCI_ADM_CREATE_PIPE:
1200       return "ADM_CREATE_PIPE";
1201     case NFA_HCI_ADM_DELETE_PIPE:
1202       return "ADM_DELETE_PIPE";
1203     case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
1204       return "ADM_NOTIFY_PIPE_CREATED";
1205     case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
1206       return "ADM_NOTIFY_PIPE_DELETED";
1207     case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1208       return "ADM_CLEAR_ALL_PIPE";
1209     case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
1210       return "ADM_NOTIFY_ALL_PIPE_CLEARED";
1211     default:
1212       return "UNKNOWN";
1213   }
1214 }
1215 
1216 /*******************************************************************************
1217 **
1218 ** Function         nfa_hciu_get_event_name
1219 **
1220 ** Description      This function returns the event code name.
1221 **
1222 ** Returns          pointer to the name
1223 **
1224 *******************************************************************************/
nfa_hciu_get_event_name(uint16_t event)1225 std::string nfa_hciu_get_event_name(uint16_t event) {
1226   switch (event) {
1227     case NFA_HCI_API_REGISTER_APP_EVT:
1228       return "API_REGISTER";
1229     case NFA_HCI_API_DEREGISTER_APP_EVT:
1230       return "API_DEREGISTER";
1231     case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
1232       return "API_GET_GATE_LIST";
1233     case NFA_HCI_API_ALLOC_GATE_EVT:
1234       return "API_ALLOC_GATE";
1235     case NFA_HCI_API_DEALLOC_GATE_EVT:
1236       return "API_DEALLOC_GATE";
1237     case NFA_HCI_API_GET_HOST_LIST_EVT:
1238       return "API_GET_HOST_LIST";
1239     case NFA_HCI_API_GET_REGISTRY_EVT:
1240       return "API_GET_REG_VALUE";
1241     case NFA_HCI_API_SET_REGISTRY_EVT:
1242       return "API_SET_REG_VALUE";
1243     case NFA_HCI_API_CREATE_PIPE_EVT:
1244       return "API_CREATE_PIPE";
1245     case NFA_HCI_API_OPEN_PIPE_EVT:
1246       return "API_OPEN_PIPE";
1247     case NFA_HCI_API_CLOSE_PIPE_EVT:
1248       return "API_CLOSE_PIPE";
1249     case NFA_HCI_API_DELETE_PIPE_EVT:
1250       return "API_DELETE_PIPE";
1251     case NFA_HCI_API_SEND_CMD_EVT:
1252       return "API_SEND_COMMAND_EVT";
1253     case NFA_HCI_API_SEND_RSP_EVT:
1254       return "API_SEND_RESPONSE_EVT";
1255     case NFA_HCI_API_SEND_EVENT_EVT:
1256       return "API_SEND_EVENT_EVT";
1257     case NFA_HCI_RSP_NV_READ_EVT:
1258       return "NV_READ_EVT";
1259     case NFA_HCI_RSP_NV_WRITE_EVT:
1260       return "NV_WRITE_EVT";
1261     case NFA_HCI_RSP_TIMEOUT_EVT:
1262       return "RESPONSE_TIMEOUT_EVT";
1263     case NFA_HCI_CHECK_QUEUE_EVT:
1264       return "CHECK_QUEUE";
1265     default:
1266       return "UNKNOWN";
1267   }
1268 }
1269 
1270 /*******************************************************************************
1271 **
1272 ** Function         nfa_hciu_get_state_name
1273 **
1274 ** Description      This function returns the state name.
1275 **
1276 ** Returns          pointer to the name
1277 **
1278 *******************************************************************************/
nfa_hciu_get_state_name(uint8_t state)1279 std::string nfa_hciu_get_state_name(uint8_t state) {
1280   switch (state) {
1281     case NFA_HCI_STATE_DISABLED:
1282       return "DISABLED";
1283     case NFA_HCI_STATE_STARTUP:
1284       return "STARTUP";
1285     case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
1286       return "WAIT_NETWK_ENABLE";
1287     case NFA_HCI_STATE_IDLE:
1288       return "IDLE";
1289     case NFA_HCI_STATE_WAIT_RSP:
1290       return "WAIT_RSP";
1291     case NFA_HCI_STATE_REMOVE_GATE:
1292       return "REMOVE_GATE";
1293     case NFA_HCI_STATE_APP_DEREGISTER:
1294       return "APP_DEREGISTER";
1295     case NFA_HCI_STATE_RESTORE:
1296       return "RESTORE";
1297     case NFA_HCI_STATE_RESTORE_NETWK_ENABLE:
1298       return "WAIT_NETWK_ENABLE_AFTER_RESTORE";
1299     default:
1300       return "UNKNOWN";
1301   }
1302 }
1303 
1304 /*******************************************************************************
1305 **
1306 ** Function         nfa_hciu_get_type_inst_names
1307 **
1308 ** Description      This function returns command/response/event name.
1309 **
1310 ** Returns          none
1311 **
1312 *******************************************************************************/
nfa_hciu_get_type_inst_names(uint8_t pipe,uint8_t type,uint8_t inst,char * p_buff)1313 char* nfa_hciu_get_type_inst_names(uint8_t pipe, uint8_t type, uint8_t inst,
1314                                    char* p_buff) {
1315   int xx;
1316 
1317   xx = sprintf(p_buff, "Type: %s [0x%02x] ", nfa_hciu_type_2_str(type).c_str(),
1318                type);
1319 
1320   switch (type) {
1321     case NFA_HCI_COMMAND_TYPE:
1322       sprintf(&p_buff[xx], "Inst: %s [0x%02x] ",
1323               nfa_hciu_instr_2_str(inst).c_str(), inst);
1324       break;
1325     case NFA_HCI_EVENT_TYPE:
1326       sprintf(&p_buff[xx], "Evt: %s [0x%02x] ",
1327               nfa_hciu_evt_2_str(pipe, inst).c_str(), inst);
1328       break;
1329     case NFA_HCI_RESPONSE_TYPE:
1330       sprintf(&p_buff[xx], "Resp: %s [0x%02x] ",
1331               nfa_hciu_get_response_name(inst).c_str(), inst);
1332       break;
1333     default:
1334       sprintf(&p_buff[xx], "Inst: %u ", inst);
1335       break;
1336   }
1337   return p_buff;
1338 }
1339 
1340 /*******************************************************************************
1341 **
1342 ** Function         nfa_hciu_evt_2_str
1343 **
1344 ** Description      This function returns the event name.
1345 **
1346 ** Returns          pointer to the name
1347 **
1348 *******************************************************************************/
nfa_hciu_evt_2_str(uint8_t pipe_id,uint8_t evt)1349 std::string nfa_hciu_evt_2_str(uint8_t pipe_id, uint8_t evt) {
1350   tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
1351   if (pipe_id != NFA_HCI_ADMIN_PIPE &&
1352       pipe_id != NFA_HCI_LINK_MANAGEMENT_PIPE && p_pipe != nullptr &&
1353       p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
1354     switch (evt) {
1355       case NFA_HCI_EVT_CONNECTIVITY:
1356         return "EVT_CONNECTIVITY";
1357       case NFA_HCI_EVT_TRANSACTION:
1358         return "EVT_TRANSACTION";
1359       case NFA_HCI_EVT_OPERATION_ENDED:
1360         return "EVT_OPERATION_ENDED";
1361       default:
1362         return "UNKNOWN";
1363     }
1364   }
1365 
1366   switch (evt) {
1367     case NFA_HCI_EVT_HCI_END_OF_OPERATION:
1368       return "EVT_END_OF_OPERATION";
1369     case NFA_HCI_EVT_POST_DATA:
1370       return "EVT_POST_DATA";
1371     case NFA_HCI_EVT_HOT_PLUG:
1372       return "EVT_HOT_PLUG";
1373     default:
1374       return "UNKNOWN";
1375   }
1376 }
1377 
handle_debug_loopback(NFC_HDR * p_buf,uint8_t type,uint8_t instruction)1378 static void handle_debug_loopback(NFC_HDR* p_buf, uint8_t type,
1379                                   uint8_t instruction) {
1380   uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1381   static uint8_t next_pipe = 0x10;
1382 
1383   if (type == NFA_HCI_COMMAND_TYPE) {
1384     switch (instruction) {
1385       case NFA_HCI_ADM_CREATE_PIPE:
1386         p[6] = next_pipe++;
1387         p[5] = p[4];
1388         p[4] = p[3];
1389         p[3] = p[2];
1390         p[2] = 3;
1391         p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1392         p_buf->len = p_buf->offset + 7;
1393         break;
1394 
1395       case NFA_HCI_ANY_GET_PARAMETER:
1396         p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1397         memcpy(&p[2], (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id,
1398                NFA_HCI_SESSION_ID_LEN);
1399         p_buf->len = p_buf->offset + 2 + NFA_HCI_SESSION_ID_LEN;
1400         break;
1401 
1402       default:
1403         p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1404         p_buf->len = p_buf->offset + 2;
1405         break;
1406     }
1407   } else if (type == NFA_HCI_RESPONSE_TYPE) {
1408     GKI_freebuf(p_buf);
1409     return;
1410   }
1411 
1412   p_buf->event = NFA_HCI_CHECK_QUEUE_EVT;
1413   nfa_sys_sendmsg(p_buf);
1414 }
1415