/******************************************************************************
 *
 *  Copyright (C) 2010-2014 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  This file contains the action functions for the NFA HCI.
 *
 ******************************************************************************/
#include <string.h>

#include <android-base/stringprintf.h>
#include <base/logging.h>
#include <log/log.h>

#include "nfa_dm_int.h"
#include "nfa_hci_api.h"
#include "nfa_hci_defs.h"
#include "nfa_hci_int.h"

using android::base::StringPrintf;

extern bool nfc_debug_enabled;

/* Static local functions       */
static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data);
static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data);
static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data);
static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data);
static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data);
static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data);
static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data);
static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);

static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
                                                  tNFA_HCI_DYN_PIPE* p_pipe);
static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
                                             tNFA_HCI_DYN_PIPE* p_pipe);
static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
                                                 uint16_t data_len,
                                                 tNFA_HCI_DYN_PIPE* p_pipe);
static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
                                            tNFA_HCI_DYN_PIPE* p_pipe);
static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
                                            tNFA_HCI_DYN_PIPE* p_pipe);
static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
                                            tNFA_HCI_DYN_GATE* p_gate,
                                            tNFA_HCI_DYN_PIPE* p_pipe);

/*******************************************************************************
**
** Function         nfa_hci_check_pending_api_requests
**
** Description      This function handles pending API requests
**
** Returns          none
**
*******************************************************************************/
void nfa_hci_check_pending_api_requests(void) {
  NFC_HDR* p_msg;
  tNFA_HCI_EVENT_DATA* p_evt_data;
  bool b_free;

  /* If busy, or API queue is empty, then exit */
  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
      ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_host_reset_api_q)) ==
       nullptr))
    return;

  /* Process API request */
  p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;

  /* Save the application handle */
  nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;

  b_free = true;
  switch (p_msg->event) {
    case NFA_HCI_API_CREATE_PIPE_EVT:
      if (nfa_hci_api_create_pipe(p_evt_data) == false) b_free = false;
      break;

    case NFA_HCI_API_GET_REGISTRY_EVT:
      if (nfa_hci_api_get_reg_value(p_evt_data) == false) b_free = false;
      break;

    case NFA_HCI_API_SET_REGISTRY_EVT:
      if (nfa_hci_api_set_reg_value(p_evt_data) == false) b_free = false;
      break;

    case NFA_HCI_API_SEND_CMD_EVT:
      if (nfa_hci_api_send_cmd(p_evt_data) == false) b_free = false;
      break;
    case NFA_HCI_API_SEND_EVENT_EVT:
      if (nfa_hci_api_send_event(p_evt_data) == false) b_free = false;
      break;
  }

  if (b_free) GKI_freebuf(p_msg);
}

/*******************************************************************************
**
** Function         nfa_hci_check_api_requests
**
** Description      This function handles API requests
**
** Returns          none
**
*******************************************************************************/
void nfa_hci_check_api_requests(void) {
  NFC_HDR* p_msg;
  tNFA_HCI_EVENT_DATA* p_evt_data;

  for (;;) {
    /* If busy, or API queue is empty, then exit */
    if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
        ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_api_q)) == nullptr))
      break;

    /* Process API request */
    p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;

    /* Save the application handle */
    nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;

    switch (p_msg->event) {
      case NFA_HCI_API_REGISTER_APP_EVT:
        nfa_hci_api_register(p_evt_data);
        break;

      case NFA_HCI_API_DEREGISTER_APP_EVT:
        nfa_hci_api_deregister(p_evt_data);
        break;

      case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
        nfa_hci_api_get_gate_pipe_list(p_evt_data);
        break;

      case NFA_HCI_API_ALLOC_GATE_EVT:
        nfa_hci_api_alloc_gate(p_evt_data);
        break;

      case NFA_HCI_API_DEALLOC_GATE_EVT:
        nfa_hci_api_dealloc_gate(p_evt_data);
        break;

      case NFA_HCI_API_GET_HOST_LIST_EVT:
        nfa_hci_api_get_host_list(p_evt_data);
        break;

      case NFA_HCI_API_GET_REGISTRY_EVT:
        if (nfa_hci_api_get_reg_value(p_evt_data) == false) continue;
        break;

      case NFA_HCI_API_SET_REGISTRY_EVT:
        if (nfa_hci_api_set_reg_value(p_evt_data) == false) continue;
        break;

      case NFA_HCI_API_CREATE_PIPE_EVT:
        if (nfa_hci_api_create_pipe(p_evt_data) == false) continue;
        break;

      case NFA_HCI_API_OPEN_PIPE_EVT:
        nfa_hci_api_open_pipe(p_evt_data);
        break;

      case NFA_HCI_API_CLOSE_PIPE_EVT:
        nfa_hci_api_close_pipe(p_evt_data);
        break;

      case NFA_HCI_API_DELETE_PIPE_EVT:
        nfa_hci_api_delete_pipe(p_evt_data);
        break;

      case NFA_HCI_API_SEND_CMD_EVT:
        if (nfa_hci_api_send_cmd(p_evt_data) == false) continue;
        break;

      case NFA_HCI_API_SEND_RSP_EVT:
        nfa_hci_api_send_rsp(p_evt_data);
        break;

      case NFA_HCI_API_SEND_EVENT_EVT:
        if (nfa_hci_api_send_event(p_evt_data) == false) continue;
        break;

      case NFA_HCI_API_ADD_STATIC_PIPE_EVT:
        nfa_hci_api_add_static_pipe(p_evt_data);
        break;

      default:
        LOG(ERROR) << StringPrintf("Unknown event: 0x%04x", p_msg->event);
        break;
    }

    GKI_freebuf(p_msg);
  }
}

/*******************************************************************************
**
** Function         nfa_hci_api_register
**
** Description      action function to register the events for the given AID
**
** Returns          None
**
*******************************************************************************/
static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_EVT_DATA evt_data;
  char* p_app_name = p_evt_data->app_info.app_name;
  tNFA_HCI_CBACK* p_cback = p_evt_data->app_info.p_cback;
  int xx, yy;
  uint8_t num_gates = 0, num_pipes = 0;
  tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;

  /* First, see if the application was already registered */
  for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
    if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
        !strncmp(p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0],
                 strlen(p_app_name))) {
      DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
          "nfa_hci_api_register (%s)  Reusing: %u", p_app_name, xx);
      break;
    }
  }

  if (xx != NFA_HCI_MAX_APP_CB) {
    nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
    /* The app was registered, find the number of gates and pipes associated to
     * the app */

    for (yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++) {
      if (pg->gate_owner == nfa_hci_cb.app_in_use) {
        num_gates++;
        num_pipes += nfa_hciu_count_pipes_on_gate(pg);
      }
    }
  } else {
    /* Not registered, look for a free entry */
    for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
      if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0) {
        memset(&nfa_hci_cb.cfg.reg_app_names[xx][0], 0,
               sizeof(nfa_hci_cb.cfg.reg_app_names[xx]));
        strncpy(&nfa_hci_cb.cfg.reg_app_names[xx][0], p_app_name,
                NFA_MAX_HCI_APP_NAME_LEN);
        nfa_hci_cb.nv_write_needed = true;
        DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
            "nfa_hci_api_register (%s)  Allocated: %u", p_app_name, xx);
        break;
      }
    }

    if (xx == NFA_HCI_MAX_APP_CB) {
      LOG(ERROR) << StringPrintf("nfa_hci_api_register (%s)  NO ENTRIES",
                                 p_app_name);

      evt_data.hci_register.status = NFA_STATUS_FAILED;
      p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
      return;
    }
  }

  evt_data.hci_register.num_pipes = num_pipes;
  evt_data.hci_register.num_gates = num_gates;
  nfa_hci_cb.p_app_cback[xx] = p_cback;

  nfa_hci_cb.cfg.b_send_conn_evts[xx] = p_evt_data->app_info.b_send_conn_evts;

  evt_data.hci_register.hci_handle = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);

  evt_data.hci_register.status = NFA_STATUS_OK;

  /* notify NFA_HCI_REGISTER_EVT to the application */
  p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
}

