/******************************************************************************
 *
 *  Copyright (C) 2001-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 the BNEP API code
 *
 ******************************************************************************/

#include "bnep_api.h"
#include <string.h>
#include "bnep_int.h"

extern fixed_queue_t* btu_general_alarm_queue;

/*******************************************************************************
 *
 * Function         BNEP_Init
 *
 * Description      This function initializes the BNEP unit. It should be called
 *                  before accessing any other APIs to initialize the control
 *                  block.
 *
 * Returns          void
 *
 ******************************************************************************/
void BNEP_Init(void) {
  memset(&bnep_cb, 0, sizeof(tBNEP_CB));

#if defined(BNEP_INITIAL_TRACE_LEVEL)
  bnep_cb.trace_level = BNEP_INITIAL_TRACE_LEVEL;
#else
  bnep_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
#endif
}

/*******************************************************************************
 *
 * Function         BNEP_Register
 *
 * Description      This function is called by the upper layer to register
 *                  its callbacks with BNEP
 *
 * Parameters:      p_reg_info - contains all callback function pointers
 *
 *
 * Returns          BNEP_SUCCESS        if registered successfully
 *                  BNEP_FAILURE        if connection state callback is missing
 *
 ******************************************************************************/
tBNEP_RESULT BNEP_Register(tBNEP_REGISTER* p_reg_info) {
  /* There should be connection state call back registered */
  if ((!p_reg_info) || (!(p_reg_info->p_conn_state_cb)))
    return BNEP_SECURITY_FAIL;

  bnep_cb.p_conn_ind_cb = p_reg_info->p_conn_ind_cb;
  bnep_cb.p_conn_state_cb = p_reg_info->p_conn_state_cb;
  bnep_cb.p_data_ind_cb = p_reg_info->p_data_ind_cb;
  bnep_cb.p_data_buf_cb = p_reg_info->p_data_buf_cb;
  bnep_cb.p_filter_ind_cb = p_reg_info->p_filter_ind_cb;
  bnep_cb.p_mfilter_ind_cb = p_reg_info->p_mfilter_ind_cb;
  bnep_cb.p_tx_data_flow_cb = p_reg_info->p_tx_data_flow_cb;

  if (bnep_register_with_l2cap()) return BNEP_SECURITY_FAIL;

  bnep_cb.profile_registered = true;
  return BNEP_SUCCESS;
}

/*******************************************************************************
 *
 * Function         BNEP_Deregister
 *
 * Description      This function is called by the upper layer to de-register
 *                  its callbacks.
 *
 * Parameters:      void
 *
 *
 * Returns          void
 *
 ******************************************************************************/
void BNEP_Deregister(void) {
  /* Clear all the call backs registered */
  bnep_cb.p_conn_ind_cb = NULL;
  bnep_cb.p_conn_state_cb = NULL;
  bnep_cb.p_data_ind_cb = NULL;
  bnep_cb.p_data_buf_cb = NULL;
  bnep_cb.p_filter_ind_cb = NULL;
  bnep_cb.p_mfilter_ind_cb = NULL;

  bnep_cb.profile_registered = false;
  L2CA_Deregister(BT_PSM_BNEP);
}

/*******************************************************************************
 *
 * Function         BNEP_Connect
 *
 * Description      This function creates a BNEP connection to a remote
 *                  device.
 *
 * Parameters:      p_rem_addr  - BD_ADDR of the peer
 *                  src_uuid    - source uuid for the connection
 *                  dst_uuid    - destination uuid for the connection
 *                  p_handle    - pointer to return the handle for the
 *                                connection
 *
 * Returns          BNEP_SUCCESS                if connection started
 *                  BNEP_NO_RESOURCES           if no resources
 *
 ******************************************************************************/
