744 lines
26 KiB
C
744 lines
26 KiB
C
/******************************************************************************
|
|
*
|
|
* 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 <string.h>
|
|
#include "bnep_api.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 *p_handle)
|
|
{
|
|
UINT16 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)
|
|
{
|
|
if ((p_bcb = bnepu_allocate_bcb (p_rem_bda)) == 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 *)&(p_bcb->prv_src_uuid), (UINT8 *)&(p_bcb->src_uuid), sizeof (tBT_UUID));
|
|
memcpy ((UINT8 *)&(p_bcb->prv_dst_uuid), (UINT8 *)&(p_bcb->dst_uuid), sizeof (tBT_UUID));
|
|
}
|
|
|
|
/* We are the originator of this connection */
|
|
p_bcb->con_flags |= BNEP_FLAGS_IS_ORIG;
|
|
|
|
memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)src_uuid, sizeof (tBT_UUID));
|
|
memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)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 (defined (BNEP_DO_AUTH_FOR_ROLE_SWITCH) && 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;
|
|
|
|
if ((cid = L2CA_ConnectReq (BT_PSM_BNEP, p_bcb->rem_bda)) != 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 handle, tBNEP_RESULT resp)
|
|
{
|
|
tBNEP_CONN *p_bcb;
|
|
UINT16 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 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID));
|
|
memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID));
|
|
}
|
|
|
|
/* Process remaining part of the setup message (extension headers) */
|
|
if (p_bcb->p_pending_data)
|
|
{
|
|
UINT8 extension_present = TRUE, *p, ext_type;
|
|
UINT16 rem_len;
|
|
|
|
rem_len = p_bcb->p_pending_data->len;
|
|
p = (UINT8 *)(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 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 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 handle,
|
|
UINT8 *p_dest_addr,
|
|
BT_HDR *p_buf,
|
|
UINT16 protocol,
|
|
UINT8 *p_src_addr,
|
|
BOOLEAN fw_ext_present)
|
|
{
|
|
tBNEP_CONN *p_bcb;
|
|
UINT8 *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 *)(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 ext, length;
|
|
UINT16 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 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 handle,
|
|
UINT8 *p_dest_addr,
|
|
UINT8 *p_data,
|
|
UINT16 len,
|
|
UINT16 protocol,
|
|
UINT8 *p_src_addr,
|
|
BOOLEAN fw_ext_present)
|
|
{
|
|
tBNEP_CONN *p_bcb;
|
|
UINT8 *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 ext, length;
|
|
UINT16 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 *)(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 handle,
|
|
UINT16 num_filters,
|
|
UINT16 *p_start_array,
|
|
UINT16 *p_end_array)
|
|
{
|
|
UINT16 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 handle,
|
|
UINT16 num_filters,
|
|
UINT8 *p_start_array,
|
|
UINT8 *p_end_array)
|
|
{
|
|
UINT16 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 BNEP_SetTraceLevel (UINT8 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 handle, tBNEP_STATUS *p_status)
|
|
{
|
|
#if (defined (BNEP_SUPPORTS_STATUS_API) && 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
|
|
}
|
|
|
|
|