/*******************************************************************************
**
** Function         nfa_hci_api_deregister
**
** Description      action function to deregister the given application
**
** Returns          None
**
*******************************************************************************/
void nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HCI_CBACK* p_cback = nullptr;
  int xx;
  tNFA_HCI_DYN_PIPE* p_pipe;
  tNFA_HCI_DYN_GATE* p_gate;

  /* If needed, find the application registration handle */
  if (p_evt_data != nullptr) {
    for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
      if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
          !strncmp(p_evt_data->app_info.app_name,
                   &nfa_hci_cb.cfg.reg_app_names[xx][0],
                   strlen(p_evt_data->app_info.app_name))) {
        DLOG_IF(INFO, nfc_debug_enabled)
            << StringPrintf("nfa_hci_api_deregister (%s) inx: %u",
                            p_evt_data->app_info.app_name, xx);
        break;
      }
    }

    if (xx == NFA_HCI_MAX_APP_CB) {
      LOG(WARNING) << StringPrintf("Unknown app: %s",
                                   p_evt_data->app_info.app_name);
      return;
    }
    nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
    p_cback = nfa_hci_cb.p_app_cback[xx];
  } else {
    nfa_sys_stop_timer(&nfa_hci_cb.timer);
    /* We are recursing through deleting all the app's pipes and gates */
    p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK];
  }

  /* See if any pipe is owned by this app */
  if (nfa_hciu_find_pipe_by_owner(nfa_hci_cb.app_in_use) == nullptr) {
    /* No pipes, release all gates owned by this app */
    while ((p_gate = nfa_hciu_find_gate_by_owner(nfa_hci_cb.app_in_use)) !=
           nullptr)
      nfa_hciu_release_gate(p_gate->gate_id);

    memset(&nfa_hci_cb.cfg
                .reg_app_names[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK][0],
           0, NFA_MAX_HCI_APP_NAME_LEN + 1);
    nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = nullptr;

    nfa_hci_cb.nv_write_needed = true;

    evt_data.hci_deregister.status = NFC_STATUS_OK;

    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;

    /* notify NFA_HCI_DEREGISTER_EVT to the application */
    if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
  } else if ((p_pipe = nfa_hciu_find_active_pipe_by_owner(
                  nfa_hci_cb.app_in_use)) == nullptr) {
    /* No pipes, release all gates owned by this app */
    while ((p_gate = nfa_hciu_find_gate_with_nopipes_by_owner(
                nfa_hci_cb.app_in_use)) != nullptr)
      nfa_hciu_release_gate(p_gate->gate_id);

    nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = nullptr;

    nfa_hci_cb.nv_write_needed = true;

    evt_data.hci_deregister.status = NFC_STATUS_FAILED;

    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;

    /* notify NFA_HCI_DEREGISTER_EVT to the application */
    if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
  } else {
    /* Delete all active pipes created for the application before de registering
    **/
    nfa_hci_cb.hci_state = NFA_HCI_STATE_APP_DEREGISTER;

    nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
  }
}

/*******************************************************************************
**
** Function         nfa_hci_api_get_gate_pipe_list
**
** Description      action function to get application allocated gates and
**                  application created pipes
**
** Returns          None
**
*******************************************************************************/
static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_EVT_DATA evt_data;
  int xx, yy;
  tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
  tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;

  evt_data.gates_pipes.num_gates = 0;
  evt_data.gates_pipes.num_pipes = 0;

  for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
    if (pg->gate_owner == p_evt_data->get_gate_pipe_list.hci_handle) {
      evt_data.gates_pipes.gate[evt_data.gates_pipes.num_gates++] = pg->gate_id;

      pp = nfa_hci_cb.cfg.dyn_pipes;

      /* Loop through looking for a match */
      for (yy = 0; yy < NFA_HCI_MAX_PIPE_CB; yy++, pp++) {
        if (pp->local_gate == pg->gate_id)
          evt_data.gates_pipes.pipe[evt_data.gates_pipes.num_pipes++] =
              *(tNFA_HCI_PIPE_INFO*)pp;
      }
    }
  }

  evt_data.gates_pipes.num_uicc_created_pipes = 0;
  /* Loop through all pipes that are connected to connectivity gate */
  for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
       xx++, pp++) {
    if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
      memcpy(&evt_data.gates_pipes.uicc_created_pipe
                  [evt_data.gates_pipes.num_uicc_created_pipes++],
             pp, sizeof(tNFA_HCI_PIPE_INFO));
    } else if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_LOOP_BACK_GATE) {
      memcpy(&evt_data.gates_pipes.uicc_created_pipe
                  [evt_data.gates_pipes.num_uicc_created_pipes++],
             pp, sizeof(tNFA_HCI_PIPE_INFO));
    } else if (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE &&
               pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE && pp->pipe_id &&
               pp->local_gate >= NFA_HCI_FIRST_PROP_GATE &&
               pp->local_gate <= NFA_HCI_LAST_PROP_GATE) {
      for (yy = 0, pg = nfa_hci_cb.cfg.dyn_gates; yy < NFA_HCI_MAX_GATE_CB;
           yy++, pg++) {
        if (pp->local_gate == pg->gate_id) {
          if (!pg->gate_owner)
            memcpy(&evt_data.gates_pipes.uicc_created_pipe
                        [evt_data.gates_pipes.num_uicc_created_pipes++],
                   pp, sizeof(tNFA_HCI_PIPE_INFO));
          break;
        }
      }
    }
  }

  evt_data.gates_pipes.status = NFA_STATUS_OK;

  /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */
  nfa_hciu_send_to_app(NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data,
                       p_evt_data->get_gate_pipe_list.hci_handle);
}

/*******************************************************************************
**
** Function         nfa_hci_api_alloc_gate
**
** Description      action function to allocate gate
**
** Returns          None
**
*******************************************************************************/
static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HANDLE app_handle = p_evt_data->comm.hci_handle;
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HCI_DYN_GATE* p_gate;

  p_gate = nfa_hciu_alloc_gate(p_evt_data->gate_info.gate, app_handle);

  if (p_gate) {
    if (!p_gate->gate_owner) {
      /* No app owns the gate yet */
      p_gate->gate_owner = app_handle;
    } else if (p_gate->gate_owner != app_handle) {
      /* Some other app owns the gate */
      p_gate = nullptr;
      LOG(ERROR) << StringPrintf("The Gate (0X%02x) already taken!",
                                 p_evt_data->gate_info.gate);
    }
  }

  evt_data.allocated.gate = p_gate ? p_gate->gate_id : 0;
  evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED;

  /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */
  nfa_hciu_send_to_app(NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle);
}

/*******************************************************************************
**
** Function         nfa_hci_api_dealloc_gate
**
** Description      action function to deallocate the given generic gate
**
** Returns          None
**
*******************************************************************************/
void nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_EVT_DATA evt_data;
  uint8_t gate_id;
  tNFA_HCI_DYN_GATE* p_gate;
  tNFA_HCI_DYN_PIPE* p_pipe;
  tNFA_HANDLE app_handle;

  /* p_evt_data may be NULL if we are recursively deleting pipes */
  if (p_evt_data) {
    gate_id = p_evt_data->gate_dealloc.gate;
    app_handle = p_evt_data->gate_dealloc.hci_handle;

  } else {
    nfa_sys_stop_timer(&nfa_hci_cb.timer);
    gate_id = nfa_hci_cb.local_gate_in_use;
    app_handle = nfa_hci_cb.app_in_use;
  }

  evt_data.deallocated.gate = gate_id;
  ;

  p_gate = nfa_hciu_find_gate_by_gid(gate_id);

  if (p_gate == nullptr) {
    evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID;
  } else if (p_gate->gate_owner != app_handle) {
    evt_data.deallocated.status = NFA_STATUS_FAILED;
  } else {
    /* See if any pipe is owned by this app */
    if (nfa_hciu_find_pipe_on_gate(p_gate->gate_id) == nullptr) {
      nfa_hciu_release_gate(p_gate->gate_id);

      nfa_hci_cb.nv_write_needed = true;
      evt_data.deallocated.status = NFA_STATUS_OK;

      if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
        nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    } else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate(p_gate->gate_id)) ==
               nullptr) {
      /* UICC is not active at the moment and cannot delete the pipe */
      nfa_hci_cb.nv_write_needed = true;
      evt_data.deallocated.status = NFA_STATUS_FAILED;

      if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
        nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    } else {
      /* Delete pipes on the gate */
      nfa_hci_cb.local_gate_in_use = gate_id;
      nfa_hci_cb.app_in_use = app_handle;
      nfa_hci_cb.hci_state = NFA_HCI_STATE_REMOVE_GATE;

      nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
      return;
    }
  }

  nfa_hciu_send_to_app(NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle);
}