tBNEP_RESULT BNEP_Connect(BD_ADDR p_rem_bda, tBT_UUID* src_uuid,
                          tBT_UUID* dst_uuid, uint16_t* p_handle) {
  uint16_t cid;
  tBNEP_CONN* p_bcb = bnepu_find_bcb_by_bd_addr(p_rem_bda);

  BNEP_TRACE_API("BNEP_Connect()  BDA: %02x-%02x-%02x-%02x-%02x-%02x",
                 p_rem_bda[0], p_rem_bda[1], p_rem_bda[2], p_rem_bda[3],
                 p_rem_bda[4], p_rem_bda[5]);

  if (!bnep_cb.profile_registered) return BNEP_WRONG_STATE;

  /* Both source and destination UUID lengths should be same */
  if (src_uuid->len != dst_uuid->len) return BNEP_CONN_FAILED_UUID_SIZE;

  if (!p_bcb) {
    p_bcb = bnepu_allocate_bcb(p_rem_bda);
    if (p_bcb == NULL) return (BNEP_NO_RESOURCES);
  } else if (p_bcb->con_state != BNEP_STATE_CONNECTED)
    return BNEP_WRONG_STATE;
  else {
    /* Backup current UUID values to restore if role change fails */
    memcpy((uint8_t*)&(p_bcb->prv_src_uuid), (uint8_t*)&(p_bcb->src_uuid),
           sizeof(tBT_UUID));
    memcpy((uint8_t*)&(p_bcb->prv_dst_uuid), (uint8_t*)&(p_bcb->dst_uuid),
           sizeof(tBT_UUID));
  }

  /* We are the originator of this connection */
  p_bcb->con_flags |= BNEP_FLAGS_IS_ORIG;

  memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)src_uuid, sizeof(tBT_UUID));
  memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)dst_uuid, sizeof(tBT_UUID));

  if (p_bcb->con_state == BNEP_STATE_CONNECTED) {
    /* Transition to the next appropriate state, waiting for connection confirm.
     */
    p_bcb->con_state = BNEP_STATE_SEC_CHECKING;

    BNEP_TRACE_API("BNEP initiating security procedures for src uuid 0x%x",
                   p_bcb->src_uuid.uu.uuid16);

#if (BNEP_DO_AUTH_FOR_ROLE_SWITCH == TRUE)
    btm_sec_mx_access_request(p_bcb->rem_bda, BT_PSM_BNEP, true,
                              BTM_SEC_PROTO_BNEP, bnep_get_uuid32(src_uuid),
                              &bnep_sec_check_complete, p_bcb);
#else
    bnep_sec_check_complete(p_bcb->rem_bda, p_bcb, BTM_SUCCESS);
#endif

  } else {
    /* Transition to the next appropriate state, waiting for connection confirm.
     */
    p_bcb->con_state = BNEP_STATE_CONN_START;

    cid = L2CA_ConnectReq(BT_PSM_BNEP, p_bcb->rem_bda);
    if (cid != 0) {
      p_bcb->l2cap_cid = cid;

    } else {
      BNEP_TRACE_ERROR("BNEP - Originate failed");
      if (bnep_cb.p_conn_state_cb)
        (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
                                   BNEP_CONN_FAILED, false);
      bnepu_release_bcb(p_bcb);
      return BNEP_CONN_FAILED;
    }

    /* Start timer waiting for connect */
    alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
                       bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
  }

  *p_handle = p_bcb->handle;
  return (BNEP_SUCCESS);
}

/*******************************************************************************
 *
 * Function         BNEP_ConnectResp
 *
 * Description      This function is called in responce to connection indication
 *
 *
 * Parameters:      handle  - handle given in the connection indication
 *                  resp    - responce for the connection indication
 *
 * Returns          BNEP_SUCCESS                if connection started
 *                  BNEP_WRONG_HANDLE           if the connection is not found
 *                  BNEP_WRONG_STATE            if the responce is not expected
 *
 ******************************************************************************/
