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