/*******************************************************************************
**
** Function         nfa_hci_api_get_host_list
**
** Description      action function to get the host list from HCI network
**
** Returns          None
**
*******************************************************************************/
static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
  uint8_t app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;

  nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;

  /* Send Get Host List command on "Internal request" or requested by registered
   * application with valid handle and callback function */
  if ((nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID) ||
      ((app_inx < NFA_HCI_MAX_APP_CB) &&
       (nfa_hci_cb.p_app_cback[app_inx] != nullptr))) {
    nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
  }
}

/*******************************************************************************
**
** Function         nfa_hci_api_create_pipe
**
** Description      action function to create a pipe
**
** Returns          TRUE, if the command is processed
**                  FALSE, if command is queued for processing later
**
*******************************************************************************/
static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_DYN_GATE* p_gate =
      nfa_hciu_find_gate_by_gid(p_evt_data->create_pipe.source_gate);
  tNFA_HCI_EVT_DATA evt_data;
  bool report_failed = false;

  /* Verify that the app owns the gate that the pipe is being created on */
  if ((p_gate == nullptr) ||
      (p_gate->gate_owner != p_evt_data->create_pipe.hci_handle)) {
    report_failed = true;
    LOG(ERROR) << StringPrintf(
        "nfa_hci_api_create_pipe Cannot create pipe! APP: 0x%02x does not own "
        "the gate:0x%x",
        p_evt_data->create_pipe.hci_handle,
        p_evt_data->create_pipe.source_gate);
  } else if (nfa_hciu_check_pipe_between_gates(
                 p_evt_data->create_pipe.source_gate,
                 p_evt_data->create_pipe.dest_host,
                 p_evt_data->create_pipe.dest_gate)) {
    report_failed = true;
    LOG(ERROR) << StringPrintf(
        "nfa_hci_api_create_pipe : Cannot create multiple pipe between the "
        "same two gates!");
  }

  if (report_failed) {
    evt_data.created.source_gate = p_evt_data->create_pipe.source_gate;
    evt_data.created.status = NFA_STATUS_FAILED;

    nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
                         p_evt_data->open_pipe.hci_handle);
  } else {
    if (nfa_hciu_is_host_reseting(p_evt_data->create_pipe.dest_gate)) {
      GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
      return false;
    }

    nfa_hci_cb.local_gate_in_use = p_evt_data->create_pipe.source_gate;
    nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
    nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
    nfa_hci_cb.app_in_use = p_evt_data->create_pipe.hci_handle;

    nfa_hciu_send_create_pipe_cmd(p_evt_data->create_pipe.source_gate,
                                  p_evt_data->create_pipe.dest_host,
                                  p_evt_data->create_pipe.dest_gate);
  }
  return true;
}

/*******************************************************************************
**
** Function         nfa_hci_api_open_pipe
**
** Description      action function to open a pipe
**
** Returns          None
**
*******************************************************************************/
static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HCI_DYN_PIPE* p_pipe =
      nfa_hciu_find_pipe_by_pid(p_evt_data->open_pipe.pipe);
  tNFA_HCI_DYN_GATE* p_gate = nullptr;

  if (p_pipe != nullptr) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);

  if ((p_pipe != nullptr) && (p_gate != nullptr) &&
      (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
      (p_gate->gate_owner == p_evt_data->open_pipe.hci_handle)) {
    if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
      nfa_hciu_send_open_pipe_cmd(p_evt_data->open_pipe.pipe);
    } else {
      evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
      evt_data.opened.status = NFA_STATUS_OK;

      nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
                           p_evt_data->open_pipe.hci_handle);
    }
  } else {
    evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
    evt_data.opened.status = NFA_STATUS_FAILED;

    nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
                         p_evt_data->open_pipe.hci_handle);
  }
}

/*******************************************************************************
**
** Function         nfa_hci_api_get_reg_value
**
** Description      action function to get the reg value of the specified index
**
** Returns          TRUE, if the command is processed
**                  FALSE, if command is queued for processing later
**
*******************************************************************************/
static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_DYN_PIPE* p_pipe =
      nfa_hciu_find_pipe_by_pid(p_evt_data->get_registry.pipe);
  tNFA_HCI_DYN_GATE* p_gate;
  tNFA_STATUS status = NFA_STATUS_FAILED;
  tNFA_HCI_EVT_DATA evt_data;

  if (p_pipe != nullptr) {
    p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);

    if ((p_gate != nullptr) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
        (p_gate->gate_owner == p_evt_data->get_registry.hci_handle)) {
      nfa_hci_cb.app_in_use = p_evt_data->get_registry.hci_handle;

      if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
        GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
        return false;
      }

      if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
        LOG(WARNING) << StringPrintf(
            "nfa_hci_api_get_reg_value pipe:%d not open",
            p_evt_data->get_registry.pipe);
      } else {
        status = nfa_hciu_send_get_param_cmd(p_evt_data->get_registry.pipe,
                                             p_evt_data->get_registry.reg_inx);
        if (status == NFA_STATUS_OK) return true;
      }
    }
  }

  evt_data.cmd_sent.status = status;

  /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
  nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
                       p_evt_data->get_registry.hci_handle);
  return true;
}

/*******************************************************************************
**
** Function         nfa_hci_api_set_reg_value
**
** Description      action function to set the reg value at specified index
**
** Returns          TRUE, if the command is processed
**                  FALSE, if command is queued for processing later
**
*******************************************************************************/
static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_DYN_PIPE* p_pipe =
      nfa_hciu_find_pipe_by_pid(p_evt_data->set_registry.pipe);
  tNFA_HCI_DYN_GATE* p_gate;
  tNFA_STATUS status = NFA_STATUS_FAILED;
  tNFA_HCI_EVT_DATA evt_data;

  if (p_pipe != nullptr) {
    p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);

    if ((p_gate != nullptr) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
        (p_gate->gate_owner == p_evt_data->set_registry.hci_handle)) {
      nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle;

      if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
        GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
        return false;
      }

      if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
        LOG(WARNING) << StringPrintf(
            "nfa_hci_api_set_reg_value pipe:%d not open",
            p_evt_data->set_registry.pipe);
      } else {
        status = nfa_hciu_send_set_param_cmd(
            p_evt_data->set_registry.pipe, p_evt_data->set_registry.reg_inx,
            p_evt_data->set_registry.size, p_evt_data->set_registry.data);
        if (status == NFA_STATUS_OK) return true;
      }
    }
  }
  evt_data.cmd_sent.status = status;

  /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
  nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
                       p_evt_data->set_registry.hci_handle);
  return true;
}

