/******************************************************************************
 *
 *  Copyright (C) 1999-2012 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 main functions to support PAN profile
 *  commands and events.
 *
 ******************************************************************************/

#include <string.h>
#include "bnep_api.h"
#include "bt_common.h"
#include "bt_types.h"
#include "bt_utils.h"
#include "hcidefs.h"
#include "l2c_api.h"
#include "osi/include/osi.h"
#include "pan_api.h"
#include "pan_int.h"
#include "sdp_api.h"
#include "sdpdefs.h"

tPAN_CB pan_cb;

#define UUID_CONSTANT_PART 12
uint8_t constant_pan_uuid[UUID_CONSTANT_PART] = {
    0, 0, 0x10, 0, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};

/*******************************************************************************
 *
 * Function         pan_register_with_bnep
 *
 * Description      This function registers PAN profile with BNEP
 *
 * Parameters:      none
 *
 * Returns          none
 *
 ******************************************************************************/
void pan_register_with_bnep(void) {
  tBNEP_REGISTER reg_info;

  memset(&reg_info, 0, sizeof(tBNEP_REGISTER));

  reg_info.p_conn_ind_cb = pan_conn_ind_cb;
  reg_info.p_conn_state_cb = pan_connect_state_cb;
  reg_info.p_data_buf_cb = pan_data_buf_ind_cb;
  reg_info.p_data_ind_cb = NULL;
  reg_info.p_tx_data_flow_cb = pan_tx_data_flow_cb;
  reg_info.p_filter_ind_cb = pan_proto_filt_ind_cb;
  reg_info.p_mfilter_ind_cb = pan_mcast_filt_ind_cb;

  BNEP_Register(&reg_info);
}

/*******************************************************************************
 *
 * Function         pan_conn_ind_cb
 *
 * Description      This function is registered with BNEP as connection
 *                  indication callback. BNEP will call this when there is
 *                  connection request from the peer. PAN should call
 *                  BNEP_ConnectResp to indicate whether to accept the
 *                  connection or reject
 *
 * Parameters:      handle      - handle for the connection
 *                  p_bda       - BD Addr of the peer requesting the connection
 *                  remote_uuid     - UUID of the source role (peer device role)
 *                  local_uuid      - UUID of the destination role (local device
 *                                                                  role)
 *                  is_role_change  - Flag to indicate that it is a role change
 *
 * Returns          none
 *
 ******************************************************************************/