tBNEP_RESULT BNEP_ConnectResp(uint16_t handle, tBNEP_RESULT resp) {
  tBNEP_CONN* p_bcb;
  uint16_t resp_code = BNEP_SETUP_CONN_OK;

  if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);

  p_bcb = &(bnep_cb.bcb[handle - 1]);

  if (p_bcb->con_state != BNEP_STATE_CONN_SETUP ||
      (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)))
    return (BNEP_WRONG_STATE);

  BNEP_TRACE_API("BNEP_ConnectResp()  for handle %d, responce %d", handle,
                 resp);

  /* Form appropriate responce based on profile responce */
  if (resp == BNEP_CONN_FAILED_SRC_UUID)
    resp_code = BNEP_SETUP_INVALID_SRC_UUID;
  else if (resp == BNEP_CONN_FAILED_DST_UUID)
    resp_code = BNEP_SETUP_INVALID_DEST_UUID;
  else if (resp == BNEP_CONN_FAILED_UUID_SIZE)
    resp_code = BNEP_SETUP_INVALID_UUID_SIZE;
  else if (resp == BNEP_SUCCESS)
    resp_code = BNEP_SETUP_CONN_OK;
  else
    resp_code = BNEP_SETUP_CONN_NOT_ALLOWED;

  bnep_send_conn_responce(p_bcb, resp_code);
  p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);

  if (resp == BNEP_SUCCESS)
    bnep_connected(p_bcb);
  else if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) {
    /* Restore the original parameters */
    p_bcb->con_state = BNEP_STATE_CONNECTED;
    p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);

    memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)&(p_bcb->prv_src_uuid),
           sizeof(tBT_UUID));
    memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)&(p_bcb->prv_dst_uuid),
           sizeof(tBT_UUID));
  }

  /* Process remaining part of the setup message (extension headers) */
  if (p_bcb->p_pending_data) {
    uint8_t extension_present = true, *p, ext_type;
    uint16_t rem_len;

    rem_len = p_bcb->p_pending_data->len;
    p = (uint8_t*)(p_bcb->p_pending_data + 1) + p_bcb->p_pending_data->offset;
    while (extension_present && p && rem_len) {
      ext_type = *p++;
      extension_present = ext_type >> 7;
      ext_type &= 0x7F;

      /* if unknown extension present stop processing */
      if (ext_type) break;

      p = bnep_process_control_packet(p_bcb, p, &rem_len, true);
    }

    osi_free_and_reset((void**)&p_bcb->p_pending_data);
  }
  return (BNEP_SUCCESS);
}

/*******************************************************************************
 *
 * Function         BNEP_Disconnect
 *
 * Description      This function is called to close the specified connection.
 *
 * Parameters:      handle   - handle of the connection
 *
 * Returns          BNEP_SUCCESS                if connection is disconnected
 *                  BNEP_WRONG_HANDLE           if no connection is not found
 *
 ******************************************************************************/
tBNEP_RESULT BNEP_Disconnect(uint16_t handle) {
  tBNEP_CONN* p_bcb;

  if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);

  p_bcb = &(bnep_cb.bcb[handle - 1]);

  if (p_bcb->con_state == BNEP_STATE_IDLE) return (BNEP_WRONG_HANDLE);

  BNEP_TRACE_API("BNEP_Disconnect()  for handle %d", handle);

  L2CA_DisconnectReq(p_bcb->l2cap_cid);

  bnepu_release_bcb(p_bcb);

  return (BNEP_SUCCESS);
}

/*******************************************************************************
 *
 * Function         BNEP_WriteBuf
 *
 * Description      This function sends data in a GKI buffer on BNEP connection
 *
 * Parameters:      handle       - handle of the connection to write
 *                  p_dest_addr  - BD_ADDR/Ethernet addr of the destination
 *                  p_buf        - pointer to address of buffer with data
 *                  protocol     - protocol type of the packet
 *                  p_src_addr   - (optional) BD_ADDR/ethernet address of the
 *                                 source
 *                                 (should be NULL if it is local BD Addr)
 *                  fw_ext_present - forwarded extensions present
 *
 * Returns:         BNEP_WRONG_HANDLE       - if passed handle is not valid
 *                  BNEP_MTU_EXCEDED        - If the data length is greater than
 *                                            the MTU
 *                  BNEP_IGNORE_CMD         - If the packet is filtered out
 *                  BNEP_Q_SIZE_EXCEEDED    - If the Tx Q is full
 *                  BNEP_SUCCESS            - If written successfully
 *
 ******************************************************************************/
tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, uint8_t* p_dest_addr, BT_HDR* p_buf,
                           uint16_t protocol, uint8_t* p_src_addr,
                           bool fw_ext_present) {
  tBNEP_CONN* p_bcb;
  uint8_t* p_data;

  if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) {
    osi_free(p_buf);
    return (BNEP_WRONG_HANDLE);
  }

  p_bcb = &(bnep_cb.bcb[handle - 1]);
  /* Check MTU size */
  if (p_buf->len > BNEP_MTU_SIZE) {
    BNEP_TRACE_ERROR("BNEP_Write() length %d exceeded MTU %d", p_buf->len,
                     BNEP_MTU_SIZE);
    osi_free(p_buf);
    return (BNEP_MTU_EXCEDED);
  }

  /* Check if the packet should be filtered out */
  p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
  if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present,
                             p_data) != BNEP_SUCCESS) {
    /*
    ** If packet is filtered and ext headers are present
    ** drop the data and forward the ext headers
    */
    if (fw_ext_present) {
      uint8_t ext, length;
      uint16_t org_len, new_len;
      /* parse the extension headers and findout the new packet len */
      org_len = p_buf->len;
      new_len = 0;
      do {
        ext = *p_data++;
        length = *p_data++;
        p_data += length;

        new_len += (length + 2);

        if (new_len > org_len) {
          osi_free(p_buf);
          return BNEP_IGNORE_CMD;
        }

      } while (ext & 0x80);

      if (protocol != BNEP_802_1_P_PROTOCOL)
        protocol = 0;
      else {
        new_len += 4;
        p_data[2] = 0;
        p_data[3] = 0;
      }
      p_buf->len = new_len;
    } else {
      osi_free(p_buf);
      return BNEP_IGNORE_CMD;
    }
  }

  /* Check transmit queue */
  if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) {
    osi_free(p_buf);
    return (BNEP_Q_SIZE_EXCEEDED);
  }

  /* Build the BNEP header */
  bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, p_dest_addr,
                       fw_ext_present);

  /* Send the data or queue it up */
  bnepu_check_send_packet(p_bcb, p_buf);

  return (BNEP_SUCCESS);
}

/*******************************************************************************
 *
 * Function         BNEP_Write
 *
 * Description      This function sends data over a BNEP connection
 *
 * Parameters:      handle       - handle of the connection to write
 *                  p_dest_addr  - BD_ADDR/Ethernet addr of the destination
 *                  p_data       - pointer to data start
 *                  protocol     - protocol type of the packet
 *                  p_src_addr   - (optional) BD_ADDR/ethernet address of the
 *                                 source
 *                                 (should be NULL if it is local BD Addr)
 *                  fw_ext_present - forwarded extensions present
 *
 * Returns:         BNEP_WRONG_HANDLE       - if passed handle is not valid
 *                  BNEP_MTU_EXCEDED        - If the data length is greater than
 *                                            the MTU
 *                  BNEP_IGNORE_CMD         - If the packet is filtered out
 *                  BNEP_Q_SIZE_EXCEEDED    - If the Tx Q is full
 *                  BNEP_NO_RESOURCES       - If not able to allocate a buffer
 *                  BNEP_SUCCESS            - If written successfully
 *
 ******************************************************************************/