/*******************************************************************************
**
** Function         nfa_hci_api_close_pipe
**
** Description      action function to close a pipe
**
** Returns          None
**
*******************************************************************************/
static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HCI_DYN_PIPE* p_pipe =
      nfa_hciu_find_pipe_by_pid(p_evt_data->close_pipe.pipe);
  tNFA_HCI_DYN_GATE* p_gate = nullptr;

  if (p_pipe != nullptr) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);

  if ((p_pipe != nullptr) && (p_gate != nullptr) &&
      (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
      (p_gate->gate_owner == p_evt_data->close_pipe.hci_handle)) {
    if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
      nfa_hciu_send_close_pipe_cmd(p_evt_data->close_pipe.pipe);
    } else {
      evt_data.closed.status = NFA_STATUS_OK;
      evt_data.closed.pipe = p_evt_data->close_pipe.pipe;

      nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
                           p_evt_data->close_pipe.hci_handle);
    }
  } else {
    evt_data.closed.status = NFA_STATUS_FAILED;
    evt_data.closed.pipe = 0x00;

    nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
                         p_evt_data->close_pipe.hci_handle);
  }
}

/*******************************************************************************
**
** Function         nfa_hci_api_delete_pipe
**
** Description      action function to delete a pipe
**
** Returns          None
**
*******************************************************************************/
static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HCI_DYN_PIPE* p_pipe =
      nfa_hciu_find_pipe_by_pid(p_evt_data->delete_pipe.pipe);
  tNFA_HCI_DYN_GATE* p_gate = nullptr;

  if (p_pipe != nullptr) {
    p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
    if ((p_gate != nullptr) &&
        (p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle) &&
        (nfa_hciu_is_active_host(p_pipe->dest_host))) {
      nfa_hciu_send_delete_pipe_cmd(p_evt_data->delete_pipe.pipe);
      return;
    }
  }

  evt_data.deleted.status = NFA_STATUS_FAILED;
  evt_data.deleted.pipe = 0x00;
  nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
                       p_evt_data->close_pipe.hci_handle);
}

/*******************************************************************************
**
** Function         nfa_hci_api_send_cmd
**
** Description      action function to send command on the given pipe
**
** Returns          TRUE, if the command is processed
**                  FALSE, if command is queued for processing later
**
*******************************************************************************/
static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_STATUS status = NFA_STATUS_FAILED;
  tNFA_HCI_DYN_PIPE* p_pipe;
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HANDLE app_handle;

  if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_cmd.pipe)) != nullptr) {
    app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_cmd.pipe);

    if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
        ((app_handle == p_evt_data->send_cmd.hci_handle ||
          p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
      if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
        GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
        return false;
      }

      if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
        nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
        status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE,
                                   p_evt_data->send_cmd.cmd_code,
                                   p_evt_data->send_cmd.cmd_len,
                                   p_evt_data->send_cmd.data);
        if (status == NFA_STATUS_OK) return true;
      } else {
        LOG(WARNING) << StringPrintf("nfa_hci_api_send_cmd pipe:%d not open",
                                     p_pipe->pipe_id);
      }
    } else {
      LOG(WARNING) << StringPrintf(
          "nfa_hci_api_send_cmd pipe:%d Owned by different application or "
          "Destination host is not active",
          p_pipe->pipe_id);
    }
  } else {
    LOG(WARNING) << StringPrintf("nfa_hci_api_send_cmd pipe:%d not found",
                                 p_evt_data->send_cmd.pipe);
  }

  evt_data.cmd_sent.status = status;

  /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
  nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
                       p_evt_data->send_cmd.hci_handle);
  return true;
}

/*******************************************************************************
**
** Function         nfa_hci_api_send_rsp
**
** Description      action function to send response on the given pipe
**
** Returns          None
**
*******************************************************************************/
static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_STATUS status = NFA_STATUS_FAILED;
  tNFA_HCI_DYN_PIPE* p_pipe;
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HANDLE app_handle;

  if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_rsp.pipe)) != nullptr) {
    app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_rsp.pipe);

    if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
        ((app_handle == p_evt_data->send_rsp.hci_handle ||
          p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
      if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
        status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
                                   p_evt_data->send_rsp.response,
                                   p_evt_data->send_rsp.size,
                                   p_evt_data->send_rsp.data);
        if (status == NFA_STATUS_OK) return;
      } else {
        LOG(WARNING) << StringPrintf("nfa_hci_api_send_rsp pipe:%d not open",
                                     p_pipe->pipe_id);
      }
    } else {
      LOG(WARNING) << StringPrintf(
          "nfa_hci_api_send_rsp pipe:%d Owned by different application or "
          "Destination host is not active",
          p_pipe->pipe_id);
    }
  } else {
    LOG(WARNING) << StringPrintf("nfa_hci_api_send_rsp pipe:%d not found",
                                 p_evt_data->send_rsp.pipe);
  }

  evt_data.rsp_sent.status = status;

  /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
  nfa_hciu_send_to_app(NFA_HCI_RSP_SENT_EVT, &evt_data,
                       p_evt_data->send_rsp.hci_handle);
}

/*******************************************************************************
**
** Function         nfa_hci_api_send_event
**
** Description      action function to send an event to the given pipe
**
** Returns          TRUE, if the event is processed
**                  FALSE, if event is queued for processing later
**
*******************************************************************************/
static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_STATUS status = NFA_STATUS_FAILED;
  tNFA_HCI_DYN_PIPE* p_pipe;
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HANDLE app_handle;

  if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_evt.pipe)) != nullptr) {
    app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_evt.pipe);

    if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
        ((app_handle == p_evt_data->send_evt.hci_handle ||
          p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
      if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
        GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
        return false;
      }

      if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
        status = nfa_hciu_send_msg(
            p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code,
            p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf);

        if (status == NFA_STATUS_OK) {
          if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
            nfa_hci_cb.w4_rsp_evt = true;
            nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
          }

          if (p_evt_data->send_evt.rsp_len) {
            nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
            nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len;
            nfa_hci_cb.p_rsp_buf = p_evt_data->send_evt.p_rsp_buf;
            if (p_evt_data->send_evt.rsp_timeout) {
              nfa_hci_cb.w4_rsp_evt = true;
              nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
                                  p_evt_data->send_evt.rsp_timeout);
            } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
                                  p_nfa_hci_cfg->hcp_response_timeout);
            }
          } else {
            if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
              nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
                                  p_nfa_hci_cfg->hcp_response_timeout);
            }
            nfa_hci_cb.rsp_buf_size = 0;
            nfa_hci_cb.p_rsp_buf = nullptr;
          }
        }
      } else {
        LOG(WARNING) << StringPrintf("nfa_hci_api_send_event pipe:%d not open",
                                     p_pipe->pipe_id);
      }
    } else {
      LOG(WARNING) << StringPrintf(
          "nfa_hci_api_send_event pipe:%d Owned by different application or "
          "Destination host is not active",
          p_pipe->pipe_id);
    }
  } else {
    LOG(WARNING) << StringPrintf("nfa_hci_api_send_event pipe:%d not found",
                                 p_evt_data->send_evt.pipe);
  }

  evt_data.evt_sent.status = status;

  /* Send NFC_HCI_EVENT_SENT_EVT to notify status */
  nfa_hciu_send_to_app(NFA_HCI_EVENT_SENT_EVT, &evt_data,
                       p_evt_data->send_evt.hci_handle);
  return true;
}

/*******************************************************************************
**
** Function         nfa_hci_api_add_static_pipe
**
** Description      action function to add static pipe
**
** Returns          None
**
*******************************************************************************/
static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
  tNFA_HCI_DYN_GATE* pg;
  tNFA_HCI_DYN_PIPE* pp;
  tNFA_HCI_EVT_DATA evt_data;

  /* Allocate a proprietary gate */
  pg = nfa_hciu_alloc_gate(p_evt_data->add_static_pipe.gate,
                           p_evt_data->add_static_pipe.hci_handle);
  if (pg != nullptr) {
    /* Assign new owner to the gate */
    pg->gate_owner = p_evt_data->add_static_pipe.hci_handle;

    /* Add the dynamic pipe to the proprietary gate */
    if (nfa_hciu_add_pipe_to_gate(p_evt_data->add_static_pipe.pipe, pg->gate_id,
                                  p_evt_data->add_static_pipe.host,
                                  p_evt_data->add_static_pipe.gate) !=
        NFA_HCI_ANY_OK) {
      /* Unable to add the dynamic pipe, so release the gate */
      nfa_hciu_release_gate(pg->gate_id);
      evt_data.pipe_added.status = NFA_STATUS_FAILED;
      nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
                           p_evt_data->add_static_pipe.hci_handle);
      return;
    }
    pp = nfa_hciu_find_pipe_by_pid(p_evt_data->add_static_pipe.pipe);
    if (pp != nullptr) {
      /* This pipe is always opened */
      pp->pipe_state = NFA_HCI_PIPE_OPENED;
      evt_data.pipe_added.status = NFA_STATUS_OK;
      nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
                           p_evt_data->add_static_pipe.hci_handle);
      return;
    }
  }
  /* Unable to add static pipe */
  evt_data.pipe_added.status = NFA_STATUS_FAILED;
  nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
                       p_evt_data->add_static_pipe.hci_handle);
}

