You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
699 lines
24 KiB
699 lines
24 KiB
/****************************************************************************** |
|
* |
|
* 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 <log/log.h> |
|
#include <string.h> |
|
#include "bnep_int.h" |
|
|
|
/******************************************************************************* |
|
* |
|
* 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(const RawAddress& 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); |
|
|
|
VLOG(0) << __func__ << " BDA:" << p_rem_bda; |
|
|
|
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_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS, |
|
bnep_conn_timer_timeout, p_bcb); |
|
} |
|
|
|
*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, const RawAddress& p_dest_addr, |
|
BT_HDR* p_buf, uint16_t protocol, |
|
const RawAddress* 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; |
|
if (new_len > org_len) { |
|
android_errorWriteLog(0x534e4554, "74947856"); |
|
return BNEP_IGNORE_CMD; |
|
} |
|
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, const RawAddress& p_dest_addr, |
|
uint8_t* p_data, uint16_t len, uint16_t protocol, |
|
const RawAddress* 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; |
|
if (new_len > org_len) { |
|
android_errorWriteLog(0x534e4554, "74947856"); |
|
return BNEP_IGNORE_CMD; |
|
} |
|
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].address, p_start_array, |
|
BD_ADDR_LEN); |
|
memcpy(p_bcb->sent_mcast_filter_end[xx].address, 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; |
|
|
|
p_status->rem_bda = p_bcb->rem_bda; |
|
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 |
|
}
|
|
|