tBNEP_RESULT BNEP_Write(uint16_t handle, uint8_t* p_dest_addr, uint8_t* p_data,
                        uint16_t len, uint16_t protocol, uint8_t* p_src_addr,
                        bool fw_ext_present) {
  tBNEP_CONN* p_bcb;
  uint8_t* p;

  /* Check MTU size. Consider the possibility of having extension headers */
  if (len > BNEP_MTU_SIZE) {
    BNEP_TRACE_ERROR("BNEP_Write() length %d exceeded MTU %d", len,
                     BNEP_MTU_SIZE);
    return (BNEP_MTU_EXCEDED);
  }

  if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);

  p_bcb = &(bnep_cb.bcb[handle - 1]);

  /* Check if the packet should be filtered out */
  if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present,
                             p_data) != BNEP_SUCCESS) {
    /*
    ** If packet is filtered and ext headers are present
    ** drop the data and forward the ext headers
    */
    if (fw_ext_present) {
      uint8_t ext, length;
      uint16_t org_len, new_len;
      /* parse the extension headers and findout the new packet len */
      org_len = len;
      new_len = 0;
      p = p_data;
      do {
        ext = *p_data++;
        length = *p_data++;
        p_data += length;

        new_len += (length + 2);

        if (new_len > org_len) return BNEP_IGNORE_CMD;

      } while (ext & 0x80);

      if (protocol != BNEP_802_1_P_PROTOCOL)
        protocol = 0;
      else {
        new_len += 4;
        p_data[2] = 0;
        p_data[3] = 0;
      }
      len = new_len;
      p_data = p;
    } else
      return BNEP_IGNORE_CMD;
  }

  /* Check transmit queue */
  if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH)
    return (BNEP_Q_SIZE_EXCEEDED);

  /* Get a buffer to copy the data into */
  BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);

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

  memcpy(p, p_data, len);

  /* Build the BNEP header */
  bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, p_dest_addr,
                       fw_ext_present);

  /* Send the data or queue it up */
  bnepu_check_send_packet(p_bcb, p_buf);

  return (BNEP_SUCCESS);
}

/*******************************************************************************
 *
 * Function         BNEP_SetProtocolFilters
 *
 * Description      This function sets the protocol filters on peer device
 *
 * Parameters:      handle        - Handle for the connection
 *                  num_filters   - total number of filter ranges
 *                  p_start_array - Array of beginings of all protocol ranges
 *                  p_end_array   - Array of ends of all protocol ranges
 *
 * Returns          BNEP_WRONG_HANDLE           - if the connection handle is
 *                                                not valid
 *                  BNEP_SET_FILTER_FAIL        - if the connection is in wrong
 *                                                state
 *                  BNEP_TOO_MANY_FILTERS       - if too many filters
 *                  BNEP_SUCCESS                - if request sent successfully
 *
 ******************************************************************************/
tBNEP_RESULT BNEP_SetProtocolFilters(uint16_t handle, uint16_t num_filters,
                                     uint16_t* p_start_array,
                                     uint16_t* p_end_array) {
  uint16_t xx;
  tBNEP_CONN* p_bcb;

  if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);

  p_bcb = &(bnep_cb.bcb[handle - 1]);

  /* Check the connection state */
  if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
      (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
    return (BNEP_WRONG_STATE);

  /* Validate the parameters */
  if (num_filters && (!p_start_array || !p_end_array))
    return (BNEP_SET_FILTER_FAIL);

  if (num_filters > BNEP_MAX_PROT_FILTERS) return (BNEP_TOO_MANY_FILTERS);

  /* Fill the filter values in connnection block */
  for (xx = 0; xx < num_filters; xx++) {
    p_bcb->sent_prot_filter_start[xx] = *p_start_array++;
    p_bcb->sent_prot_filter_end[xx] = *p_end_array++;
  }

  p_bcb->sent_num_filters = num_filters;

  bnepu_send_peer_our_filters(p_bcb);

  return (BNEP_SUCCESS);
}

/*******************************************************************************
 *
 * Function         BNEP_SetMulticastFilters
 *
 * Description      This function sets the filters for multicast addresses for
 *                  BNEP.
 *
 * Parameters:      handle        - Handle for the connection
 *                  num_filters   - total number of filter ranges
 *                  p_start_array - Pointer to sequence of beginings of all
 *                                         multicast address ranges
 *                  p_end_array   - Pointer to sequence of ends of all
 *                                         multicast address ranges
 *
 * Returns          BNEP_WRONG_HANDLE           - if the connection handle is
 *                                                not valid
 *                  BNEP_SET_FILTER_FAIL        - if the connection is in wrong
 *                                                state
 *                  BNEP_TOO_MANY_FILTERS       - if too many filters
 *                  BNEP_SUCCESS                - if request sent successfully
 *
 ******************************************************************************/