/*******************************************************************************
**
** Function         nfa_hci_handle_link_mgm_gate_cmd
**
** Description      This function handles incoming link management gate hci
**                  commands
**
** Returns          none
**
*******************************************************************************/
void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data) {
  uint8_t index;
  uint8_t data[2];
  uint8_t rsp_len = 0;
  uint8_t response = NFA_HCI_ANY_OK;

  if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) &&
      (nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE)) {
    nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE,
                      NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, nullptr);
    return;
  }

  switch (nfa_hci_cb.inst) {
    case NFA_HCI_ANY_SET_PARAMETER:
      STREAM_TO_UINT8(index, p_data);

      if (index == 1) {
        STREAM_TO_UINT16(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
      } else
        response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
      break;

    case NFA_HCI_ANY_GET_PARAMETER:
      STREAM_TO_UINT8(index, p_data);
      if (index == 1) {
        data[0] =
            (uint8_t)((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF);
        data[1] = (uint8_t)(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F);
        rsp_len = 2;
      } else
        response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
      break;

    case NFA_HCI_ANY_OPEN_PIPE:
      data[0] = 0;
      rsp_len = 1;
      nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED;
      break;

    case NFA_HCI_ANY_CLOSE_PIPE:
      nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
      break;

    default:
      response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
      break;
  }

  nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE,
                    response, rsp_len, data);
}

/*******************************************************************************
**
** Function         nfa_hci_handle_pipe_open_close_cmd
**
** Description      This function handles all generic gates (excluding
**                  connectivity gate) commands
**
** Returns          none
**
*******************************************************************************/
void nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE* p_pipe) {
  uint8_t data[1];
  uint8_t rsp_len = 0;
  tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
  tNFA_HCI_DYN_GATE* p_gate;

  if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
    if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != nullptr)
      data[0] = nfa_hciu_count_open_pipes_on_gate(p_gate);
    else
      data[0] = 0;

    p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
    rsp_len = 1;
  } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
    p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
  }

  nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
                    data);
}

/*******************************************************************************
**
** Function         nfa_hci_handle_admin_gate_cmd
**
** Description      This function handles incoming commands on ADMIN gate
**
** Returns          none
**
*******************************************************************************/
void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data) {
  uint8_t source_host, source_gate, dest_host, dest_gate, pipe;
  uint8_t data = 0;
  uint8_t rsp_len = 0;
  tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
  tNFA_HCI_DYN_GATE* pgate;
  tNFA_HCI_EVT_DATA evt_data;

  switch (nfa_hci_cb.inst) {
    case NFA_HCI_ANY_OPEN_PIPE:
      nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
      data = 0;
      rsp_len = 1;
      break;

    case NFA_HCI_ANY_CLOSE_PIPE:
      nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
      /* Reopen the pipe immediately */
      nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response,
                        rsp_len, &data);
      nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
      nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
      return;
      break;

    case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
      STREAM_TO_UINT8(source_host, p_data);
      STREAM_TO_UINT8(source_gate, p_data);
      STREAM_TO_UINT8(dest_host, p_data);
      STREAM_TO_UINT8(dest_gate, p_data);
      STREAM_TO_UINT8(pipe, p_data);

      if ((dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) ||
          (dest_gate == NFA_HCI_LOOP_BACK_GATE)) {
        response = nfa_hciu_add_pipe_to_static_gate(dest_gate, pipe,
                                                    source_host, source_gate);
      } else {
        if ((pgate = nfa_hciu_find_gate_by_gid(dest_gate)) != nullptr) {
          /* If the gate is valid, add the pipe to it  */
          if (nfa_hciu_check_pipe_between_gates(dest_gate, source_host,
                                                source_gate)) {
            /* Already, there is a pipe between these two gates, so will reject
             */
            response = NFA_HCI_ANY_E_NOK;
          } else {
            response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host,
                                                 source_gate);
            if (response == NFA_HCI_ANY_OK) {
              /* Tell the application a pipe was created with its gate */

              evt_data.created.status = NFA_STATUS_OK;
              evt_data.created.pipe = pipe;
              evt_data.created.source_gate = dest_gate;
              evt_data.created.dest_host = source_host;
              evt_data.created.dest_gate = source_gate;

              nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
                                   pgate->gate_owner);
            }
          }
        } else {
          response = NFA_HCI_ANY_E_NOK;
          if ((dest_gate >= NFA_HCI_FIRST_PROP_GATE) &&
              (dest_gate <= NFA_HCI_LAST_PROP_GATE)) {
            if (nfa_hciu_alloc_gate(dest_gate, 0))
              response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host,
                                                   source_gate);
          }
        }
      }
      break;

    case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
      STREAM_TO_UINT8(pipe, p_data);
      response = nfa_hciu_release_pipe(pipe);
      break;

    case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
      STREAM_TO_UINT8(source_host, p_data);

      nfa_hciu_remove_all_pipes_from_host(source_host);

      if (source_host == NFA_HCI_HOST_CONTROLLER) {
        nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;

        /* Reopen the admin pipe immediately */
        nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
        nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
        return;
      } else {
        uint8_t host_index = 0;

        if ((source_host == NFA_HCI_HOST_ID_UICC0) ||
            (source_host >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
          while (host_index < NFA_HCI_MAX_HOST_IN_NETWORK) {
            if (nfa_hci_cb.reset_host[host_index] == 0x0) {
              nfa_hci_cb.reset_host[host_index] = source_host;
              break;
            }
            host_index++;
          }
        }
      }
      break;

    default:
      response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
      break;
  }

  nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response,
                    rsp_len, &data);
}