void pan_conn_ind_cb(uint16_t handle, BD_ADDR p_bda, tBT_UUID* remote_uuid,
                     tBT_UUID* local_uuid, bool is_role_change) {
  tPAN_CONN* pcb;
  uint8_t req_role;
  bool wrong_uuid;

  /*
  ** If we are in GN or NAP role and have one or more
  ** active connections and the received connection is
  ** for user role reject it.
  ** If we are in user role with one connection active
  ** reject the connection.
  ** Allocate PCB and store the parameters
  ** Make bridge request to the host system if connection
  ** is for NAP
  */
  wrong_uuid = false;
  if (remote_uuid->len == 16) {
    /*
    ** If the UUID is 16 bytes forst two bytes should be zeros
    ** and last 12 bytes should match the spec defined constant value
    */
    if (memcmp(constant_pan_uuid, remote_uuid->uu.uuid128 + 4,
               UUID_CONSTANT_PART))
      wrong_uuid = true;

    if (remote_uuid->uu.uuid128[0] || remote_uuid->uu.uuid128[1])
      wrong_uuid = true;

    /* Extract the 16 bit equivalent of the UUID */
    remote_uuid->uu.uuid16 = (uint16_t)((remote_uuid->uu.uuid128[2] << 8) |
                                        remote_uuid->uu.uuid128[3]);
    remote_uuid->len = 2;
  }
  if (remote_uuid->len == 4) {
    /* First two bytes should be zeros */
    if (remote_uuid->uu.uuid32 & 0xFFFF0000) wrong_uuid = true;

    remote_uuid->uu.uuid16 = (uint16_t)remote_uuid->uu.uuid32;
    remote_uuid->len = 2;
  }

  if (wrong_uuid) {
    PAN_TRACE_ERROR("PAN Connection failed because of wrong remote UUID ");
    BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID);
    return;
  }

  wrong_uuid = false;
  if (local_uuid->len == 16) {
    /*
    ** If the UUID is 16 bytes forst two bytes should be zeros
    ** and last 12 bytes should match the spec defined constant value
    */
    if (memcmp(constant_pan_uuid, local_uuid->uu.uuid128 + 4,
               UUID_CONSTANT_PART))
      wrong_uuid = true;

    if (local_uuid->uu.uuid128[0] || local_uuid->uu.uuid128[1])
      wrong_uuid = true;

    /* Extract the 16 bit equivalent of the UUID */
    local_uuid->uu.uuid16 = (uint16_t)((local_uuid->uu.uuid128[2] << 8) |
                                       local_uuid->uu.uuid128[3]);
    local_uuid->len = 2;
  }
  if (local_uuid->len == 4) {
    /* First two bytes should be zeros */
    if (local_uuid->uu.uuid32 & 0xFFFF0000) wrong_uuid = true;

    local_uuid->uu.uuid16 = (uint16_t)local_uuid->uu.uuid32;
    local_uuid->len = 2;
  }

  if (wrong_uuid) {
    PAN_TRACE_ERROR("PAN Connection failed because of wrong local UUID ");
    BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
    return;
  }

  PAN_TRACE_EVENT(
      "pan_conn_ind_cb - for handle %d, current role %d, dst uuid 0x%x, src "
      "uuid 0x%x, role change %s",
      handle, pan_cb.role, local_uuid->uu.uuid16, remote_uuid->uu.uuid16,
      is_role_change ? "YES" : "NO");
  /* The acceptable UUID size is only 2 */
  if (remote_uuid->len != 2) {
    PAN_TRACE_ERROR("PAN Connection failed because of wrong UUID size %d",
                    remote_uuid->len);
    BNEP_ConnectResp(handle, BNEP_CONN_FAILED_UUID_SIZE);
    return;
  }

  /* Check if the source UUID is a valid one */
  if (remote_uuid->uu.uuid16 != UUID_SERVCLASS_PANU &&
      remote_uuid->uu.uuid16 != UUID_SERVCLASS_NAP &&
      remote_uuid->uu.uuid16 != UUID_SERVCLASS_GN) {
    PAN_TRACE_ERROR("Src UUID 0x%x is not valid", remote_uuid->uu.uuid16);
    BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID);
    return;
  }

  /* Check if the destination UUID is a valid one */
  if (local_uuid->uu.uuid16 != UUID_SERVCLASS_PANU &&
      local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP &&
      local_uuid->uu.uuid16 != UUID_SERVCLASS_GN) {
    PAN_TRACE_ERROR("Dst UUID 0x%x is not valid", remote_uuid->uu.uuid16);
    BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
    return;
  }

  /* Check if currently we support the destination role requested */
  if (((!(pan_cb.role & UUID_SERVCLASS_PANU)) &&
       local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) ||
      ((!(pan_cb.role & UUID_SERVCLASS_GN)) &&
       local_uuid->uu.uuid16 == UUID_SERVCLASS_GN) ||
      ((!(pan_cb.role & UUID_SERVCLASS_NAP)) &&
       local_uuid->uu.uuid16 == UUID_SERVCLASS_NAP)) {
    PAN_TRACE_ERROR(
        "PAN Connection failed because of unsupported destination UUID 0x%x",
        local_uuid->uu.uuid16);
    BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
    return;
  }

  /* Check for valid interactions between the three PAN profile roles */
  /*
   * For reference, see Table 1 in PAN Profile v1.0 spec.
   * Note: the remote is the initiator.
   */
  bool is_valid_interaction = false;
  switch (remote_uuid->uu.uuid16) {
    case UUID_SERVCLASS_NAP:
    case UUID_SERVCLASS_GN:
      if (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU)
        is_valid_interaction = true;
      break;
    case UUID_SERVCLASS_PANU:
      is_valid_interaction = true;
      break;
  }
  /*
   * Explicitly disable connections to the local PANU if the remote is
   * not PANU.
   */
  if ((local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) &&
      (remote_uuid->uu.uuid16 != UUID_SERVCLASS_PANU)) {
    is_valid_interaction = false;
  }
  if (!is_valid_interaction) {
    PAN_TRACE_ERROR(
        "PAN Connection failed because of invalid PAN profile roles "
        "interaction: Remote UUID 0x%x Local UUID 0x%x",
        remote_uuid->uu.uuid16, local_uuid->uu.uuid16);
    BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID);
    return;
  }

  /* Requested destination role is */
  if (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU)
    req_role = PAN_ROLE_CLIENT;
  else if (local_uuid->uu.uuid16 == UUID_SERVCLASS_GN)
    req_role = PAN_ROLE_GN_SERVER;
  else
    req_role = PAN_ROLE_NAP_SERVER;

  /* If the connection indication is for the existing connection
  ** Check if the new destination role is acceptable
  */
  pcb = pan_get_pcb_by_handle(handle);
  if (pcb) {
    if (pan_cb.num_conns > 1 && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) {
      /* There are connections other than this one
      ** so we cann't accept PANU role. Reject
      */
      PAN_TRACE_ERROR(
          "Dst UUID should be either GN or NAP only because there are other "
          "connections");
      BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
      return;
    }

    /* If it is already in connected state check for bridging status */
    if (pcb->con_state == PAN_STATE_CONNECTED) {
      PAN_TRACE_EVENT("PAN Role changing New Src 0x%x Dst 0x%x",
                      remote_uuid->uu.uuid16, local_uuid->uu.uuid16);

      pcb->prv_src_uuid = pcb->src_uuid;
      pcb->prv_dst_uuid = pcb->dst_uuid;

      if (pcb->src_uuid == UUID_SERVCLASS_NAP &&
          local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP) {
        /* Remove bridging */
        if (pan_cb.pan_bridge_req_cb)
          (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, false);
      }
    }
    /* Set the latest active PAN role */
    pan_cb.active_role = req_role;
    pcb->src_uuid = local_uuid->uu.uuid16;
    pcb->dst_uuid = remote_uuid->uu.uuid16;
    BNEP_ConnectResp(handle, BNEP_SUCCESS);
    return;
  } else {
    /* If this a new connection and destination is PANU role and
    ** we already have a connection then reject the request.
    ** If we have a connection in PANU role then reject it
    */
    if (pan_cb.num_conns && (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU ||
                             pan_cb.active_role == PAN_ROLE_CLIENT)) {
      PAN_TRACE_ERROR("PAN already have a connection and can't be user");
      BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID);
      return;
    }
  }

  /* This is a new connection */
  PAN_TRACE_DEBUG("New connection indication for handle %d", handle);
  pcb = pan_allocate_pcb(p_bda, handle);
  if (!pcb) {
    PAN_TRACE_ERROR("PAN no control block for new connection");
    BNEP_ConnectResp(handle, BNEP_CONN_FAILED);
    return;
  }

  PAN_TRACE_EVENT("PAN connection destination UUID is 0x%x",
                  local_uuid->uu.uuid16);
  /* Set the latest active PAN role */
  pan_cb.active_role = req_role;
  pcb->src_uuid = local_uuid->uu.uuid16;
  pcb->dst_uuid = remote_uuid->uu.uuid16;
  pcb->con_state = PAN_STATE_CONN_START;
  pan_cb.num_conns++;

  BNEP_ConnectResp(handle, BNEP_SUCCESS);
  return;
}