tBNEP_RESULT BNEP_SetMulticastFilters(uint16_t handle, uint16_t num_filters,
                                      uint8_t* p_start_array,
                                      uint8_t* p_end_array) {
  uint16_t xx;
  tBNEP_CONN* p_bcb;

  if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);

  p_bcb = &(bnep_cb.bcb[handle - 1]);

  /* Check the connection state */
  if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
      (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
    return (BNEP_WRONG_STATE);

  /* Validate the parameters */
  if (num_filters && (!p_start_array || !p_end_array))
    return (BNEP_SET_FILTER_FAIL);

  if (num_filters > BNEP_MAX_MULTI_FILTERS) return (BNEP_TOO_MANY_FILTERS);

  /* Fill the multicast filter values in connnection block */
  for (xx = 0; xx < num_filters; xx++) {
    memcpy(p_bcb->sent_mcast_filter_start[xx], p_start_array, BD_ADDR_LEN);
    memcpy(p_bcb->sent_mcast_filter_end[xx], p_end_array, BD_ADDR_LEN);

    p_start_array += BD_ADDR_LEN;
    p_end_array += BD_ADDR_LEN;
  }

  p_bcb->sent_mcast_filters = num_filters;

  bnepu_send_peer_our_multi_filters(p_bcb);

  return (BNEP_SUCCESS);
}

/*******************************************************************************
 *
 * Function         BNEP_SetTraceLevel
 *
 * Description      This function sets the trace level for BNEP. If called with
 *                  a value of 0xFF, it simply reads the current trace level.
 *
 * Returns          the new (current) trace level
 *
 ******************************************************************************/
uint8_t BNEP_SetTraceLevel(uint8_t new_level) {
  if (new_level != 0xFF) bnep_cb.trace_level = new_level;

  return (bnep_cb.trace_level);
}

/*******************************************************************************
 *
 * Function         BNEP_GetStatus
 *
 * Description      This function gets the status information for BNEP
 *                  connection
 *
 * Returns          BNEP_SUCCESS            - if the status is available
 *                  BNEP_NO_RESOURCES       - if no structure is passed for
 *                                            output
 *                  BNEP_WRONG_HANDLE       - if the handle is invalid
 *                  BNEP_WRONG_STATE        - if not in connected state
 *
 ******************************************************************************/
tBNEP_RESULT BNEP_GetStatus(uint16_t handle, tBNEP_STATUS* p_status) {
#if (BNEP_SUPPORTS_STATUS_API == TRUE)
  tBNEP_CONN* p_bcb;

  if (!p_status) return BNEP_NO_RESOURCES;

  if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) return (BNEP_WRONG_HANDLE);

  p_bcb = &(bnep_cb.bcb[handle - 1]);

  memset(p_status, 0, sizeof(tBNEP_STATUS));
  if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
      (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)))
    return BNEP_WRONG_STATE;

  /* Read the status parameters from the connection control block */
  p_status->con_status = BNEP_STATUS_CONNECTED;
  p_status->l2cap_cid = p_bcb->l2cap_cid;
  p_status->rem_mtu_size = p_bcb->rem_mtu_size;
  p_status->xmit_q_depth = fixed_queue_length(p_bcb->xmit_q);
  p_status->sent_num_filters = p_bcb->sent_num_filters;
  p_status->sent_mcast_filters = p_bcb->sent_mcast_filters;
  p_status->rcvd_num_filters = p_bcb->rcvd_num_filters;
  p_status->rcvd_mcast_filters = p_bcb->rcvd_mcast_filters;

  memcpy(p_status->rem_bda, p_bcb->rem_bda, BD_ADDR_LEN);
  memcpy(&(p_status->src_uuid), &(p_bcb->src_uuid), sizeof(tBT_UUID));
  memcpy(&(p_status->dst_uuid), &(p_bcb->dst_uuid), sizeof(tBT_UUID));

  return BNEP_SUCCESS;
#else
  return (BNEP_IGNORE_CMD);
#endif
}