/*******************************************************************************
**
** Function         nfa_hci_handle_admin_gate_rsp
**
** Description      This function handles response received on admin gate
**
** Returns          none
**
*******************************************************************************/
void nfa_hci_handle_admin_gate_rsp(uint8_t* p_data, uint8_t data_len) {
  uint8_t source_host;
  uint8_t source_gate = nfa_hci_cb.local_gate_in_use;
  uint8_t dest_host = nfa_hci_cb.remote_host_in_use;
  uint8_t dest_gate = nfa_hci_cb.remote_gate_in_use;
  uint8_t pipe = 0;
  tNFA_STATUS status;
  tNFA_HCI_EVT_DATA evt_data;
  uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
                                                     0xFF, 0xFF, 0xFF, 0xFF};
  uint8_t host_count = 0;
  uint8_t host_id = 0;
  uint32_t os_tick;

  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
      "nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s  App: 0x%04x  Gate: "
      "0x%02x  Pipe: 0x%02x",
      nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent).c_str(), nfa_hci_cb.app_in_use,
      nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);

  /* If starting up, handle events here */
  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ||
      (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
    if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED) {
      nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
      return;
    }

    if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) {
      LOG(ERROR) << StringPrintf(
          "nfa_hci_handle_admin_gate_rsp - Initialization failed");
      nfa_hci_startup_complete(NFA_STATUS_FAILED);
      return;
    }

    switch (nfa_hci_cb.cmd_sent) {
      case NFA_HCI_ANY_SET_PARAMETER:
        if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
          /* Set WHITELIST */
          nfa_hciu_send_set_param_cmd(
              NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
              p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
        } else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX) {
          if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
              (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))
            nfa_hci_dh_startup_complete();
          if (NFA_GetNCIVersion() == NCI_VERSION_2_0) {
            nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
            NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
            nfa_hci_enable_one_nfcee();
          }
        }
        break;

      case NFA_HCI_ANY_GET_PARAMETER:
        if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
          uint8_t host_index = 0;

          memset(nfa_hci_cb.active_host, 0x0, NFA_HCI_MAX_HOST_IN_NETWORK);

          host_count = 0;

          /* Collect active host in the Host Network */
          while ((host_count < data_len) &&
                 (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)) {
            host_id = (uint8_t)*p_data++;

            if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
                (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
              nfa_hci_cb.active_host[host_index] = host_id;
              uint8_t index = 0;
              while (index < NFA_HCI_MAX_HOST_IN_NETWORK) {
                if (nfa_hci_cb.reset_host[index] == host_id) {
                  nfa_hci_cb.reset_host[index] = 0x0;
                  break;
                }
                index++;
              }
              host_index++;
            }
            host_count++;
          }

          nfa_hci_startup_complete(NFA_STATUS_OK);
        } else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
          /* The only parameter we get when initializing is the session ID.
           * Check for match. */
          if (data_len >= NFA_HCI_SESSION_ID_LEN &&
              !memcmp((uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id, p_data,
                      NFA_HCI_SESSION_ID_LEN)) {
            /* Session has not changed, Set WHITELIST */
            nfa_hciu_send_set_param_cmd(
                NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
                p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
          } else {
            /* Something wrong, NVRAM data could be corrupt or first start with
             * default session id */
            nfa_hciu_send_clear_all_pipe_cmd();
            nfa_hci_cb.b_hci_netwk_reset = true;
            if (data_len < NFA_HCI_SESSION_ID_LEN) {
              android_errorWriteLog(0x534e4554, "124524315");
            }
          }
        }
        break;

      case NFA_HCI_ANY_OPEN_PIPE:
        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;

        if (nfa_hci_cb.b_hci_netwk_reset) {
          nfa_hci_cb.b_hci_netwk_reset = false;
          /* Session ID is reset, Set New session id */
          memcpy(
              &nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2],
              nfa_hci_cb.cfg.admin_gate.session_id,
              (NFA_HCI_SESSION_ID_LEN / 2));
          os_tick = GKI_get_os_tick_count();
          memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
                 (NFA_HCI_SESSION_ID_LEN / 2));
          nfa_hciu_send_set_param_cmd(
              NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
              NFA_HCI_SESSION_ID_LEN,
              (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
        } else {
          /* First thing is to get the session ID */
          nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
                                      NFA_HCI_SESSION_IDENTITY_INDEX);
        }
        break;

      case NFA_HCI_ADM_CLEAR_ALL_PIPE:
        nfa_hciu_remove_all_pipes_from_host(0);
        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
        nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
        nfa_hci_cb.nv_write_needed = true;

        /* Open admin */
        nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
        break;
    }
  } else {
    status =
        (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;

    switch (nfa_hci_cb.cmd_sent) {
      case NFA_HCI_ANY_SET_PARAMETER:
        if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
          nfa_hci_api_deregister(nullptr);
        else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
          nfa_hci_api_dealloc_gate(nullptr);
        break;

      case NFA_HCI_ANY_GET_PARAMETER:
        if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
          if (data_len >= NFA_HCI_SESSION_ID_LEN &&
              !memcmp((uint8_t*)default_session, p_data,
                      NFA_HCI_SESSION_ID_LEN)) {
            memcpy(&nfa_hci_cb.cfg.admin_gate
                        .session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
                   nfa_hci_cb.cfg.admin_gate.session_id,
                   (NFA_HCI_SESSION_ID_LEN / 2));
            os_tick = GKI_get_os_tick_count();
            memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
                   (NFA_HCI_SESSION_ID_LEN / 2));
            nfa_hci_cb.nv_write_needed = true;
            nfa_hciu_send_set_param_cmd(
                NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
                NFA_HCI_SESSION_ID_LEN,
                (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
          } else {
            if (data_len < NFA_HCI_SESSION_ID_LEN) {
              android_errorWriteLog(0x534e4554, "124524315");
            }
            if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
              nfa_hci_api_deregister(nullptr);
            else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
              nfa_hci_api_dealloc_gate(nullptr);
          }
        } else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
          evt_data.hosts.status = status;
          if (data_len > NFA_HCI_MAX_HOST_IN_NETWORK) {
            data_len = NFA_HCI_MAX_HOST_IN_NETWORK;
            android_errorWriteLog(0x534e4554, "124524315");
          }
          evt_data.hosts.num_hosts = data_len;
          memcpy(evt_data.hosts.host, p_data, data_len);

          uint8_t host_index = 0;

          memset(nfa_hci_cb.active_host, 0x0, NFA_HCI_MAX_HOST_IN_NETWORK);

          host_count = 0;
          /* Collect active host in the Host Network */
          while ((host_count < data_len) &&
                 (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)) {
            host_id = (uint8_t)*p_data++;

            if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
                (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
              nfa_hci_cb.active_host[host_index] = host_id;
              uint8_t index = 0;
              while (index < NFA_HCI_MAX_HOST_IN_NETWORK) {
                if (nfa_hci_cb.reset_host[index] == host_id) {
                  nfa_hci_cb.reset_host[index] = 0x0;
                  break;
                }
                index++;
              }
              host_index++;
            }
            host_count++;
          }

          if (nfa_hciu_is_no_host_resetting())
            nfa_hci_check_pending_api_requests();
          nfa_hciu_send_to_app(NFA_HCI_HOST_LIST_EVT, &evt_data,
                               nfa_hci_cb.app_in_use);
        }
        break;

      case NFA_HCI_ADM_CREATE_PIPE:
        // p_data should have at least 5 bytes length for pipe info
        if (data_len >= 5 && status == NFA_STATUS_OK) {
          STREAM_TO_UINT8(source_host, p_data);
          STREAM_TO_UINT8(source_gate, p_data);
          STREAM_TO_UINT8(dest_host, p_data);
          STREAM_TO_UINT8(dest_gate, p_data);
          STREAM_TO_UINT8(pipe, p_data);

          /* Sanity check */
          if (source_gate != nfa_hci_cb.local_gate_in_use) {
            LOG(WARNING) << StringPrintf(
                "nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u "
                "got back: %u",
                nfa_hci_cb.local_gate_in_use, source_gate);
            break;
          }

          nfa_hciu_add_pipe_to_gate(pipe, source_gate, dest_host, dest_gate);
        } else if (data_len < 5 && status == NFA_STATUS_OK) {
          android_errorWriteLog(0x534e4554, "124524315");
          status = NFA_STATUS_FAILED;
        }

        /* Tell the application his pipe was created or not */
        evt_data.created.status = status;
        evt_data.created.pipe = pipe;
        evt_data.created.source_gate = source_gate;
        evt_data.created.dest_host = dest_host;
        evt_data.created.dest_gate = dest_gate;

        nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
                             nfa_hci_cb.app_in_use);
        break;

      case NFA_HCI_ADM_DELETE_PIPE:
        if (status == NFA_STATUS_OK) {
          nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);

          /* If only deleting one pipe, tell the app we are done */
          if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
            evt_data.deleted.status = status;
            evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;

            nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
                                 nfa_hci_cb.app_in_use);
          } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
            nfa_hci_api_deregister(nullptr);
          else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
            nfa_hci_api_dealloc_gate(nullptr);
        } else {
          /* If only deleting one pipe, tell the app we are done */
          if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
            evt_data.deleted.status = status;
            evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;

            nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
                                 nfa_hci_cb.app_in_use);
          } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) {
            nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
            nfa_hci_api_deregister(nullptr);
          } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) {
            nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
            nfa_hci_api_dealloc_gate(nullptr);
          }
        }
        break;

      case NFA_HCI_ANY_OPEN_PIPE:
        nfa_hci_cb.cfg.admin_gate.pipe01_state =
            status ? NFA_HCI_PIPE_CLOSED : NFA_HCI_PIPE_OPENED;
        nfa_hci_cb.nv_write_needed = true;
        if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED) {
          /* First thing is to get the session ID */
          nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
                                      NFA_HCI_SESSION_IDENTITY_INDEX);
        }
        break;

      case NFA_HCI_ADM_CLEAR_ALL_PIPE:
        nfa_hciu_remove_all_pipes_from_host(0);
        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
        nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
        nfa_hci_cb.nv_write_needed = true;
        /* Open admin */
        nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
        break;
    }
  }
}