/*******************************************************************************
 *
 * Function         pan_connect_state_cb
 *
 * Description      This function is registered with BNEP as connection state
 *                  change callback. BNEP will call this when the connection
 *                  is established successfully or terminated
 *
 * Parameters:      handle  - handle for the connection given in the connection
 *                            indication callback
 *                  rem_bda - remote device bd addr
 *                  result  - indicates whether the connection is up or down
 *                            BNEP_SUCCESS if the connection is up all other
 *                            values indicate appropriate errors.
 *                  is_role_change - flag to indicate that it is a role change
 *
 * Returns          none
 *
 ******************************************************************************/
void pan_connect_state_cb(uint16_t handle, UNUSED_ATTR BD_ADDR rem_bda,
                          tBNEP_RESULT result, bool is_role_change) {
  tPAN_CONN* pcb;
  uint8_t peer_role;

  PAN_TRACE_EVENT("pan_connect_state_cb - for handle %d, result %d", handle,
                  result);
  pcb = pan_get_pcb_by_handle(handle);
  if (!pcb) {
    PAN_TRACE_ERROR("PAN State change indication for wrong handle %d", handle);
    return;
  }

  /* If the connection is getting terminated remove bridging */
  if (result != BNEP_SUCCESS) {
    /* Inform the application that connection is down */
    if (pan_cb.pan_conn_state_cb)
      (*pan_cb.pan_conn_state_cb)(pcb->handle, pcb->rem_bda, result,
                                  is_role_change, PAN_ROLE_INACTIVE,
                                  PAN_ROLE_INACTIVE);

    /* Check if this failure is for role change only */
    if (pcb->con_state != PAN_STATE_CONNECTED &&
        (pcb->con_flags & PAN_FLAGS_CONN_COMPLETED)) {
      /* restore the original values */
      PAN_TRACE_EVENT("restoring the connection state to active");
      pcb->con_state = PAN_STATE_CONNECTED;
      pcb->con_flags &= (~PAN_FLAGS_CONN_COMPLETED);

      pcb->src_uuid = pcb->prv_src_uuid;
      pcb->dst_uuid = pcb->prv_dst_uuid;
      pan_cb.active_role = pan_cb.prv_active_role;

      if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb)
        (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, true);

      return;
    }

    if (pcb->con_state == PAN_STATE_CONNECTED) {
      /* If the connections destination role is NAP remove bridging */
      if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb)
        (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, false);
    }

    pan_cb.num_conns--;
    pan_release_pcb(pcb);
    return;
  }

  /* Requested destination role is */
  if (pcb->src_uuid == UUID_SERVCLASS_PANU)
    pan_cb.active_role = PAN_ROLE_CLIENT;
  else if (pcb->src_uuid == UUID_SERVCLASS_GN)
    pan_cb.active_role = PAN_ROLE_GN_SERVER;
  else
    pan_cb.active_role = PAN_ROLE_NAP_SERVER;

  if (pcb->dst_uuid == UUID_SERVCLASS_PANU)
    peer_role = PAN_ROLE_CLIENT;
  else if (pcb->dst_uuid == UUID_SERVCLASS_GN)
    peer_role = PAN_ROLE_GN_SERVER;
  else
    peer_role = PAN_ROLE_NAP_SERVER;

  pcb->con_state = PAN_STATE_CONNECTED;

  /* Inform the application that connection is down */
  if (pan_cb.pan_conn_state_cb)
    (*pan_cb.pan_conn_state_cb)(pcb->handle, pcb->rem_bda, PAN_SUCCESS,
                                is_role_change, pan_cb.active_role, peer_role);

  /* Create bridge if the destination role is NAP */
  if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP) {
    PAN_TRACE_EVENT("PAN requesting for bridge");
    (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, true);
  }
}

