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