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