/*******************************************************************************
 *
 * Function         pan_data_ind_cb
 *
 * Description      This function is registered with BNEP as data indication
 *                  callback. BNEP will call this when the peer sends any data
 *                  on this connection
 *
 * Parameters:      handle      - handle for the connection
 *                  src         - source BD Addr
 *                  dst         - destination BD Addr
 *                  protocol    - Network protocol of the Eth packet
 *                  p_data      - pointer to the data
 *                  len         - length of the data
 *                  fw_ext_present - to indicate whether the data contains any
 *                                         extension headers before the payload
 *
 * Returns          none
 *
 ******************************************************************************/
void pan_data_ind_cb(uint16_t handle, uint8_t* src, uint8_t* dst,
                     uint16_t protocol, uint8_t* p_data, uint16_t len,
                     bool ext) {
  tPAN_CONN* pcb;
  uint16_t i;
  bool forward;

  /*
  ** Check the connection status
  ** If the destination address is MAC broadcast send on all links
  ** except on the one received
  ** If the destination uuid is for NAP send to host system also
  ** If the destination address is one of the devices connected
  ** send the packet to over that link
  ** If the destination address is unknown and destination uuid is NAP
  ** send it to the host system
  */

  PAN_TRACE_EVENT("pan_data_ind_cb - for handle %d", handle);
  pcb = pan_get_pcb_by_handle(handle);
  if (!pcb) {
    PAN_TRACE_ERROR("PAN Data indication for wrong handle %d", handle);
    return;
  }

  if (pcb->con_state != PAN_STATE_CONNECTED) {
    PAN_TRACE_ERROR("PAN Data indication in wrong state %d for handle %d",
                    pcb->con_state, handle);
    return;
  }

  /* Check if it is broadcast packet */
  if (dst[0] & 0x01) {
    PAN_TRACE_DEBUG("PAN received broadcast packet on handle %d, src uuid 0x%x",
                    handle, pcb->src_uuid);
    for (i = 0; i < MAX_PAN_CONNS; i++) {
      if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
          pan_cb.pcb[i].handle != handle &&
          pcb->src_uuid == pan_cb.pcb[i].src_uuid) {
        BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
      }
    }

    if (pan_cb.pan_data_ind_cb)
      (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len,
                                ext, true);

    return;
  }

  /* Check if it is for any other PAN connection */
  for (i = 0; i < MAX_PAN_CONNS; i++) {
    if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
        pcb->src_uuid == pan_cb.pcb[i].src_uuid) {
      if (memcmp(pan_cb.pcb[i].rem_bda, dst, BD_ADDR_LEN) == 0) {
        BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
        return;
      }
    }
  }

  if (pcb->src_uuid == UUID_SERVCLASS_NAP)
    forward = true;
  else
    forward = false;

  /* Send it over the LAN or give it to host software */
  if (pan_cb.pan_data_ind_cb)
    (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len, ext,
                              forward);

  return;
}