/*******************************************************************************
**
** Function         nfa_hci_handle_admin_gate_evt
**
** Description      This function handles events received on admin gate
**
** Returns          none
**
*******************************************************************************/
void nfa_hci_handle_admin_gate_evt() {
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HCI_API_GET_HOST_LIST* p_msg;

  if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG) {
    LOG(ERROR) << StringPrintf(
        "nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
    return;
  }

  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
      "nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe");
  nfa_hci_cb.num_hot_plug_evts++;

  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
    /* Received Hot Plug evt while waiting for other Host in the network to
     * bootup after DH host bootup is complete */
    if ((nfa_hci_cb.ee_disable_disc) &&
        (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
        (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
      /* Received expected number of Hot Plug event(s) before as many number of
       * EE DISC REQ Ntf(s) are received */
      nfa_sys_stop_timer(&nfa_hci_cb.timer);
      /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ
       * Ntf(s) */
      nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
                          p_nfa_hci_cfg->hci_netwk_enable_timeout);
    }
  } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
             (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
    /* Received Hot Plug evt during DH host bootup */
    if ((nfa_hci_cb.ee_disable_disc) &&
        (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
        (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
      /* Received expected number of Hot Plug event(s) before as many number of
       * EE DISC REQ Ntf(s) are received */
      nfa_hci_cb.w4_hci_netwk_init = false;
    }
  } else {
    /* Received Hot Plug evt on UICC self reset */
    evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
    /* Notify all registered application with the HOT_PLUG_EVT */
    nfa_hciu_send_to_all_apps(NFA_HCI_EVENT_RCVD_EVT, &evt_data);

    /* Send Get Host List after receiving any pending response */
    p_msg = (tNFA_HCI_API_GET_HOST_LIST*)GKI_getbuf(
        sizeof(tNFA_HCI_API_GET_HOST_LIST));
    if (p_msg != nullptr) {
      p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT;
      /* Set Invalid handle to identify this Get Host List command is internal
       */
      p_msg->hci_handle = NFA_HANDLE_INVALID;

      nfa_sys_sendmsg(p_msg);
    }
  }
}

/*******************************************************************************
**
** Function         nfa_hci_handle_dyn_pipe_pkt
**
** Description      This function handles data received via dynamic pipe
**
** Returns          none
**
*******************************************************************************/
void nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id, uint8_t* p_data,
                                 uint16_t data_len) {
  tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
  tNFA_HCI_DYN_GATE* p_gate;

  if (p_pipe == nullptr) {
    /* Invalid pipe ID */
    LOG(ERROR) << StringPrintf("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",
                               pipe_id);
    if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
      nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
                        nullptr);
    return;
  }

  if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
    nfa_hci_handle_identity_mgmt_gate_pkt(p_data, p_pipe);
  } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
    nfa_hci_handle_loopback_gate_pkt(p_data, data_len, p_pipe);
  } else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
    nfa_hci_handle_connectivity_gate_pkt(p_data, data_len, p_pipe);
  } else {
    p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
    if (p_gate == nullptr) {
      LOG(ERROR) << StringPrintf(
          "nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",
          p_pipe->local_gate);
      if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
        nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
                          nullptr);
      return;
    }

    /* Check if data packet is a command, response or event */
    switch (nfa_hci_cb.type) {
      case NFA_HCI_COMMAND_TYPE:
        nfa_hci_handle_generic_gate_cmd(p_data, (uint8_t)data_len, p_pipe);
        break;

      case NFA_HCI_RESPONSE_TYPE:
        nfa_hci_handle_generic_gate_rsp(p_data, (uint8_t)data_len, p_pipe);
        break;

      case NFA_HCI_EVENT_TYPE:
        nfa_hci_handle_generic_gate_evt(p_data, data_len, p_gate, p_pipe);
        break;
    }
  }
}

/*******************************************************************************
**
** Function         nfa_hci_handle_identity_mgmt_gate_pkt
**
** Description      This function handles incoming Identity Management gate hci
**                  commands
**
** Returns          none
**
*******************************************************************************/
static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
                                                  tNFA_HCI_DYN_PIPE* p_pipe) {
  uint8_t data[20];
  uint8_t index;
  uint8_t gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
  uint16_t rsp_len = 0;
  uint8_t* p_rsp = data;
  tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;

  /* We never send commands on a pipe where the local gate is the identity
   * management
   * gate, so only commands should be processed.
   */
  if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE) return;

  switch (nfa_hci_cb.inst) {
    case NFA_HCI_ANY_GET_PARAMETER:
      index = *(p_data++);
      if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
        switch (index) {
          case NFA_HCI_VERSION_SW_INDEX:
            data[0] = (uint8_t)((NFA_HCI_VERSION_SW >> 16) & 0xFF);
            data[1] = (uint8_t)((NFA_HCI_VERSION_SW >> 8) & 0xFF);
            data[2] = (uint8_t)((NFA_HCI_VERSION_SW)&0xFF);
            rsp_len = 3;
            break;

          case NFA_HCI_HCI_VERSION_INDEX:
            data[0] = NFA_HCI_VERSION;
            rsp_len = 1;
            break;

          case NFA_HCI_VERSION_HW_INDEX:
            data[0] = (uint8_t)((NFA_HCI_VERSION_HW >> 16) & 0xFF);
            data[1] = (uint8_t)((NFA_HCI_VERSION_HW >> 8) & 0xFF);
            data[2] = (uint8_t)((NFA_HCI_VERSION_HW)&0xFF);
            rsp_len = 3;
            break;

          case NFA_HCI_VENDOR_NAME_INDEX:
            memcpy(data, NFA_HCI_VENDOR_NAME, strlen(NFA_HCI_VENDOR_NAME));
            rsp_len = (uint8_t)strlen(NFA_HCI_VENDOR_NAME);
            break;

          case NFA_HCI_MODEL_ID_INDEX:
            data[0] = NFA_HCI_MODEL_ID;
            rsp_len = 1;
            break;

          case NFA_HCI_GATES_LIST_INDEX:
            gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
            gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
            gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
            num_gates = nfa_hciu_get_allocated_gate_list(&gate_rsp[3]);
            rsp_len = num_gates + 3;
            p_rsp = gate_rsp;
            break;

          default:
            response = NFA_HCI_ANY_E_NOK;
            break;
        }
      } else {
        response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
      }
      break;

    case NFA_HCI_ANY_OPEN_PIPE:
      data[0] = 0;
      rsp_len = 1;
      p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
      break;

    case NFA_HCI_ANY_CLOSE_PIPE:
      p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
      break;

    default:
      response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
      break;
  }

  nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
                    p_rsp);
}

