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