/*******************************************************************************
 *
 * Function         pan_data_buf_ind_cb
 *
 * Description      This function is registered with BNEP as data buffer
 *                  indication callback. BNEP will call this when the peer sends
 *                  any data on this connection. PAN is responsible to release
 *                  the buffer
 *
 * Parameters:      handle      - handle for the connection
 *                  src         - source BD Addr
 *                  dst         - destination BD Addr
 *                  protocol    - Network protocol of the Eth packet
 *                  p_buf       - pointer to the data buffer
 *                  ext         - to indicate whether the data contains any
 *                                         extension headers before the payload
 *
 * Returns          none
 *
 ******************************************************************************/
void pan_data_buf_ind_cb(uint16_t handle, uint8_t* src, uint8_t* dst,
                         uint16_t protocol, BT_HDR* p_buf, bool ext) {
  tPAN_CONN *pcb, *dst_pcb;
  tBNEP_RESULT result;
  uint16_t i, len;
  uint8_t* p_data;
  bool forward = false;

  /* Check if the connection is in right state */
  pcb = pan_get_pcb_by_handle(handle);
  if (!pcb) {
    PAN_TRACE_ERROR("PAN Data buffer indication for wrong handle %d", handle);
    osi_free(p_buf);
    return;
  }

  if (pcb->con_state != PAN_STATE_CONNECTED) {
    PAN_TRACE_ERROR("PAN Data indication in wrong state %d for handle %d",
                    pcb->con_state, handle);
    osi_free(p_buf);
    return;
  }

  p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
  len = p_buf->len;

  PAN_TRACE_EVENT(
      "pan_data_buf_ind_cb - for handle %d, protocol 0x%x, length %d, ext %d",
      handle, protocol, len, ext);

  if (pcb->src_uuid == UUID_SERVCLASS_NAP)
    forward = true;
  else
    forward = false;

  /* Check if it is broadcast or multicast packet */
  if (pcb->src_uuid != UUID_SERVCLASS_PANU) {
    if (dst[0] & 0x01) {
      PAN_TRACE_DEBUG(
          "PAN received broadcast packet on handle %d, src uuid 0x%x", handle,
          pcb->src_uuid);
      for (i = 0; i < MAX_PAN_CONNS; i++) {
        if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
            pan_cb.pcb[i].handle != handle &&
            pcb->src_uuid == pan_cb.pcb[i].src_uuid) {
          BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, src,
                     ext);
        }
      }

      if (pan_cb.pan_data_buf_ind_cb)
        (*pan_cb.pan_data_buf_ind_cb)(pcb->handle, src, dst, protocol, p_buf,
                                      ext, forward);
      else if (pan_cb.pan_data_ind_cb) {
        (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len,
                                  ext, forward);
        osi_free(p_buf);
      }

      return;
    }

    /* Check if it is for any other PAN connection */
    dst_pcb = pan_get_pcb_by_addr(dst);
    if (dst_pcb) {
      PAN_TRACE_EVENT(
          "%s - destination PANU found on handle %d and sending data, len: %d",
          __func__, dst_pcb->handle, len);

      result =
          BNEP_Write(dst_pcb->handle, dst, p_data, len, protocol, src, ext);
      if (result != BNEP_SUCCESS && result != BNEP_IGNORE_CMD)
        PAN_TRACE_ERROR("Failed to write data for PAN connection handle %d",
                        dst_pcb->handle);
      osi_free(p_buf);
      return;
    }
  }

  /* Send it over the LAN or give it to host software */
  if (pan_cb.pan_data_buf_ind_cb)
    (*pan_cb.pan_data_buf_ind_cb)(pcb->handle, src, dst, protocol, p_buf, ext,
                                  forward);
  else if (pan_cb.pan_data_ind_cb) {
    (*pan_cb.pan_data_ind_cb)(pcb->handle, src, dst, protocol, p_data, len, ext,
                              forward);
    osi_free(p_buf);
  } else
    osi_free(p_buf);

  return;
}