/*******************************************************************************
**
** Function         nfa_hci_handle_generic_gate_cmd
**
** Description      This function handles all generic gates (excluding
**                  connectivity gate) commands
**
** Returns          none
**
*******************************************************************************/
static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
                                            tNFA_HCI_DYN_PIPE* p_pipe) {
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner(p_pipe->pipe_id);

  switch (nfa_hci_cb.inst) {
    case NFA_HCI_ANY_SET_PARAMETER:
      evt_data.registry.pipe = p_pipe->pipe_id;
      evt_data.registry.index = *p_data++;
      if (data_len > 0) data_len--;
      evt_data.registry.data_len = data_len;

      memcpy(evt_data.registry.reg_data, p_data, data_len);

      nfa_hciu_send_to_app(NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
      break;

    case NFA_HCI_ANY_GET_PARAMETER:
      evt_data.registry.pipe = p_pipe->pipe_id;
      evt_data.registry.index = *p_data;
      evt_data.registry.data_len = 0;

      nfa_hciu_send_to_app(NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
      break;

    case NFA_HCI_ANY_OPEN_PIPE:
      nfa_hci_handle_pipe_open_close_cmd(p_pipe);

      evt_data.opened.pipe = p_pipe->pipe_id;
      evt_data.opened.status = NFA_STATUS_OK;

      nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
      break;

    case NFA_HCI_ANY_CLOSE_PIPE:
      nfa_hci_handle_pipe_open_close_cmd(p_pipe);

      evt_data.closed.pipe = p_pipe->pipe_id;
      evt_data.opened.status = NFA_STATUS_OK;

      nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
      break;

    default:
      /* Could be application specific command, pass it on */
      evt_data.cmd_rcvd.status = NFA_STATUS_OK;
      evt_data.cmd_rcvd.pipe = p_pipe->pipe_id;
      ;
      evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
      evt_data.cmd_rcvd.cmd_len = data_len;

      if (data_len <= NFA_MAX_HCI_CMD_LEN)
        memcpy(evt_data.cmd_rcvd.cmd_data, p_data, data_len);

      nfa_hciu_send_to_app(NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
      break;
  }
}

/*******************************************************************************
**
** Function         nfa_hci_handle_generic_gate_rsp
**
** Description      This function handles all generic gates (excluding
**                  connectivity) response
**
** Returns          none
**
*******************************************************************************/
static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
                                            tNFA_HCI_DYN_PIPE* p_pipe) {
  tNFA_HCI_EVT_DATA evt_data;
  tNFA_STATUS status = NFA_STATUS_OK;

  if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) status = NFA_STATUS_FAILED;

  if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) {
    if (status == NFA_STATUS_OK) p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;

    nfa_hci_cb.nv_write_needed = true;
    /* Tell application */
    evt_data.opened.status = status;
    evt_data.opened.pipe = p_pipe->pipe_id;

    nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
                         nfa_hci_cb.app_in_use);
  } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) {
    p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;

    nfa_hci_cb.nv_write_needed = true;
    /* Tell application */
    evt_data.opened.status = status;
    ;
    evt_data.opened.pipe = p_pipe->pipe_id;

    nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
                         nfa_hci_cb.app_in_use);
  } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) {
    /* Tell application */
    evt_data.registry.status = status;
    evt_data.registry.pipe = p_pipe->pipe_id;
    evt_data.registry.data_len = data_len;
    evt_data.registry.index = nfa_hci_cb.param_in_use;

    memcpy(evt_data.registry.reg_data, p_data, data_len);

    nfa_hciu_send_to_app(NFA_HCI_GET_REG_RSP_EVT, &evt_data,
                         nfa_hci_cb.app_in_use);
  } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER) {
    /* Tell application */
    evt_data.registry.status = status;
    ;
    evt_data.registry.pipe = p_pipe->pipe_id;

    nfa_hciu_send_to_app(NFA_HCI_SET_REG_RSP_EVT, &evt_data,
                         nfa_hci_cb.app_in_use);
  } else {
    /* Could be a response to application specific command sent, pass it on */
    evt_data.rsp_rcvd.status = NFA_STATUS_OK;
    evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
    ;
    evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
    evt_data.rsp_rcvd.rsp_len = data_len;

    if (data_len <= NFA_MAX_HCI_RSP_LEN)
      memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);

    nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
                         nfa_hci_cb.app_in_use);
  }
}

/*******************************************************************************
**
** Function         nfa_hci_handle_connectivity_gate_pkt
**
** Description      This function handles incoming connectivity gate packets
**
** Returns          none
**
*******************************************************************************/
static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
                                                 uint16_t data_len,
                                                 tNFA_HCI_DYN_PIPE* p_pipe) {
  tNFA_HCI_EVT_DATA evt_data;

  if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
    switch (nfa_hci_cb.inst) {
      case NFA_HCI_ANY_OPEN_PIPE:
      case NFA_HCI_ANY_CLOSE_PIPE:
        nfa_hci_handle_pipe_open_close_cmd(p_pipe);
        break;

      case NFA_HCI_CON_PRO_HOST_REQUEST:
        /* A request to the DH to activate another host. This is not supported
         * for */
        /* now, we will implement it when the spec is clearer and UICCs need it.
         */
        nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
                          NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, nullptr);
        break;

      default:
        nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
                          NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, nullptr);
        break;
    }
  } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
    if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
        (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
      p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
    else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
      p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;

    /* Could be a response to application specific command sent, pass it on */
    evt_data.rsp_rcvd.status = NFA_STATUS_OK;
    evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
    ;
    evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
    evt_data.rsp_rcvd.rsp_len = data_len;

    if (data_len <= NFA_MAX_HCI_RSP_LEN)
      memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);

    nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
                         nfa_hci_cb.app_in_use);
  } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
    evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
    evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
    evt_data.rcvd_evt.evt_len = data_len;
    evt_data.rcvd_evt.p_evt_buf = p_data;

    /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
    nfa_hciu_send_to_apps_handling_connectivity_evts(NFA_HCI_EVENT_RCVD_EVT,
                                                     &evt_data);
  }
}

/*******************************************************************************
**
** Function         nfa_hci_handle_loopback_gate_pkt
**
** Description      This function handles incoming loopback gate hci events
**
** Returns          none
**
*******************************************************************************/
static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
                                             tNFA_HCI_DYN_PIPE* p_pipe) {
  uint8_t data[1];
  uint8_t rsp_len = 0;
  tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
  tNFA_HCI_EVT_DATA evt_data;

  /* Check if data packet is a command, response or event */
  if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
    if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
      data[0] = 0;
      rsp_len = 1;
      p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
    } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
      p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
    } else
      response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;

    nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
                      data);
  } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
    if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
        (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
      p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
    else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
      p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;

    /* Could be a response to application specific command sent, pass it on */
    evt_data.rsp_rcvd.status = NFA_STATUS_OK;
    evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
    ;
    evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
    evt_data.rsp_rcvd.rsp_len = data_len;

    if (data_len <= NFA_MAX_HCI_RSP_LEN)
      memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);

    nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
                         nfa_hci_cb.app_in_use);
  } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
    if (nfa_hci_cb.w4_rsp_evt) {
      evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
      evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
      evt_data.rcvd_evt.evt_len = data_len;
      evt_data.rcvd_evt.p_evt_buf = p_data;

      nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data,
                           nfa_hci_cb.app_in_use);
    } else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA) {
      /* Send back the same data we got */
      nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_EVENT_TYPE,
                        NFA_HCI_EVT_POST_DATA, data_len, p_data);
    }
  }
}

/*******************************************************************************
**
** Function         nfa_hci_handle_generic_gate_evt
**
** Description      This function handles incoming Generic gate hci events
**
** Returns          none
**
*******************************************************************************/
static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
                                            tNFA_HCI_DYN_GATE* p_gate,
                                            tNFA_HCI_DYN_PIPE* p_pipe) {
  tNFA_HCI_EVT_DATA evt_data;

  evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
  evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
  evt_data.rcvd_evt.evt_len = data_len;

  if (nfa_hci_cb.assembly_failed)
    evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL;
  else
    evt_data.rcvd_evt.status = NFA_STATUS_OK;

  evt_data.rcvd_evt.p_evt_buf = p_data;
  nfa_hci_cb.rsp_buf_size = 0;
  nfa_hci_cb.p_rsp_buf = nullptr;

  /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
  nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
}