/*******************************************************************************
 *
 * Function         pan_proto_filt_ind_cb
 *
 * Description      This function is registered with BNEP to receive tx data
 *					flow status
 *
 * Parameters:      handle      - handle for the connection
 *					event       - flow status
 *
 * Returns          none
 *
 ******************************************************************************/
void pan_tx_data_flow_cb(uint16_t handle, tBNEP_RESULT event) {
  if (pan_cb.pan_tx_data_flow_cb) (*pan_cb.pan_tx_data_flow_cb)(handle, event);

  return;
}

/*******************************************************************************
 *
 * Function         pan_proto_filt_ind_cb
 *
 * Description      This function is registered with BNEP as proto filter
 *                  indication callback. BNEP will call this when the peer sends
 *                  any protocol filter set for the connection or to indicate
 *                  the result of the protocol filter set by the local device
 *
 * Parameters:      handle      - handle for the connection
 *                  indication  - true if this is indication
 *                                false if it is called to give the result of
 *                                      local device protocol filter set
 *                  result      - This gives the result of the filter set
 *                                      operation
 *                  num_filters - number of filters set by the peer device
 *                  p_filters   - pointer to the filters set by the peer device
 *
 * Returns          none
 *
 ******************************************************************************/
void pan_proto_filt_ind_cb(uint16_t handle, bool indication,
                           tBNEP_RESULT result, uint16_t num_filters,
                           uint8_t* p_filters) {
  PAN_TRACE_EVENT(
      "pan_proto_filt_ind_cb - called for handle %d with ind %d, result %d, "
      "num %d",
      handle, indication, result, num_filters);

  if (pan_cb.pan_pfilt_ind_cb)
    (*pan_cb.pan_pfilt_ind_cb)(handle, indication, result, num_filters,
                               p_filters);
}

/*******************************************************************************
 *
 * Function         pan_mcast_filt_ind_cb
 *
 * Description      This function is registered with BNEP as mcast filter
 *                  indication callback. BNEP will call this when the peer sends
 *                  any multicast filter set for the connection or to indicate
 *                  the result of the multicast filter set by the local device
 *
 * Parameters:      handle      - handle for the connection
 *                  indication  - true if this is indication
 *                                false if it is called to give the result of
 *                                      local device multicast filter set
 *                  result      - This gives the result of the filter set
 *                                operation
 *                  num_filters - number of filters set by the peer device
 *                  p_filters   - pointer to the filters set by the peer device
 *
 * Returns          none
 *
 ******************************************************************************/
void pan_mcast_filt_ind_cb(uint16_t handle, bool indication,
                           tBNEP_RESULT result, uint16_t num_filters,
                           uint8_t* p_filters) {
  PAN_TRACE_EVENT(
      "pan_mcast_filt_ind_cb - called for handle %d with ind %d, result %d, "
      "num %d",
      handle, indication, result, num_filters);

  if (pan_cb.pan_mfilt_ind_cb)
    (*pan_cb.pan_mfilt_ind_cb)(handle, indication, result, num_filters,
                               p_filters);
}
