fix(bt/bluedroid): fixed issues from AI review in GAP, SPP, HID, L2CAP and HCI

This commit is contained in:
Jin Cheng
2026-07-23 07:52:39 +08:00
parent 2b49bba8a8
commit b19ab411cb
65 changed files with 2211 additions and 1160 deletions
@@ -24,13 +24,23 @@
#include "ble_log.h"
#endif /* CONFIG_BLE_LOG_ENABLED */
#if (BT_CONTROLLER_INCLUDED != TRUE)
static esp_bluedroid_hci_driver_operations_t s_hci_driver_ops = { 0 };
#endif
esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *p_ops)
{
#if (BT_CONTROLLER_INCLUDED == TRUE)
ESP_UNUSED(p_ops);
return ESP_ERR_NOT_SUPPORTED;
#else
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_UNINITIALIZED) {
return ESP_ERR_INVALID_STATE;
}
if (!p_ops) {
ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__);
return ESP_FAIL;
return ESP_ERR_INVALID_ARG;
}
s_hci_driver_ops.send = p_ops->send;
@@ -38,15 +48,24 @@ esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operati
s_hci_driver_ops.register_host_callback = p_ops->register_host_callback;
return ESP_OK;
#endif
}
esp_err_t esp_bluedroid_detach_hci_driver(void)
{
#if (BT_CONTROLLER_INCLUDED == TRUE)
return ESP_ERR_NOT_SUPPORTED;
#else
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_UNINITIALIZED) {
return ESP_ERR_INVALID_STATE;
}
s_hci_driver_ops.send = NULL;
s_hci_driver_ops.check_send_available = NULL;
s_hci_driver_ops.register_host_callback = NULL;
return ESP_OK;
#endif
}
/****************************************************************
@@ -100,11 +119,11 @@ esp_err_t hci_host_register_callback(const esp_bluedroid_hci_driver_callbacks_t
if (!callback) {
ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__);
return ESP_FAIL;
return ESP_ERR_INVALID_ARG;
}
#if (BT_CONTROLLER_INCLUDED == TRUE)
ret = esp_vhci_host_register_callback((esp_vhci_host_callback_t *)callback);
ret = esp_vhci_host_register_callback((const esp_vhci_host_callback_t *)callback);
#else /* BT_CONTROLLER_INCLUDED == TRUE */
if (s_hci_driver_ops.register_host_callback) {
ret = s_hci_driver_ops.register_host_callback(callback);
+116 -73
View File
@@ -25,7 +25,7 @@ esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback)
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (callback == NULL) {
return ESP_FAIL;
return ESP_ERR_INVALID_ARG;
}
btc_profile_cb_set(BTC_PID_GAP_BT, callback);
@@ -34,11 +34,21 @@ esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback)
esp_err_t esp_bt_gap_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_discovery_mode_t d_mode)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((c_mode != ESP_BT_NON_CONNECTABLE) &&
(c_mode != ESP_BT_CONNECTABLE)) {
return ESP_ERR_INVALID_ARG;
}
if ((d_mode != ESP_BT_NON_DISCOVERABLE) &&
(d_mode != ESP_BT_LIMITED_DISCOVERABLE) &&
(d_mode != ESP_BT_GENERAL_DISCOVERABLE)) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_SET_SCAN_MODE;
@@ -50,8 +60,8 @@ esp_err_t esp_bt_gap_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_disco
esp_err_t esp_bt_gap_start_discovery(esp_bt_inq_mode_t mode, uint8_t inq_len, uint8_t num_rsps)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -78,7 +88,7 @@ esp_err_t esp_bt_gap_start_discovery(esp_bt_inq_mode_t mode, uint8_t inq_len, ui
esp_err_t esp_bt_gap_cancel_discovery(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -91,11 +101,15 @@ esp_err_t esp_bt_gap_cancel_discovery(void)
esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (remote_bda == NULL) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_GET_REMOTE_SERVICES;
@@ -106,12 +120,16 @@ esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda)
esp_err_t esp_bt_gap_get_remote_service_record(esp_bd_addr_t remote_bda, esp_bt_uuid_t *uuid)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (uuid == NULL) {
if ((remote_bda == NULL) || (uuid == NULL)) {
return ESP_ERR_INVALID_ARG;
}
if ((uuid->len != LEN_UUID_16) && (uuid->len != LEN_UUID_32) && (uuid->len != LEN_UUID_128)) {
return ESP_ERR_INVALID_ARG;
}
@@ -155,8 +173,8 @@ uint8_t *esp_bt_gap_resolve_eir_data(uint8_t *eir, esp_bt_eir_type_t type, uint8
esp_err_t esp_bt_gap_config_eir_data(esp_bt_eir_data_t *eir_data)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -186,8 +204,8 @@ esp_err_t esp_bt_gap_config_eir_data(esp_bt_eir_data_t *eir_data)
esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -216,14 +234,20 @@ esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode)
esp_err_t esp_bt_gap_get_cod(esp_bt_cod_t *cod)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (cod == NULL) {
return ESP_ERR_INVALID_ARG;
}
return btc_gap_bt_get_cod(cod);
}
esp_err_t esp_bt_gap_read_rssi_delta(esp_bd_addr_t remote_addr)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -238,8 +262,8 @@ esp_err_t esp_bt_gap_read_rssi_delta(esp_bd_addr_t remote_addr)
#if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
esp_err_t esp_bt_gap_read_acl_real_rssi(esp_bd_addr_t remote_addr)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -253,7 +277,7 @@ esp_err_t esp_bt_gap_read_acl_real_rssi(esp_bd_addr_t remote_addr)
esp_err_t esp_bt_gap_read_new_conn_tx_pwr_rng(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -266,8 +290,8 @@ esp_err_t esp_bt_gap_read_new_conn_tx_pwr_rng(void)
esp_err_t esp_bt_gap_write_new_conn_tx_pwr_rng(int8_t pwr_lvl_min, int8_t pwr_lvl_max)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -289,8 +313,8 @@ esp_err_t esp_bt_gap_write_new_conn_tx_pwr_rng(int8_t pwr_lvl_min, int8_t pwr_lv
esp_err_t esp_bt_gap_read_tx_pwr_lvl(esp_bt_gap_tx_pwr_lvl_type_t type)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -314,8 +338,8 @@ esp_err_t esp_bt_gap_read_tx_pwr_lvl(esp_bt_gap_tx_pwr_lvl_type_t type)
esp_err_t esp_bt_gap_write_tx_pwr_lvl(esp_bt_gap_tx_pwr_lvl_type_t type, int8_t tx_power)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -344,11 +368,15 @@ esp_err_t esp_bt_gap_write_tx_pwr_lvl(esp_bt_gap_tx_pwr_lvl_type_t type, int8_t
esp_err_t esp_bt_gap_remove_bond_device(esp_bd_addr_t bd_addr)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE;
@@ -359,7 +387,9 @@ esp_err_t esp_bt_gap_remove_bond_device(esp_bd_addr_t bd_addr)
int esp_bt_gap_get_bond_device_num(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_FAIL;
}
return btc_storage_get_num_bt_bond_devices();
}
@@ -381,11 +411,14 @@ esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list)
esp_err_t esp_bt_gap_set_pin(esp_bt_pin_type_t pin_type, uint8_t pin_code_len, esp_bt_pin_code_t pin_code)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((pin_type != ESP_BT_PIN_TYPE_VARIABLE) && (pin_type != ESP_BT_PIN_TYPE_FIXED)) {
return ESP_ERR_INVALID_ARG;
}
if (pin_type == ESP_BT_PIN_TYPE_FIXED) {
if ((pin_code == NULL) || (pin_code_len == 0) || (pin_code_len > ESP_BT_PIN_CODE_LEN)) {
return ESP_ERR_INVALID_ARG;
@@ -410,11 +443,14 @@ esp_err_t esp_bt_gap_set_pin(esp_bt_pin_type_t pin_type, uint8_t pin_code_len, e
esp_err_t esp_bt_gap_pin_reply(esp_bd_addr_t bd_addr, bool accept, uint8_t pin_code_len, esp_bt_pin_code_t pin_code)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (accept && ((pin_code == NULL) || (pin_code_len == 0) || (pin_code_len > ESP_BT_PIN_CODE_LEN))) {
return ESP_ERR_INVALID_ARG;
}
@@ -437,8 +473,8 @@ esp_err_t esp_bt_gap_pin_reply(esp_bd_addr_t bd_addr, bool accept, uint8_t pin_c
esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
void *value, uint8_t len)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -465,11 +501,14 @@ esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (!(bluedroid_config_get()->get_ssp_enabled())) {
ESP_LOGE(TAG, "%s is not supported when `ssp_en` in `esp_bluedroid_config_t` is disabled!", __func__);
return ESP_ERR_NOT_SUPPORTED;
@@ -487,11 +526,14 @@ esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint3
esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (!(bluedroid_config_get()->get_ssp_enabled())) {
ESP_LOGE(TAG, "%s is not supported when `ssp_en` in `esp_bluedroid_config_t` is disabled!", __func__);
return ESP_ERR_NOT_SUPPORTED;
@@ -508,11 +550,15 @@ esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
esp_err_t esp_bt_gap_set_afh_channels(esp_bt_gap_afh_channels channels)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (channels == NULL) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_SET_AFH_CHANNELS;
@@ -524,11 +570,15 @@ esp_err_t esp_bt_gap_set_afh_channels(esp_bt_gap_afh_channels channels)
esp_err_t esp_bt_gap_read_remote_name(esp_bd_addr_t remote_bda)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (remote_bda == NULL) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_READ_REMOTE_NAME;
@@ -539,12 +589,12 @@ esp_err_t esp_bt_gap_read_remote_name(esp_bd_addr_t remote_bda)
esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (t_poll < ESP_BT_GAP_TPOLL_MIN || t_poll > ESP_BT_GAP_TPOLL_MAX) {
if (remote_bda == NULL || t_poll < ESP_BT_GAP_TPOLL_MIN || t_poll > ESP_BT_GAP_TPOLL_MAX) {
return ESP_ERR_INVALID_ARG;
}
@@ -559,12 +609,11 @@ esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll)
esp_err_t esp_bt_gap_set_page_timeout(uint16_t page_to)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (page_to < HCI_MIN_PAGE_TOUT) {
return ESP_ERR_INVALID_ARG;
}
@@ -579,11 +628,9 @@ esp_err_t esp_bt_gap_set_page_timeout(uint16_t page_to)
esp_err_t esp_bt_gap_get_page_timeout(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
@@ -594,11 +641,13 @@ esp_err_t esp_bt_gap_get_page_timeout(void)
esp_err_t esp_bt_gap_set_acl_pkt_types(esp_bd_addr_t remote_bda, uint16_t pkt_types)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (remote_bda == NULL) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
@@ -613,12 +662,10 @@ esp_err_t esp_bt_gap_set_acl_pkt_types(esp_bd_addr_t remote_bda, uint16_t pkt_ty
#if (ENC_KEY_SIZE_CTRL_MODE != ENC_KEY_SIZE_CTRL_MODE_NONE)
esp_err_t esp_bt_gap_set_min_enc_key_size(uint8_t key_size)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (key_size < ESP_BT_ENC_KEY_SIZE_CTRL_MIN || key_size > ESP_BT_ENC_KEY_SIZE_CTRL_MAX) {
return ESP_ERR_INVALID_ARG;
@@ -635,12 +682,10 @@ esp_err_t esp_bt_gap_set_min_enc_key_size(uint8_t key_size)
esp_err_t esp_bt_gap_set_device_name(const char *name)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
btc_msg_t msg = {0};
btc_gap_bt_args_t arg = {0};
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((!name) || (strlen(name) > BTC_MAX_LOC_BD_NAME_LEN)) {
return ESP_ERR_INVALID_ARG;
}
@@ -656,11 +701,9 @@ esp_err_t esp_bt_gap_set_device_name(const char *name)
esp_err_t esp_bt_gap_get_device_name(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
+13 -17
View File
@@ -31,7 +31,7 @@ esp_err_t esp_bt_hid_device_init(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HD;
msg.act = BTC_HD_INIT_EVT;
@@ -45,7 +45,7 @@ esp_err_t esp_bt_hid_device_deinit(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HD;
msg.act = BTC_HD_DEINIT_EVT;
@@ -68,9 +68,8 @@ esp_err_t esp_bt_hid_device_register_app(esp_hidd_app_param_t* app_param, esp_hi
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_hidd_args_t args;
memset(&args, 0, sizeof(btc_hidd_args_t));
btc_msg_t msg = {0};
btc_hidd_args_t args = {0};
args.register_app.app_param = app_param;
args.register_app.in_qos = in_qos;
args.register_app.out_qos = out_qos;
@@ -88,7 +87,7 @@ esp_err_t esp_bt_hid_device_unregister_app(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HD;
msg.act = BTC_HD_UNREGISTER_APP_EVT;
@@ -105,9 +104,8 @@ esp_err_t esp_bt_hid_device_connect(esp_bd_addr_t bd_addr)
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_hidd_args_t args;
memset(&args, 0, sizeof(btc_hidd_args_t));
btc_msg_t msg = {0};
btc_hidd_args_t args = {0};
memcpy(args.connect.bd_addr, bd_addr, sizeof(esp_bd_addr_t));
msg.sig = BTC_SIG_API_CALL;
@@ -122,7 +120,7 @@ esp_err_t esp_bt_hid_device_disconnect(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HD;
msg.act = BTC_HD_DISCONNECT_EVT;
@@ -139,13 +137,12 @@ esp_err_t esp_bt_hid_device_send_report(esp_hidd_report_type_t type, uint8_t id,
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HD;
msg.act = BTC_HD_SEND_REPORT_EVT;
btc_hidd_args_t args;
memset(&args, 0, sizeof(btc_hidd_args_t));
btc_hidd_args_t args = {0};
args.send_report.type = type;
args.send_report.id = id;
args.send_report.len = len;
@@ -165,13 +162,12 @@ esp_err_t esp_bt_hid_device_report_error(esp_hidd_handshake_error_t error)
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HD;
msg.act = BTC_HD_REPORT_ERROR_EVT;
btc_hidd_args_t args;
memset(&args, 0, sizeof(btc_hidd_args_t));
btc_hidd_args_t args = {0};
args.error = error;
bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), NULL, NULL);
@@ -182,7 +178,7 @@ esp_err_t esp_bt_hid_device_virtual_cable_unplug(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HD;
msg.act = BTC_HD_UNPLUG_EVT;
+25 -25
View File
@@ -29,7 +29,7 @@ esp_err_t esp_bt_hid_host_register_callback(esp_hh_cb_t callback)
esp_err_t esp_bt_hid_host_init(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HH;
@@ -42,7 +42,7 @@ esp_err_t esp_bt_hid_host_init(void)
esp_err_t esp_bt_hid_host_deinit(void)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HH;
@@ -55,8 +55,8 @@ esp_err_t esp_bt_hid_host_deinit(void)
esp_err_t esp_bt_hid_host_connect(esp_bd_addr_t bd_addr)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -75,8 +75,8 @@ esp_err_t esp_bt_hid_host_connect(esp_bd_addr_t bd_addr)
esp_err_t esp_bt_hid_host_disconnect(esp_bd_addr_t bd_addr)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -95,8 +95,8 @@ esp_err_t esp_bt_hid_host_disconnect(esp_bd_addr_t bd_addr)
esp_err_t esp_bt_hid_host_virtual_cable_unplug(esp_bd_addr_t bd_addr)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -115,12 +115,12 @@ esp_err_t esp_bt_hid_host_virtual_cable_unplug(esp_bd_addr_t bd_addr)
esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *hid_info)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((bd_addr == NULL) || (hid_info == NULL) || (hid_info->dl_len < 0) || (hid_info->dl_len > BTHH_MAX_DSC_LEN)) {
if ((bd_addr == NULL) || (hid_info == NULL) || (hid_info->dl_len <= 0) || (hid_info->dl_len > BTHH_MAX_DSC_LEN)) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HH;
@@ -137,8 +137,8 @@ esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *h
esp_err_t esp_bt_hid_host_get_protocol(esp_bd_addr_t bd_addr)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -157,8 +157,8 @@ esp_err_t esp_bt_hid_host_get_protocol(esp_bd_addr_t bd_addr)
esp_err_t esp_bt_hid_host_set_protocol(esp_bd_addr_t bd_addr, esp_hidh_protocol_mode_t protocol_mode)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -178,8 +178,8 @@ esp_err_t esp_bt_hid_host_set_protocol(esp_bd_addr_t bd_addr, esp_hidh_protocol_
esp_err_t esp_bt_hid_host_get_idle(esp_bd_addr_t bd_addr)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -198,8 +198,8 @@ esp_err_t esp_bt_hid_host_get_idle(esp_bd_addr_t bd_addr)
esp_err_t esp_bt_hid_host_set_idle(esp_bd_addr_t bd_addr, uint16_t idle_time)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -220,8 +220,8 @@ esp_err_t esp_bt_hid_host_get_report(esp_bd_addr_t bd_addr, esp_hidh_report_type
int buffer_size)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@@ -248,8 +248,8 @@ esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HH;
@@ -272,8 +272,8 @@ esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_hidh_args_t arg;
btc_msg_t msg = {0};
btc_hidh_args_t arg = {0};
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HH;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -29,7 +29,7 @@ esp_err_t esp_bt_l2cap_register_callback(esp_bt_l2cap_cb_t callback)
esp_err_t esp_bt_l2cap_init(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
@@ -41,7 +41,7 @@ esp_err_t esp_bt_l2cap_init(void)
esp_err_t esp_bt_l2cap_deinit(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
@@ -53,14 +53,19 @@ esp_err_t esp_bt_l2cap_deinit(void)
esp_err_t esp_bt_l2cap_connect(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t remote_psm, esp_bd_addr_t peer_bd_addr)
{
btc_msg_t msg;
btc_msg_t msg = {0};
btc_l2cap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (peer_bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_CONNECT;
memset(&arg, 0, sizeof(btc_l2cap_args_t));
arg.connect.sec_mask = (cntl_flag & 0xffff);
arg.connect.remote_psm = remote_psm;
memcpy(arg.connect.peer_bd_addr, peer_bd_addr, ESP_BD_ADDR_LEN);
@@ -70,7 +75,7 @@ esp_err_t esp_bt_l2cap_connect(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t rem
esp_err_t esp_bt_l2cap_start_srv(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t local_psm)
{
btc_msg_t msg;
btc_msg_t msg = {0};
btc_l2cap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -78,6 +83,7 @@ esp_err_t esp_bt_l2cap_start_srv(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t l
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_START_SRV;
memset(&arg, 0, sizeof(btc_l2cap_args_t));
arg.start_srv.sec_mask = (cntl_flag & 0xffff);
arg.start_srv.local_psm = local_psm;
@@ -86,7 +92,7 @@ esp_err_t esp_bt_l2cap_start_srv(esp_bt_l2cap_cntl_flags_t cntl_flag, uint16_t l
esp_err_t esp_bt_l2cap_stop_all_srv(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
btc_l2cap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -94,6 +100,7 @@ esp_err_t esp_bt_l2cap_stop_all_srv(void)
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_STOP_SRV;
memset(&arg, 0, sizeof(btc_l2cap_args_t));
arg.stop_srv.psm = BTC_L2CAP_INVALID_PSM;
return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
@@ -101,7 +108,7 @@ esp_err_t esp_bt_l2cap_stop_all_srv(void)
esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm)
{
btc_msg_t msg;
btc_msg_t msg = {0};
btc_l2cap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@@ -109,6 +116,7 @@ esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm)
msg.pid = BTC_PID_L2CAP;
msg.act = BTC_L2CAP_ACT_STOP_SRV;
memset(&arg, 0, sizeof(btc_l2cap_args_t));
arg.stop_srv.psm = local_psm;
return (btc_transfer_context(&msg, &arg, sizeof(btc_l2cap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
@@ -116,7 +124,7 @@ esp_err_t esp_bt_l2cap_stop_srv(uint16_t local_psm)
esp_err_t esp_bt_l2cap_vfs_register(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
@@ -128,7 +136,7 @@ esp_err_t esp_bt_l2cap_vfs_register(void)
esp_err_t esp_bt_l2cap_vfs_unregister(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
+26 -18
View File
@@ -24,7 +24,7 @@ esp_err_t esp_spp_register_callback(esp_spp_cb_t callback)
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (callback == NULL) {
return ESP_FAIL;
return ESP_ERR_INVALID_ARG;
}
btc_profile_cb_set(BTC_PID_SPP, callback);
@@ -45,8 +45,8 @@ esp_err_t esp_spp_init(esp_spp_mode_t mode)
esp_err_t esp_spp_enhanced_init(const esp_spp_cfg_t *cfg)
{
btc_msg_t msg;
btc_spp_args_t arg;
btc_msg_t msg = {0};
btc_spp_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (!cfg || (cfg->mode == ESP_SPP_MODE_VFS && (cfg->tx_buffer_size < ESP_SPP_MIN_TX_BUFFER_SIZE ||
@@ -68,7 +68,7 @@ esp_err_t esp_spp_enhanced_init(const esp_spp_cfg_t *cfg)
esp_err_t esp_spp_deinit(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
@@ -81,11 +81,15 @@ esp_err_t esp_spp_deinit(void)
esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr)
{
btc_msg_t msg;
btc_spp_args_t arg;
btc_msg_t msg = {0};
btc_spp_args_t arg = {0};
tSDP_UUID sdp_uuid;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
}
sdp_uuid.len = 16;
memcpy(sdp_uuid.uu.uuid128, UUID_SPP, sizeof(sdp_uuid.uu.uuid128));
@@ -104,10 +108,14 @@ esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr)
esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask,
esp_spp_role_t role, uint8_t remote_scn, esp_bd_addr_t peer_bd_addr)
{
btc_msg_t msg;
btc_spp_args_t arg;
btc_msg_t msg = {0};
btc_spp_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (peer_bd_addr == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (sec_mask != ESP_SPP_SEC_NONE &&
sec_mask != ESP_SPP_SEC_AUTHENTICATE &&
sec_mask != (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)) {
@@ -129,8 +137,8 @@ esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask,
esp_err_t esp_spp_disconnect(uint32_t handle)
{
btc_msg_t msg;
btc_spp_args_t arg;
btc_msg_t msg = {0};
btc_spp_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
@@ -157,8 +165,8 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
esp_err_t esp_spp_start_srv_with_cfg(const esp_spp_start_srv_cfg_t *cfg)
{
btc_msg_t msg;
btc_spp_args_t arg;
btc_msg_t msg = {0};
btc_spp_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (cfg == NULL || cfg->name == NULL || strlen(cfg->name) > ESP_SPP_SERVER_NAME_MAX) {
@@ -194,8 +202,8 @@ esp_err_t esp_spp_start_srv_with_cfg(const esp_spp_start_srv_cfg_t *cfg)
esp_err_t esp_spp_stop_srv(void)
{
btc_msg_t msg;
btc_spp_args_t arg;
btc_msg_t msg = {0};
btc_spp_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
@@ -208,8 +216,8 @@ esp_err_t esp_spp_stop_srv(void)
esp_err_t esp_spp_stop_srv_scn(uint8_t scn)
{
btc_msg_t msg;
btc_spp_args_t arg;
btc_msg_t msg = {0};
btc_spp_args_t arg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((scn == 0) || (scn >= PORT_MAX_RFC_PORTS)) {
@@ -240,7 +248,7 @@ esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data)
esp_err_t esp_spp_vfs_register(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
@@ -252,7 +260,7 @@ esp_err_t esp_spp_vfs_register(void)
esp_err_t esp_spp_vfs_unregister(void)
{
btc_msg_t msg;
btc_msg_t msg = {0};
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
@@ -624,11 +624,11 @@ static inline uint32_t esp_bt_gap_get_cod_major_dev(uint32_t cod)
}
/**
* @brief get minor service field of COD
* @brief get minor device field of COD
*
* @param[in] cod: Class of Device
*
* @return minor service bits
* @return minor device bits
*/
static inline uint32_t esp_bt_gap_get_cod_minor_dev(uint32_t cod)
{
@@ -673,6 +673,8 @@ static inline bool esp_bt_gap_is_valid_cod(uint32_t cod)
*
* @return
* - ESP_OK : Succeed
* - ESP_ERR_INVALID_ARG: if argument invalid
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*/
esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback);
@@ -3944,7 +3944,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
}
bdcpy(conn.link_down.bd_addr, p_bda);
conn.link_down.reason = (UINT8) btm_get_acl_disc_reason_code();
conn.link_down.reason = btm_get_acl_disc_reason_code();
if ( bta_dm_cb.p_sec_cback ) {
bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
if ( issue_unpair_cb ) {
@@ -584,7 +584,6 @@ void BTA_DmWriteBredrTxPwrLvl(tBTM_TX_PWR_LVL_TYPE type, INT8 tx_power, tBTA_CMP
*******************************************************************************/
void BTA_DmSetVisibility(tBTA_DM_DISC disc_mode, tBTA_DM_CONN conn_mode, UINT8 pairable_mode, UINT8 conn_filter )
{
tBTA_DM_API_SET_VISIBILITY *p_msg;
if ((p_msg = (tBTA_DM_API_SET_VISIBILITY *) osi_malloc(sizeof(tBTA_DM_API_SET_VISIBILITY))) != NULL) {
@@ -594,11 +593,8 @@ void BTA_DmSetVisibility(tBTA_DM_DISC disc_mode, tBTA_DM_CONN conn_mode, UINT8 p
p_msg->pair_mode = pairable_mode;
p_msg->conn_paired_only = conn_filter;
bta_sys_sendmsg(p_msg);
}
}
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
@@ -616,7 +612,6 @@ void BTA_DmSetVisibility(tBTA_DM_DISC disc_mode, tBTA_DM_CONN conn_mode, UINT8 p
*******************************************************************************/
void BTA_DmSearch(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK services, tBTA_DM_SEARCH_CBACK *p_cback)
{
tBTA_DM_API_SEARCH *p_msg;
if ((p_msg = (tBTA_DM_API_SEARCH *) osi_malloc(sizeof(tBTA_DM_API_SEARCH))) != NULL) {
@@ -629,7 +624,6 @@ void BTA_DmSearch(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK services, tBTA_DM_SEA
p_msg->rs_res = BTA_DM_RS_NONE;
bta_sys_sendmsg(p_msg);
}
}
@@ -107,20 +107,20 @@ BOOLEAN bta_dm_co_get_compress_memory(tBTA_SYS_ID id, UINT8 **memory_p, UINT32 *
**
** Parameters bt_io_cap - IO capabilities
**
** @return - ESP_BT_STATUS_SUCCESS : success
** @return - ESP_OK : success
** - other : failed
**
*******************************************************************************/
#if (CLASSIC_BT_INCLUDED == TRUE)
esp_err_t bta_dm_co_bt_set_io_cap(UINT8 bt_io_cap)
{
esp_err_t ret = ESP_BT_STATUS_SUCCESS;
esp_err_t ret = ESP_OK;
if(bt_io_cap < BTM_IO_CAP_MAX ) {
btm_cb.devcb.loc_io_caps = bt_io_cap;
ret = ESP_BT_STATUS_SUCCESS;
ret = ESP_OK;
} else {
ret = ESP_BT_STATUS_FAIL;
ret = ESP_FAIL;
APPL_TRACE_ERROR("%s error:Invalid io cap value.",__func__);
}
@@ -71,28 +71,47 @@ static bool check_descriptor(uint8_t *data, uint16_t length, bool *has_report_id
******************************************************************************/
void bta_hd_api_enable(tBTA_HD_DATA *p_data)
{
tBTA_HD_STATUS status = BTA_HD_ERROR;
tHID_STATUS ret;
tBTA_HD_STATUS status = BTA_HD_ERROR;
tBTA_HD_CBACK *p_cback = p_data->api_enable.p_cback;
APPL_TRACE_API("%s", __func__);
HID_DevInit();
do {
ret = HID_DevInit();
if (ret != HID_SUCCESS) {
APPL_TRACE_ERROR("%HID_DevInit failed (%d)", ret);
break;
}
memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
ret = HID_DevSetSecurityLevel(BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
if (ret != HID_SUCCESS) {
APPL_TRACE_ERROR("HD ailed to set security level (%d)", ret);
HID_DevDeinit();
break;
}
HID_DevSetSecurityLevel(BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
/* store parameters */
bta_hd_cb.p_cback = p_data->api_enable.p_cback;
ret = HID_DevRegister(bta_hd_cback);
if (ret != HID_SUCCESS) {
APPL_TRACE_ERROR("%s: Failed to register HID device (%d)", __func__, ret);
HID_DevDeinit();
break;
}
ret = HID_DevRegister(bta_hd_cback);
if (ret == HID_SUCCESS) {
/* store parameters */
bta_hd_cb.p_cback = p_data->api_enable.p_cback;
status = BTA_HD_OK;
} else {
APPL_TRACE_ERROR("%s: Failed to register HID device (%d)", __func__, ret);
} while (0);
if (ret != HID_SUCCESS) {
bta_sys_deregister(BTA_ID_HD);
}
/* signal BTA call back event */
(*bta_hd_cb.p_cback)(BTA_HD_ENABLE_EVT, (tBTA_HD *)&status);
if (p_cback) {
(*p_cback)(BTA_HD_ENABLE_EVT, (tBTA_HD *)&status);
}
}
/*******************************************************************************
@@ -145,52 +164,73 @@ void bta_hd_api_disable(void)
******************************************************************************/
void bta_hd_register_act(tBTA_HD_DATA *p_data)
{
tBTA_HD ret;
tBTA_HD ret = {0};
tBTA_HD_REGISTER_APP *p_app_data = (tBTA_HD_REGISTER_APP *)p_data;
bool use_report_id = FALSE;
bool old_use_report_id = bta_hd_cb.use_report_id;
APPL_TRACE_API("%s", __func__);
ret.reg_status.in_use = FALSE;
do {
if (!p_app_data) {
ret.reg_status.status = BTA_HD_ERROR;
break;
}
/* Check if len doesn't exceed BTA_HD_APP_DESCRIPTOR_LEN and descriptor
* itself is well-formed. Also check if descriptor has Report Id item so we
* know if report will have prefix or not. */
if (p_app_data->d_len > BTA_HD_APP_DESCRIPTOR_LEN ||
!check_descriptor(p_app_data->d_data, p_app_data->d_len, &use_report_id)) {
APPL_TRACE_ERROR("%s: Descriptor is too long or malformed", __func__);
ret.reg_status.status = BTA_HD_ERROR;
(*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
return;
}
ret.reg_status.in_use = FALSE;
ret.reg_status.status = BTA_HD_OK;
/* Check if len doesn't exceed BTA_HD_APP_DESCRIPTOR_LEN and descriptor
* itself is well-formed. Also check if descriptor has Report Id item so we
* know if report will have prefix or not. */
if (p_app_data->d_len > BTA_HD_APP_DESCRIPTOR_LEN ||
!check_descriptor(p_app_data->d_data, p_app_data->d_len, &use_report_id)) {
APPL_TRACE_ERROR("%s: Descriptor is too long or malformed", __func__);
ret.reg_status.status = BTA_HD_ERROR;
break;
}
/* Remove old record if for some reason it's already registered */
if (bta_hd_cb.sdp_handle != 0) {
SDP_DeleteRecord(bta_hd_cb.sdp_handle);
}
/* Remove old record if for some reason it's already registered */
if (bta_hd_cb.sdp_handle != 0) {
SDP_DeleteRecord(bta_hd_cb.sdp_handle);
bta_hd_cb.sdp_handle = 0;
}
bta_hd_cb.use_report_id = use_report_id;
bta_hd_cb.sdp_handle = SDP_CreateRecord();
HID_DevAddRecord(bta_hd_cb.sdp_handle, p_app_data->name, p_app_data->description, p_app_data->provider,
p_app_data->subclass, p_app_data->d_len, p_app_data->d_data);
bta_sys_add_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
bta_hd_cb.use_report_id = use_report_id;
bta_hd_cb.sdp_handle = SDP_CreateRecord();
if (bta_hd_cb.sdp_handle == 0) {
bta_hd_cb.use_report_id = old_use_report_id;
ret.reg_status.status = BTA_HD_ERROR;
break;
}
tHID_STATUS status = HID_DevAddRecord(bta_hd_cb.sdp_handle, p_app_data->name, p_app_data->description, p_app_data->provider,
p_app_data->subclass, p_app_data->d_len, p_app_data->d_data);
if (status != HID_SUCCESS) {
SDP_DeleteRecord(bta_hd_cb.sdp_handle);
bta_hd_cb.sdp_handle = 0;
bta_hd_cb.use_report_id = old_use_report_id;
ret.reg_status.status = BTA_HD_ERROR;
break;
}
HID_DevSetIncomingQos(p_app_data->in_qos.service_type, p_app_data->in_qos.token_rate,
p_app_data->in_qos.token_bucket_size, p_app_data->in_qos.peak_bandwidth,
p_app_data->in_qos.access_latency, p_app_data->in_qos.delay_variation);
bta_sys_add_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
HID_DevSetOutgoingQos(p_app_data->out_qos.service_type, p_app_data->out_qos.token_rate,
p_app_data->out_qos.token_bucket_size, p_app_data->out_qos.peak_bandwidth,
p_app_data->out_qos.access_latency, p_app_data->out_qos.delay_variation);
HID_DevSetIncomingQos(p_app_data->in_qos.service_type, p_app_data->in_qos.token_rate,
p_app_data->in_qos.token_bucket_size, p_app_data->in_qos.peak_bandwidth,
p_app_data->in_qos.access_latency, p_app_data->in_qos.delay_variation);
// application is registered so we can accept incoming connections
HID_DevSetIncomingPolicy(TRUE);
HID_DevSetOutgoingQos(p_app_data->out_qos.service_type, p_app_data->out_qos.token_rate,
p_app_data->out_qos.token_bucket_size, p_app_data->out_qos.peak_bandwidth,
p_app_data->out_qos.access_latency, p_app_data->out_qos.delay_variation);
if (HID_DevGetDevice(&ret.reg_status.bda) == HID_SUCCESS) {
ret.reg_status.in_use = TRUE;
}
// application is registered so we can accept incoming connections
HID_DevSetIncomingPolicy(TRUE);
if (HID_DevGetDevice(&ret.reg_status.bda) == HID_SUCCESS) {
ret.reg_status.in_use = TRUE;
}
ret.reg_status.status = BTA_HD_OK;
} while (0);
(*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret);
}
@@ -260,14 +300,14 @@ extern void bta_hd_connect_act(tBTA_HD_DATA *p_data)
{
tHID_STATUS ret;
tBTA_HD_DEVICE_CTRL *p_ctrl = (tBTA_HD_DEVICE_CTRL *)p_data;
tBTA_HD cback_data;
tBTA_HD cback_data = {0};
APPL_TRACE_API("%s", __func__);
do {
ret = HID_DevPlugDevice(p_ctrl->addr);
if (ret != HID_SUCCESS) {
APPL_TRACE_WARNING("%s: HID_DevPlugDevice returned %d", __func__, ret);
return;
break;
}
ret = HID_DevConnect();
@@ -279,7 +319,7 @@ extern void bta_hd_connect_act(tBTA_HD_DATA *p_data)
bdcpy(cback_data.conn.bda, p_ctrl->addr);
cback_data.conn.status = (ret == HID_SUCCESS ? BTA_HD_OK : BTA_HD_ERROR);
cback_data.conn.conn_status = BTA_HD_CONN_STATE_CONNECTING;
cback_data.conn.conn_status = (ret == HID_SUCCESS ? BTA_HD_CONN_STATE_CONNECTING : BTA_HD_CONN_STATE_DISCONNECTED);
bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
}
@@ -441,11 +481,13 @@ extern void bta_hd_vc_unplug_act(UNUSED_ATTR tBTA_HD_DATA *p_data)
}
APPL_TRACE_DEBUG("%s local VUP, remove bda: %02x:%02x:%02x:%02x:%02x:%02x", __func__, plugged_addr[0],
plugged_addr[1], plugged_addr[2], plugged_addr[3], plugged_addr[4], plugged_addr[5]);
bdcpy(cback_data.conn.bda, plugged_addr);
cback_data.conn.status = BTA_HD_OK;
cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED;
bta_hd_cb.p_cback(BTA_HD_VC_UNPLUG_EVT, &cback_data);
return;
} else if (ret != HID_SUCCESS) {
bta_hd_cb.vc_unplug = FALSE;
APPL_TRACE_WARNING("%s: HID_DevVirtualCableUnplug returned %d", __func__, ret);
}
@@ -532,7 +574,7 @@ extern void bta_hd_intr_data_act(tBTA_HD_DATA *p_data)
BT_HDR *p_msg = p_cback->p_data;
uint16_t len = p_msg->len;
uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
tBTA_HD_INTR_DATA ret;
tBTA_HD_INTR_DATA ret = {0};
APPL_TRACE_API("%s", __func__);
@@ -636,7 +678,7 @@ extern void bta_hd_set_report_act(tBTA_HD_DATA *p_data)
BT_HDR *p_msg = p_cback->p_data;
uint16_t len = p_msg->len;
uint8_t *p_buf = (uint8_t *)(p_msg + 1) + p_msg->offset;
tBTA_HD_SET_REPORT ret = {0, 0, 0, NULL};
tBTA_HD ret = {0};
APPL_TRACE_API("%s", __func__);
@@ -644,7 +686,7 @@ extern void bta_hd_set_report_act(tBTA_HD_DATA *p_data)
goto _exit;
}
ret.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
ret.set_report.report_type = *p_buf & HID_PAR_REP_TYPE_MASK;
p_buf++;
len--;
@@ -652,16 +694,16 @@ extern void bta_hd_set_report_act(tBTA_HD_DATA *p_data)
if (len < 1) {
goto _exit;
}
ret.report_id = *p_buf;
ret.set_report.report_id = *p_buf;
len--;
p_buf++;
} else {
ret.report_id = 0;
ret.set_report.report_id = 0;
}
ret.len = len;
ret.p_data = p_buf;
(*bta_hd_cb.p_cback)(BTA_HD_SET_REPORT_EVT, (tBTA_HD *)&ret);
ret.set_report.len = len;
ret.set_report.p_data = p_buf;
(*bta_hd_cb.p_cback)(BTA_HD_SET_REPORT_EVT, &ret);
_exit:
if (p_msg) {
@@ -49,6 +49,17 @@ void BTA_HdEnable(tBTA_HD_CBACK *p_cback)
{
tBTA_HD_API_ENABLE *p_buf;
APPL_TRACE_API("%s", __func__);
if (bta_sys_is_register(BTA_ID_HD) == TRUE) {
APPL_TRACE_WARNING("%s HD already enable", __func__);
if (p_cback) {
tBTA_HD param = {0};
param.status = BTA_HD_OK;
(*p_cback)(BTA_HD_ENABLE_EVT, &param);
}
return;
}
p_buf = (tBTA_HD_API_ENABLE *)osi_malloc(sizeof(tBTA_HD_API_ENABLE));
if (p_buf != NULL) {
bta_sys_register(BTA_ID_HD, &bta_hd_reg);
@@ -71,8 +82,8 @@ void BTA_HdDisable(void)
{
BT_HDR *p_buf;
APPL_TRACE_API("%s", __func__);
bta_sys_deregister(BTA_ID_HD);
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
bta_sys_deregister(BTA_ID_HD);
p_buf->event = BTA_HD_API_DISABLE_EVT;
bta_sys_sendmsg(p_buf);
}
@@ -322,7 +322,7 @@ tBTA_STATUS bta_hd_bqb_set_local_di_record(void)
{
tBTA_STATUS status = BTA_FAILURE;
tBTA_DI_RECORD bqb_device_info;
tBTA_DI_RECORD bqb_device_info = {0};
bqb_device_info.vendor = 0;
bqb_device_info.vendor_id_source = 0xff; // BTA_HH_VENDOR_ID_INVALID
bqb_device_info.product = 1;
@@ -70,6 +70,7 @@ void bta_hh_api_enable(tBTA_HH_DATA *p_data)
{
tBTA_HH_STATUS status = BTA_HH_ERR;
UINT8 xx;
tBTA_HH_CBACK *p_cback = p_data->api_enable.p_cback;
/* initialize BTE HID */
HID_HostInit();
@@ -81,7 +82,7 @@ void bta_hh_api_enable(tBTA_HH_DATA *p_data)
/* Register with L2CAP */
if ( HID_HostRegister (bta_hh_cback) == HID_SUCCESS) {
/* store parameters */
bta_hh_cb.p_cback = p_data->api_enable.p_cback;
bta_hh_cb.p_cback = p_cback;
status = BTA_HH_OK;
/* initialize device CB */
@@ -104,8 +105,8 @@ void bta_hh_api_enable(tBTA_HH_DATA *p_data)
#endif
{
/* signal BTA call back event */
if (bta_hh_cb.p_cback) {
(* bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, (tBTA_HH *)&status);
if (p_cback) {
(*p_cback)(BTA_HH_ENABLE_EVT, (tBTA_HH *)&status);
}
}
}
@@ -189,7 +190,8 @@ static void bta_hh_sdp_cback(UINT16 result, UINT16 attr_mask,
{
tBTA_HH_DEV_CB *p_cb = bta_hh_cb.p_cur;
UINT8 hdl = 0;
tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
tBTA_HH_DATA data = {0};
/* make sure sdp succeeded and hh has not been disabled */
if ((result == SDP_SUCCESS) && (p_cb != NULL)) {
@@ -244,7 +246,8 @@ static void bta_hh_sdp_cback(UINT16 result, UINT16 attr_mask,
utl_freebuf((void **)&bta_hh_cb.p_disc_db);
/* send SDP_CMPL_EVT into state machine */
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);
data.status = status;
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &data);
return;
}
@@ -260,7 +263,8 @@ static void bta_hh_sdp_cback(UINT16 result, UINT16 attr_mask,
static void bta_hh_di_sdp_cback(UINT16 result)
{
tBTA_HH_DEV_CB *p_cb = bta_hh_cb.p_cur;
tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
tBTA_HH_DATA data = {0};
tSDP_DI_GET_RECORD di_rec;
tHID_STATUS ret;
#if BTA_HH_DEBUG
@@ -299,7 +303,8 @@ static void bta_hh_di_sdp_cback(UINT16 result)
if (status != BTA_HH_OK) {
utl_freebuf((void **)&bta_hh_cb.p_disc_db);
/* send SDP_CMPL_EVT into state machine */
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);
data.status = status;
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &data);
}
return;
@@ -321,12 +326,12 @@ static void bta_hh_di_sdp_cback(UINT16 result)
void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
{
tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
tBTA_HH_DATA data = {0};
UINT8 hdl;
p_cb->sec_mask = p_data->api_conn.sec_mask;
p_cb->mode = p_data->api_conn.mode;
p_cb->new_mode = p_data->api_conn.mode;
bta_hh_cb.p_cur = p_cb;
#if (BTA_HH_LE_INCLUDED == TRUE)
if (bta_hh_is_le_device(p_cb, p_data->api_conn.bd_addr)) {
@@ -356,7 +361,8 @@ void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
status = BTA_HH_ERR_NO_RES;
}
}
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);
data.status = status;
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &data);
return;
}
@@ -386,7 +392,8 @@ void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
}
if (status != BTA_HH_OK) {
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);
data.status = status;
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &data);
}
return;
@@ -531,7 +538,7 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
bta_hh_cb.cnt_num ++;
/* initialize device driver */
bta_hh_co_open(p_cb->hid_handle, p_cb->sub_class,
bta_hh_co_open(dev_handle, p_cb->sub_class,
p_cb->attr_mask, p_cb->app_id);
#if (BTA_HH_LE_INCLUDED == TRUE)
@@ -647,7 +654,7 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
{
tBTA_HH_CBDATA cback_data ;
tBTA_HH_HSDATA hs_data;
tBTA_HH_CONN conn ;
tBTA_HH_CONN conn = {0};
#if BTA_HH_DEBUG
APPL_TRACE_DEBUG("HANDSHAKE received for: event = %s data= %d",
@@ -854,7 +861,7 @@ void bta_hh_open_failure(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
*******************************************************************************/
void bta_hh_close_act (tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
{
tBTA_HH_CONN conn_dat ;
tBTA_HH_CONN conn_dat = {0};
tBTA_HH_CBDATA disc_dat = {BTA_HH_OK, 0};
UINT32 reason = p_data->hid_cback.data; /* Reason for closing (32-bit) */
@@ -980,6 +987,7 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
if (HID_HostAddDev(p_dev_info->bda, p_dev_info->attr_mask, &dev_handle)\
== HID_SUCCESS) {
dev_info.handle = dev_handle;
dev_info.status = BTA_HH_OK;
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
/* update DI information */
@@ -1026,6 +1034,7 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
bta_hh_le_remove_dev_bg_conn(p_cb);
bta_hh_sm_execute(p_cb, BTA_HH_API_CLOSE_EVT, NULL);
bta_hh_clean_up_kdev(p_cb);
dev_info.status = BTA_HH_OK;
} else
#endif
{
@@ -63,15 +63,14 @@ void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback)
{
tBTA_HH_API_ENABLE *p_buf;
/* register with BTA system manager */
bta_sys_register(BTA_ID_HH, &bta_hh_reg);
APPL_TRACE_API("%s sec_mask:0x%x p_cback:%p", __func__, sec_mask, p_cback);
p_buf = (tBTA_HH_API_ENABLE *)osi_malloc(sizeof(tBTA_HH_API_ENABLE));
if (p_buf != NULL) {
memset(p_buf, 0, sizeof(tBTA_HH_API_ENABLE));
/* register with BTA system manager */
bta_sys_register(BTA_ID_HH, &bta_hh_reg);
memset(p_buf, 0, sizeof(tBTA_HH_API_ENABLE));
p_buf->hdr.event = BTA_HH_API_ENABLE_EVT;
p_buf->p_cback = p_cback;
p_buf->sec_mask = sec_mask;
@@ -308,6 +307,7 @@ void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR *p_data)
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
if (p_data->layer_specific != BTA_HH_RPTT_OUTPUT) {
APPL_TRACE_ERROR("ERROR! Wrong report type! Write Command only valid for output report!");
utl_freebuf((void **)&p_data);
return;
}
#endif
@@ -327,8 +327,8 @@ void BTA_HhGetDscpInfo(UINT8 dev_handle)
{
BT_HDR *p_buf;
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
memset(p_buf, 0, sizeof(BT_HDR));
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(tBTA_HH_DATA))) != NULL) {
memset(p_buf, 0, sizeof(tBTA_HH_DATA));
p_buf->event = BTA_HH_API_GET_DSCP_EVT;
p_buf->layer_specific = (UINT16) dev_handle;
@@ -253,8 +253,8 @@ tBTA_HH_CB *bta_hh_cb_ptr;
** Static functions
*****************************************************************************/
#if BTA_HH_DEBUG == TRUE
static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
static char *bta_hh_state_code(tBTA_HH_STATE state_code);
static const char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
static const char *bta_hh_state_code(tBTA_HH_STATE state_code);
#endif
/*******************************************************************************
@@ -447,7 +447,9 @@ BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
uint8_t hdl = BTA_HH_IDX_INVALID;
if (HID_HostGetDev(((tBTA_HH_CBACK_DATA *)p_msg)->addr, &hdl) == HID_SUCCESS && hdl != BTA_HH_IDX_INVALID) {
bta_hh_cb.cb_index[hdl] = bta_hh_cb.kdev[index].index;
if (index != BTA_HH_IDX_INVALID) {
bta_hh_cb.cb_index[hdl] = bta_hh_cb.kdev[index].index;
}
}
} else {
index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
@@ -478,7 +480,7 @@ BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
** Returns void
**
*******************************************************************************/
static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
static const char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
{
switch (evt_code) {
case BTA_HH_API_DISABLE_EVT:
@@ -543,11 +545,11 @@ static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
** Returns void
**
*******************************************************************************/
static char *bta_hh_state_code(tBTA_HH_STATE state_code)
static const char *bta_hh_state_code(tBTA_HH_STATE state_code)
{
switch (state_code) {
case BTA_HH_NULL_ST:
return"BTA_HH_NULL_ST";
return "BTA_HH_NULL_ST";
case BTA_HH_IDLE_ST:
return "BTA_HH_IDLE_ST";
case BTA_HH_W4_CONN_ST:
@@ -60,11 +60,14 @@ UINT8 bta_hh_find_cb(BD_ADDR bda)
{
UINT8 xx;
if (!bdcmp(bda, bd_addr_null)) {
return BTA_HH_IDX_INVALID;
}
/* See how many active devices there are. */
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
/* check if any active/known devices is a match */
if ((!bdcmp (bda, bta_hh_cb.kdev[xx].addr) &&
bdcmp(bda, bd_addr_null) != 0) ) {
if (!bdcmp (bda, bta_hh_cb.kdev[xx].addr)) {
#if BTA_HH_DEBUG
APPL_TRACE_DEBUG("found kdev_cb[%d] hid_handle = %d ", xx,
bta_hh_cb.kdev[xx].hid_handle)
@@ -201,8 +204,9 @@ void bta_hh_add_device_to_list(tBTA_HH_DEV_CB *p_cb, UINT8 handle,
p_cb->dscp_info.ssr_min_tout = ssr_min_tout;
/* store report descriptor info */
if ( p_dscp_info) {
if (p_dscp_info) {
utl_freebuf((void **)&p_cb->dscp_info.descriptor.dsc_list);
p_cb->dscp_info.descriptor.dl_len = 0;
if (p_dscp_info->dl_len &&
(p_cb->dscp_info.descriptor.dsc_list =
@@ -336,8 +340,8 @@ void bta_hh_parse_keybd_rpt(tBTA_HH_BOOT_RPT *p_kb_data, UINT8 *p_report,
#if BTA_HH_DEBUG
APPL_TRACE_DEBUG("found keycode %02x ", this_report[xx]);
#endif
p_data->caps_lock = p_kb->caps_lock;
p_data->num_lock = p_kb->num_lock;
p_data->caps_lock = p_kb->caps_lock;
p_data->num_lock = p_kb->num_lock;
}
memset (p_kb->last_report, 0, BTA_HH_MAX_RPT_CHARS);
@@ -362,8 +366,7 @@ void bta_hh_parse_mice_rpt(tBTA_HH_BOOT_RPT *p_mice_data, UINT8 *p_report,
#if BTA_HH_DEBUG
UINT8 xx;
APPL_TRACE_DEBUG("bta_hh_parse_mice_rpt: bta_keybd_rpt_rcvd(report=%p, \
report_len=%d) called", p_report, report_len);
APPL_TRACE_DEBUG("bta_hh_parse_mice_rpt: (report=%p, report_len=%d) called", p_report, report_len);
#endif
if ((report_len < 3) || (p_report == NULL)) {
@@ -413,9 +416,9 @@ tBTA_HH_STATUS bta_hh_read_ssr_param(BD_ADDR bd_addr, UINT16 *p_max_ssr_lat, UIN
tBTA_HH_STATUS status = BTA_HH_ERR;
tBTA_HH_CB *p_cb = &bta_hh_cb;
UINT8 i;
UINT16 ssr_max_latency;
UINT16 ssr_max_latency = 0;
for (i = 0; i < BTA_HH_MAX_KNOWN; i ++) {
for (i = 0; i < BTA_HH_MAX_DEVICE; i ++) {
if (memcmp(p_cb->kdev[i].addr, bd_addr, BD_ADDR_LEN) == 0) {
/* if remote device does not have HIDSSRHostMaxLatency attribute in SDP,
@@ -479,7 +482,9 @@ void bta_hh_cleanup_disable(tBTA_HH_STATUS status)
utl_freebuf((void **)&bta_hh_cb.p_disc_db);
if (bta_hh_cb.p_cback) {
(*bta_hh_cb.p_cback)(BTA_HH_DISABLE_EVT, (tBTA_HH*)&status);
tBTA_HH data = {0};
data.status = status;
(*bta_hh_cb.p_cback)(BTA_HH_DISABLE_EVT, &data);
/* all connections are down, no waiting for disconnect */
memset(&bta_hh_cb, 0, sizeof(tBTA_HH_CB));
}
@@ -499,6 +504,10 @@ UINT8 bta_hh_dev_handle_to_cb_idx(UINT8 dev_handle)
{
UINT8 index = BTA_HH_IDX_INVALID;
if (dev_handle == BTA_HH_INVALID_HANDLE) {
return BTA_HH_IDX_INVALID;
}
#if BTA_HH_LE_INCLUDED == TRUE
if (BTA_HH_IS_LE_DEV_HDL(dev_handle)) {
if (BTA_HH_IS_LE_DEV_HDL_VALID(dev_handle)) {
@@ -97,11 +97,11 @@ static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected
static void fcchan_data_cbk(UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf);
#endif /* BTA_JV_L2CAP_INCLUDED */
extern void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str);
extern void uuid_to_string_legacy(const bt_uuid_t *p_uuid, char *str);
static inline void logu(const char *title, const uint8_t *p_uuid)
{
char uuids[128];
uuid_to_string_legacy((bt_uuid_t *)p_uuid, uuids);
uuid_to_string_legacy((const bt_uuid_t *)p_uuid, uuids);
APPL_TRACE_DEBUG("%s: %s", title, uuids);
}
@@ -172,7 +172,7 @@ UNUSED_ATTR static int get_rfc_cb_used(void)
}
}
if (used == BTA_JV_MAX_RFC_CONN) {
APPL_TRACE_ERROR("get_sec_id_used, rfc ctrl block exceeds the limit:%d",
APPL_TRACE_ERROR("get_rfc_cb_used, rfc ctrl block exceeds the limit:%d",
BTA_JV_MAX_RFC_CONN);
}
return used;
@@ -283,7 +283,7 @@ tBTA_JV_RFC_CB *bta_jv_rfc_port_to_cb(UINT16 port_handle)
handle = bta_jv_cb.port_cb[port_handle - 1].handle;
handle &= BTA_JV_RFC_HDL_MASK;
handle &= ~BTA_JV_RFCOMM_MASK;
if (handle) {
if ((handle > 0) && (handle <= BTA_JV_MAX_RFC_CONN)) {
p_cb = &bta_jv_cb.rfc_cb[handle - 1];
}
} else {
@@ -724,12 +724,14 @@ BOOLEAN bta_jv_check_psm(UINT16 psm)
void bta_jv_enable(tBTA_JV_MSG *p_data)
{
tBTA_UTL_COD cod;
tBTA_JV_STATUS status = BTA_JV_SUCCESS;
tBTA_JV data = {0};
data.status = BTA_JV_SUCCESS;
memset(bta_jv_cb.free_psm_list, 0, sizeof(bta_jv_cb.free_psm_list));
bta_jv_cb.p_dm_cback = p_data->enable.p_cback;
bta_jv_cb.p_dm_cback(BTA_JV_ENABLE_EVT, (tBTA_JV *)&status, 0);
bta_jv_cb.p_dm_cback(BTA_JV_ENABLE_EVT, &data, 0);
/* Set the Class of Device */
cod.major = BTM_COD_MAJOR_UNCLASSIFIED;
@@ -783,7 +785,7 @@ static UINT16 bta_jv_get_free_psm(void)
for (int i = 0; i < cnt; i++) {
UINT16 psm = bta_jv_cb.free_psm_list[i];
if (psm != 0) {
APPL_TRACE_DEBUG("%s(): Reusing PSM: 0x%04d", __func__, psm)
APPL_TRACE_DEBUG("%s(): Reusing PSM: 0x%04x", __func__, psm);
bta_jv_cb.free_psm_list[i] = 0;
return psm;
}
@@ -804,7 +806,7 @@ static void bta_jv_set_free_psm(UINT16 psm)
}
if (free_index != -1) {
bta_jv_cb.free_psm_list[free_index] = psm;
APPL_TRACE_DEBUG("%s(): Recycling PSM: 0x%04d", __func__, psm)
APPL_TRACE_DEBUG("%s(): Recycling PSM: 0x%04x", __func__, psm);
} else {
APPL_TRACE_ERROR("%s unable to free psm 0x%x no more free slots", __func__, psm);
}
@@ -842,7 +844,9 @@ void bta_jv_get_channel_id(tBTA_JV_MSG *p_data)
scn = (UINT8) channel;
}
if (bta_jv_cb.p_dm_cback) {
bta_jv_cb.p_dm_cback(BTA_JV_GET_SCN_EVT, (tBTA_JV *)&scn,
tBTA_JV param = {0};
param.scn = scn;
bta_jv_cb.p_dm_cback(BTA_JV_GET_SCN_EVT, &param,
p_data->alloc_channel.user_data);
}
return;
@@ -861,7 +865,9 @@ void bta_jv_get_channel_id(tBTA_JV_MSG *p_data)
}
if (bta_jv_cb.p_dm_cback) {
bta_jv_cb.p_dm_cback(BTA_JV_GET_PSM_EVT, (tBTA_JV *)&psm, p_data->alloc_channel.user_data);
tBTA_JV param = {0};
param.psm = psm;
bta_jv_cb.p_dm_cback(BTA_JV_GET_PSM_EVT, &param, p_data->alloc_channel.user_data);
}
}
@@ -932,7 +938,6 @@ static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID *u)
static uint8_t bt_base_uuid[] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
logu("in, uuid:", u->uu.uuid128);
APPL_TRACE_DEBUG("uuid len:%d", u->len);
if (u->len == 16) {
if (memcmp(&u->uu.uuid128[4], &bt_base_uuid[4], 12) == 0) {
@@ -976,7 +981,7 @@ static void bta_jv_start_discovery_cback(UINT16 result, void *user_data)
bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_NONE;
if (bta_jv_cb.p_dm_cback) {
tBTA_JV_DISCOVERY_COMP dcomp;
tBTA_JV_DISCOVERY_COMP dcomp = {0};
dcomp.scn_num = 0;
status = BTA_JV_FAILURE;
if (result == SDP_SUCCESS || result == SDP_DB_FULL) {
@@ -1222,19 +1227,19 @@ static int add_spp_sdp(const char *name, const int channel) {
void bta_jv_create_record(tBTA_JV_MSG *p_data)
{
tBTA_JV_API_CREATE_RECORD *cr = &(p_data->create_record);
tBTA_JV_CREATE_RECORD evt_data;
tBTA_JV evt_data = {0};
int handle = add_spp_sdp(cr->name, cr->channel);
evt_data.handle = handle;
evt_data.create_rec.handle = handle;
if (handle) {
evt_data.status = BTA_JV_SUCCESS;
evt_data.create_rec.status = BTA_JV_SUCCESS;
} else {
evt_data.status = BTA_JV_FAILURE;
evt_data.create_rec.status = BTA_JV_FAILURE;
}
if(bta_jv_cb.p_dm_cback) {
//callback user immediately to create his own sdp record in stack thread context
bta_jv_cb.p_dm_cback(BTA_JV_CREATE_RECORD_EVT, (tBTA_JV *)&evt_data, cr->user_data);
bta_jv_cb.p_dm_cback(BTA_JV_CREATE_RECORD_EVT, &evt_data, cr->user_data);
}
}
@@ -1499,7 +1504,7 @@ void bta_jv_l2cap_start_server(tBTA_JV_MSG *p_data)
UINT8 sec_id;
UINT16 handle;
tL2CAP_CFG_INFO cfg;
tBTA_JV_L2CAP_START evt_data;
tBTA_JV_L2CAP_START evt_data = {0};
tBTA_JV_API_L2CAP_SERVER *ls = &(p_data->l2cap_server);
// INT32 use_etm = FALSE;
UINT8 chan_mode_mask = GAP_FCR_CHAN_OPT_BASIC;
@@ -1665,27 +1670,42 @@ void bta_jv_l2cap_write(tBTA_JV_MSG *p_data)
*******************************************************************************/
void bta_jv_l2cap_write_fixed(tBTA_JV_MSG *p_data)
{
tBTA_JV_L2CAP_WRITE_FIXED evt_data;
tBTA_JV_L2CAP_WRITE_FIXED evt_data = {0};
tBTA_JV_API_L2CAP_WRITE_FIXED *ls = &(p_data->l2cap_write_fixed);
BT_HDR *msg = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + ls->len + L2CAP_MIN_OFFSET);
if (!msg) {
APPL_TRACE_ERROR("%s() could not allocate msg buffer", __func__);
return;
}
BT_HDR *msg = NULL;
evt_data.status = BTA_JV_FAILURE;
evt_data.channel = ls->channel;
memcpy(evt_data.addr, ls->addr, sizeof(evt_data.addr));
evt_data.req_id = ls->req_id;
evt_data.len = 0;
msg = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + ls->len + L2CAP_MIN_OFFSET);
if (!msg) {
APPL_TRACE_ERROR("%s() could not allocate msg buffer", __func__);
if (ls->p_cback) {
ls->p_cback(BTA_JV_L2CAP_WRITE_FIXED_EVT, (tBTA_JV *)&evt_data, ls->user_data);
}
return;
}
memcpy(((uint8_t *)(msg + 1)) + L2CAP_MIN_OFFSET, ls->p_data, ls->len);
msg->len = ls->len;
msg->offset = L2CAP_MIN_OFFSET;
L2CA_SendFixedChnlData(ls->channel, ls->addr, msg);
UINT16 ret = L2CA_SendFixedChnlData(ls->channel, ls->addr, msg);
if (ret == L2CAP_DW_SUCCESS) {
evt_data.status = BTA_JV_SUCCESS;
evt_data.len = ls->len;
} else if (ret == L2CAP_DW_CONGESTED) {
evt_data.status = BTA_JV_SUCCESS;
evt_data.len = ls->len;
evt_data.cong = TRUE;
}
ls->p_cback(BTA_JV_L2CAP_WRITE_FIXED_EVT, (tBTA_JV *)&evt_data, ls->user_data);
if (ls->p_cback) {
ls->p_cback(BTA_JV_L2CAP_WRITE_FIXED_EVT, (tBTA_JV *)&evt_data, ls->user_data);
}
}
#endif /* BTA_JV_L2CAP_INCLUDED */
@@ -2367,18 +2387,20 @@ void bta_jv_rfcomm_read(tBTA_JV_MSG *p_data)
tBTA_JV_API_RFCOMM_READ *rc = &(p_data->rfcomm_read);
tBTA_JV_RFC_CB *p_cb = rc->p_cb;
tBTA_JV_PCB *p_pcb = rc->p_pcb;
tBTA_JV_RFCOMM_READ evt_data;
tBTA_JV evt_data = {0};
evt_data.status = BTA_JV_FAILURE;
evt_data.handle = p_pcb->handle;
evt_data.req_id = rc->req_id;
evt_data.p_data = rc->p_data;
if (PORT_ReadData(rc->p_pcb->port_handle, (char *)rc->p_data, rc->len, &evt_data.len) ==
evt_data.rfc_read.status = BTA_JV_FAILURE;
evt_data.rfc_read.handle = p_pcb->handle;
evt_data.rfc_read.req_id = rc->req_id;
evt_data.rfc_read.p_data = rc->p_data;
if (PORT_ReadData(rc->p_pcb->port_handle, (char *)rc->p_data, rc->len, &evt_data.rfc_read.len) ==
PORT_SUCCESS) {
evt_data.status = BTA_JV_SUCCESS;
evt_data.rfc_read.status = BTA_JV_SUCCESS;
}
p_cb->p_cback(BTA_JV_RFCOMM_READ_EVT, (tBTA_JV *)&evt_data, p_pcb->user_data);
if (p_cb->p_cback) {
p_cb->p_cback(BTA_JV_RFCOMM_READ_EVT, &evt_data, p_pcb->user_data);
}
}
/*******************************************************************************
@@ -2577,8 +2599,8 @@ static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB *p_cb)
*******************************************************************************/
static void bta_jv_pm_state_change(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE state)
{
APPL_TRACE_API("bta_jv_pm_state_change(p_cb: 0x%x, handle: 0x%x, busy/idle_state: %d"
", app_id: %d, conn_state: %d)", (uint32_t)p_cb, p_cb->handle, p_cb->state,
APPL_TRACE_API("bta_jv_pm_state_change(p_cb: %p, handle: 0x%x, busy/idle_state: %d"
", app_id: %d, conn_state: %d)", p_cb, p_cb->handle, p_cb->state,
p_cb->app_id, state);
switch (state) {
@@ -2826,7 +2848,6 @@ static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected
//found: create a normal connection socket and assign the connection to it
new_conn = fcclient_alloc(chan, FALSE, &t->sec_id);
if (new_conn) {
memcpy(&new_conn->remote_addr, bd_addr, sizeof(new_conn->remote_addr));
new_conn->p_cback = NULL; //for now
new_conn->init_called = TRUE; /*nop need to do it again */
@@ -2835,6 +2856,8 @@ static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected
user_data = t->user_data;
t = new_conn;
} else {
t = NULL;
}
} else {
//drop it
@@ -2844,9 +2867,7 @@ static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected
}
if (t) {
if (!t->init_called) {
call_init = TRUE;
t->init_called = TRUE;
@@ -2912,6 +2933,10 @@ static void fcchan_data_cbk(UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf)
if (sock_cback) {
sock_cback(BTA_JV_L2CAP_DATA_IND_EVT, &evt_data, sock_user_data);
} else {
if (p_buf) {
osi_free(p_buf);
}
}
}
@@ -3025,7 +3050,7 @@ void bta_jv_l2cap_stop_server_le(tBTA_JV_MSG *p_data)
void bta_jv_l2cap_start_server_le(tBTA_JV_MSG *p_data)
{
tBTA_JV_API_L2CAP_SERVER *ss = &(p_data->l2cap_server);
tBTA_JV_L2CAP_START evt_data;
tBTA_JV_L2CAP_START evt_data = {0};
struct fc_client *t;
// uint16_t handle;
@@ -92,15 +92,23 @@ tBTA_JV_STATUS BTA_JvEnable(tBTA_JV_DM_CBACK *p_cback)
bta_jv_cb.pm_cb[i].handle = BTA_JV_PM_HANDLE_CLEAR;
}
/* register with BTA system manager */
bta_sys_register(BTA_ID_JV, &bta_jv_reg);
if (p_cback && (p_buf = (tBTA_JV_API_ENABLE *) osi_malloc(sizeof(tBTA_JV_API_ENABLE))) != NULL) {
if ((p_buf = (tBTA_JV_API_ENABLE *) osi_malloc(sizeof(tBTA_JV_API_ENABLE))) != NULL) {
/* register with BTA system manager */
bta_sys_register(BTA_ID_JV, &bta_jv_reg);
p_buf->hdr.event = BTA_JV_API_ENABLE_EVT;
p_buf->p_cback = p_cback;
bta_sys_sendmsg(p_buf);
status = BTA_JV_SUCCESS;
}
#if BTA_DYNAMIC_MEMORY == TRUE
else
{
osi_free(p_bta_jv_cfg->p_sdp_raw_data);
p_bta_jv_cfg->p_sdp_raw_data = NULL;
osi_free( p_bta_jv_cfg->p_sdp_db);
p_bta_jv_cfg->p_sdp_db = NULL;
}
#endif
} else if (p_cback == NULL) {
APPL_TRACE_ERROR("No p_cback.");
} else {
@@ -124,8 +132,8 @@ void BTA_JvDisable(tBTA_JV_RFCOMM_CBACK *p_cback)
tBTA_JV_API_DISABLE *p_buf;
APPL_TRACE_API( "BTA_JvDisable");
bta_sys_deregister(BTA_ID_JV);
if ((p_buf = (tBTA_JV_API_DISABLE *) osi_malloc(sizeof(tBTA_JV_API_DISABLE))) != NULL) {
bta_sys_deregister(BTA_ID_JV);
p_buf->hdr.event = BTA_JV_API_DISABLE_EVT;
p_buf->p_cback = p_cback;
bta_sys_sendmsg(p_buf);
@@ -183,8 +191,8 @@ BOOLEAN BTA_JvIsEncrypted(BD_ADDR bd_addr)
if (BTM_GetSecurityFlags(bd_addr, &sec_flags) &&
BTM_GetSecurityFlagsByTransport(bd_addr, &le_flags, BT_TRANSPORT_LE)) {
if (sec_flags & BTM_SEC_FLAG_ENCRYPTED ||
le_flags & BTM_SEC_FLAG_ENCRYPTED) {
if ((sec_flags & BTM_SEC_FLAG_ENCRYPTED) ||
(le_flags & BTM_SEC_FLAG_ENCRYPTED)) {
is_encrypted = TRUE;
}
}
@@ -285,7 +293,7 @@ tBTA_JV_STATUS BTA_JvStartDiscovery(BD_ADDR bd_addr, UINT16 num_uuid,
tBTA_JV_API_START_DISCOVERY *p_msg;
APPL_TRACE_API( "BTA_JvStartDiscovery");
if ((num_uuid > BTA_JV_MAX_UUIDS) || ((num_uuid > 0) && (p_uuid_list == NULL))) {
if ((num_uuid == 0) || (num_uuid > BTA_JV_MAX_UUIDS) || (p_uuid_list == NULL)) {
APPL_TRACE_ERROR("invalid uuid list: num_uuid=%u", num_uuid);
return BTA_JV_FAILURE;
}
@@ -747,7 +755,7 @@ tBTA_JV_STATUS BTA_JvL2capReceive(UINT32 handle, UINT32 req_id, UINT8 *p_data, U
tBTA_JV_STATUS status = BTA_JV_FAILURE;
tBTA_JV_L2CAP_RECEIVE evt_data;
UINT32 left_over = 0;
UINT16 max_len, read_len;
UINT16 max_len, read_len = 0;
APPL_TRACE_API( "%s", __func__);
@@ -765,7 +773,9 @@ tBTA_JV_STATUS BTA_JvL2capReceive(UINT32 handle, UINT32 req_id, UINT8 *p_data, U
GAP_GetRxQueueCnt ((UINT16)handle, &left_over);
while (left_over) {
max_len = (left_over > 0xFFFF) ? 0xFFFF : left_over;
GAP_ConnReadData ((UINT16)handle, NULL, max_len, &read_len);
if (BT_PASS != GAP_ConnReadData ((UINT16)handle, NULL, max_len, &read_len)) {
break;
}
left_over -= read_len;
}
}
@@ -860,8 +870,11 @@ tBTA_JV_STATUS BTA_JvL2capWriteFixed(UINT16 channel, BD_ADDR *addr, UINT32 req_i
APPL_TRACE_API( "%s", __func__);
if ((p_msg =
(tBTA_JV_API_L2CAP_WRITE_FIXED *)osi_malloc(sizeof(tBTA_JV_API_L2CAP_WRITE_FIXED))) != NULL) {
if (addr == NULL) {
return BTA_JV_FAILURE;
}
if ((p_msg = (tBTA_JV_API_L2CAP_WRITE_FIXED *)osi_malloc(sizeof(tBTA_JV_API_L2CAP_WRITE_FIXED))) != NULL) {
p_msg->hdr.event = BTA_JV_API_L2CAP_WRITE_FIXED_EVT;
p_msg->channel = channel;
memcpy(p_msg->addr, addr, sizeof(p_msg->addr));
@@ -90,7 +90,8 @@ const tBTA_JV_ACTION bta_jv_action[] = {
** Description State machine event handling function for JV
**
**
** Returns void
** Returns TRUE if the caller needs to free the buffer
FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_jv_sm_execute(BT_HDR *p_msg)
@@ -99,16 +100,14 @@ BOOLEAN bta_jv_sm_execute(BT_HDR *p_msg)
return FALSE;
}
BOOLEAN ret = FALSE;
UINT16 action = (p_msg->event & 0x00ff);
/* execute action functions */
if (action < BTA_JV_NUM_ACTIONS) {
(*bta_jv_action[action])((tBTA_JV_MSG *)p_msg);
ret = TRUE;
}
return (ret);
return TRUE;
}
#endif ///defined BTA_JV_INCLUDED && BTA_JV_INCLUDED == TRUE
@@ -297,7 +297,7 @@ void uuid128_be_to_esp_uuid(esp_bt_uuid_t *u, uint8_t* uuid128)
return;
}
void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str)
void uuid_to_string_legacy(const bt_uuid_t *p_uuid, char *str)
{
uint32_t uuid0, uuid4;
uint16_t uuid1, uuid2, uuid3, uuid5;
@@ -54,7 +54,7 @@ UINT32 devclass2uint(DEV_CLASS dev_class);
void uint2devclass(UINT32 dev, DEV_CLASS dev_class);
void uuid128_be_to_esp_uuid(esp_bt_uuid_t *u, uint8_t* uuid128);
void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str);
void uuid_to_string_legacy(const bt_uuid_t *p_uuid, char *str);
esp_bt_status_t btc_hci_to_esp_status(uint8_t hci_status);
esp_bt_status_t btc_btm_status_to_esp_status(uint8_t btm_status);
@@ -58,9 +58,6 @@ static void btc_bt_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_discove
tBTA_DM_DISC disc_mode;
tBTA_DM_CONN conn_mode;
gap_bt_local_param.conn_mode = c_mode;
gap_bt_local_param.disc_mode = d_mode;
switch (c_mode) {
case ESP_BT_NON_CONNECTABLE:
conn_mode = BTA_DM_NON_CONN;
@@ -88,12 +85,15 @@ static void btc_bt_set_scan_mode(esp_bt_connection_mode_t c_mode, esp_bt_discove
return;
}
gap_bt_local_param.conn_mode = c_mode;
gap_bt_local_param.disc_mode = d_mode;
BTA_DmSetVisibility(disc_mode, conn_mode, BTA_DM_IGNORE, BTA_DM_IGNORE);
}
static void btc_gap_bt_start_discovery(btc_gap_bt_args_t *arg)
{
tBTA_DM_INQ inq_params;
tBTA_DM_INQ inq_params = {0};
tBTA_SERVICE_MASK services = 0;
BTIF_TRACE_EVENT("%s", __func__);
@@ -118,9 +118,9 @@ static void btc_gap_bt_cancel_discovery(void)
BTA_DmSearchCancel();
}
static void btc_gap_bt_get_remote_services(bt_bdaddr_t *remote_bda)
static void btc_gap_bt_get_remote_services(btc_gap_bt_args_t *arg)
{
BTA_DmDiscover(remote_bda->address, BTA_ALL_SERVICE_MASK,
BTA_DmDiscover(arg->bda.address, BTA_ALL_SERVICE_MASK,
bte_dm_search_services_evt, TRUE);
}
@@ -129,8 +129,7 @@ static void btc_gap_bt_get_remote_service_record(btc_gap_bt_args_t *arg)
esp_bt_uuid_t *uuid = &arg->get_rmt_srv_rcd.uuid;
bt_bdaddr_t *remote_bda = &arg->get_rmt_srv_rcd.bda;
tSDP_UUID sdp_uuid;
tSDP_UUID sdp_uuid = {0};
sdp_uuid.len = uuid->len;
memcpy(&sdp_uuid.uu, &uuid->uuid, uuid->len);
@@ -150,16 +149,25 @@ static void btc_gap_bt_get_remote_service_record(btc_gap_bt_args_t *arg)
*******************************************************************************/
static void search_devices_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
{
tBTA_DM_SEARCH_PARAM *p_dest_data = (tBTA_DM_SEARCH_PARAM *) p_dest;
tBTA_DM_SEARCH_PARAM *p_src_data = (tBTA_DM_SEARCH_PARAM *) p_src;
tBTA_DM_SEARCH_PARAM *p_dest_data = (tBTA_DM_SEARCH_PARAM *) p_dest;
tBTA_DM_SEARCH_PARAM *p_src_data = (tBTA_DM_SEARCH_PARAM *) p_src;
if (!p_src) {
return;
}
if (!p_src_data || (p_dest_data->len < sizeof(tBTA_DM_SEARCH))) {
p_dest_data->p_data = NULL;
return;
}
p_dest_data->p_data = (void *)osi_malloc(p_dest_data->len);
if (!p_dest_data->p_data) {
BTC_TRACE_ERROR("%s: osi_malloc failed", __func__);
p_dest_data->len = 0;
return;
}
memset(p_dest_data->p_data, 0x00, p_dest_data->len);
memcpy(p_dest_data->p_data, p_src_data->p_data, p_dest_data->len);
memcpy(p_dest_data->p_data, p_src_data->p_data, sizeof(tBTA_DM_SEARCH));
if ( p_dest_data->len > sizeof(tBTA_DM_SEARCH)){
if (p_dest_data->len > sizeof(tBTA_DM_SEARCH)){
switch (p_dest_data->event) {
case BTA_DM_INQ_RES_EVT: {
if (p_src_data->p_data->inq_res.p_eir) {
@@ -199,9 +207,21 @@ static void search_service_record_copy_cb(btc_msg_t *msg, void *p_dest, void *p_
if (!p_src) {
return;
}
if (!p_src_data->p_data || (p_dest_data->len < sizeof(tBTA_DM_SEARCH))) {
p_dest_data->p_data = NULL;
p_dest_data->len = 0;
return;
}
p_dest_data->p_data = osi_malloc(p_dest_data->len);
if (!p_dest_data->p_data) {
p_dest_data->len = 0;
BTC_TRACE_ERROR("%s: osi_malloc failed", __func__);
return;
}
memset(p_dest_data->p_data, 0x00, p_dest_data->len);
memcpy(p_dest_data->p_data, p_src_data->p_data, p_dest_data->len);
memcpy(p_dest_data->p_data, p_src_data->p_data, sizeof(tBTA_DM_SEARCH));
if ( p_dest_data->len > sizeof(tBTA_DM_SEARCH)){
switch (p_dest_data->event) {
case BTA_DM_DISC_RES_EVT: {
@@ -250,13 +270,14 @@ static BOOLEAN check_eir_remote_name(tBTA_DM_SEARCH *p_search_data,
remote_name_len = BD_NAME_LEN;
}
if (p_remote_name && p_remote_name_len) {
memcpy(p_remote_name, p_eir_remote_name, remote_name_len);
*(p_remote_name + remote_name_len) = 0;
*p_remote_name_len = remote_name_len;
if (remote_name_len > 0) {
if (p_remote_name && p_remote_name_len) {
memcpy(p_remote_name, p_eir_remote_name, remote_name_len);
*(p_remote_name + remote_name_len) = 0;
*p_remote_name_len = remote_name_len;
}
return TRUE;
}
return TRUE;
}
}
@@ -308,7 +329,7 @@ static void bte_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_d
search.len = param_len;
do {
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_SEARCH_DEVICES_EVT;
@@ -321,60 +342,66 @@ static void btc_gap_bt_search_devices_evt(tBTA_DM_SEARCH_PARAM *p_data)
{
switch (p_data->event) {
case BTA_DM_DISC_RES_EVT: {
/* remote name update */
uint32_t bdname_len = strlen((const char *)p_data->p_data->disc_res.bd_name);
if (bdname_len) {
esp_bt_gap_dev_prop_t prop[1];
tBTA_DM_SEARCH *p_search_data = p_data->p_data;
if (p_search_data) {
/* remote name update */
uint32_t bdname_len = strlen((const char *)p_search_data->disc_res.bd_name);
if (bdname_len) {
esp_bt_gap_dev_prop_t prop[1];
BTC_STORAGE_FILL_PROPERTY(&prop[0], ESP_BT_GAP_DEV_PROP_BDNAME, bdname_len + 1, p_data->p_data->disc_res.bd_name);
BTC_STORAGE_FILL_PROPERTY(&prop[0], ESP_BT_GAP_DEV_PROP_BDNAME, bdname_len + 1, p_search_data->disc_res.bd_name);
esp_bt_gap_cb_param_t param;
bdcpy(param.disc_res.bda, p_data->p_data->disc_res.bd_addr);
param.disc_res.num_prop = 1;
param.disc_res.prop = prop;
btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_RES_EVT, &param);
esp_bt_gap_cb_param_t param = {0};
bdcpy(param.disc_res.bda, p_search_data->disc_res.bd_addr);
param.disc_res.num_prop = 1;
param.disc_res.prop = prop;
btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_RES_EVT, &param);
}
}
break;
}
case BTA_DM_INQ_RES_EVT: {
/* inquiry result */
uint32_t cod = devclass2uint (p_data->p_data->inq_res.dev_class);
tBTA_DM_SEARCH *p_search_data = p_data->p_data;
if (p_search_data) {
/* inquiry result */
uint32_t cod = devclass2uint (p_search_data->inq_res.dev_class);
if (cod == 0) {
BTC_TRACE_DEBUG("%s cod is 0, set as unclassified", __func__);
cod = COD_UNCLASSIFIED;
}
do {
esp_bt_gap_dev_prop_t prop[3];
int num_prop = 0;
memset(prop, 0, sizeof(prop));
BTC_STORAGE_FILL_PROPERTY(&prop[0], ESP_BT_GAP_DEV_PROP_COD, sizeof(cod), &cod);
num_prop++;
BTC_STORAGE_FILL_PROPERTY(&prop[1], ESP_BT_GAP_DEV_PROP_RSSI, 1, &(p_data->p_data->inq_res.rssi));
num_prop++;
if (p_data->p_data->inq_res.p_eir) {
BTC_STORAGE_FILL_PROPERTY(&prop[2], ESP_BT_GAP_DEV_PROP_EIR, HCI_EXT_INQ_RESPONSE_LEN, p_data->p_data->inq_res.p_eir);
num_prop++;
if (cod == 0) {
BTC_TRACE_DEBUG("%s cod is 0, set as unclassified", __func__);
cod = COD_UNCLASSIFIED;
}
/* Callback to notify upper layer of device */
esp_bt_gap_cb_param_t param;
bdcpy(param.disc_res.bda, p_data->p_data->inq_res.bd_addr);
param.disc_res.num_prop = num_prop;
param.disc_res.prop = prop;
btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_RES_EVT, &param);
} while (0);
do {
esp_bt_gap_dev_prop_t prop[3];
int num_prop = 0;
memset(prop, 0, sizeof(prop));
BTC_STORAGE_FILL_PROPERTY(&prop[0], ESP_BT_GAP_DEV_PROP_COD, sizeof(cod), &cod);
num_prop++;
BTC_STORAGE_FILL_PROPERTY(&prop[1], ESP_BT_GAP_DEV_PROP_RSSI, 1, &(p_search_data->inq_res.rssi));
num_prop++;
if (p_search_data->inq_res.p_eir) {
BTC_STORAGE_FILL_PROPERTY(&prop[2], ESP_BT_GAP_DEV_PROP_EIR, HCI_EXT_INQ_RESPONSE_LEN, p_search_data->inq_res.p_eir);
num_prop++;
}
/* Callback to notify upper layer of device */
esp_bt_gap_cb_param_t param = {0};
bdcpy(param.disc_res.bda, p_search_data->inq_res.bd_addr);
param.disc_res.num_prop = num_prop;
param.disc_res.prop = prop;
btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_RES_EVT, &param);
} while (0);
}
}
break;
case BTA_DM_INQ_CMPL_EVT:
break;
case BTA_DM_DISC_CMPL_EVT: {
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STOPPED;
btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_STATE_CHANGED_EVT, &param);
break;
@@ -388,7 +415,7 @@ static void btc_gap_bt_search_devices_evt(tBTA_DM_SEARCH_PARAM *p_data)
* but instead wait for the cancel_cmpl_evt_via the busy level
*/
if (gap_bt_local_param.disc_stat == ESP_BT_GAP_DISCOVERY_STOPPED) {
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STOPPED;
btc_gap_bt_cb_to_app(ESP_BT_GAP_DISC_STATE_CHANGED_EVT, &param);
}
@@ -411,8 +438,8 @@ static void btc_gap_bt_search_service_record(char *p_param)
switch (p_data->event) {
case BTA_DM_DISC_RES_EVT: {
esp_bt_gap_cb_param_t param;
memcpy(param.rmt_srvcs.bda, p_data->p_data->disc_res.bd_addr, BD_ADDR_LEN);
esp_bt_gap_cb_param_t param = {0};
memcpy(param.rmt_srvc_rec.bda, p_data->p_data->disc_res.bd_addr, BD_ADDR_LEN);
if (p_data->p_data->disc_res.p_raw_data && p_data->p_data->disc_res.raw_data_size > 0) {
param.rmt_srvc_rec.stat = ESP_BT_STATUS_SUCCESS;
// param.rmt_srvc_rec.raw_data_size = p_data->p_data->disc_res.raw_data_size;
@@ -460,7 +487,7 @@ static void bte_dm_remote_service_record_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_S
}
search.len = param_len;
do {
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT;
@@ -484,30 +511,35 @@ static void btc_gap_bt_search_services(char *p_param)
switch (p_data->event) {
case BTA_DM_DISC_RES_EVT: {
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
esp_bt_uuid_t *uuid_list = NULL;
memcpy(param.rmt_srvcs.bda, p_data->p_data->disc_res.bd_addr, BD_ADDR_LEN);
param.rmt_srvcs.stat = ESP_BT_STATUS_FAIL;
if (p_data->p_data->disc_res.result == BTA_SUCCESS) {
uuid_list = osi_malloc(sizeof(esp_bt_uuid_t) * p_data->p_data->disc_res.num_uuids);
if (uuid_list) {
param.rmt_srvcs.stat = ESP_BT_STATUS_SUCCESS;
param.rmt_srvcs.num_uuids = p_data->p_data->disc_res.num_uuids;
param.rmt_srvcs.uuid_list = uuid_list;
// copy UUID list
uint8_t *i_uu = (uint8_t *)p_data->p_data->disc_res.p_uuid_list;
esp_bt_uuid_t *o_uu = uuid_list;
for (int i = 0; i < p_data->p_data->disc_res.num_uuids; i++, i_uu += ESP_UUID_LEN_128, o_uu++) {
uuid128_be_to_esp_uuid(o_uu, i_uu);
param.rmt_srvcs.num_uuids = 0;
param.rmt_srvcs.uuid_list = NULL;
if (p_data->p_data) {
memcpy(param.rmt_srvcs.bda, p_data->p_data->disc_res.bd_addr, BD_ADDR_LEN);
if (p_data->p_data->disc_res.result == BTA_SUCCESS) {
if (p_data->p_data->disc_res.num_uuids > 0) {
uuid_list = osi_malloc(sizeof(esp_bt_uuid_t) * p_data->p_data->disc_res.num_uuids);
if (uuid_list) {
param.rmt_srvcs.stat = ESP_BT_STATUS_SUCCESS;
param.rmt_srvcs.num_uuids = p_data->p_data->disc_res.num_uuids;
param.rmt_srvcs.uuid_list = uuid_list;
// copy UUID list
uint8_t *i_uu = (uint8_t *)p_data->p_data->disc_res.p_uuid_list;
esp_bt_uuid_t *o_uu = uuid_list;
for (int i = 0; i < p_data->p_data->disc_res.num_uuids; i++, i_uu += ESP_UUID_LEN_128, o_uu++) {
uuid128_be_to_esp_uuid(o_uu, i_uu);
}
}
} else {
param.rmt_srvcs.stat = ESP_BT_STATUS_SUCCESS;
}
}
}
if (param.rmt_srvcs.stat == ESP_BT_STATUS_FAIL) {
param.rmt_srvcs.num_uuids = 0;
param.rmt_srvcs.uuid_list = NULL;
}
btc_gap_bt_cb_to_app(ESP_BT_GAP_RMT_SRVCS_EVT, &param);
if (uuid_list) {
@@ -553,7 +585,7 @@ static void bte_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH
}
search.len = param_len;
do {
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_SEARCH_SERVICES_EVT;
@@ -569,18 +601,28 @@ static void search_services_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
if (!p_src) {
return;
}
p_dest_data->p_data = osi_malloc(p_dest_data->len);
memset(p_dest_data->p_data, 0x00, p_dest_data->len);
memcpy(p_dest_data->p_data, p_src_data->p_data, p_dest_data->len);
if (!p_src_data->p_data || (p_dest_data->len < sizeof(tBTA_DM_SEARCH))) {
return;
}
if ( p_dest_data->len > sizeof(tBTA_DM_SEARCH)){
p_dest_data->p_data = osi_malloc(p_dest_data->len);
if (p_dest_data->p_data) {
memset(p_dest_data->p_data, 0x00, p_dest_data->len);
memcpy(p_dest_data->p_data, p_src_data->p_data, sizeof(tBTA_DM_SEARCH));
} else {
BTC_TRACE_ERROR("%s: osi_malloc failed", __func__);
}
if (p_dest_data->len > sizeof(tBTA_DM_SEARCH)){
switch (p_dest_data->event) {
case BTA_DM_DISC_RES_EVT: {
if (p_src_data->p_data->disc_res.result == BTA_SUCCESS) {
if (p_src_data->p_data->disc_res.num_uuids > 0) {
p_dest_data->p_data->disc_res.p_uuid_list = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->disc_res.p_uuid_list, p_src_data->p_data->disc_res.p_uuid_list,
p_src_data->p_data->disc_res.num_uuids * MAX_UUID_SIZE);
if (p_dest_data->p_data) {
p_dest_data->p_data->disc_res.p_uuid_list = (UINT8 *)(p_dest_data->p_data) + sizeof(tBTA_DM_SEARCH);
memcpy(p_dest_data->p_data->disc_res.p_uuid_list, p_src_data->p_data->disc_res.p_uuid_list,
p_src_data->p_data->disc_res.num_uuids * MAX_UUID_SIZE);
}
osi_free(p_src_data->p_data->disc_res.p_uuid_list);
p_src_data->p_data->disc_res.p_uuid_list = NULL;
}
@@ -596,7 +638,7 @@ static void search_services_copy_cb(btc_msg_t *msg, void *p_dest, void *p_src)
static void btc_gap_bt_set_cod(btc_gap_bt_args_t *arg)
{
tBTA_UTL_COD p_cod;
tBTA_UTL_COD p_cod = {0};
esp_bt_cod_t *cod = &(arg->set_cod.cod);
p_cod.reserved_2 = cod->reserved_2;
p_cod.minor = cod->minor << 2;
@@ -610,25 +652,25 @@ static void btc_gap_bt_set_cod(btc_gap_bt_args_t *arg)
esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod)
{
tBTA_UTL_COD p_cod;
tBTA_UTL_COD p_cod = {0};
bool ret = utl_get_device_class(&p_cod);
if (!ret){
BTC_TRACE_ERROR("%s get class of device failed!",__func__);
return ESP_BT_STATUS_FAIL;
return ESP_FAIL;
}
cod->reserved_2 = p_cod.reserved_2;
cod->minor = p_cod.minor >> 2;
cod->major = p_cod.major;
cod->service = p_cod.service >> 5;
return ESP_BT_STATUS_SUCCESS;
return ESP_OK;
}
static void btc_gap_bt_read_rssi_delta_cmpl_callback(void *p_data)
{
tBTA_RSSI_RESULTS *result = (tBTA_RSSI_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_READ_RSSI_DELTA_EVT;
@@ -653,9 +695,9 @@ static void btc_gap_bt_read_rssi_delta(btc_gap_bt_args_t *arg)
static void btc_gap_bt_read_acl_real_rssi_cmpl_callback(void *p_data)
{
tBTM_ACL_REAL_RSSI_RESULTS *result = (tBTM_ACL_REAL_RSSI_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_READ_ACL_REAL_RSSI_EVT;
@@ -679,9 +721,9 @@ static void btc_gap_bt_read_acl_real_rssi(btc_gap_bt_args_t *arg)
static void btc_gap_bt_read_new_conn_tx_pwr_lvl_cmpl_callback(void *p_data)
{
tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS *result = (tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
@@ -701,9 +743,9 @@ static void btc_gap_bt_read_new_conn_tx_pwr_lvl_cmpl_callback(void *p_data)
static void btc_gap_bt_write_new_conn_tx_pwr_lvl_cmpl_callback(void *p_data)
{
tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS *result = (tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
@@ -734,9 +776,9 @@ static void btc_gap_bt_write_new_conn_tx_pwr_lvl(btc_gap_bt_args_t *arg)
static void btc_gap_bt_read_tx_pwr_lvl_cmpl_callback(void *p_data)
{
tBTM_READ_TX_PWR_LVL_RESULTS *result = (tBTM_READ_TX_PWR_LVL_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
@@ -756,9 +798,9 @@ static void btc_gap_bt_read_tx_pwr_lvl_cmpl_callback(void *p_data)
static void btc_gap_bt_write_tx_pwr_lvl_cmpl_callback(void *p_data)
{
tBTM_WRITE_TX_PWR_LVL_RESULTS *result = (tBTM_WRITE_TX_PWR_LVL_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
@@ -791,9 +833,9 @@ static esp_err_t btc_gap_bt_remove_bond_device(btc_gap_bt_args_t *arg)
BD_ADDR bd_addr;
memcpy(bd_addr, arg->rm_bond_device.bda.address, sizeof(BD_ADDR));
if(BTA_DmRemoveDevice(bd_addr, BT_TRANSPORT_BR_EDR) == BTA_SUCCESS){
return ESP_BT_STATUS_SUCCESS;
return ESP_OK;
}
return ESP_BT_STATUS_FAIL;
return ESP_FAIL;
}
static void btc_gap_bt_set_pin_type(btc_gap_bt_args_t *arg){
@@ -816,7 +858,7 @@ static esp_err_t btc_gap_bt_set_security_param(btc_gap_bt_args_t *arg)
break;
}
default:
ret = ESP_BT_STATUS_FAIL;
ret = ESP_FAIL;
break;
}
return ret;
@@ -834,7 +876,7 @@ static void btc_gap_bt_ssp_confirm(btc_gap_bt_args_t *arg)
static void btc_gap_bt_config_eir(btc_gap_bt_args_t *arg)
{
tBTA_DM_EIR_CONF eir_config;
tBTA_DM_EIR_CONF eir_config = {0};
esp_bt_eir_data_t *eir_data = &arg->config_eir.eir_data;
eir_config.bta_dm_eir_fec_required = eir_data->fec_required;
@@ -853,9 +895,9 @@ static void btc_gap_bt_config_eir(btc_gap_bt_args_t *arg)
static void btc_gap_bt_set_afh_channels_cmpl_callback(void *p_data)
{
tBTA_SET_AFH_CHANNELS_RESULTS *result = (tBTA_SET_AFH_CHANNELS_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_SET_AFH_CHANNELS_EVT;
@@ -878,9 +920,9 @@ static void btc_gap_bt_set_afh_channels(btc_gap_bt_args_t *arg)
static void btc_gap_bt_set_page_timeout_cmpl_callback(void *p_data)
{
tBTA_SET_PAGE_TIMEOUT_RESULTS *result = (tBTA_SET_PAGE_TIMEOUT_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_SET_PAGE_TO_EVT;
@@ -901,9 +943,9 @@ static void btc_gap_set_page_timeout(btc_gap_bt_args_t *arg)
static void btc_gap_bt_get_page_timeout_cmpl_callback(void *p_data)
{
tBTA_GET_PAGE_TIMEOUT_RESULTS *result = (tBTA_GET_PAGE_TIMEOUT_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_GET_PAGE_TO_EVT;
@@ -925,9 +967,9 @@ static void btc_gap_get_page_timeout(void)
static void btc_gap_bt_set_acl_pkt_types_cmpl_callback(void *p_data)
{
tBTA_SET_ACL_PKT_TYPES_RESULTS *result = (tBTA_SET_ACL_PKT_TYPES_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_SET_ACL_PKT_TYPES_EVT;
@@ -953,9 +995,9 @@ static void btc_gap_set_acl_pkt_types(btc_gap_bt_args_t *arg)
static void btc_gap_bt_set_min_enc_key_size_cmpl_callback(void *p_data)
{
tBTA_SET_MIN_ENC_KEY_SIZE_RESULTS *result = (tBTA_SET_MIN_ENC_KEY_SIZE_RESULTS *)p_data;
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_SET_MIN_ENC_KEY_SIZE_EVT;
@@ -977,8 +1019,8 @@ static void btc_gap_set_min_enc_key_size(btc_gap_bt_args_t *arg)
static void btc_gap_bt_read_remote_name_cmpl_callback(void *p_data)
{
tBTA_REMOTE_DEV_NAME *result = (tBTA_REMOTE_DEV_NAME *)p_data;
esp_bt_gap_cb_param_t param;
btc_msg_t msg;
esp_bt_gap_cb_param_t param = {0};
btc_msg_t msg = {0};
bt_status_t ret;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
@@ -986,7 +1028,8 @@ static void btc_gap_bt_read_remote_name_cmpl_callback(void *p_data)
memcpy(param.read_rmt_name.bda,result->bd_addr,BD_ADDR_LEN);
param.read_rmt_name.stat = btc_btm_status_to_esp_status(result->status);
memcpy(param.read_rmt_name.rmt_name,result->remote_bd_name,ESP_BT_GAP_MAX_BDNAME_LEN);
memcpy(param.read_rmt_name.rmt_name, result->remote_bd_name, ESP_BT_GAP_MAX_BDNAME_LEN);
param.read_rmt_name.rmt_name[ESP_BT_GAP_MAX_BDNAME_LEN] = '\0';
ret = btc_transfer_context(&msg, &param, sizeof(esp_bt_gap_cb_param_t), NULL, NULL);
if (ret != BT_STATUS_SUCCESS) {
@@ -1003,8 +1046,8 @@ static void btc_gap_bt_read_remote_name(btc_gap_bt_args_t *arg)
static void btc_gap_bt_set_qos_cmpl_callback(void *p_data)
{
tBTM_QOS_SETUP_CMPL *result = (tBTM_QOS_SETUP_CMPL *)p_data;
esp_bt_gap_cb_param_t param;
btc_msg_t msg;
esp_bt_gap_cb_param_t param = {0};
btc_msg_t msg = {0};
bt_status_t ret;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BT;
@@ -1032,7 +1075,7 @@ static void btc_gap_bt_set_qos(btc_gap_bt_args_t *arg)
static void btc_gap_bt_get_dev_name_callback(UINT8 status, char *name)
{
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg = {0};
@@ -1231,7 +1274,7 @@ void btc_gap_bt_call_handler(btc_msg_t *msg)
break;
}
case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES: {
btc_gap_bt_get_remote_services((bt_bdaddr_t *)msg->arg);
btc_gap_bt_get_remote_services(arg);
break;
}
case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD: {
@@ -1343,7 +1386,7 @@ void btc_gap_bt_call_handler(btc_msg_t *msg)
void btc_gap_bt_busy_level_updated(uint8_t bl_flags)
{
esp_bt_gap_cb_param_t param;
esp_bt_gap_cb_param_t param = {0};
if (bl_flags == BTM_BL_INQUIRY_STARTED) {
param.disc_st_chg.state = ESP_BT_GAP_DISCOVERY_STARTED;
@@ -1534,6 +1577,7 @@ void btc_gap_bt_init(void)
#if BTC_GAP_BT_DYNAMIC_MEMORY == TRUE
if ((gap_bt_local_param_ptr = (gap_bt_local_param_t *)osi_malloc(sizeof(gap_bt_local_param_t))) == NULL) {
BTC_TRACE_ERROR("%s malloc failed\n", __func__);
assert(0);
return;
}
memset((void *)gap_bt_local_param_ptr, 0, sizeof(gap_bt_local_param_t));
@@ -1594,6 +1638,12 @@ void btc_gap_bt_acl_link_num_update(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat)
void btc_gap_bt_status_get(esp_bt_gap_profile_status_t *param)
{
#if BTC_GAP_BT_DYNAMIC_MEMORY == TRUE
if (!gap_bt_local_param_ptr) {
BTC_TRACE_ERROR("%s: gap_bt_local_param_ptr is NULL\n", __func__);
return;
}
#endif
param->disc_stat = gap_bt_local_param.disc_stat;
param->conn_mode = gap_bt_local_param.conn_mode;
param->disc_mode = gap_bt_local_param.disc_mode;
@@ -233,7 +233,7 @@ static void btc_hd_init(void)
} while (0);
if (ret != ESP_HIDD_SUCCESS) {
esp_hidd_cb_param_t param;
esp_hidd_cb_param_t param = {0};
param.init.status = ret;
btc_hd_cb_to_app(ESP_HIDD_INIT_EVT, &param);
}
@@ -279,7 +279,7 @@ static void btc_hd_deinit(void)
} while (0);
if (ret != ESP_HIDD_SUCCESS) {
esp_hidd_cb_param_t param;
esp_hidd_cb_param_t param = {0};
param.deinit.status = ret;
btc_hd_cb_to_app(ESP_HIDD_DEINIT_EVT, &param);
}
@@ -365,7 +365,7 @@ static void btc_hd_register_app(esp_hidd_app_param_t *p_app_param, esp_hidd_qos_
} while(0);
if (ret != ESP_HIDD_SUCCESS) {
esp_hidd_cb_param_t param;
esp_hidd_cb_param_t param = {0};
param.register_app.status = ret;
param.register_app.in_use = false;
memset(param.register_app.bd_addr, 0, BD_ADDR_LEN);
@@ -487,7 +487,7 @@ static void btc_hh_init(void)
} while (0);
if (ret != ESP_HIDH_OK) {
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
param.init.status = ret;
btc_hh_cb_to_app(ESP_HIDH_INIT_EVT, &param);
}
@@ -513,6 +513,12 @@ static void btc_hh_deinit(void)
break;
}
if (btc_hh_cb.status == BTC_HH_DISABLING) {
BTC_TRACE_ERROR("%s HH is during deiniting!", __func__);
ret = ESP_HIDH_ERR;
break;
}
// close all connections
for (uint8_t i = 0; i < BTC_HH_MAX_HID; i++) {
if(btc_hh_cb.devices[i].dev_status == ESP_HIDH_CONN_STATE_CONNECTED){
@@ -525,7 +531,7 @@ static void btc_hh_deinit(void)
} while (0);
if (ret != ESP_HIDH_OK) {
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
param.deinit.status = ret;
btc_hh_cb_to_app(ESP_HIDH_DEINIT_EVT, &param);
}
@@ -546,7 +552,9 @@ static void btc_hh_connect(btc_hidh_args_t *arg)
esp_hidh_status_t ret = ESP_HIDH_OK;
btc_hh_added_device_t* added_dev = NULL;
btc_hh_device_t* dev = NULL;
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
param.open.handle = BTA_HH_INVALID_HANDLE;
do {
if (!is_hidh_init()) {
@@ -570,6 +578,7 @@ static void btc_hh_connect(btc_hidh_args_t *arg)
BTC_TRACE_WARNING("%s Device[%s] already connected", __func__,
bdaddr_to_string((const bt_bdaddr_t *)arg->connect.bd_addr, bdstr, sizeof(bdstr)));
param.open.conn_status = ESP_HIDH_CONN_STATE_CONNECTED;
param.open.handle = dev->dev_handle;
break;
}
@@ -606,7 +615,6 @@ static void btc_hh_connect(btc_hidh_args_t *arg)
param.open.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTED;
}
param.open.status = ret;
param.open.handle = BTA_HH_INVALID_HANDLE;
memcpy(param.open.bd_addr, arg->connect.bd_addr, BD_ADDR_LEN);
param.open.is_orig = true;
btc_hh_cb_to_app(ESP_HIDH_OPEN_EVT, &param);
@@ -626,7 +634,7 @@ static void btc_hh_disconnect(btc_hidh_args_t *arg)
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
btc_hh_device_t *p_dev;
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
do {
if (!is_hidh_init()) {
@@ -669,7 +677,7 @@ static void btc_hh_virtual_unplug(btc_hidh_args_t *arg)
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
btc_hh_device_t *p_dev;
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
do {
if (!is_hidh_init()) {
@@ -729,8 +737,8 @@ static void btc_hh_set_info(btc_hidh_args_t *arg)
{
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
esp_hidh_cb_param_t param;
tBTA_HH_DEV_DSCP_INFO dscp_info;
esp_hidh_cb_param_t param = {0};
tBTA_HH_DEV_DSCP_INFO dscp_info = {0};
if (!arg->set_info.hid_info) {
ret = ESP_HIDH_ERR;
@@ -756,20 +764,24 @@ static void btc_hh_set_info(btc_hidh_args_t *arg)
dscp_info.ctry_code = arg->set_info.hid_info->ctry_code;
dscp_info.descriptor.dl_len = arg->set_info.hid_info->dl_len;
dscp_info.descriptor.dsc_list = (uint8_t *)osi_malloc(dscp_info.descriptor.dl_len);
if (dscp_info.descriptor.dsc_list == NULL) {
BTC_TRACE_ERROR("%s malloc dsc_list failed!", __func__);
ret = ESP_HIDH_ERR_NO_RES;
break;
if (dscp_info.descriptor.dl_len > 0) {
dscp_info.descriptor.dsc_list = (uint8_t *)osi_malloc(dscp_info.descriptor.dl_len);
if (dscp_info.descriptor.dsc_list == NULL) {
BTC_TRACE_ERROR("%s malloc dsc_list failed!", __func__);
ret = ESP_HIDH_ERR_NO_RES;
break;
}
memcpy(dscp_info.descriptor.dsc_list, arg->set_info.hid_info->dsc_list, dscp_info.descriptor.dl_len);
} else {
dscp_info.descriptor.dsc_list = NULL;
}
memcpy(dscp_info.descriptor.dsc_list, arg->set_info.hid_info->dsc_list, dscp_info.descriptor.dl_len);
if (btc_hh_add_added_dev(arg->set_info.bd_addr, arg->set_info.hid_info->attr_mask)) {
btc_hh_cb.add_event = BTC_HH_SET_INFO_EVT;
BTA_HhAddDev(arg->set_info.bd_addr, arg->set_info.hid_info->attr_mask, arg->set_info.hid_info->sub_class,
arg->set_info.hid_info->app_id, dscp_info);
} else {
BTC_TRACE_ERROR("%s malloc dsc_list failed!", __func__);
BTC_TRACE_ERROR("%s add added device failed!", __func__);
ret = ESP_HIDH_ERR;
break;
}
@@ -798,7 +810,7 @@ static void btc_hh_get_protocol(btc_hidh_args_t *arg)
{
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
btc_hh_device_t *p_dev;
do {
@@ -837,7 +849,7 @@ static void btc_hh_set_protocol(btc_hidh_args_t *arg)
{
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
btc_hh_device_t *p_dev;
do {
@@ -880,7 +892,7 @@ static void btc_hh_get_report(btc_hidh_args_t *arg)
{
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
btc_hh_device_t *p_dev;
do {
@@ -954,8 +966,8 @@ static void btc_hh_set_report(btc_hidh_args_t *arg)
{
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
esp_hidh_cb_param_t param;
btc_hh_device_t *p_dev;
esp_hidh_cb_param_t param = {0};
btc_hh_device_t *p_dev = NULL;
do {
if (!is_hidh_init()) {
@@ -989,7 +1001,11 @@ static void btc_hh_set_report(btc_hidh_args_t *arg)
} while(0);
if (ret != ESP_HIDH_OK) {
param.set_rpt.handle = BTA_HH_INVALID_HANDLE;
if (p_dev == NULL) {
param.set_rpt.handle = BTA_HH_INVALID_HANDLE;
} else {
param.set_rpt.handle = p_dev->dev_handle;
}
param.set_rpt.status = ret;
btc_hh_cb_to_app(ESP_HIDH_SET_RPT_EVT, &param);
}
@@ -1008,7 +1024,7 @@ static void btc_hh_send_data(btc_hidh_args_t *arg)
{
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
btc_hh_device_t *p_dev;
do {
@@ -1059,7 +1075,7 @@ static void btc_hh_get_idle_time(btc_hidh_args_t *arg)
{
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
btc_hh_device_t *p_dev;
do {
@@ -1099,7 +1115,7 @@ static void btc_hh_set_idle_time(btc_hidh_args_t *arg)
{
BTC_TRACE_API("%s", __func__);
esp_hidh_status_t ret = ESP_HIDH_OK;
esp_hidh_cb_param_t param;
esp_hidh_cb_param_t param = {0};
btc_hh_device_t *p_dev;
do {
@@ -1233,9 +1249,16 @@ bool btc_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO *dest, tBTA_HH_DEV_DSCP_INFO *sr
bool btc_hh_cb_copy_hid_info(esp_hidh_cb_param_t *param, tBTA_HH_DEV_DSCP_INFO *src)
{
if ((src->descriptor.dl_len > 0) && (src->descriptor.dsc_list == NULL)) {
return false;
}
param->dscp.dl_len = 0;
if (src->descriptor.dl_len > 0) {
param->dscp.dsc_list = (uint8_t *)osi_malloc(src->descriptor.dl_len);
if (!param->dscp.dsc_list) {
return false;
}
}
if (param->dscp.dsc_list) {
memcpy(param->dscp.dsc_list, src->descriptor.dsc_list, src->descriptor.dl_len);
@@ -1357,7 +1380,7 @@ void btc_hh_cb_handler(btc_msg_t *msg)
}
if (btc_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) {
tBTA_HH_DEV_DSCP_INFO dscp_info;
tBTA_HH_DEV_DSCP_INFO dscp_info = {0};
bt_status_t ret;
btc_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
btc_hh_cb.add_event = BTC_HH_CONNECT_EVT;
@@ -1382,7 +1405,9 @@ void btc_hh_cb_handler(btc_msg_t *msg)
BTC_TRACE_WARNING("%s: Device already added ", __func__);
param.dscp.added = true;
}
btc_hh_cb_copy_hid_info(&param, &p_data->dscp_info);
if (!btc_hh_cb_copy_hid_info(&param, &p_data->dscp_info)) {
param.dscp.status = ESP_HIDH_ERR;
}
param.dscp.handle = p_dev->dev_handle;
} while(0);
btc_hh_cb_to_app(ESP_HIDH_GET_DSCP_EVT, &param);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -191,6 +191,7 @@ static l2cap_slot_t *l2cap_malloc_slot(void)
if (((*slot) = (l2cap_slot_t *)osi_malloc(sizeof(l2cap_slot_t))) == NULL) {
return NULL;
}
memset((*slot), 0, sizeof(l2cap_slot_t));
(*slot)->id = l2cap_local_param.l2cap_slot_id;
(*slot)->psm = 0;
(*slot)->serial = i;
@@ -250,7 +251,9 @@ static void l2cap_free_slot(l2cap_slot_t *slot)
}
l2cap_local_param.l2cap_slots[slot->serial] = NULL;
esp_vfs_unregister_fd(l2cap_local_param.l2cap_vfs_id, slot->fd);
xEventGroupSetBits(l2cap_local_param.tx_event_group, SLOT_CLOSE_BIT(slot->serial));
if (l2cap_local_param.tx_event_group) {
xEventGroupSetBits(l2cap_local_param.tx_event_group, SLOT_CLOSE_BIT(slot->serial));
}
free_slot_data(&slot->tx);
free_slot_data(&slot->rx);
if (slot->close_alarm) {
@@ -266,6 +269,8 @@ static void l2cap_free_slot(l2cap_slot_t *slot)
static void l2cap_free_pending_slots(void)
{
l2cap_slot_t *slot = NULL;
osi_mutex_lock(&l2cap_local_param.l2cap_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
for (size_t i = 1; i <= BTA_JV_MAX_L2C_CONN; i++) {
slot = l2cap_local_param.l2cap_slots[i];
if (slot) {
@@ -273,6 +278,62 @@ static void l2cap_free_pending_slots(void)
l2cap_free_slot(slot);
}
}
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
}
static int btc_l2cap_jv_param_len(tBTA_JV_EVT event)
{
int param_len = 0;
switch (event) {
case BTA_JV_ENABLE_EVT:
case BTA_JV_DISABLE_EVT:
param_len = sizeof(tBTA_JV_STATUS);
break;
case BTA_JV_GET_SCN_EVT:
param_len = sizeof(UINT8);
break;
case BTA_JV_GET_PSM_EVT:
param_len = sizeof(UINT16);
break;
case BTA_JV_CREATE_RECORD_EVT:
param_len = sizeof(tBTA_JV_CREATE_RECORD);
break;
#if BTA_JV_L2CAP_INCLUDED
case BTA_JV_L2CAP_OPEN_EVT:
param_len = sizeof(tBTA_JV_L2CAP_OPEN);
break;
case BTA_JV_L2CAP_CLOSE_EVT:
param_len = sizeof(tBTA_JV_L2CAP_CLOSE);
break;
case BTA_JV_L2CAP_START_EVT:
param_len = sizeof(tBTA_JV_L2CAP_START);
break;
case BTA_JV_L2CAP_CL_INIT_EVT:
param_len = sizeof(tBTA_JV_L2CAP_CL_INIT);
break;
case BTA_JV_L2CAP_DATA_IND_EVT:
param_len = sizeof(tBTA_JV_DATA_IND);
break;
case BTA_JV_L2CAP_CONG_EVT:
param_len = sizeof(tBTA_JV_L2CAP_CONG);
break;
case BTA_JV_L2CAP_READ_EVT:
param_len = sizeof(tBTA_JV_L2CAP_READ);
break;
case BTA_JV_L2CAP_WRITE_EVT:
param_len = sizeof(tBTA_JV_L2CAP_WRITE);
break;
#endif /* BTA_JV_L2CAP_INCLUDED */
case BTA_JV_FREE_SCN_EVT:
param_len = sizeof(tBTA_JV_FREE_SCN);
break;
default:
param_len = sizeof(tBTA_JV);
break;
}
return param_len;
}
static void close_timeout_handler(void *arg)
@@ -285,7 +346,7 @@ static void close_timeout_handler(void *arg)
msg.pid = BTC_PID_L2CAP;
msg.act = BTA_JV_L2CAP_CLOSE_EVT;
status = btc_transfer_context(&msg, slot->alarm_arg, sizeof(tBTA_JV), NULL, NULL);
status = btc_transfer_context(&msg, slot->alarm_arg, sizeof(tBTA_JV_L2CAP_CLOSE), NULL, NULL);
if (slot->alarm_arg) {
osi_free(slot->alarm_arg);
@@ -297,7 +358,7 @@ static void close_timeout_handler(void *arg)
}
}
static inline void btc_l2cap_cb_to_app(esp_bt_l2cap_cb_event_t event, esp_bt_l2cap_cb_param_t *param)
static inline void btc_l2cap_cb_to_app(esp_bt_l2cap_cb_event_t event, esp_bt_l2cap_cb_param_t *param)
{
esp_bt_l2cap_cb_t btc_l2cap_cb = (esp_bt_l2cap_cb_t)btc_profile_cb_get(BTC_PID_L2CAP);
if (btc_l2cap_cb) {
@@ -330,7 +391,7 @@ static void *btc_l2cap_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
slot = l2cap_find_slot_by_id(id);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find L2CAP slot, event:%d!", __func__, event);
p_data->l2c_open.status = ESP_BT_L2CAP_NO_CONNECTION;
p_data->l2c_start.status = ESP_BT_L2CAP_NO_CONNECTION;
break;
}
slot->handle = p_data->l2c_start.handle;
@@ -338,7 +399,7 @@ static void *btc_l2cap_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
case BTA_JV_L2CAP_CLOSE_EVT:
slot = l2cap_find_slot_by_id(id);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
BTC_TRACE_ERROR("%s unable to find L2CAP slot, event:%d!", __func__, event);
p_data->l2c_close.status = ESP_BT_L2CAP_NO_CONNECTION;
break;
}
@@ -386,7 +447,7 @@ static void *btc_l2cap_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
msg.pid = BTC_PID_L2CAP;
msg.act = event;
status = btc_transfer_context(&msg, p_data, sizeof(tBTA_JV), NULL, NULL);
status = btc_transfer_context(&msg, p_data, btc_l2cap_jv_param_len(event), NULL, NULL);
if (status != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
@@ -399,26 +460,20 @@ static void btc_l2cap_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user
bt_status_t status;
btc_msg_t msg;
switch (event) {
default:
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_L2CAP;
msg.act = event;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_L2CAP;
msg.act = event;
status = btc_transfer_context(&msg, p_data, sizeof(tBTA_JV), NULL, NULL);
if (status != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
break;
status = btc_transfer_context(&msg, p_data, btc_l2cap_jv_param_len(event), NULL, NULL);
if (status != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
return;
}
static void btc_l2cap_init(void)
{
esp_bt_l2cap_status_t ret = ESP_BT_L2CAP_SUCCESS;
esp_bt_l2cap_cb_param_t param;
esp_bt_l2cap_cb_param_t param = {0};
do {
if (is_l2cap_init()) {
@@ -462,6 +517,15 @@ static void btc_l2cap_init(void)
ret = ESP_BT_L2CAP_SUCCESS;
param.init.status = ESP_BT_L2CAP_SUCCESS;
btc_l2cap_cb_to_app(ESP_BT_L2CAP_INIT_EVT, &param);
} else if (BTA_JV_SUCCESS != ret) {
BTC_TRACE_ERROR("l2cap BTA_JvEnable failed\n");
vEventGroupDelete(l2cap_local_param.tx_event_group);
osi_mutex_free(&l2cap_local_param.l2cap_slot_mutex);
#if L2CAP_DYNAMIC_MEMORY == TRUE
osi_free(l2cap_local_param_ptr);
l2cap_local_param_ptr = NULL;
#endif
ret = ESP_BT_L2CAP_NO_RESOURCE;
}
} while (0);
@@ -508,8 +572,11 @@ static void btc_l2cap_uninit(void)
assert(0);
}
BTA_JvFreeChannel(l2cap_local_param.l2cap_slots[i]->psm, BTA_JV_CONN_TYPE_L2CAP,
(tBTA_JV_RFCOMM_CBACK *)btc_l2cap_inter_cb, (void *)user_data);
tBTA_JV_STATUS status = BTA_JvFreeChannel(l2cap_local_param.l2cap_slots[i]->psm, BTA_JV_CONN_TYPE_L2CAP,
(tBTA_JV_RFCOMM_CBACK *)btc_l2cap_inter_cb, (void *)user_data);
if (status != BTA_JV_SUCCESS) {
osi_free(user_data);
}
}
}
BTA_JvDisable((tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb);
@@ -517,7 +584,7 @@ static void btc_l2cap_uninit(void)
} while(0);
if (ret != ESP_BT_L2CAP_SUCCESS) {
esp_bt_l2cap_cb_param_t param;
esp_bt_l2cap_cb_param_t param = {0};
param.uninit.status = ret;
btc_l2cap_cb_to_app(ESP_BT_L2CAP_UNINIT_EVT, &param);
}
@@ -554,13 +621,19 @@ static void btc_l2cap_start_srv(btc_l2cap_args_t *arg)
memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
cfg.fcr_present = TRUE;
cfg.fcr = obex_l2c_fcr_opts_def;
BTA_JvL2capStartServer(slot->security, slot->role, &obex_l2c_etm_opt, slot->psm,
BTC_L2CAP_RX_MTU, &cfg, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id);
tBTA_JV_STATUS status = BTA_JvL2capStartServer(slot->security, slot->role, &obex_l2c_etm_opt, slot->psm,
BTC_L2CAP_RX_MTU, &cfg, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id);
if (status != BTA_JV_SUCCESS) {
l2cap_free_slot(slot);
ret = ESP_BT_L2CAP_FAILURE;
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
break;
}
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
} while(0);
if (ret != ESP_BT_L2CAP_SUCCESS) {
esp_bt_l2cap_cb_param_t param;
esp_bt_l2cap_cb_param_t param = {0};
param.start.status = ret;
param.start.handle = 0xffff;
param.start.sec_id = 0;
@@ -574,7 +647,7 @@ static void btc_l2cap_stop_srv(btc_l2cap_args_t *arg)
esp_bt_l2cap_status_t ret = ESP_BT_L2CAP_SUCCESS;
bool is_remove_all = false;
uint8_t i, j, srv_cnt = 0;
uint16_t *srv_psm_arr = osi_malloc(BTA_JV_MAX_L2C_CONN);
uint16_t *srv_psm_arr = osi_malloc(BTA_JV_MAX_L2C_CONN * sizeof(uint16_t));
tBTA_JV_SERVER_STATUS server_status = BTA_JV_SERVER_RUNNING;
if (arg->stop_srv.psm == BTC_L2CAP_INVALID_PSM) {
@@ -613,6 +686,7 @@ static void btc_l2cap_stop_srv(btc_l2cap_args_t *arg)
BTC_TRACE_ERROR("%s can not find server:%d!\n", __func__, arg->stop_srv.psm);
}
ret = ESP_BT_L2CAP_NO_SERVER;
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
break;
}
@@ -646,8 +720,11 @@ static void btc_l2cap_stop_srv(btc_l2cap_args_t *arg)
BTC_TRACE_ERROR("%s unable to malloc user data!", __func__);
assert(0);
}
BTA_JvFreeChannel(l2cap_local_param.l2cap_slots[i]->psm, BTA_JV_CONN_TYPE_L2CAP,
tBTA_JV_STATUS status = BTA_JvFreeChannel(l2cap_local_param.l2cap_slots[i]->psm, BTA_JV_CONN_TYPE_L2CAP,
(tBTA_JV_RFCOMM_CBACK *)btc_l2cap_inter_cb, (void *)user_data);
if (status != BTA_JV_SUCCESS) {
osi_free(user_data);
}
}
}
}
@@ -655,7 +732,7 @@ static void btc_l2cap_stop_srv(btc_l2cap_args_t *arg)
} while (0);
if (ret != ESP_BT_L2CAP_SUCCESS) {
esp_bt_l2cap_cb_param_t param;
esp_bt_l2cap_cb_param_t param = {0};
param.srv_stop.status = ret;
param.srv_stop.psm = BTC_L2CAP_INVALID_PSM;
btc_l2cap_cb_to_app(ESP_BT_L2CAP_SRV_STOP_EVT, &param);
@@ -695,13 +772,19 @@ static void btc_l2cap_connect(btc_l2cap_args_t *arg)
cfg.fcr_present = TRUE;
cfg.fcr = obex_l2c_fcr_opts_def;
BTA_JvL2capConnect(slot->security, slot->role, &obex_l2c_etm_opt, slot->psm,
BTC_L2CAP_RX_MTU, &cfg, slot->addr, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id);
tBTA_JV_STATUS status = BTA_JvL2capConnect(slot->security, slot->role, &obex_l2c_etm_opt, slot->psm,
BTC_L2CAP_RX_MTU, &cfg, slot->addr, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id);
if (status != BTA_JV_SUCCESS) {
l2cap_free_slot(slot);
ret = ESP_BT_L2CAP_FAILURE;
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
break;
}
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
} while (0);
if (ret != ESP_BT_L2CAP_SUCCESS) {
esp_bt_l2cap_cb_param_t param;
esp_bt_l2cap_cb_param_t param = {0};
param.open.status = ret;
param.open.handle = 0;
param.open.fd = -1;
@@ -733,7 +816,12 @@ static void btc_l2cap_write(uint32_t handle)
if ((p_buf = fixed_queue_try_peek_first(slot->tx.queue)) != NULL && p_buf->layer_specific == 0) {
p_buf->event++;
p_buf->layer_specific = 1;
BTA_JvL2capWrite(handle, slot->id, p_buf->data + p_buf->offset, p_buf->len, (void *)slot->id);
tBTA_JV_STATUS status = BTA_JvL2capWrite(handle, slot->id, p_buf->data + p_buf->offset, p_buf->len, (void *)slot->id);
if (status != BTA_JV_SUCCESS) {
BTC_TRACE_ERROR("%s BTA_JvL2capWrite failed: %d", __func__, status);
p_buf->layer_specific = 0;
p_buf->event--;
}
}
} while (0);
}
@@ -759,13 +847,16 @@ static void btc_l2cap_disconnect(uint32_t handle)
ret = ESP_BT_L2CAP_NO_CONNECTION;
break;
}
BTA_JvL2capClose(handle, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id);
tBTA_JV_STATUS status = BTA_JvL2capClose(handle, (tBTA_JV_L2CAP_CBACK *)btc_l2cap_inter_cb, (void *)slot->id);
if (status != BTA_JV_SUCCESS) {
ret = ESP_BT_L2CAP_FAILURE;
}
} while(0);
if (ret != ESP_BT_L2CAP_SUCCESS) {
esp_bt_l2cap_cb_param_t param;
esp_bt_l2cap_cb_param_t param = {0};
param.close.status = ret;
param.close.handle = 0;
param.close.handle = handle;
param.close.async = FALSE;
btc_l2cap_cb_to_app(ESP_BT_L2CAP_CLOSE_EVT, &param);
}
@@ -805,7 +896,7 @@ void btc_l2cap_call_handler(btc_msg_t *msg)
void btc_l2cap_cb_handler(btc_msg_t *msg)
{
esp_bt_l2cap_cb_param_t param;
esp_bt_l2cap_cb_param_t param = {0};
tBTA_JV *p_data = (tBTA_JV *)msg->arg;
l2cap_slot_t *slot = NULL;
uint8_t event = msg->act;
@@ -874,14 +965,14 @@ void btc_l2cap_cb_handler(btc_msg_t *msg)
}
// if rx still has data, delay free slot
if (slot->close_alarm == NULL && slot->rx.queue && fixed_queue_length(slot->rx.queue) > 0) {
tBTA_JV *p_arg = NULL;
if ((p_arg = osi_malloc(sizeof(tBTA_JV))) == NULL) {
tBTA_JV_L2CAP_CLOSE *p_arg = NULL;
if ((p_arg = (tBTA_JV_L2CAP_CLOSE *)osi_malloc(sizeof(tBTA_JV_L2CAP_CLOSE))) == NULL) {
param.close.status = ESP_BT_L2CAP_NO_RESOURCE;
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
BTC_TRACE_ERROR("%s unable to malloc slot close_alarm arg!", __func__);
break;
}
memcpy(p_arg, p_data, sizeof(tBTA_JV));
memcpy(p_arg, &p_data->l2c_close, sizeof(tBTA_JV_L2CAP_CLOSE));
slot->alarm_arg = (void *)p_arg;
if ((slot->close_alarm =
osi_alarm_new("slot", close_timeout_handler, (void *)slot, VFS_CLOSE_TIMEOUT)) == NULL) {
@@ -896,6 +987,7 @@ void btc_l2cap_cb_handler(btc_msg_t *msg)
osi_free(p_arg);
slot->alarm_arg = NULL;
osi_alarm_free(slot->close_alarm);
slot->close_alarm = NULL;
param.close.status = ESP_BT_L2CAP_BUSY;
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
BTC_TRACE_ERROR("%s set slot close_alarm failed!", __func__);
@@ -1066,6 +1158,7 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size)
l2cap_slot_t *slot = NULL;
uint8_t serial = 0;
int tx_mtu = 0;
osi_mutex_lock(&l2cap_local_param.l2cap_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
slot = l2cap_find_slot_by_fd(fd);
if (!slot) {
@@ -1075,6 +1168,7 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size)
return -1;
}
serial = slot->serial;
tx_mtu = slot->tx_mtu;
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
ssize_t sent = 0, write_size = 0;
@@ -1086,11 +1180,10 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size)
tx_event_group_val = 0;
if (size) {
if (p_buf == NULL) {
write_size = size < slot->tx_mtu ? size : slot->tx_mtu;
write_size = size < tx_mtu ? size : tx_mtu;
if ((p_buf = osi_malloc(sizeof(BT_HDR) + write_size)) == NULL) {
BTC_TRACE_ERROR("%s malloc failed!", __func__);
errno = ENOMEM;
sent = -1;
break;
}
p_buf->offset = 0;
@@ -1117,14 +1210,12 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size)
if (tx_event_group_val & SLOT_CLOSE_BIT(serial)) {
BTC_TRACE_ERROR("%s exit for L2CAP close, fd:%d!", __func__, fd);
errno = EPIPE;
sent = -1;
break;
} else if (tx_event_group_val & SLOT_WRITE_BIT(serial)) {
continue;
} else if (tx_event_group_val == 0) {
BTC_TRACE_ERROR("%s exit for time out, fd:%d!", __func__, fd);
errno = EBUSY;
sent = -1;
break;
}
}
@@ -1137,7 +1228,6 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size)
} else {
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
errno = EPIPE;
sent = -1;
break;
}
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
@@ -1149,6 +1239,12 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size)
p_buf = NULL;
}
if (errno != 0) {
if (sent == 0) {
sent = -1;
}
}
return sent;
}
@@ -1228,10 +1324,8 @@ static ssize_t l2cap_vfs_read(int fd, void * dst, size_t size)
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
BTC_TRACE_ERROR("%s peer close, data will be discarded!\n", __func__);
errno = EPIPE;
item_size = -1;
break;
}
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
if (p_buf->len <= size) {
memcpy(dst, p_buf->data + p_buf->offset, p_buf->len);
@@ -1247,7 +1341,15 @@ static ssize_t l2cap_vfs_read(int fd, void * dst, size_t size)
p_buf->len -= size;
size = 0;
}
osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex);
}
if (errno != 0) {
if (item_size == 0) {
item_size = -1;
}
}
return item_size;
}
@@ -1262,7 +1364,13 @@ static void btc_l2cap_vfs_register(void)
break;
}
esp_vfs_t vfs = {
if (l2cap_local_param.l2cap_vfs_id != -1) {
BTC_TRACE_WARNING("l2cap vfs id already registered\n");
ret = ESP_BT_L2CAP_SUCCESS;
break;
}
const esp_vfs_t vfs = {
.flags = ESP_VFS_FLAG_DEFAULT,
.write = l2cap_vfs_write,
.open = NULL,
@@ -218,6 +218,12 @@ static spp_slot_t *spp_find_slot_by_id(uint32_t id)
static spp_slot_t *spp_find_slot_by_handle(uint32_t handle)
{
#if SPP_DYNAMIC_MEMORY == TRUE
if (!spp_local_param_ptr) {
return NULL;
}
#endif
spp_slot_t *slot = NULL;
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
slot = spp_local_param.spp_slots[i];
@@ -230,6 +236,12 @@ static spp_slot_t *spp_find_slot_by_handle(uint32_t handle)
static spp_slot_t *spp_find_slot_by_fd(int fd)
{
#if SPP_DYNAMIC_MEMORY == TRUE
if (!spp_local_param_ptr) {
return NULL;
}
#endif
spp_slot_t *slot = NULL;
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
slot = spp_local_param.spp_slots[i];
@@ -242,6 +254,12 @@ static spp_slot_t *spp_find_slot_by_fd(int fd)
static spp_slot_t *spp_find_slot_by_scn(uint32_t scn)
{
#if SPP_DYNAMIC_MEMORY == TRUE
if (!spp_local_param_ptr) {
return NULL;
}
#endif
spp_slot_t *slot = NULL;
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
slot = spp_local_param.spp_slots[i];
@@ -300,6 +318,7 @@ static void spp_free_slot(spp_slot_t *slot)
static void spp_free_pending_slots(void)
{
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
spp_slot_t *slot = NULL;
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
slot = spp_local_param.spp_slots[i];
@@ -308,6 +327,7 @@ static void spp_free_pending_slots(void)
spp_free_slot(slot);
}
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
}
static inline void btc_spp_cb_to_app(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
@@ -463,7 +483,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
{
bt_status_t status;
btc_msg_t msg;
btc_msg_t msg = {0};
uint32_t id = (uintptr_t)user_data;
spp_slot_t *slot = NULL;
@@ -477,9 +497,9 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
break;
}
if (p_data->scn == 0) {
btc_create_server_fail_cb();
spp_free_slot(slot);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
btc_create_server_fail_cb();
BTC_TRACE_ERROR("%s unable to get scn, start server fail!", __func__);
break;
}
@@ -509,7 +529,6 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
slot->max_session, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)slot->id);
} else {
BTC_TRACE_ERROR("%s unable to create record, start server fail!", __func__);
btc_create_server_fail_cb();
tBTA_JV_FREE_SCN_USER_DATA *user_data = osi_malloc(sizeof(tBTA_JV_FREE_SCN_USER_DATA));
if (user_data) {
user_data->server_status = BTA_JV_SERVER_START_FAILED;
@@ -518,8 +537,15 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
BTC_TRACE_ERROR("%s unable to malloc user data!", __func__);
assert(0);
}
BTA_JvFreeChannel(slot->scn, BTA_JV_CONN_TYPE_RFCOMM,
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)user_data);
tBTA_JV_STATUS status = BTA_JvFreeChannel(slot->scn, BTA_JV_CONN_TYPE_RFCOMM,
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)user_data);
if (status != BTA_JV_SUCCESS) {
osi_free(user_data);
spp_free_slot(slot);
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
btc_create_server_fail_cb();
break;
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
break;
@@ -628,8 +654,11 @@ static void btc_spp_uninit(void)
BTC_TRACE_ERROR("%s unable to malloc user data!", __func__);
assert(0);
}
BTA_JvFreeChannel(spp_local_param.spp_slots[i]->scn, BTA_JV_CONN_TYPE_RFCOMM,
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)user_data);
tBTA_JV_STATUS status = BTA_JvFreeChannel(spp_local_param.spp_slots[i]->scn, BTA_JV_CONN_TYPE_RFCOMM,
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)user_data);
if (status != BTA_JV_SUCCESS) {
osi_free(user_data);
}
}
}
BTA_JvDisable((tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb);
@@ -660,9 +689,9 @@ static void btc_spp_start_discovery(btc_spp_args_t *arg)
} while (0);
if (ret != ESP_SPP_SUCCESS) {
esp_spp_cb_param_t param;
esp_spp_cb_param_t param = { 0 };
param.disc_comp.status = ret;
param.disc_comp.scn_num = 0xff;
param.disc_comp.scn_num = 0;
memset(param.disc_comp.scn, 0xff, ESP_SPP_MAX_SCN);
btc_spp_cb_to_app(ESP_SPP_DISCOVERY_COMP_EVT, &param);
}
@@ -690,8 +719,14 @@ static void btc_spp_connect(btc_spp_args_t *arg)
slot->scn = arg->connect.remote_scn;
memcpy(slot->addr, arg->connect.peer_bd_addr, ESP_BD_ADDR_LEN);
BTA_JvRfcommConnect(arg->connect.sec_mask, arg->connect.role, arg->connect.remote_scn,
arg->connect.peer_bd_addr, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)slot->id);
tBTA_JV_STATUS status = BTA_JvRfcommConnect(arg->connect.sec_mask, arg->connect.role, arg->connect.remote_scn,
arg->connect.peer_bd_addr, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)slot->id);
if (status != BTA_JV_SUCCESS) {
spp_free_slot(slot);
ret = ESP_SPP_FAILURE;
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
break;
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
} while (0);
@@ -727,7 +762,11 @@ static void btc_spp_disconnect(btc_spp_args_t *arg)
ret = ESP_SPP_NO_CONNECTION;
break;
}
BTA_JvRfcommClose(arg->disconnect.handle, (void *)slot->id);
if (BTA_JvRfcommClose(arg->disconnect.handle, (void *)slot->id) != BTA_JV_SUCCESS) {
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
ret = ESP_SPP_FAILURE;
break;
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
} while(0);
@@ -735,7 +774,7 @@ static void btc_spp_disconnect(btc_spp_args_t *arg)
esp_spp_cb_param_t param;
param.close.status = ret;
param.close.port_status = PORT_ERR_MAX;
param.close.handle = 0;
param.close.handle = arg->disconnect.handle;
param.close.async = FALSE;
btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, &param);
}
@@ -769,7 +808,13 @@ static void btc_spp_start_srv(btc_spp_args_t *arg)
slot->max_session = arg->start_srv.max_session;
strcpy(slot->service_name, arg->start_srv.name);
BTA_JvGetChannelId(BTA_JV_CONN_TYPE_RFCOMM, (void *)slot->id, arg->start_srv.local_scn);
tBTA_JV_STATUS status = BTA_JvGetChannelId(BTA_JV_CONN_TYPE_RFCOMM, (void *)slot->id, arg->start_srv.local_scn);
if (status != BTA_JV_SUCCESS) {
spp_free_slot(slot);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
ret = ESP_SPP_NO_RESOURCE;
break;
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
} while(0);
@@ -827,6 +872,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg)
BTC_TRACE_ERROR("%s can not find server:%d!\n", __func__, arg->stop_srv.scn);
}
ret = ESP_SPP_NO_SERVER;
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
break;
}
@@ -864,8 +910,11 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg)
BTC_TRACE_ERROR("%s unable to malloc user data!", __func__);
assert(0);
}
BTA_JvFreeChannel(spp_local_param.spp_slots[i]->scn, BTA_JV_CONN_TYPE_RFCOMM,
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)user_data);
tBTA_JV_STATUS status = BTA_JvFreeChannel(spp_local_param.spp_slots[i]->scn, BTA_JV_CONN_TYPE_RFCOMM,
(tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)user_data);
if (status != BTA_JV_SUCCESS) {
osi_free(user_data);
}
}
}
}
@@ -916,17 +965,27 @@ static void btc_spp_write(btc_spp_args_t *arg)
size_t item_size = 0;
uint8_t *data = xRingbufferReceiveUpTo(slot->ringbuf_write, &item_size, 0, slot->mtu);
if (item_size > 0) {
slot->write_data = data;
slot->write_data_len = item_size;
slot->is_writing = true;
BTA_JvRfcommWrite(arg->write.handle, slot->id, item_size, data);
if (BTA_JvRfcommWrite(arg->write.handle, slot->id, item_size, data) == BTA_JV_SUCCESS) {
slot->write_data = data;
slot->write_data_len = item_size;
slot->is_writing = true;
} else {
vRingbufferReturnItem(slot->ringbuf_write, data);
ret = ESP_SPP_NO_RESOURCE;
}
}
} else {
if (fixed_queue_enqueue(slot->tx.queue, arg->write.p_data, 0)) {
BTA_JvRfcommWrite(arg->write.handle, slot->id, arg->write.len, arg->write.p_data);
// The TX queue of SPP will handle this memory properly.
// Set it to NULL here to prevent deep free handler from releasing it.
arg->write.p_data = NULL;
if (arg->write.len > 0 && arg->write.p_data == NULL) {
ret = ESP_SPP_NO_RESOURCE;
} else if (fixed_queue_enqueue(slot->tx.queue, arg->write.p_data, 0)) {
if (BTA_JvRfcommWrite(arg->write.handle, slot->id, arg->write.len, arg->write.p_data) == BTA_JV_SUCCESS) {
// The TX queue of SPP will handle this memory properly.
// Set it to NULL here to prevent deep free handler from releasing it.
arg->write.p_data = NULL;
} else {
fixed_queue_try_remove_from_queue(slot->tx.queue, arg->write.p_data);
ret = ESP_SPP_NO_RESOURCE;
}
} else {
ret = ESP_SPP_NO_RESOURCE;
}
@@ -937,7 +996,7 @@ static void btc_spp_write(btc_spp_args_t *arg)
if (ret != ESP_SPP_SUCCESS && spp_local_param.spp_mode == ESP_SPP_MODE_CB) {
esp_spp_cb_param_t param;
param.write.status = ret;
param.write.handle = 0;
param.write.handle = arg->write.handle;
param.write.len = -1;
param.write.cong = false;
btc_spp_cb_to_app(ESP_SPP_WRITE_EVT, &param);
@@ -1331,6 +1390,11 @@ void btc_spp_cb_handler(btc_msg_t *msg)
}
if (count != 0) {
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
slot = spp_local_param.spp_slots[serial];
if (slot == NULL || slot->rfc_handle != p_data->data_ind.handle) {
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
break;
}
slot->credit_rx += count;
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
BTA_JvRfcommFlowControl(p_data->data_ind.handle, count);
@@ -1398,6 +1462,13 @@ int bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf)
p_data.data_ind.handle = slot->rfc_handle;
p_data.data_ind.p_buf = NULL;
if (slot->credit_rx == 0) {
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
osi_free(p_buf);
BTC_TRACE_WARNING("slot credit exhausted");
return 0;
}
if (spp_local_param.spp_mode == ESP_SPP_MODE_CB) {
size_t rx_len = fixed_queue_length(slot->rx.queue);
fixed_queue_enqueue(slot->rx.queue, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
@@ -1522,24 +1593,27 @@ static ssize_t spp_vfs_write(int fd, const void * data, size_t size)
if (tx_event_group_val & SLOT_CLOSE_BIT(serial)) {
BTC_TRACE_ERROR("%s exit for RFCOMM close, fd:%d!", __func__, fd);
errno = EPIPE;
sent = -1;
break;
} else if (tx_event_group_val & SLOT_WRITE_BIT(serial)) {
continue;
} else if (tx_event_group_val == 0) {
BTC_TRACE_ERROR("%s exit for time out, fd:%d!", __func__, fd);
errno = EBUSY;
sent = -1;
break;
}
} else {
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
errno = EPIPE;
sent = -1;
break;
}
}
if (errno != 0) {
if (sent == 0) {
sent = -1;
}
}
return sent;
}
@@ -1621,10 +1695,8 @@ static ssize_t spp_vfs_read(int fd, void * dst, size_t size)
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
BTC_TRACE_ERROR("%s peer close, data will be discarded!\n", __func__);
errno = EPIPE;
item_size = -1;
break;
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
if (p_buf->len <= size) {
memcpy(dst, p_buf->data + p_buf->offset, p_buf->len);
@@ -1640,16 +1712,24 @@ static ssize_t spp_vfs_read(int fd, void * dst, size_t size)
p_buf->len -= size;
size = 0;
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
}
if (count > 0) {
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
slot->credit_rx += count;
if ((slot = spp_local_param.spp_slots[serial]) != NULL) {
slot->credit_rx += count;
BTA_JvRfcommFlowControl(slot->rfc_handle, count);
BTC_TRACE_DEBUG("%s give credits:%d\n", __func__, count);
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
}
if (errno != 0) {
if (item_size == 0) {
item_size = -1;
}
}
return item_size;
}
@@ -1665,6 +1745,18 @@ static void btc_spp_vfs_register(void)
break;
}
if (spp_local_param.spp_mode != ESP_SPP_MODE_VFS) {
BTC_TRACE_ERROR("SPP not in VFS mode");
ret = ESP_SPP_FAILURE;
break;
}
if (spp_local_param.spp_vfs_id != -1) {
BTC_TRACE_ERROR("SPP VFS ID already exist");
ret = ESP_SPP_BUSY;
break;
}
esp_vfs_t vfs = {
.flags = ESP_VFS_FLAG_DEFAULT,
.write = spp_vfs_write,
@@ -2510,11 +2510,6 @@
#define GAP_INCLUDED TRUE
#endif
/* This is set to enable posting event for data write */
#ifndef GAP_CONN_POST_EVT_INCLUDED
#define GAP_CONN_POST_EVT_INCLUDED FALSE
#endif
/* The maximum number of simultaneous GAP L2CAP connections. */
#ifndef GAP_MAX_CONNECTIONS
#define GAP_MAX_CONNECTIONS 10 // 30
@@ -435,6 +435,12 @@ static bool supports_interlaced_inquiry_scan(void)
return HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(controller_param.features_classic[0].as_array);
}
static bool supports_interlaced_page_scan(void)
{
assert(controller_param.readable);
return HCI_LMP_INTERLACED_PAGE_SCAN_SUPPORTED(controller_param.features_classic[0].as_array);
}
static bool supports_rssi_with_inquiry_results(void)
{
assert(controller_param.readable);
@@ -604,6 +610,7 @@ static const controller_t interface = {
supports_simultaneous_le_bredr,
supports_reading_remote_extended_features,
supports_interlaced_inquiry_scan,
supports_interlaced_page_scan,
supports_rssi_with_inquiry_results,
supports_extended_inquiry_response,
supports_master_slave_role_switch,
@@ -49,6 +49,7 @@ typedef struct controller_t {
bool (*supports_simultaneous_le_bredr)(void);
bool (*supports_reading_remote_extended_features)(void);
bool (*supports_interlaced_inquiry_scan)(void);
bool (*supports_interlaced_page_scan)(void);
bool (*supports_rssi_with_inquiry_results)(void);
bool (*supports_extended_inquiry_response)(void);
bool (*supports_master_slave_role_switch)(void);
@@ -309,8 +309,14 @@ static void hci_packet_complete(BT_HDR *packet){
uint16_t num_packets = 1;
uint8_t *stream = packet->data + packet->offset;
if (packet->len < 1) {
return;
}
STREAM_TO_UINT8(type, stream);
if (type == DATA_TYPE_ACL/* || type == DATA_TYPE_SCO*/) {
if (packet->len < 3) {
return;
}
STREAM_TO_UINT16(handle, stream);
handle = handle & HCI_DATA_HANDLE_MASK;
btsnd_hcic_host_num_xmitted_pkts(1, &handle, &num_packets);
@@ -480,6 +486,10 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
hci_packet_complete(packet);
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
if (packet->len < 1) {
osi_free(packet);
return;
}
STREAM_TO_UINT8(type, stream);
packet->offset++;
packet->len--;
+12 -8
View File
@@ -215,14 +215,18 @@ static void hci_layer_deinit_env(void)
if (hci_host_env.command_queue) {
fixed_pkt_queue_free(hci_host_env.command_queue, (fixed_pkt_queue_free_cb)osi_free_func);
hci_host_env.command_queue = NULL;
}
if (hci_host_env.packet_queue) {
fixed_queue_free(hci_host_env.packet_queue, osi_free_func);
hci_host_env.packet_queue = NULL;
}
cmd_wait_q = &hci_host_env.cmd_waiting_q;
list_free(cmd_wait_q->commands_pending_response);
cmd_wait_q->commands_pending_response = NULL;
osi_mutex_free(&cmd_wait_q->commands_pending_response_lock);
cmd_wait_q->commands_pending_response_lock = NULL;
osi_alarm_free(cmd_wait_q->command_response_timer);
cmd_wait_q->command_response_timer = NULL;
#if ((BLE_50_FEATURE_SUPPORT == TRUE) || (BLE_42_FEATURE_SUPPORT == TRUE))
@@ -405,10 +409,16 @@ static void command_timed_out(void *context)
{
command_waiting_response_t *cmd_wait_q = (command_waiting_response_t *)context;
pkt_linked_item_t *wait_entry;
uint16_t opcode = 0;
osi_mutex_lock(&cmd_wait_q->commands_pending_response_lock, OSI_MUTEX_MAX_TIMEOUT);
wait_entry = (list_is_empty(cmd_wait_q->commands_pending_response) ?
NULL : list_front(cmd_wait_q->commands_pending_response));
if (wait_entry != NULL) {
hci_cmd_metadata_t *metadata = (hci_cmd_metadata_t *)(wait_entry->data);
opcode = metadata->opcode;
UNUSED(opcode);
}
osi_mutex_unlock(&cmd_wait_q->commands_pending_response_lock);
if (wait_entry == NULL) {
@@ -417,9 +427,7 @@ static void command_timed_out(void *context)
// We shouldn't try to recover the stack from this command timeout.
// If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
{
hci_cmd_metadata_t *metadata = (hci_cmd_metadata_t *)(wait_entry->data);
HCI_TRACE_ERROR("%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, metadata->opcode);
UNUSED(metadata);
HCI_TRACE_ERROR("%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, opcode);
}
}
@@ -742,11 +750,7 @@ const char *hci_status_code_to_string(uint8_t status)
case HCI_ERR_CONN_TOUT_DUE_TO_MIC_FAILURE: return "MIC Failure"; /* 0x3D */
case HCI_ERR_CONN_FAILED_ESTABLISHMENT: return "Conn Failed"; /* 0x3E */
case HCI_ERR_MAC_CONNECTION_FAILED: return "Previously Used"; /* 0x3F */
default: {
static char buf[24];
snprintf(buf, sizeof(buf), "Unknown Status (0x%02X)", status);
return buf;
}
default: return "Unknown Status";
}
}
#endif
@@ -162,7 +162,7 @@ static BT_HDR *make_ble_read_buffer_size(void)
#if (BLE_FEAT_ISO_EN == TRUE)
static BT_HDR *make_ble_read_buffer_size_v2(void)
{
return make_command_no_params(HCI_BLE_READ_BUFFER_SZIE_V2);
return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE_V2);
}
#endif // #if (BLE_FEAT_ISO_EN == TRUE)
@@ -164,7 +164,7 @@ static void parse_ble_read_buffer_size_response_v2 (
uint8_t *iso_pkt_num_ptr)
{
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_BUFFER_SZIE_V2, 6 /* bytes after: 2+1+2+1 */);
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_BUFFER_SIZE_V2, 6 /* bytes after: 2+1+2+1 */);
assert(stream != NULL);
STREAM_TO_UINT16(*data_size_ptr, stream);
STREAM_TO_UINT8(*acl_buffer_count_ptr, stream);
+124 -74
View File
@@ -58,6 +58,7 @@
static void btm_read_remote_features (UINT16 handle);
static void btm_read_remote_ext_features (UINT16 handle, UINT8 page_number);
static void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages);
static BOOLEAN btm_get_acl_db(void *p_acl_db_node, void *context);
#define BTM_DEV_REPLY_TIMEOUT 3 /* 3 second timeout waiting for responses */
@@ -65,7 +66,7 @@ static void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read
static void btm_read_acl_real_rssi_vsc_cmpl_cb(tBTM_VSC_CMPL *p1)
{
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_acl_real_rssi_cmpl_cb;
tBTM_ACL_REAL_RSSI_RESULTS results;
tBTM_ACL_REAL_RSSI_RESULTS results = {0};
UINT16 handle = 0;
tACL_CONN *p_acl_cb = NULL;
@@ -94,14 +95,16 @@ static void btm_read_acl_real_rssi_vsc_cmpl_cb(tBTM_VSC_CMPL *p1)
}
STREAM_TO_UINT16(handle, p);
p_acl_cb = btm_handle_to_acl(handle);
if (!p_acl_cb) {
results.status = BTM_UNKNOWN_ADDR;
goto out;
}
memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
STREAM_TO_UINT8(results.rssi, p);
results.status = BTM_SUCCESS;
p_acl_cb = btm_handle_to_acl(handle);
if (p_acl_cb) {
memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
}
out:
if (p_cb) {
(*p_cb)(&results);
@@ -193,38 +196,38 @@ void btm_acl_init (void)
** NULL if not found.
**
*******************************************************************************/
BOOLEAN btm_get_acl_db(void *p_acl_db_node, void *context)
static BOOLEAN btm_get_acl_db(void *p_acl_db_node, void *context)
{
tACL_CONN *p_acl_db =(tACL_CONN *)p_acl_db_node;
BOOLEAN ret = TRUE;
tACL_DB_PARAM *p_param = (tACL_DB_PARAM *)context;
switch(p_param->type) {
case ACL_DB_BDA:
{
UINT8 *p_bda = (UINT8 *)p_param->p_data1;
{
UINT8 *p_bda = (UINT8 *)p_param->p_data1;
#if BLE_INCLUDED == TRUE
tBT_TRANSPORT transport = (tBT_TRANSPORT)(*((UINT8 *)p_param->p_data2));
tBT_TRANSPORT transport = (tBT_TRANSPORT)(*((UINT8 *)p_param->p_data2));
#endif
if (p_acl_db->in_use
if (p_acl_db->in_use
&& !memcmp(p_bda, p_acl_db->remote_addr, BD_ADDR_LEN)
#if BLE_INCLUDED == TRUE
&& transport == p_acl_db->transport
#endif
) {
ret = FALSE;
}
) {
ret = FALSE;
}
break;
}
}
case ACL_DB_HANDLE:
{
{
UINT16 handle = (UINT16) *((UINT16 *)p_param->p_data1);
if (p_acl_db->in_use && handle == p_acl_db->hci_handle) {
ret = FALSE;
}
}
break;
}
default:
break;
}
default:
break;
}
return ret;
}
@@ -403,8 +406,12 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L
#if (CLASSIC_BT_INCLUDED == TRUE)
p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
p->p_pm_mode_db = btm_pm_sm_alloc();
if (!p->p_pm_mode_db) {
list_remove(btm_cb.p_acl_db_list, p);
p = NULL;
return;
}
#if BTM_PM_DEBUG == TRUE
BTM_TRACE_DEBUG( "btm_pm_sm_alloc handle:%d st:%d", hci_handle, p->p_pm_mode_db->state);
@@ -599,7 +606,10 @@ void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport)
}
#endif
#if (CLASSIC_BT_INCLUDED == TRUE)
list_remove(btm_cb.p_pm_mode_db_list, p->p_pm_mode_db);
if (p->p_pm_mode_db) {
list_remove(btm_cb.p_pm_mode_db_list, p->p_pm_mode_db);
p->p_pm_mode_db = NULL;
}
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#if (BLE_50_FEATURE_SUPPORT == TRUE) && (BLE_50_EXTEND_ADV_EN == TRUE)
if (p->transport == BT_TRANSPORT_LE) {
@@ -707,14 +717,13 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event)
|| (old_inquiry_state != btm_cb.is_inquiry)
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
) {
tBTM_BL_UPDATE_DATA evt = {
.event = BTM_BL_UPDATE_EVT,
.busy_level = busy_level,
.busy_level_flags = busy_level_flags,
};
tBTM_BL_EVENT_DATA evt = {0};
evt.update.event = BTM_BL_UPDATE_EVT;
evt.update.busy_level = busy_level;
evt.update.busy_level_flags = busy_level_flags;
btm_cb.busy_level = busy_level;
if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_UPDATE_MASK)) {
(*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA *)&evt);
(*btm_cb.p_bl_changed_cb)(&evt);
}
}
}
@@ -913,7 +922,7 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
{
tACL_CONN *p;
tBTM_SEC_DEV_REC *p_dev_rec;
tBTM_BL_ROLE_CHG_DATA evt;
tBTM_BL_ROLE_CHG_DATA evt = {0};
BTM_TRACE_DEBUG ("btm_acl_encrypt_change handle=%d status=%d encr_enable=%d\n",
handle, status, encr_enable);
@@ -955,14 +964,20 @@ void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
else if (p->switch_role_state == BTM_ACL_SWKEY_STATE_ENCRYPTION_ON) {
p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
BD_ADDR remote_bd_addr;
UINT8 role = btm_cb.devcb.switch_role_ref_data.role;
UINT8 hci_status = btm_cb.devcb.switch_role_ref_data.hci_status;
bdcpy(remote_bd_addr, btm_cb.devcb.switch_role_ref_data.remote_bd_addr);
btm_acl_report_role_change(btm_cb.devcb.switch_role_ref_data.hci_status, p->remote_addr);
/* if role change event is registered, report it now */
if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_ROLE_CHG_MASK)) {
evt.event = BTM_BL_ROLE_CHG_EVT;
evt.new_role = btm_cb.devcb.switch_role_ref_data.role;
evt.p_bda = btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
evt.hci_status = btm_cb.devcb.switch_role_ref_data.hci_status;
evt.new_role = role;
evt.p_bda = remote_bd_addr;
evt.hci_status = hci_status;
(*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA *)&evt);
BTM_TRACE_DEBUG("Role Switch Event: new_role 0x%02x, HCI Status 0x%02x, rs_st:%d\n",
@@ -1063,10 +1078,12 @@ void BTM_SetDefaultLinkPolicy (UINT16 settings)
}
BTM_TRACE_DEBUG("Set DefaultLinkPolicy:0x%04x\n", settings);
btm_cb.btm_def_link_policy = settings;
/* Set the default Link Policy of the controller */
btsnd_hcic_write_def_policy_set(settings);
if (btsnd_hcic_write_def_policy_set(settings) == TRUE) {
btm_cb.btm_def_link_policy = settings;
} else {
BTM_TRACE_WARNING("Failed to issue command of write_default_link_policy\n");
}
}
#endif // (CLASSIC_BT_INCLUDED == TRUE)
/*******************************************************************************
@@ -1079,23 +1096,32 @@ void BTM_SetDefaultLinkPolicy (UINT16 settings)
** Returns void
**
*******************************************************************************/
void btm_read_remote_version_complete (UINT8 *p)
void btm_read_remote_version_complete (UINT8 *p, UINT16 evt_len)
{
tACL_CONN *p_acl_cb = NULL;
UINT8 status;
UINT16 handle;
UINT16 remain_len = evt_len;
BTM_TRACE_DEBUG ("btm_read_remote_version_complete\n");
if (remain_len < 3) {
return;
}
STREAM_TO_UINT8 (status, p);
STREAM_TO_UINT16 (handle, p);
remain_len -= 3;
/* Look up the connection by handle and copy features */
p_acl_cb = btm_handle_to_acl(handle);
if (p_acl_cb) {
if (status == HCI_SUCCESS) {
STREAM_TO_UINT8 (p_acl_cb->lmp_version, p);
STREAM_TO_UINT16 (p_acl_cb->manufacturer, p);
STREAM_TO_UINT16 (p_acl_cb->lmp_subversion, p);
if (remain_len >= 5) {
STREAM_TO_UINT8 (p_acl_cb->lmp_version, p);
STREAM_TO_UINT16 (p_acl_cb->manufacturer, p);
STREAM_TO_UINT16 (p_acl_cb->lmp_subversion, p);
remain_len -= 5;
}
}
#if BLE_INCLUDED == TRUE
if (p_acl_cb->transport == BT_TRANSPORT_LE) {
@@ -1140,6 +1166,9 @@ void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages)
if (p_dev_rec == NULL) {
/* Get a new device; might be doing dedicated bonding */
p_dev_rec = btm_find_or_alloc_dev (p_acl_cb->remote_addr);
if (p_dev_rec == NULL) {
return;
}
}
p_acl_cb->num_read_pages = num_read_pages;
@@ -1189,7 +1218,7 @@ void btm_read_remote_features (UINT16 handle)
p_acl_cb = btm_handle_to_acl(handle);
if (p_acl_cb == NULL) {
BTM_TRACE_ERROR("btm_read_remote_features handle=%d invalid\n", handle);
return;
return;
}
p_acl_cb->num_read_pages = 0;
@@ -1247,7 +1276,7 @@ void btm_read_remote_features_complete (UINT8 *p)
p_acl_cb = btm_handle_to_acl(handle);
if (p_acl_cb == NULL) {
BTM_TRACE_ERROR("btm_read_remote_features_complete handle=%d invalid\n", handle);
return;
return;
}
/* Copy the received features page */
@@ -1306,6 +1335,11 @@ void btm_read_remote_ext_features_complete (UINT8 *p)
BTM_TRACE_ERROR("btm_read_remote_ext_features_complete page=%d unknown", max_page);
}
if (page_num > HCI_EXT_FEATURES_PAGE_MAX) {
BTM_TRACE_ERROR("btm_read_remote_ext_features_complete page_num=%u invalid", page_num);
page_num = HCI_EXT_FEATURES_PAGE_MAX;
goto exit;
}
/* Copy the received features page */
STREAM_TO_ARRAY(p_acl_cb->peer_lmp_features[page_num], p, HCI_FEATURE_BYTES_PER_PAGE);
@@ -1322,6 +1356,7 @@ void btm_read_remote_ext_features_complete (UINT8 *p)
/* Reading of remote feature pages is complete */
BTM_TRACE_DEBUG("BTM reached last remote extended features page (%d)\n", page_num);
exit:
/* Process the pages */
btm_process_remote_ext_features (p_acl_cb, (UINT8) (page_num + 1));
@@ -1349,7 +1384,7 @@ void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle)
p_acl_cb = btm_handle_to_acl(handle);
if (p_acl_cb == NULL) {
BTM_TRACE_ERROR("btm_read_remote_ext_features_failed handle=%d invalid\n", handle);
return;
return;
}
/* Process supported features only */
@@ -1525,7 +1560,10 @@ UINT16 BTM_GetNumAclLinks (void)
{
uint16_t num_acl = 0;
num_acl = list_length(btm_cb.p_acl_db_list);
if (btm_cb.p_acl_db_list) {
num_acl = list_length(btm_cb.p_acl_db_list);
}
return num_acl;
}
@@ -1536,10 +1574,10 @@ UINT16 BTM_GetNumAclLinks (void)
** Description This function is called to get the disconnection reason code
** returned by the HCI at disconnection complete event.
**
** Returns TRUE if connection is up, else FALSE.
** Returns UINT the HCI disconnection reason code
**
*******************************************************************************/
UINT16 btm_get_acl_disc_reason_code (void)
UINT8 btm_get_acl_disc_reason_code (void)
{
UINT8 res = btm_cb.acl_disc_reason;
BTM_TRACE_DEBUG ("btm_get_acl_disc_reason_code\n");
@@ -1732,7 +1770,7 @@ UINT8 BTM_AllocateSCN(void)
#if (CLASSIC_BT_INCLUDED == TRUE)
BOOLEAN BTM_TryAllocateSCN(UINT8 scn)
{
if (scn >= BTM_MAX_SCN) {
if ((scn == 0) || (scn >= BTM_MAX_SCN)) {
return FALSE;
}
@@ -1758,13 +1796,12 @@ BOOLEAN BTM_TryAllocateSCN(UINT8 scn)
BOOLEAN BTM_FreeSCN(UINT8 scn)
{
BTM_TRACE_DEBUG ("BTM_FreeSCN \n");
if (scn <= BTM_MAX_SCN) {
if ((scn > 0) && (scn <= BTM_MAX_SCN)) {
btm_cb.btm_scn[scn - 1] = FALSE;
return (TRUE);
} else {
return (FALSE); /* Illegal SCN passed in */
}
return (FALSE);
}
#endif ///CLASSIC_BT_INCLUDED == TRUE
@@ -1986,13 +2023,12 @@ tBTM_STATUS BTM_RegBusyLevelNotif (tBTM_BL_CHANGE_CB *p_cb, UINT8 *p_level,
*p_level = btm_cb.busy_level;
}
btm_cb.bl_evt_mask = evt_mask;
if (!p_cb) {
btm_cb.p_bl_changed_cb = NULL;
} else if (btm_cb.p_bl_changed_cb) {
return (BTM_BUSY);
} else {
btm_cb.bl_evt_mask = evt_mask;
btm_cb.p_bl_changed_cb = p_cb;
}
@@ -2033,7 +2069,7 @@ tBTM_STATUS BTM_SetQoS (BD_ADDR bd, FLOW_SPEC *p_flow, tBTM_CMPL_CB *p_cb)
bd[0], bd[1], bd[2],
bd[3], bd[4], bd[5]);
/* If someone already waiting on the version, do not allow another */
/* If someone already waiting on the QoS, do not allow another */
if (btm_cb.devcb.p_qossu_cmpl_cb) {
return (BTM_BUSY);
}
@@ -2135,7 +2171,8 @@ tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL
BTM_TRACE_API ("BTM_ReadRSSI: RemBdAddr: %02x%02x%02x%02x%02x%02x\n",
remote_bda[0], remote_bda[1], remote_bda[2],
remote_bda[3], remote_bda[4], remote_bda[5]);
tBTM_RSSI_RESULTS result;
tBTM_RSSI_RESULTS result = {0};
memcpy(result.rem_bda, remote_bda, BD_ADDR_LEN);
/* If someone already waiting on the version, do not allow another */
if (btm_cb.devcb.p_rssi_cmpl_cb) {
result.status = BTM_BUSY;
@@ -2159,10 +2196,11 @@ tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL
} else {
return (BTM_CMD_STARTED);
}
} else {
result.status = BTM_UNKNOWN_ADDR;
(*p_cb)(&result);
return (BTM_UNKNOWN_ADDR);
}
/* If here, no BD Addr found */
return (BTM_UNKNOWN_ADDR);
}
#if (CLASSIC_BT_INCLUDED == TRUE)
@@ -2214,13 +2252,13 @@ tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_C
#if CLASSIC_BT_INCLUDED == TRUE
tBTM_STATUS ret = BTM_UNKNOWN_ADDR;
tACL_CONN *p;
tBTM_SET_ACL_PKT_TYPES_RESULTS result;
tBTM_SET_ACL_PKT_TYPES_RESULTS result = {0};
/* If someone already waiting on the version, do not allow another */
if (btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb) {
result.status = HCI_ERR_REPEATED_ATTEMPTS;
result.status = BTM_BUSY;
(*p_cb)(&result);
return (BTM_BUSY);;
return (BTM_BUSY);
}
p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
@@ -2233,12 +2271,16 @@ tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_C
if (btm_set_packet_types(p, pkt_types) != BTM_CMD_STARTED) {
btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb = NULL;
btu_stop_timer (&btm_cb.devcb.set_acl_pkt_types_timer);
result.status = HCI_ERR_MEMORY_FULL;
result.status = BTM_NO_RESOURCES;
(*p_cb)(&result);
ret = BTM_NO_RESOURCES;
} else {
ret = BTM_CMD_STARTED;
}
} else {
result.status = BTM_UNKNOWN_ADDR;
(*p_cb)(&result);
return (BTM_UNKNOWN_ADDR);
}
/* If here, no BD Addr found */
return ret;
@@ -2251,7 +2293,7 @@ void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types)
{
BTM_TRACE_DEBUG ("btm_acl_pkt_types_changed\n");
tACL_CONN *conn = NULL;
tBTM_SET_ACL_PKT_TYPES_RESULTS results;
tBTM_SET_ACL_PKT_TYPES_RESULTS results = {0};
btu_stop_timer (&btm_cb.devcb.set_acl_pkt_types_timer);
/* If there is a callback registered for packet types changed, call it */
@@ -2265,8 +2307,10 @@ void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types)
/* Search through the list of active channels for the correct BD Addr */
if ((conn = btm_handle_to_acl(handle)) != NULL) {
memcpy(results.rem_bda, conn->remote_addr, BD_ADDR_LEN);
(*btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb)(&results);
} else {
results.status = BTM_UNKNOWN_ADDR;
}
(*btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb)(&results);
btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb = NULL;
}
}
@@ -2296,6 +2340,7 @@ tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda)
remote_bda[0], remote_bda[1], remote_bda[2],
remote_bda[3], remote_bda[4], remote_bda[5]);
memcpy(result.rem_bda, remote_bda, BD_ADDR_LEN);
memset(result.channel_map, 0, sizeof(result.channel_map)); // Clear channel map data
/* If someone already waiting for the channel map, do not allow another */
if (btm_cb.devcb.is_ch_map_cb) {
@@ -2483,7 +2528,7 @@ err_out:
void btm_read_link_quality_complete (UINT8 *p)
{
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_lnk_qual_cmpl_cb;
tBTM_LINK_QUALITY_RESULTS results;
tBTM_LINK_QUALITY_RESULTS results = {0};
UINT16 handle;
tACL_CONN *p_acl_cb = NULL;
BTM_TRACE_DEBUG ("btm_read_link_quality_complete\n");
@@ -2505,10 +2550,12 @@ void btm_read_link_quality_complete (UINT8 *p)
results.link_quality, results.hci_status);
/* Search through the list of active channels for the correct BD Addr */
p_acl_cb = btm_handle_to_acl(handle);
if (p_acl_cb) {
p_acl_cb = btm_handle_to_acl(handle);
if (p_acl_cb) {
memcpy (results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
}
} else {
results.status = BTM_UNKNOWN_ADDR;
}
} else {
results.status = BTM_ERR_PROCESSING;
}
@@ -2531,11 +2578,10 @@ tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport)
{
UINT16 hci_handle = BTM_GetHCIConnHandle(bd_addr, transport);
tBTM_STATUS status = BTM_SUCCESS;
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
BTM_TRACE_DEBUG ("btm_remove_acl\n");
#if BTM_DISC_DURING_RS == TRUE
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
/* Role Switch is pending, postpone until completed */
if (p_dev_rec && (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING)) {
p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
@@ -2591,6 +2637,7 @@ void btm_cont_rswitch (tACL_CONN *p, tBTM_SEC_DEV_REC *p_dev_rec,
UINT8 hci_status)
{
BOOLEAN sw_ok = TRUE;
UINT8 final_status = hci_status;
BTM_TRACE_DEBUG ("btm_cont_rswitch\n");
/* Check to see if encryption needs to be turned off if pending
change of link key or role switch */
@@ -2625,8 +2672,9 @@ void btm_cont_rswitch (tACL_CONN *p, tBTM_SEC_DEV_REC *p_dev_rec,
}
if (!sw_ok) {
final_status = HCI_ERR_MEMORY_FULL;
p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
btm_acl_report_role_change(hci_status, p->remote_addr);
btm_acl_report_role_change(final_status, p->remote_addr);
}
}
}
@@ -2777,23 +2825,23 @@ void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type)
{
/* 3 and 5 slot packets? */
if (!HCI_3_SLOT_PACKETS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
*p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3);
*p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH3 | BTM_ACL_PKT_TYPES_MASK_DM3);
}
if (!HCI_5_SLOT_PACKETS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
*p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5);
*p_pkt_type &= ~(BTM_ACL_PKT_TYPES_MASK_DH5 | BTM_ACL_PKT_TYPES_MASK_DM5);
}
/* 2 and 3 MPS support? */
if (!HCI_EDR_ACL_2MPS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
/* Not supported. Add 'not_supported' mask for all 2MPS packet types */
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 +
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 | BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 |
BTM_ACL_PKT_TYPES_MASK_NO_2_DH5);
}
if (!HCI_EDR_ACL_3MPS_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
/* Not supported. Add 'not_supported' mask for all 3MPS packet types */
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 +
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 | BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 |
BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
}
@@ -2803,13 +2851,13 @@ void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type)
if (!HCI_3_SLOT_EDR_ACL_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
/* Not supported. Add 'not_supported' mask for all 3-slot EDR packet types */
{
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH3);
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 | BTM_ACL_PKT_TYPES_MASK_NO_3_DH3);
}
if (!HCI_5_SLOT_EDR_ACL_SUPPORTED(p->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
/* Not supported. Add 'not_supported' mask for all 5-slot EDR packet types */
{
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
*p_pkt_type |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 | BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
}
}
}
@@ -2824,8 +2872,10 @@ void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type)
void btm_acl_free(void)
{
list_free(btm_cb.p_acl_db_list);
btm_cb.p_acl_db_list = NULL;
#if (CLASSIC_BT_INCLUDED == TRUE)
list_free(btm_cb.p_pm_mode_db_list);
btm_cb.p_pm_mode_db_list = NULL;
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
}
@@ -27,7 +27,7 @@
static void btm_read_new_conn_tx_pwr_lvl_vsc_cmpl_cb(tBTM_VSC_CMPL *p1)
{
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_read_new_conn_tx_pwr_lvl_cmpl_cb;
tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS result;
tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS result = {0};
btu_stop_timer(&btm_cb.devcb.read_new_conn_tx_pwr_lvl_timer);
btm_cb.devcb.p_read_new_conn_tx_pwr_lvl_cmpl_cb = NULL;
@@ -63,11 +63,13 @@ out:
tBTM_STATUS BTM_ReadNewConnTxPwrLvl(tBTM_CMPL_CB *p_cb)
{
tBTM_STATUS status;
tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS result;
tBTM_READ_NEW_CONN_TX_PWR_LVL_RESULTS result = {0};
if (btm_cb.devcb.p_read_new_conn_tx_pwr_lvl_cmpl_cb) {
result.status = BTM_BUSY;
(*p_cb)(&result);
if (p_cb) {
(*p_cb)(&result);
}
return BTM_BUSY;
}
@@ -82,7 +84,9 @@ tBTM_STATUS BTM_ReadNewConnTxPwrLvl(tBTM_CMPL_CB *p_cb)
btm_cb.devcb.p_read_new_conn_tx_pwr_lvl_cmpl_cb = NULL;
btu_stop_timer(&btm_cb.devcb.read_new_conn_tx_pwr_lvl_timer);
result.status = status;
(*p_cb)(&result);
if (p_cb) {
(*p_cb)(&result);
}
return BTM_NO_RESOURCES;
}
@@ -92,12 +96,11 @@ tBTM_STATUS BTM_ReadNewConnTxPwrLvl(tBTM_CMPL_CB *p_cb)
static void btm_write_new_conn_tx_pwr_lvl_vsc_cmpl_cb(tBTM_VSC_CMPL *p1)
{
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_write_new_conn_tx_pwr_lvl_cmpl_cb;
tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS result;
tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS result = {0};
btu_stop_timer(&btm_cb.devcb.write_new_conn_tx_pwr_lvl_timer);
btm_cb.devcb.p_write_new_conn_tx_pwr_lvl_cmpl_cb = NULL;
memset(&result, 0, sizeof(result));
result.status = BTM_ERR_PROCESSING;
result.hci_status = HCI_ERR_UNSPECIFIED;
@@ -122,13 +125,15 @@ out:
tBTM_STATUS BTM_WriteNewConnTxPwrLvl(INT8 pwr_lvl_min, INT8 pwr_lvl_max, tBTM_CMPL_CB *p_cb)
{
tBTM_STATUS status;
tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS result;
tBTM_WRITE_NEW_CONN_TX_PWR_LVL_RESULTS result = {0};
UINT8 param[2];
UINT8 *p = param;
if (btm_cb.devcb.p_write_new_conn_tx_pwr_lvl_cmpl_cb) {
result.status = BTM_BUSY;
(*p_cb)(&result);
if (p_cb) {
(*p_cb)(&result);
}
return BTM_BUSY;
}
@@ -145,7 +150,9 @@ tBTM_STATUS BTM_WriteNewConnTxPwrLvl(INT8 pwr_lvl_min, INT8 pwr_lvl_max, tBTM_CM
btm_cb.devcb.p_write_new_conn_tx_pwr_lvl_cmpl_cb = NULL;
btu_stop_timer(&btm_cb.devcb.write_new_conn_tx_pwr_lvl_timer);
result.status = status;
(*p_cb)(&result);
if (p_cb) {
(*p_cb)(&result);
}
return BTM_NO_RESOURCES;
}
@@ -156,7 +163,7 @@ static void btm_read_tx_pwr_lvl_vsc_cmpl_cb(tBTM_TX_PWR_LVL_TYPE type, tBTM_VSC_
TIMER_LIST_ENT *timer, tBTM_CMPL_CB **pp_cb)
{
tBTM_CMPL_CB *p_cb = *pp_cb;
tBTM_READ_TX_PWR_LVL_RESULTS result;
tBTM_READ_TX_PWR_LVL_RESULTS result = {0};
btu_stop_timer(timer);
*pp_cb = NULL;
@@ -220,7 +227,7 @@ tBTM_STATUS BTM_ReadBredrTxPwrLvl(tBTM_TX_PWR_LVL_TYPE type, tBTM_CMPL_CB *p_cb)
tBTM_VSC_CMPL_CB *p_vsc_cb;
tBTM_STATUS status;
tBTM_READ_TX_PWR_LVL_RESULTS result;
tBTM_READ_TX_PWR_LVL_RESULTS result = {0};
#endif // #if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
switch (type) {
@@ -288,7 +295,7 @@ static void btm_write_tx_pwr_lvl_vsc_cmpl_cb(tBTM_TX_PWR_LVL_TYPE type, tBTM_VSC
TIMER_LIST_ENT *timer, tBTM_CMPL_CB **pp_cb)
{
tBTM_CMPL_CB *p_cb = *pp_cb;
tBTM_WRITE_TX_PWR_LVL_RESULTS result;
tBTM_WRITE_TX_PWR_LVL_RESULTS result = {0};
btu_stop_timer(timer);
*pp_cb = NULL;
@@ -347,7 +354,7 @@ tBTM_STATUS BTM_WriteBredrTxPwrLvl(tBTM_TX_PWR_LVL_TYPE type, INT8 tx_power, tBT
tBTM_VSC_CMPL_CB *p_vsc_cb;
tBTM_STATUS status;
tBTM_WRITE_TX_PWR_LVL_RESULTS result;
tBTM_WRITE_TX_PWR_LVL_RESULTS result = {0};
UINT8 param[1];
UINT8 *p = param;
#endif // #if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
@@ -425,12 +432,12 @@ tBTM_STATUS BTM_WriteBredrTxPwrLvl(tBTM_TX_PWR_LVL_TYPE type, INT8 tx_power, tBT
void btm_bredr_pwr_ctrl_timeout(TIMER_LIST_ENT *p_tle)
{
if (p_tle == &btm_cb.devcb.write_inq_txpwer_timer) {
btm_write_inq_tx_power_complete(NULL);
btm_write_inq_tx_power_complete(NULL, 0);
} else if (p_tle == &btm_cb.devcb.read_iscan_txpwer_timer) {
btm_read_iscan_tx_power_complete(NULL);
btm_read_iscan_tx_power_complete(NULL, 0);
}
#if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
} else if (p_tle == &btm_cb.devcb.read_new_conn_tx_pwr_lvl_timer) {
else if (p_tle == &btm_cb.devcb.read_new_conn_tx_pwr_lvl_timer) {
btm_read_new_conn_tx_pwr_lvl_vsc_cmpl_cb(NULL);
} else if (p_tle == &btm_cb.devcb.write_new_conn_tx_pwr_lvl_timer) {
btm_write_new_conn_tx_pwr_lvl_vsc_cmpl_cb(NULL);
@@ -446,9 +453,8 @@ void btm_bredr_pwr_ctrl_timeout(TIMER_LIST_ENT *p_tle)
btm_write_page_tx_pwr_lvl_vsc_cmpl_cb(NULL);
} else if (p_tle == &btm_cb.devcb.write_pscan_tx_pwr_lvl_timer) {
btm_write_pscan_tx_pwr_lvl_vsc_cmpl_cb(NULL);
#endif // #if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
}
#endif // #if (ESP_BT_CLASSIC_ENABLE_POWER_CTRL_VSC == TRUE)
}
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
@@ -22,6 +22,7 @@
*
******************************************************************************/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
//#include <stdio.h>
@@ -77,7 +78,11 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
if(p_dev_rec) {
BTM_TRACE_DEBUG("%s alloc a new dev rec %p bd_addr="MACSTR"",
__func__, p_dev_rec, MAC2STR(bd_addr));
list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec);
if (!list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec)) {
osi_free(p_dev_rec);
p_dev_rec = NULL;
return FALSE;
}
/* Mark this record as in use and initialize */
memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
p_dev_rec->sec_flags = BTM_SEC_IN_USE;
@@ -188,17 +193,18 @@ BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport)
return FALSE;
}
if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL) {
#if (CLASSIC_BT_INCLUDED == TRUE)
/* Tell controller to get rid of the link key, if it has one stored */
if (transport != BT_TRANSPORT_LE) {
BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);
}
#endif // (CLASSIC_BT_INCLUDED == TRUE)
btm_sec_free_dev(p_dev_rec, transport);
if ((p_dev_rec = btm_find_dev(bd_addr)) == NULL) {
return FALSE;
}
#if (CLASSIC_BT_INCLUDED == TRUE)
/* Tell controller to get rid of the link key, if it has one stored */
if (transport != BT_TRANSPORT_LE) {
BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);
}
#endif // (CLASSIC_BT_INCLUDED == TRUE)
btm_sec_free_dev(p_dev_rec, transport);
#if (BLE_SMP_ID_RESET_ENABLE == TRUE)
/*
* There are tracking risks associated with using a fixed or static IRK.
@@ -277,45 +283,45 @@ BOOLEAN btm_find_sec_dev_in_list (void *p_node_data, void *context)
if (dev_free == p_context->free_check) {
switch (p_context->type) {
case SEC_DEV_BDA:
if (!memcmp(p_context->context.p_bd_addr, p_sec_dev->bd_addr, BD_ADDR_LEN)) {
ret = FALSE;
}
break;
if (!memcmp(p_context->context.p_bd_addr, p_sec_dev->bd_addr, BD_ADDR_LEN)) {
ret = FALSE;
}
break;
case SEC_DEV_HDL:
if (p_context->context.handle == p_sec_dev->hci_handle
if (p_context->context.handle == p_sec_dev->hci_handle
#if BLE_INCLUDED == TRUE
|| (p_context->context.handle == p_sec_dev->ble_hci_handle)
#endif
) {
ret = FALSE;
}
break;
) {
ret = FALSE;
}
break;
#if BLE_PRIVACY_SPT == TRUE
case SEC_DEV_ID_ADDR:
if (!memcmp(p_context->context.p_bd_addr, p_sec_dev->ble.static_addr, BD_ADDR_LEN)) {
ret = FALSE;
}
break;
case SEC_DEV_ID_ADDR:
if (!memcmp(p_context->context.p_bd_addr, p_sec_dev->ble.static_addr, BD_ADDR_LEN)) {
ret = FALSE;
}
break;
#endif //BLE_PRIVACY_SPT == TRUE
case SEC_DEV_BTDM_BDA:
if (!memcmp(p_context->context.p_bd_addr, p_sec_dev->bd_addr, BD_ADDR_LEN)) {
ret = FALSE;
}
if (!memcmp(p_context->context.p_bd_addr, p_sec_dev->bd_addr, BD_ADDR_LEN)) {
ret = FALSE;
}
#if BLE_INCLUDED == TRUE
// If a LE random address is looking for device record
if (memcmp(p_sec_dev->ble.pseudo_addr, bd_addr_null, BD_ADDR_LEN) != 0 &&
!memcmp(p_sec_dev->ble.pseudo_addr, p_context->context.p_bd_addr, BD_ADDR_LEN)) {
ret = FALSE;
}
if (memcmp(p_sec_dev->ble.pseudo_addr, bd_addr_null, BD_ADDR_LEN) != 0 &&
!memcmp(p_sec_dev->ble.pseudo_addr, p_context->context.p_bd_addr, BD_ADDR_LEN)) {
ret = FALSE;
}
if (btm_ble_addr_resolvable(p_context->context.p_bd_addr, p_sec_dev)) {
ret = FALSE;
}
if (btm_ble_addr_resolvable(p_context->context.p_bd_addr, p_sec_dev)) {
ret = FALSE;
}
#endif
break;
default:
break;
}
break;
default:
break;
}
}
return ret;
}
@@ -489,6 +495,13 @@ void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec, tBT_TRANSPORT transport)
btm_sec_clear_ble_keys (p_dev_rec);
#endif
}
#if (SMP_INCLUDED == TRUE)
if (p_dev_rec == btm_cb.p_collided_dev_rec) {
btm_cb.p_collided_dev_rec = NULL;
btm_cb.sec_collision_tle.param = 0;
btu_stop_timer(&btm_cb.sec_collision_tle);
}
#endif
/* No BLE keys and BT keys, clear the sec_flags */
if(p_dev_rec->sec_flags == BTM_SEC_IN_USE) {
p_dev_rec->sec_flags = 0;
@@ -585,16 +598,18 @@ tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle)
*******************************************************************************/
tBTM_SEC_DEV_REC *btm_find_dev(BD_ADDR bd_addr)
{
if(bd_addr) {
list_node_t *p_node = NULL;
tSecDevContext context;
context.type = SEC_DEV_BTDM_BDA;
context.context.p_bd_addr = bd_addr;
context.free_check = FALSE;
p_node = list_foreach(btm_cb.p_sec_dev_rec_list, btm_find_sec_dev_in_list, &context);
if (p_node) {
return(list_node(p_node));
}
if (bd_addr) {
if (btm_cb.p_sec_dev_rec_list) {
list_node_t *p_node = NULL;
tSecDevContext context = {0};
context.type = SEC_DEV_BTDM_BDA;
context.context.p_bd_addr = bd_addr;
context.free_check = FALSE;
p_node = list_foreach(btm_cb.p_sec_dev_rec_list, btm_find_sec_dev_in_list, &context);
if (p_node) {
return (list_node(p_node));
}
}
}
return (NULL);
}
@@ -791,6 +806,7 @@ BOOLEAN btm_set_bond_type_dev(BD_ADDR bd_addr, tBTM_BOND_TYPE bond_type)
void btm_sec_dev_init(void)
{
btm_cb.p_sec_dev_rec_list = list_new(osi_free_func);
assert(btm_cb.p_sec_dev_rec_list != NULL);
}
/*******************************************************************************
@@ -802,5 +818,8 @@ void btm_sec_dev_init(void)
*******************************************************************************/
void btm_sec_dev_free(void)
{
list_free(btm_cb.p_sec_dev_rec_list);
if (btm_cb.p_sec_dev_rec_list) {
list_free(btm_cb.p_sec_dev_rec_list);
btm_cb.p_sec_dev_rec_list = NULL;
}
}
@@ -93,15 +93,15 @@ void btm_dev_init (void)
btm_cb.devcb.rln_timer.param = (TIMER_PARAM_TYPE)TT_DEV_RLN;
#endif // (CLASSIC_BT_INCLUDED == TRUE)
btm_cb.btm_acl_pkt_types_supported = BTM_ACL_PKT_TYPES_MASK_DH1 + BTM_ACL_PKT_TYPES_MASK_DM1 +
BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3 +
BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5;
btm_cb.btm_acl_pkt_types_supported = BTM_ACL_PKT_TYPES_MASK_DH1 | BTM_ACL_PKT_TYPES_MASK_DM1 |
BTM_ACL_PKT_TYPES_MASK_DH3 | BTM_ACL_PKT_TYPES_MASK_DM3 |
BTM_ACL_PKT_TYPES_MASK_DH5 | BTM_ACL_PKT_TYPES_MASK_DM5;
#if (CLASSIC_BT_INCLUDED == TRUE)
btm_cb.btm_sco_pkt_types_supported = BTM_SCO_PKT_TYPES_MASK_HV1 +
BTM_SCO_PKT_TYPES_MASK_HV2 +
BTM_SCO_PKT_TYPES_MASK_HV3 +
BTM_SCO_PKT_TYPES_MASK_EV3 +
BTM_SCO_PKT_TYPES_MASK_EV4 +
btm_cb.btm_sco_pkt_types_supported = BTM_SCO_PKT_TYPES_MASK_HV1 |
BTM_SCO_PKT_TYPES_MASK_HV2 |
BTM_SCO_PKT_TYPES_MASK_HV3 |
BTM_SCO_PKT_TYPES_MASK_EV3 |
BTM_SCO_PKT_TYPES_MASK_EV4 |
BTM_SCO_PKT_TYPES_MASK_EV5;
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
}
@@ -132,6 +132,17 @@ static void btm_db_reset (void)
(*p_cb)((void *) NULL);
}
}
if (btm_cb.devcb.p_page_to_set_cmpl_cb) {
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_page_to_set_cmpl_cb;
tBTM_SET_PAGE_TIMEOUT_RESULTS results = {0};
results.status = BTM_DEV_RESET;
btm_cb.devcb.p_page_to_set_cmpl_cb = NULL;
btu_free_timer(&btm_cb.devcb.page_timeout_set_timer);
(*p_cb)(&results);
}
#endif // (CLASSIC_BT_INCLUDED == TRUE)
if (btm_cb.devcb.p_rssi_cmpl_cb) {
@@ -188,7 +199,7 @@ static void reset_complete(void)
btm_pm_reset();
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
l2c_link_processs_num_bufs(controller->get_acl_buffer_count_classic());
l2c_link_process_num_bufs(controller->get_acl_buffer_count_classic());
#if BTM_SCO_HCI_INCLUDED == TRUE
btm_sco_process_num_bufs(controller->get_sco_buffer_count());
#endif
@@ -297,29 +308,29 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
case HCI_EXT_FEATURES_PAGE_0:
/* Create ACL supported packet types mask */
btm_cb.btm_acl_pkt_types_supported = (BTM_ACL_PKT_TYPES_MASK_DH1 +
btm_cb.btm_acl_pkt_types_supported = (BTM_ACL_PKT_TYPES_MASK_DH1 |
BTM_ACL_PKT_TYPES_MASK_DM1);
if (HCI_3_SLOT_PACKETS_SUPPORTED(p_features)) {
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH3 +
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH3 |
BTM_ACL_PKT_TYPES_MASK_DM3);
}
if (HCI_5_SLOT_PACKETS_SUPPORTED(p_features)) {
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH5 +
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH5 |
BTM_ACL_PKT_TYPES_MASK_DM5);
}
/* Add in EDR related ACL types */
if (!HCI_EDR_ACL_2MPS_SUPPORTED(p_features)) {
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 +
BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 +
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 |
BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 |
BTM_ACL_PKT_TYPES_MASK_NO_2_DH5);
}
if (!HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) {
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 +
BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 +
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 |
BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 |
BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
}
@@ -327,12 +338,12 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
if (HCI_EDR_ACL_2MPS_SUPPORTED(p_features) ||
HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) {
if (!HCI_3_SLOT_EDR_ACL_SUPPORTED(p_features)) {
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 +
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 |
BTM_ACL_PKT_TYPES_MASK_NO_3_DH3);
}
if (!HCI_5_SLOT_EDR_ACL_SUPPORTED(p_features)) {
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 +
btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 |
BTM_ACL_PKT_TYPES_MASK_NO_3_DH5);
}
}
@@ -378,7 +389,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_NO_2_EV5;
}
} else {
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 +
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 |
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5);
}
@@ -387,7 +398,7 @@ static void btm_decode_ext_features_page (UINT8 page_number, const BD_FEATURES p
btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_NO_3_EV5;
}
} else {
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 +
btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5);
}
}
@@ -635,8 +646,6 @@ tBTM_STATUS BTM_SetDeviceClass (DEV_CLASS dev_class)
return (BTM_SUCCESS);
}
memcpy (btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN);
if (!controller_get_interface()->get_is_ready()) {
return (BTM_DEV_RESET);
}
@@ -645,6 +654,8 @@ tBTM_STATUS BTM_SetDeviceClass (DEV_CLASS dev_class)
return (BTM_NO_RESOURCES);
}
memcpy (btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN);
return (BTM_SUCCESS);
}
@@ -691,7 +702,7 @@ UINT8 *BTM_ReadLocalFeatures (void)
** save the pointer to the function that is return and
** call it when processing of the event is complete
**
** Returns status of the operation
** Returns original device status callback
**
*******************************************************************************/
tBTM_DEV_STATUS_CB *BTM_RegisterForDeviceStatusNotif (tBTM_DEV_STATUS_CB *p_cb)
@@ -725,6 +736,10 @@ tBTM_STATUS BTM_VendorSpecificCommand(UINT16 opcode, UINT8 param_len,
BTM_TRACE_EVENT ("BTM: BTM_VendorSpecificCommand: Opcode: 0x%04X, ParamLen: %i.",
opcode, param_len);
if ((param_len > 0) && (p_param_buf == NULL)) {
return BTM_ILLEGAL_VALUE;
}
/* Allocate a buffer to hold HCI command plus the callback function */
if ((p_buf = HCI_GET_CMD_BUF(param_len)) != NULL) {
/* Send the HCI command (opcode will be OR'd with HCI_GRP_VENDOR_SPECIFIC) */
@@ -769,51 +784,68 @@ tBTM_STATUS BTM_ConfigCoexStatus(tBTM_COEX_OPERATION op, tBTM_COEX_TYPE type, UI
void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
tBTM_CMPL_CB *p_vsc_cplt_cback)
{
UINT8 *p_orig = p;
UINT16 remain_len = evt_len;
#if (BLE_INCLUDED == TRUE)
switch(opcode) {
case HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST: {
#if ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE))
uint8_t subcode, status; uint32_t length;
STREAM_TO_UINT8(status, p);
STREAM_TO_UINT8(subcode, p);
STREAM_TO_UINT32(length, p);
if (remain_len >= 6) {
uint8_t subcode, status; uint32_t length;
STREAM_TO_UINT8(status, p);
STREAM_TO_UINT8(subcode, p);
STREAM_TO_UINT32(length, p);
remain_len -= 6;
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
cb_params.exception_list_up.status = status;
cb_params.exception_list_up.subcode = subcode;
cb_params.exception_list_up.length = length;
cb_params.exception_list_up.device_info = p;
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_EXCEPTION_LIST_UPDATE_EVT, &cb_params);
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
cb_params.exception_list_up.status = status;
cb_params.exception_list_up.subcode = subcode;
cb_params.exception_list_up.length = length;
cb_params.exception_list_up.device_info = p;
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_EXCEPTION_LIST_UPDATE_EVT, &cb_params);
}
#endif // ((BLE_42_SCAN_EN == TRUE) || (BLE_50_EXTEND_SCAN_EN == TRUE))
break;
}
case HCI_VENDOR_BLE_CLEAR_ADV: {
uint8_t status;
STREAM_TO_UINT8(status, p);
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_CLEAR_ADV_COMPLETE_EVT, &cb_params);
if (remain_len >= 1) {
uint8_t status;
STREAM_TO_UINT8(status, p);
remain_len -= 1;
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_CLEAR_ADV_COMPLETE_EVT, &cb_params);
}
break;
}
case HCI_VENDOR_BLE_SET_CSA_SUPPORT: {
uint8_t status;
STREAM_TO_UINT8(status, p);
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_CSA_SUPPORT_COMPLETE_EVT, &cb_params);
if (remain_len >= 1) {
uint8_t status;
STREAM_TO_UINT8(status, p);
remain_len -= 1;
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_CSA_SUPPORT_COMPLETE_EVT, &cb_params);
}
break;
}
case HCI_VENDOR_BLE_SET_EVT_MASK: {
uint8_t status;
STREAM_TO_UINT8(status, p);
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_VENDOR_EVT_MASK_COMPLETE_EVT, &cb_params);
if (remain_len >= 1) {
uint8_t status;
STREAM_TO_UINT8(status, p);
remain_len -= 1;
tBTM_BLE_LEGACY_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_LegacyBleCallbackTrigger(BTM_BLE_LEGACY_GAP_SET_VENDOR_EVT_MASK_COMPLETE_EVT, &cb_params);
}
break;
}
default:
break;
}
#else
UNUSED(remain_len);
#endif // (BLE_INCLUDED == TRUE)
tBTM_VSC_CMPL vcs_cplt_params;
@@ -822,7 +854,7 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
/* Pass parameters to the callback function */
vcs_cplt_params.opcode = opcode; /* Number of bytes in return info */
vcs_cplt_params.param_len = evt_len; /* Number of bytes in return info */
vcs_cplt_params.p_param_buf = p;
vcs_cplt_params.p_param_buf = p_orig;
(*p_vsc_cplt_cback)(&vcs_cplt_params); /* Call the VSC complete callback function */
}
@@ -897,16 +929,29 @@ void btm_vendor_specific_evt (UINT8 *p, UINT8 evt_len)
#if (CLASSIC_BT_INCLUDED == TRUE)
UINT8 sub_event;
UINT8 remain_len = evt_len;
UINT8 *p_evt = p;
if (remain_len < 1) {
goto exit;
}
STREAM_TO_UINT8(sub_event, p_evt);
remain_len -= 1;
/* Check in subevent if authentication is through Legacy Authentication. */
if (sub_event == HCI_VENDOR_LEGACY_REM_AUTH_EVT_SUBCODE) {
if (remain_len < 2) {
goto exit;
}
UINT16 hci_handle;
STREAM_TO_UINT16(hci_handle, p_evt);
remain_len -= 2;
btm_sec_handle_remote_legacy_auth_cmp(hci_handle);
}
exit:
#endif /// (CLASSIC_BT_INCLUDED == TRUE)
for (i = 0; i < BTM_MAX_VSE_CALLBACKS; i++) {
if (btm_cb.devcb.p_vend_spec_cb[i]) {
(*btm_cb.devcb.p_vend_spec_cb[i])(evt_len, p);
@@ -932,16 +977,22 @@ tBTM_STATUS BTM_WritePageTimeout(UINT16 timeout, tBTM_CMPL_CB *p_cb)
{
BTM_TRACE_EVENT ("BTM: BTM_WritePageTimeout: Timeout: %d.", timeout);
if (timeout >= HCI_MIN_PAGE_TOUT) {
btm_cb.btm_inq_vars.page_timeout = timeout;
if (btm_cb.devcb.p_page_to_set_cmpl_cb) {
return BTM_BUSY;
}
btm_cb.devcb.p_page_to_set_cmpl_cb = p_cb;
/* Send the HCI command */
if (!btsnd_hcic_write_page_tout (timeout)) {
btm_cb.devcb.p_page_to_set_cmpl_cb = NULL;
return (BTM_NO_RESOURCES);
}
if (timeout >= HCI_MIN_PAGE_TOUT) {
btm_cb.btm_inq_vars.page_timeout = timeout;
}
if (p_cb) {
btu_start_timer(&btm_cb.devcb.page_timeout_set_timer, BTU_TTYPE_BTM_SET_PAGE_TO, BTM_DEV_REPLY_TIMEOUT);
}
@@ -981,6 +1032,14 @@ tBTM_STATUS BTM_SetMinEncKeySize(UINT8 key_size, tBTM_CMPL_CB *p_cb)
status = BTM_SUCCESS;
}
#endif
if (status != BTM_SUCCESS) {
if (p_cb) {
btm_cb.devcb.p_set_min_enc_key_size_cmpl_cb = NULL;
tBTM_SET_MIN_ENC_KEY_SIZE_RESULTS results = {0};
results.hci_status = HCI_ERR_MEMORY_FULL;
(*p_cb)(&results);
}
}
return status;
}
#endif
@@ -1065,7 +1124,7 @@ tBTM_STATUS BTM_ReadPageTimeout(tBTM_CMPL_CB *p_cb)
BTM_TRACE_EVENT ("BTM: BTM_ReadPageTimeout");
/* Get the page timeout */
tBTM_GET_PAGE_TIMEOUT_RESULTS results;
tBTM_GET_PAGE_TIMEOUT_RESULTS results = {0};
if (p_cb) {
results.hci_status = HCI_SUCCESS;
@@ -1142,6 +1201,7 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb)
/* Send the HCI command */
btm_cb.devcb.p_stored_link_key_cmpl_cb = p_cb;
if (!btsnd_hcic_delete_stored_key (bd_addr, delete_all_flag)) {
btm_cb.devcb.p_stored_link_key_cmpl_cb = NULL;
return (BTM_NO_RESOURCES);
} else {
return (BTM_SUCCESS);
@@ -1161,7 +1221,7 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB *p_cb)
void btm_delete_stored_link_key_complete (UINT8 *p, UINT16 evt_len)
{
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_stored_link_key_cmpl_cb;
tBTM_DELETE_STORED_LINK_KEY_COMPLETE result;
tBTM_DELETE_STORED_LINK_KEY_COMPLETE result = {0};
/* If there was a callback registered for read stored link key, call it */
btm_cb.devcb.p_stored_link_key_cmpl_cb = NULL;
@@ -1232,6 +1292,7 @@ tBTM_STATUS BTM_SetAfhChannels (AFH_CHANNELS channels, tBTM_CMPL_CB *p_afh_chann
btm_cb.devcb.p_afh_channels_cmpl_cb = p_afh_channels_cmpl_cback;
if (!btsnd_hcic_set_afh_channels (channels)) {
btm_cb.devcb.p_afh_channels_cmpl_cb = NULL;
return (BTM_NO_RESOURCES);
}
@@ -213,11 +213,11 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter
memcpy (temp_lap[0], limited_inq_lap, LAP_LEN);
memcpy (temp_lap[1], general_inq_lap, LAP_LEN);
if (!btsnd_hcic_write_cur_iac_lap (2, (LAP * const) temp_lap)) {
if (!btsnd_hcic_write_cur_iac_lap (2, temp_lap)) {
return (BTM_NO_RESOURCES); /* Cannot continue */
}
} else {
if (!btsnd_hcic_write_cur_iac_lap (1, (LAP * const) &general_inq_lap)) {
if (!btsnd_hcic_write_cur_iac_lap (1, &general_inq_lap)) {
return (BTM_NO_RESOURCES); /* Cannot continue */
}
}
@@ -290,7 +290,8 @@ tBTM_STATUS BTM_SetInquiryScanType (UINT16 scan_type)
}
/* whatever app wants if device is not 1.2 scan type should be STANDARD */
if (!controller_get_interface()->supports_interlaced_inquiry_scan()) {
if ((scan_type == BTM_SCAN_TYPE_INTERLACED) &&
!controller_get_interface()->supports_interlaced_inquiry_scan()) {
return (BTM_MODE_UNSUPPORTED);
}
@@ -329,7 +330,8 @@ tBTM_STATUS BTM_SetPageScanType (UINT16 scan_type)
}
/* whatever app wants if device is not 1.2 scan type should be STANDARD */
if (!controller_get_interface()->supports_interlaced_inquiry_scan()) {
if ((scan_type == BTM_SCAN_TYPE_INTERLACED) &&
!controller_get_interface()->supports_interlaced_page_scan()) {
return (BTM_MODE_UNSUPPORTED);
}
@@ -368,6 +370,10 @@ tBTM_STATUS BTM_SetInquiryMode (UINT8 mode)
{
const controller_t *controller = controller_get_interface();
BTM_TRACE_API ("BTM_SetInquiryMode\n");
if (!BTM_IsDeviceUp()) {
return (BTM_WRONG_MODE);
}
if (mode == BTM_INQ_RESULT_STANDARD) {
/* mandatory mode */
} else if (mode == BTM_INQ_RESULT_WITH_RSSI) {
@@ -382,10 +388,6 @@ tBTM_STATUS BTM_SetInquiryMode (UINT8 mode)
return (BTM_ILLEGAL_VALUE);
}
if (!BTM_IsDeviceUp()) {
return (BTM_WRONG_MODE);
}
if (!btsnd_hcic_write_inquiry_mode (mode)) {
return (BTM_NO_RESOURCES);
}
@@ -519,7 +521,7 @@ tBTM_STATUS BTM_SetPeriodicInquiryMode (tBTM_INQ_PARMS *p_inqparms, UINT16 max_d
/* If set filter command is not successful reset the state */
p_inq->p_inq_results_cb = NULL;
p_inq->state = BTM_INQ_INACTIVE_STATE;
p_inq->inq_active = BTM_INQUIRY_INACTIVE;
}
return (status);
@@ -631,11 +633,11 @@ tBTM_STATUS BTM_SetConnectability (UINT16 page_mode, UINT16 window, UINT16 inter
if ((window != p_inq->page_scan_window) ||
(interval != p_inq->page_scan_period)) {
p_inq->page_scan_window = window;
p_inq->page_scan_period = interval;
if (!btsnd_hcic_write_pagescan_cfg (interval, window)) {
return (BTM_NO_RESOURCES);
}
p_inq->page_scan_window = window;
p_inq->page_scan_period = interval;
}
/* Keep the inquiry scan as previouosly set */
@@ -804,10 +806,8 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p
/* Only one active inquiry is allowed in this implementation.
Also do not allow an inquiry if the inquiry filter is being updated */
if (p_inq->inq_active || p_inq->inqfilt_active) {
{
return (BTM_BUSY);
BTM_TRACE_API("BTM_StartInquiry: return BUSY\n");
}
BTM_TRACE_API("BTM_StartInquiry: return BUSY\n");
return (BTM_BUSY);
} else {
p_inq->scan_type = INQ_GENERAL;
}
@@ -911,8 +911,9 @@ tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb
/* Use the remote device's clock offset if it is in the local inquiry database */
if ((p_i = btm_inq_db_find (remote_bda)) != NULL) {
p_cur = &p_i->inq_info;
} else {
BTM_TRACE_API ("no device found in inquiry db\n");
}
BTM_TRACE_API ("no device found in inquiry db\n");
#if (BLE_INCLUDED == TRUE)
if (transport == BT_TRANSPORT_LE) {
@@ -1049,7 +1050,7 @@ tBTM_INQ_INFO *BTM_InqDbNext (tBTM_INQ_INFO *p_cur)
}
}
/* If here, more entries found */
/* If here, no entries found */
return ((tBTM_INQ_INFO *)NULL);
} else {
return (BTM_InqDbFirst());
@@ -1194,9 +1195,9 @@ tBTM_STATUS BTM_WriteInquiryTxPower(INT8 tx_power, tBTM_CMPL_CB *p_cb)
*******************************************************************************/
void btm_inq_db_reset (void)
{
tBTM_REMOTE_DEV_NAME rem_name;
tBTM_REMOTE_DEV_NAME rem_name = {0};
tBTM_INQUIRY_CMPL cmpl_param = {0};
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
UINT8 num_responses;
UINT8 temp_inq_active;
tBTM_STATUS status;
@@ -1212,16 +1213,18 @@ void btm_inq_db_reset (void)
if (temp_inq_active == BTM_LIMITED_INQUIRY_ACTIVE ||
temp_inq_active == BTM_GENERAL_INQUIRY_ACTIVE) {
if (p_inq->p_inq_cmpl_cb) {
num_responses = 0;
(*p_inq->p_inq_cmpl_cb)(&num_responses);
cmpl_param.status = BTM_SUCCESS;
cmpl_param.num_resp = 0;
(*p_inq->p_inq_cmpl_cb)(&cmpl_param);
}
}
}
/* Cancel a remote name request if active, and notify the caller (if waiting) */
if (p_inq->remname_active ) {
if (p_inq->remname_active) {
btu_stop_timer (&p_inq->rmt_name_timer_ent);
p_inq->remname_active = FALSE;
memcpy(rem_name.bd_addr, p_inq->remname_bda, BD_ADDR_LEN);
memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
if (p_inq->p_remname_cmpl_cb) {
@@ -1560,13 +1563,12 @@ static tBTM_STATUS btm_set_inq_event_filter (UINT8 filter_cond_type,
return (BTM_ILLEGAL_VALUE); /* Bad parameter was passed in */
}
btm_cb.btm_inq_vars.inqfilt_active = TRUE;
/* Filter the inquiry results for the specified condition type and value */
if (btsnd_hcic_set_event_filter(HCI_FILTER_INQUIRY_RESULT, filter_cond_type,
p_cond, condition_length))
{
btm_cb.btm_inq_vars.inqfilt_active = TRUE;
return (BTM_CMD_STARTED);
} else {
return (BTM_NO_RESOURCES);
@@ -1734,7 +1736,7 @@ static void btm_initiate_inquiry (tBTM_INQUIRY_VAR_ST *p_inq)
** Returns void
**
*******************************************************************************/
void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
void btm_process_inq_results (UINT8 *p, UINT16 evt_len, UINT8 inq_res_mode)
{
UINT8 num_resp, xx;
BD_ADDR bda;
@@ -1752,6 +1754,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
DEV_CLASS dc;
UINT16 clock_offset;
UINT8 *p_eir_data = NULL;
UINT16 remain_len = evt_len;
#if (BTM_INQ_DEBUG == TRUE)
BTM_TRACE_DEBUG ("btm_process_inq_results inq_active:0x%x state:%d inqfilt_active:%d inq_res_mode=%d\n",
@@ -1762,23 +1765,45 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
return;
}
if (remain_len < 1) {
return;
}
STREAM_TO_UINT8 (num_resp, p);
remain_len -= 1;
for (xx = 0; xx < num_resp; xx++) {
update = FALSE;
is_new = TRUE;
if (remain_len < 8) {
return;
}
/* Extract inquiry results */
STREAM_TO_BDADDR (bda, p);
STREAM_TO_UINT8 (page_scan_rep_mode, p);
STREAM_TO_UINT8 (page_scan_per_mode, p);
remain_len -= 8;
if (inq_res_mode == BTM_INQ_RESULT_STANDARD) {
if (remain_len < 1) {
return;
}
STREAM_TO_UINT8(page_scan_mode, p);
remain_len -= 1;
}
if (remain_len < 5) {
return;
}
STREAM_TO_DEVCLASS (dc, p);
STREAM_TO_UINT16 (clock_offset, p);
remain_len -= 5;
if (inq_res_mode != BTM_INQ_RESULT_STANDARD) {
if (remain_len < 1) {
return;
}
STREAM_TO_UINT8(rssi, p);
remain_len -= 1;
}
p_i = btm_inq_db_find (bda);
@@ -2101,13 +2126,6 @@ tBTM_STATUS btm_initiate_rem_name (BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur,
if (p_inq->remname_active) {
return (BTM_BUSY);
} else {
/* If there is no remote name request running,call the callback function and start timer */
p_inq->p_remname_cmpl_cb = p_cb;
memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
btu_start_timer (&p_inq->rmt_name_timer_ent,
BTU_TTYPE_BTM_RMT_NAME,
timeout);
/* If the database entry exists for the device, use its clock offset */
if (p_cur) {
cmd_ok = btsnd_hcic_rmt_name_req (remote_bda,
@@ -2120,6 +2138,10 @@ tBTM_STATUS btm_initiate_rem_name (BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur,
HCI_MANDATARY_PAGE_SCAN_MODE, 0);
}
if (cmd_ok) {
/* If there is no remote name request running,call the callback function and start timer */
p_inq->p_remname_cmpl_cb = p_cb;
memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
btu_start_timer (&p_inq->rmt_name_timer_ent, BTU_TTYPE_BTM_RMT_NAME, timeout);
p_inq->remname_active = TRUE;
return BTM_CMD_STARTED;
} else {
@@ -2144,7 +2166,7 @@ tBTM_STATUS btm_initiate_rem_name (BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur,
*******************************************************************************/
void btm_process_remote_name (BD_ADDR bda, BD_NAME bdn, UINT16 evt_len, UINT8 hci_status)
{
tBTM_REMOTE_DEV_NAME rem_name;
tBTM_REMOTE_DEV_NAME rem_name = {0};
tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
tBTM_CMPL_CB *p_cb = p_inq->p_remname_cmpl_cb;
UINT8 *p_n1;
@@ -2250,36 +2272,36 @@ void btm_inq_rmt_name_failed (void)
** Returns void
**
*******************************************************************************/
void btm_read_iscan_tx_power_complete(UINT8 *p)
void btm_read_iscan_tx_power_complete(UINT8 *p, UINT16 evt_len)
{
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_read_iscan_txpwer_cmpl_cb;
tBTM_READ_TX_PWR_LVL_RESULTS results;
memset(&results, 0, sizeof(results));
results.type = BTM_TX_PWR_LVL_ISCAN;
results.status = BTM_ERR_PROCESSING;
btu_stop_timer (&btm_cb.devcb.read_iscan_txpwer_timer);
/* If there was a callback registered for read inq tx power, call it */
btm_cb.devcb.p_read_iscan_txpwer_cmpl_cb = NULL;
if (p_cb) {
if (p) {
STREAM_TO_UINT8 (results.hci_status, p);
if (!p_cb) {
return;
}
if (p) {
if (evt_len >= 2) {
STREAM_TO_UINT8 (results.hci_status, p);
if (results.hci_status == HCI_SUCCESS) {
results.status = BTM_SUCCESS;
STREAM_TO_UINT8 (results.tx_power, p);
BTM_TRACE_EVENT ("BTM INQ TX POWER Complete: tx_power %d, hci status 0x%02x\n",
results.tx_power, results.hci_status);
} else {
results.status = BTM_ERR_PROCESSING;
}
} else {
results.status = BTM_ERR_PROCESSING;
}
(*p_cb)(&results);
}
(*p_cb)(&results);
}
/*******************************************************************************
@@ -2291,26 +2313,31 @@ void btm_read_iscan_tx_power_complete(UINT8 *p)
** Returns void
**
*******************************************************************************/
void btm_write_inq_tx_power_complete(UINT8 *p)
void btm_write_inq_tx_power_complete(UINT8 *p, UINT16 evt_len)
{
tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_write_inq_txpwer_cmpl_cb;
tBTM_WRITE_TX_PWR_LVL_RESULTS results;
tBTM_WRITE_TX_PWR_LVL_RESULTS results = {0};
memset(&results, 0, sizeof(results));
results.type = BTM_TX_PWR_LVL_INQ;
results.status = BTM_ERR_PROCESSING;
btu_stop_timer(&btm_cb.devcb.write_inq_txpwer_timer);
btm_cb.devcb.p_write_inq_txpwer_cmpl_cb = NULL;
if (p_cb) {
if (p) {
STREAM_TO_UINT8(results.hci_status, p);
results.status = (results.hci_status == HCI_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING;
} else {
results.status = BTM_ERR_PROCESSING;
}
(*p_cb)(&results);
if (!p_cb) {
return;
}
if (p) {
if (evt_len >= 1) {
STREAM_TO_UINT8(results.hci_status, p);
if (results.hci_status == HCI_SUCCESS) {
results.status = BTM_SUCCESS;
}
}
}
(*p_cb)(&results);
}
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
@@ -2326,19 +2353,25 @@ void btm_write_inq_tx_power_complete(UINT8 *p)
**
** Returns BTM_SUCCESS - if successful
** BTM_MODE_UNSUPPORTED - if local device cannot support it
** BTM_NO_RESOURCES - if command failed to issue
**
*******************************************************************************/
tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff, BOOLEAN fec_required)
{
tBTM_STATUS status = BTM_SUCCESS;
if (controller_get_interface()->supports_extended_inquiry_response()) {
BTM_TRACE_API("Write Extended Inquiry Response to controller\n");
btsnd_hcic_write_ext_inquiry_response (p_buff, fec_required);
osi_free(p_buff);
return BTM_SUCCESS;
if (!btsnd_hcic_write_ext_inquiry_response (p_buff, fec_required)) {
status = BTM_NO_RESOURCES;
}
} else {
osi_free(p_buff);
return BTM_MODE_UNSUPPORTED;
status = BTM_MODE_UNSUPPORTED;
}
if (p_buff) {
osi_free(p_buff);
p_buff = NULL;
}
return status;
}
/*******************************************************************************
@@ -2357,18 +2390,12 @@ tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff, BOOLEAN fec_required)
UINT8 *BTM_CheckEirData( UINT8 *p_eir, UINT8 type, UINT8 *p_length )
{
UINT8 *p = p_eir;
UINT8 *p_data_length = p_length;
UINT8 temp_length = 0;
UINT8 *p_data_length = (p_length ? p_length : &temp_length);
UINT8 length;
UINT8 eir_type;
BTM_TRACE_API("BTM_CheckEirData type=0x%02X\n", type);
if (!p_length) {
if ((p_data_length = (UINT8 *)osi_malloc(sizeof(UINT8))) == NULL) {
BTM_TRACE_ERROR("%s: Memory allocation failed.", __func__);
return NULL;
}
}
STREAM_TO_UINT8(length, p);
while ( length ) {
STREAM_TO_UINT8(eir_type, p);
@@ -2398,9 +2425,6 @@ UINT8 *BTM_CheckEirData( UINT8 *p_eir, UINT8 type, UINT8 *p_length )
p = NULL;
exit:
if (!p_length) {
osi_free(p_data_length);
}
return p;
}
@@ -25,6 +25,7 @@
#include "stack/bt_types.h"
#include "common/bt_target.h"
#include <assert.h>
#include <string.h>
#include "btm_int.h"
#include "osi/allocator.h"
@@ -61,14 +62,17 @@ void btm_init (void)
{
#if BTM_DYNAMIC_MEMORY
btm_cb_ptr = (tBTM_CB *)osi_malloc(sizeof(tBTM_CB));
assert(btm_cb_ptr != NULL);
#endif /* #if BTM_DYNAMIC_MEMORY */
/* All fields are cleared; nonzero fields are reinitialized in appropriate function */
memset(&btm_cb, 0, sizeof(tBTM_CB));
#if (CLASSIC_BT_INCLUDED == TRUE)
btm_cb.page_queue = fixed_queue_new(QUEUE_SIZE_MAX);
assert(btm_cb.page_queue != NULL);
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
#if (SMP_INCLUDED == TRUE)
btm_cb.sec_pending_q = fixed_queue_new(QUEUE_SIZE_MAX);
assert(btm_cb.sec_pending_q != NULL);
#endif // (SMP_INCLUDED == TRUE)
#if defined(BTM_INITIAL_TRACE_LEVEL)
btm_cb.trace_level = BTM_INITIAL_TRACE_LEVEL;
@@ -114,6 +118,11 @@ void btm_init (void)
*******************************************************************************/
void btm_free(void)
{
#if BTM_DYNAMIC_MEMORY
if (!btm_cb_ptr) {
return;
}
#endif
#if (CLASSIC_BT_INCLUDED == TRUE)
fixed_queue_free(btm_cb.page_queue, osi_free_func);
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
@@ -125,6 +134,7 @@ void btm_free(void)
#if BTM_SCO_INCLUDED == TRUE
btm_sco_free();
#endif
FREE_AND_RESET(btm_cb.btm_inq_vars.p_bd_db);
#if BTM_DYNAMIC_MEMORY
FREE_AND_RESET(btm_cb_ptr);
#endif
+51 -24
View File
@@ -195,6 +195,19 @@ tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p
/* take out the force bit */
mode = p_mode->mode & ~BTM_PM_MD_FORCE;
switch (mode) {
case BTM_PM_MD_ACTIVE:
case BTM_PM_MD_HOLD:
case BTM_PM_MD_SNIFF:
case BTM_PM_MD_PARK: {
break;
}
default: {
return BTM_ILLEGAL_VALUE;
break;
}
}
p_acl_cb = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
if (p_acl_cb == NULL){
return BTM_UNKNOWN_ADDR;
@@ -321,6 +334,9 @@ tBTM_STATUS BTM_SetSsrParams (BD_ADDR remote_bda, UINT16 max_lat,
return (BTM_UNKNOWN_ADDR);
}
p_cb = p_acl_cb->p_pm_mode_db;
if (!p_cb) {
return BTM_NO_RESOURCES;
}
if (BTM_PM_STS_ACTIVE == p_cb->state ||
BTM_PM_STS_SNIFF == p_cb->state) {
@@ -352,6 +368,7 @@ tBTM_STATUS BTM_SetSsrParams (BD_ADDR remote_bda, UINT16 max_lat,
void btm_pm_reset(void)
{
int xx;
tACL_CONN *p_acl_cb = NULL;
tBTM_PM_STATUS_CBACK *cb = NULL;
/* clear the pending request for application */
@@ -367,7 +384,11 @@ void btm_pm_reset(void)
}
if (cb != NULL && btm_cb.pm_pend_link_hdl != BTM_INVALID_HANDLE) {
(*cb)((btm_handle_to_acl(btm_cb.pm_pend_link_hdl))->remote_addr, BTM_PM_STS_ERROR, BTM_DEV_RESET, 0);
p_acl_cb = btm_handle_to_acl(btm_cb.pm_pend_link_hdl);
if (p_acl_cb != NULL) {
/* safe to use remote_addr */
(*cb)(p_acl_cb->remote_addr, BTM_PM_STS_ERROR, BTM_DEV_RESET, 0);
}
}
/* no command pending */
@@ -674,15 +695,22 @@ static void btm_pm_check_stored(void)
tACL_CONN *p_acl_cb = NULL;
list_node_t *p_node = NULL;
for (p_node = list_begin(btm_cb.p_acl_db_list); p_node; p_node = list_next(p_node)) {
p_acl_cb = list_node(p_node);
p_acl_cb = list_node(p_node);
if (!p_acl_cb || !p_acl_cb->p_pm_mode_db) {
continue;
}
if (p_acl_cb->p_pm_mode_db->state & BTM_PM_STORED_MASK) {
tBTM_PM_STATE old_state = p_acl_cb->p_pm_mode_db->state;
p_acl_cb->p_pm_mode_db->state &= ~BTM_PM_STORED_MASK;
BTM_TRACE_DEBUG( "btm_pm_check_stored :%d", p_acl_cb->hci_handle);
btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, p_acl_cb->hci_handle, NULL);
break;
tBTM_STATUS status = btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, p_acl_cb->hci_handle, NULL);
if (status == BTM_CMD_STARTED) {
break;
} else if (status == BTM_NO_RESOURCES) {
p_acl_cb->p_pm_mode_db->state = old_state;
}
}
}
}
@@ -757,9 +785,9 @@ void btm_pm_proc_cmd_status(UINT8 status)
*******************************************************************************/
void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, UINT16 interval)
{
int i;
tACL_CONN *p;
tBTM_PM_MCB *p_cb = NULL;
int yy;
tBTM_PM_STATE old_state;
tL2C_LCB *p_lcb;
@@ -768,9 +796,12 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U
if (!p) {
return;
}
/* update control block */
p_cb = p->p_pm_mode_db;
if (!p_cb) {
return;
}
old_state = p_cb->state;
p_cb->state = mode;
p_cb->interval = interval;
@@ -787,39 +818,32 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U
}
/* notify registered parties */
for (yy = 0; yy <= BTM_MAX_PM_RECORDS; yy++) {
for (i = 0; i <= BTM_MAX_PM_RECORDS; i++) {
/* set req_mode HOLD mode->ACTIVE */
if ( (mode == BTM_PM_MD_ACTIVE) && (p_cb->req_mode[yy].mode == BTM_PM_MD_HOLD) ) {
p_cb->req_mode[yy].mode = BTM_PM_MD_ACTIVE;
if ( (mode == BTM_PM_MD_ACTIVE) && (p_cb->req_mode[i].mode == BTM_PM_MD_HOLD) ) {
p_cb->req_mode[i].mode = BTM_PM_MD_ACTIVE;
}
}
/* new request has been made. - post a message to BTU task */
if (old_state & BTM_PM_STORED_MASK) {
#if BTM_PM_DEBUG == TRUE
BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending stored req:%d", xx);
BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending stored req");
#endif // BTM_PM_DEBUG
btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, hci_handle, NULL);
} else {
list_node_t *p_node = NULL;
for (p_node =(list_begin(btm_cb.p_pm_mode_db_list)); p_node; p_node = (list_next(p_node))) {
p_cb = (tBTM_PM_MCB *)list_node(p_node);
if (p_cb->chg_ind == TRUE) {
if (p_cb->chg_ind == TRUE) {
#if BTM_PM_DEBUG == TRUE
BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending PM req :%d", zz);
BTM_TRACE_DEBUG( "btm_pm_proc_mode_change: Sending PM req");
#endif // BTM_PM_DEBUG
btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, hci_handle, NULL);
break;
}
btm_pm_snd_md_req(BTM_PM_SET_ONLY_ID, hci_handle, NULL);
}
}
/* notify registered parties */
for (yy = 0; yy < BTM_MAX_PM_RECORDS; yy++) {
if (btm_cb.pm_reg_db[yy].mask & BTM_PM_REG_NOTIF) {
(*btm_cb.pm_reg_db[yy].cback)( p->remote_addr, mode, interval, hci_status);
for (i = 0; i < BTM_MAX_PM_RECORDS; i++) {
if (btm_cb.pm_reg_db[i].mask & BTM_PM_REG_NOTIF) {
(*btm_cb.pm_reg_db[i].cback)( p->remote_addr, mode, interval, hci_status);
}
}
#if (CLASSIC_BT_INCLUDED == TRUE)
@@ -861,6 +885,9 @@ void btm_pm_proc_ssr_evt (UINT8 *p, UINT16 evt_len)
return;
}
p_cb = p_acl->p_pm_mode_db;
if (!p_cb) {
return;
}
if (p_cb->interval == max_rx_lat) {
/* using legacy sniff */
use_ssr = FALSE;
+177 -71
View File
@@ -135,7 +135,7 @@ static const BOOLEAN btm_sec_io_map [BTM_IO_CAP_MAX][BTM_IO_CAP_MAX] = {
#if (SMP_INCLUDED == TRUE)
static BOOLEAN btm_dev_authenticated (tBTM_SEC_DEV_REC *p_dev_rec)
{
if (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) {
if (p_dev_rec && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED)) {
return (TRUE);
}
return (FALSE);
@@ -291,6 +291,12 @@ BOOLEAN BTM_SecAddRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback)
{
int i;
for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
if (btm_cb.p_rmt_name_callback[i] == p_callback) {
return FALSE;
}
}
for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
if (btm_cb.p_rmt_name_callback[i] == NULL) {
btm_cb.p_rmt_name_callback[i] = p_callback;
@@ -316,6 +322,10 @@ BOOLEAN BTM_SecDeleteRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback)
{
int i;
if (p_callback == NULL) {
return FALSE;
}
for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
if (btm_cb.p_rmt_name_callback[i] == p_callback) {
btm_cb.p_rmt_name_callback[i] = NULL;
@@ -339,6 +349,10 @@ BOOLEAN BTM_GetSecurityFlags (BD_ADDR bd_addr, UINT8 *p_sec_flags)
{
tBTM_SEC_DEV_REC *p_dev_rec;
if (!bd_addr || !p_sec_flags) {
return FALSE;
}
if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL) {
*p_sec_flags = (UINT8) p_dev_rec->sec_flags;
return (TRUE);
@@ -366,6 +380,10 @@ BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, UINT8 *p_sec_flags,
{
tBTM_SEC_DEV_REC *p_dev_rec;
if (!bd_addr || !p_sec_flags) {
return FALSE;
}
if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL) {
if (transport == BT_TRANSPORT_BR_EDR) {
*p_sec_flags = (UINT8) p_dev_rec->sec_flags;
@@ -396,8 +414,8 @@ BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, UINT8 *p_sec_flags,
*******************************************************************************/
void BTM_SetPinType (UINT8 pin_type, PIN_CODE pin_code, UINT8 pin_code_len)
{
BTM_TRACE_API ("BTM_SetPinType: pin type %d [variable-0, fixed-1], code %s, length %d\n",
pin_type, (char *) pin_code, pin_code_len);
BTM_TRACE_API ("BTM_SetPinType: pin type %d [variable-0, fixed-1], code %.*s, length %d\n",
pin_type, pin_code_len, (char *) pin_code, pin_code_len);
/* If device is not up security mode will be set as a part of startup */
if ( (btm_cb.cfg.pin_type != pin_type)
@@ -757,6 +775,9 @@ UINT8 BTM_SecClrService (UINT8 service_id)
#if (L2CAP_UCD_INCLUDED == TRUE)
p_srec->ucd_security_flags = 0;
#endif
if (btm_cb.p_out_serv == p_srec) {
btm_cb.p_out_serv = NULL;
}
num_freed++;
}
}
@@ -793,6 +814,9 @@ UINT8 btm_sec_clr_service_by_psm (UINT16 psm)
if ((p_srec->security_flags & BTM_SEC_IN_USE) && (p_srec->psm == psm) ) {
BTM_TRACE_API("BTM_SEC_CLR[%d]: id %d\n", i, p_srec->service_id);
p_srec->security_flags = 0;
#if (L2CAP_UCD_INCLUDED == TRUE)
p_srec->ucd_security_flags = 0;
#endif
num_freed++;
}
}
@@ -883,12 +907,11 @@ void BTM_PINCodeReply (BD_ADDR bd_addr, UINT8 res, UINT8 pin_len, UINT8 *p_pin,
/* use BTM_PAIR_STATE_WAIT_AUTH_COMPLETE to report authentication failed event */
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
btsnd_hcic_pin_code_neg_reply (bd_addr);
} else {
p_dev_rec->security_required = BTM_SEC_NONE;
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
}
btsnd_hcic_pin_code_neg_reply (bd_addr);
return;
}
if (trusted_mask) {
@@ -1025,7 +1048,8 @@ tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
if (p_pin && (pin_len <= PIN_CODE_LEN) && (pin_len != 0)) {
btm_cb.pin_code_len = pin_len;
p_dev_rec->pin_code_length = pin_len;
memcpy (btm_cb.pin_code, p_pin, PIN_CODE_LEN);
memset (btm_cb.pin_code, 0, PIN_CODE_LEN);
memcpy (btm_cb.pin_code, p_pin, pin_len);
}
#endif ///CLASSIC_BT_INCLUDED == TRUE
@@ -1324,8 +1348,8 @@ tBTM_STATUS BTM_SecGetDeviceLinkKey (BD_ADDR bd_addr, LINK_KEY link_key)
** BTM_UNKNOWN_ADDR if Security Manager does not know about
** the device or device record does not contain link key info
**
** Returns BTM_LKEY_TYPE_IGNORE if link key is unknown, link type
** otherwise.
** Returns Link key type for the specified device, or BTM_LKEY_TYPE_IGNORE
** if no valid link key is available.
**
*******************************************************************************/
tBTM_LINK_KEY_TYPE BTM_SecGetDeviceLinkKeyType (BD_ADDR bd_addr)
@@ -1403,7 +1427,6 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SE
return (BTM_SUCCESS);
}
p_dev_rec->enc_init_by_we = TRUE;
/* enqueue security request if security is active */
if (p_dev_rec->p_callback || (p_dev_rec->sec_state != BTM_SEC_STATE_IDLE)) {
BTM_TRACE_WARNING ("Security Manager: BTM_SetEncryption busy, enqueue request\n");
@@ -1418,6 +1441,11 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SE
}
}
UINT16 old_security_required = p_dev_rec->security_required;
BOOLEAN old_is_originator = p_dev_rec->is_originator;
BOOLEAN old_enc_init_by_we = p_dev_rec->enc_init_by_we;
p_dev_rec->enc_init_by_we = TRUE;
p_dev_rec->p_callback = p_callback;
p_dev_rec->p_ref_data = p_ref_data;
p_dev_rec->security_required |= (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT);
@@ -1443,9 +1471,17 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SE
}
if (rc != BTM_CMD_STARTED && rc != BTM_BUSY) {
if (p_callback) {
if (rc != BTM_SUCCESS) {
p_dev_rec->p_callback = NULL;
p_dev_rec->p_ref_data = NULL;
p_dev_rec->security_required = old_security_required;
p_dev_rec->is_originator = old_is_originator;
p_dev_rec->enc_init_by_we = old_enc_init_by_we;
} else {
p_dev_rec->p_callback = NULL;
(*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, rc);
}
if (p_callback) {
(*p_callback) (bd_addr, transport, p_ref_data, rc);
}
}
@@ -1493,14 +1529,16 @@ static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UIN
break;
}
#if BTM_DISC_DURING_RS == TRUE
/* If a role switch is in progress, delay the HCI Disconnect to avoid controller problem */
if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING && p_dev_rec->hci_handle == conn_handle) {
BTM_TRACE_DEBUG("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect\n");
p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
status = BTM_SUCCESS;
}
} else
/* Tear down the HCI link */
else if (!btsnd_hcic_disconnect (conn_handle, reason)) {
#endif
if (!btsnd_hcic_disconnect (conn_handle, reason)) {
/* could not send disconnect. restore old state */
p_dev_rec->sec_state = old_state;
status = BTM_NO_RESOURCES;
@@ -1637,7 +1675,9 @@ void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type)
{
/* This API only make sense between PASSKEY_REQ and SP complete */
if (btm_cb.pairing_state == BTM_PAIR_STATE_KEY_ENTRY) {
btsnd_hcic_send_keypress_notif (bd_addr, type);
if (bd_addr) {
btsnd_hcic_send_keypress_notif (bd_addr, type);
}
}
}
#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
@@ -1959,7 +1999,7 @@ void BTM_SetOutService(BD_ADDR bd_addr, UINT8 service_id, UINT32 mx_chan_id)
tBTM_SEC_DEV_REC *p_dev_rec;
tBTM_SEC_SERV_REC *p_serv_rec = &btm_cb.sec_serv_rec[0];
btm_cb.p_out_serv = p_serv_rec;
btm_cb.p_out_serv = NULL;
p_dev_rec = btm_find_dev (bd_addr);
for (int i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++) {
@@ -2017,6 +2057,7 @@ static BOOLEAN btm_sec_is_upgrade_possible(tBTM_SEC_DEV_REC *p_dev_rec, BOOLEAN
/* has unauthenticated
link key */
&& (p_dev_rec->rmt_io_caps < BTM_IO_CAP_MAX) /* a valid peer IO cap */
&& (btm_cb.devcb.loc_io_caps < BTM_IO_CAP_MAX) /* a valid local IO cap */
&& (btm_sec_io_map[p_dev_rec->rmt_io_caps][btm_cb.devcb.loc_io_caps]))
/* authenticated
link key is possible */
@@ -2129,6 +2170,12 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
/* Find or get oldest record */
p_dev_rec = btm_find_or_alloc_dev (bd_addr);
if (!p_dev_rec) {
if (p_callback) {
(*p_callback) (bd_addr, transport, p_ref_data, BTM_NO_RESOURCES);
}
return BTM_NO_RESOURCES;
}
p_dev_rec->hci_handle = handle;
@@ -2464,6 +2511,12 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o
BTM_TRACE_DEBUG ("%s() is_originator: %d\n", __func__, is_originator);
/* Find or get oldest record */
p_dev_rec = btm_find_or_alloc_dev (bd_addr);
if (!p_dev_rec) {
if (p_callback) {
(*p_callback)(bd_addr, transport, p_ref_data, BTM_NO_RESOURCES);
}
return BTM_NO_RESOURCES;
}
/* Find the service record for the PSM */
p_serv_rec = btm_sec_find_mx_serv (is_originator, psm, mx_proto_id, mx_chan_id);
@@ -2550,8 +2603,14 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o
}
if (rc == BTM_CMD_STARTED) {
BTM_TRACE_EVENT("%s: call btm_sec_queue_mx_request\n", __FUNCTION__);
btm_sec_queue_mx_request (bd_addr, psm, is_originator, mx_proto_id,
mx_chan_id, p_callback, p_ref_data);
BOOLEAN ret = btm_sec_queue_mx_request (bd_addr, psm, is_originator, mx_proto_id,
mx_chan_id, p_callback, p_ref_data);
if (!ret) {
rc = BTM_NO_RESOURCES;
if (p_callback) {
(*p_callback) (bd_addr, transport, p_ref_data, (UINT8)rc);
}
}
} else { /* rc == BTM_SUCCESS */
/* access granted */
if (p_callback) {
@@ -2903,7 +2962,7 @@ void btm_sec_dev_reset (void)
/* set the default IO capabilities */
btm_cb.devcb.loc_io_caps = BTM_LOCAL_IO_CAPS;
/* add mx service to use no security */
BTM_SetSecurityLevel(FALSE, "RFC_MUX\n", BTM_SEC_SERVICE_RFC_MUX,
BTM_SetSecurityLevel(FALSE, "RFC_MUX", BTM_SEC_SERVICE_RFC_MUX,
BTM_SEC_NONE, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, 0);
} else {
btm_cb.security_mode = BTM_SEC_MODE_SERVICE;
@@ -3024,7 +3083,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
if (p_bd_addr) {
p_dev_rec = btm_find_dev (p_bd_addr);
} else {
list_node_t *p_node = NULL;
list_node_t *p_node = NULL;
for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
p_dev_rec = list_node(p_node);
if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
@@ -3032,20 +3091,18 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
p_bd_addr = p_dev_rec->bd_addr;
break;
}
}
}
if (!p_bd_addr) {
p_dev_rec = NULL;
}
p_dev_rec = NULL;
}
}
/* Commenting out trace due to obf/compilation problems.
*/
#if (BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE)
if (!p_bd_name) {
p_bd_name = (UINT8 *)"";
}
/* Commenting out trace due to obf/compilation problems.
*/
#if (BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE)
if (p_dev_rec) {
BTM_TRACE_EVENT ("Security Manager: rmt_name_complete PairState: %s RemName: %s status: %d State:%d p_dev_rec: %p \n",
btm_pair_state_descr (btm_cb.pairing_state), p_bd_name,
@@ -3264,6 +3321,10 @@ void btm_sec_rmt_host_support_feat_evt (UINT8 *p)
STREAM_TO_BDADDR (bd_addr, p);
p_dev_rec = btm_find_or_alloc_dev (bd_addr);
if (!p_dev_rec) {
BTM_TRACE_ERROR("Unable to allocate or find device record for remote features event");
return;
}
BTM_TRACE_EVENT ("btm_sec_rmt_host_support_feat_evt sm4: 0x%x p[0]: 0x%x\n", p_dev_rec->sm4, p[0]);
@@ -3309,6 +3370,11 @@ void btm_io_capabilities_req (UINT8 *p)
BTM_TRACE_EVENT("%s: State: %s\n", __FUNCTION__, btm_pair_state_descr(btm_cb.pairing_state));
#endif ///BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE
p_dev_rec = btm_find_or_alloc_dev (evt_data.bd_addr);
if (!p_dev_rec) {
BTM_TRACE_ERROR("%s: unable to allocate device record", __func__);
btsnd_hcic_io_cap_req_neg_reply(evt_data.bd_addr, HCI_ERR_HOST_REJECT_RESOURCES);
return;
}
BTM_TRACE_DEBUG("%s:Security mode: %d, Num Read Remote Feat pages: %d\n", __FUNCTION__,
btm_cb.security_mode, p_dev_rec->num_read_pages);
@@ -3667,11 +3733,15 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
** Returns void
**
*******************************************************************************/
void btm_keypress_notif_evt (UINT8 *p)
void btm_keypress_notif_evt (UINT8 *p, UINT16 evt_len)
{
tBTM_SP_KEYPRESS evt_data;
UINT8 *p_bda;
if (evt_len < 7) {
return;
}
/* parse & report BTM_SP_KEYPRESS_EVT */
if (btm_cb.api.p_sp_callback) {
p_bda = evt_data.bd_addr;
@@ -3693,13 +3763,17 @@ void btm_keypress_notif_evt (UINT8 *p)
** Returns void
**
*******************************************************************************/
void btm_simple_pair_complete (UINT8 *p)
void btm_simple_pair_complete (UINT8 *p, UINT16 evt_len)
{
tBTM_SP_COMPLT evt_data;
tBTM_SEC_DEV_REC *p_dev_rec;
UINT8 status;
BOOLEAN disc = FALSE;
if (evt_len < 7) {
return;
}
status = *p++;
STREAM_TO_BDADDR (evt_data.bd_addr, p);
@@ -4287,6 +4361,10 @@ static void btm_sec_connect_after_reject_timeout (TIMER_LIST_ENT *p_tle)
btm_cb.sec_collision_tle.param = 0;
btm_cb.p_collided_dev_rec = 0;
if (!p_dev_rec) {
return;
}
if (btm_sec_dd_create_conn(p_dev_rec) != BTM_CMD_STARTED) {
BTM_TRACE_WARNING ("Security Manager: btm_sec_connect_after_reject_timeout: failed to start connection\n");
@@ -4413,8 +4491,6 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
#endif
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
&& (memcmp (btm_cb.pairing_bda, bda, BD_ADDR_LEN) == 0) ) {
/* if we rejected incoming connection from bonding device */
@@ -4550,7 +4626,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
if ( res ) {
if (res && (p_dev_rec != NULL)) {
/* Let l2cap start bond timer */
l2cu_update_lcb_4_bonding (p_dev_rec->bd_addr, TRUE);
}
@@ -4629,8 +4705,8 @@ tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason)
/* In some weird race condition we may not have a record */
if (!p_dev_rec) {
btsnd_hcic_disconnect (handle, reason);
return (BTM_SUCCESS);
BOOLEAN ret = btsnd_hcic_disconnect (handle, reason);
return (ret ? BTM_SUCCESS : BTM_NO_RESOURCES);
}
/* If we are in the process of bonding we need to tell client that auth failed */
@@ -4677,8 +4753,6 @@ BOOLEAN btm_sec_disconnected (UINT16 handle, UINT8 reason)
p_dev_rec->enc_init_by_we = FALSE;
transport = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR : BT_TRANSPORT_LE;
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
#if BTM_DISC_DURING_RS == TRUE
p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
#endif
@@ -4781,6 +4855,10 @@ void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UINT8 key_t
/* If connection was made to do bonding restore link security if changed */
btm_restore_mode();
if (p_dev_rec == NULL) {
return;
}
/* Store the previous state of secure connection as current state. Since
* this is the first encounter with the remote device, whatever the remote
* device's SC state is, it cannot lower the SC level from this. */
@@ -4927,6 +5005,7 @@ void btm_sec_link_key_request (UINT8 *p_bda)
if ( (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ) &&
(btm_cb.collision_start_time != 0) &&
(btm_cb.p_collided_dev_rec != NULL) &&
(memcmp (btm_cb.p_collided_dev_rec->bd_addr, p_bda, BD_ADDR_LEN) == 0) ) {
BTM_TRACE_EVENT ("btm_sec_link_key_request() rejecting link key req "
"State: %d START_TIMEOUT : %d\n",
@@ -4969,7 +5048,7 @@ static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle)
tBTM_AUTH_REQ auth_req = BTM_AUTH_AP_YES;
#endif
#endif
UINT8 name[2];
tBTM_BD_NAME name = {0};
UNUSED(p_tle);
p_cb->pairing_tle.param = 0;
@@ -5141,6 +5220,12 @@ void btm_sec_pin_code_request (UINT8 *p_bda)
}
p_dev_rec = btm_find_or_alloc_dev (p_bda);
if (!p_dev_rec) {
BTM_TRACE_ERROR ("btm_sec_pin_code_request no device record available\n");
btsnd_hcic_pin_code_neg_reply (p_bda);
return;
}
/* received PIN code request. must be non-sm4 */
p_dev_rec->sm4 = BTM_SM4_KNOWN;
@@ -5491,7 +5576,7 @@ static BOOLEAN btm_sec_start_encryption (tBTM_SEC_DEV_REC *p_dev_rec)
*******************************************************************************/
static UINT8 btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec)
{
UINT8 result;
UINT8 result = BTM_SUCCESS;
UINT8 *p_service_name = NULL;
UINT8 service_id;
@@ -5543,7 +5628,9 @@ static UINT8 btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec)
}
return (result);
}
btm_sec_start_get_name (p_dev_rec);
if (!btm_sec_start_get_name (p_dev_rec)) {
return BTM_NO_RESOURCES;
}
return (BTM_CMD_STARTED);
}
#endif ///SMP_INCLUDED == TRUE
@@ -5697,6 +5784,10 @@ static void btm_sec_collision_timeout (TIMER_LIST_ENT *p_tle)
BTM_TRACE_EVENT ("%s()\n", __func__);
btm_cb.sec_collision_tle.param = 0;
if (!btm_cb.p_collided_dev_rec) {
return;
}
tBTM_STATUS status = btm_sec_execute_procedure (btm_cb.p_collided_dev_rec);
/* If result is pending reply from the user or from the device is pending */
@@ -5763,15 +5854,17 @@ UINT32 *BTM_ReadTrustedMask (BD_ADDR bd_addr)
static void btm_restore_mode(void)
{
if (btm_cb.security_mode_changed) {
btm_cb.security_mode_changed = FALSE;
BTM_TRACE_DEBUG("%s() Auth enable -> %d\n", __func__, (btm_cb.security_mode == BTM_SEC_MODE_LINK));
btsnd_hcic_write_auth_enable ((UINT8)(btm_cb.security_mode == BTM_SEC_MODE_LINK));
if (btsnd_hcic_write_auth_enable ((UINT8)(btm_cb.security_mode == BTM_SEC_MODE_LINK))) {
btm_cb.security_mode_changed = FALSE;
}
}
#if (CLASSIC_BT_INCLUDED == TRUE)
if (btm_cb.pin_type_changed) {
btm_cb.pin_type_changed = FALSE;
btsnd_hcic_write_pin_type (btm_cb.cfg.pin_type);
if (btsnd_hcic_write_pin_type (btm_cb.cfg.pin_type)) {
btm_cb.pin_type_changed = FALSE;
}
}
#endif ///CLASSIC_BT_INCLUDED == TRUE
}
@@ -5794,7 +5887,7 @@ tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state)
list_node_t *p_node = NULL;
for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
p_dev_rec = list_node(p_node);
if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
&& (p_dev_rec->sec_state == state)) {
return (p_dev_rec);
}
@@ -5945,9 +6038,14 @@ static BOOLEAN btm_sec_queue_mx_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN
BTM_TRACE_EVENT ("%s() PSM: 0x%04x Is_Orig: %u mx_proto_id: %u mx_chan_id: %u\n",
__func__, psm, is_orig, mx_proto_id, mx_chan_id);
fixed_queue_enqueue(btm_cb.sec_pending_q, p_e, FIXED_QUEUE_MAX_TIMEOUT);
if (fixed_queue_enqueue(btm_cb.sec_pending_q, p_e, FIXED_QUEUE_MAX_TIMEOUT)) {
return (TRUE);
}
}
return (TRUE);
if (p_e) {
osi_free(p_e);
p_e = NULL;
}
return (FALSE);
@@ -5958,7 +6056,6 @@ static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC *p_dev_rec)
#if (CLASSIC_BT_INCLUDED == TRUE)
UINT8 major = (UINT8)(p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK);
UINT8 minor = (UINT8)(p_dev_rec->dev_class[2] & BTM_COD_MINOR_CLASS_MASK);
rv = TRUE;
if ((major == BTM_COD_MAJOR_AUDIO)
&& ((minor == BTM_COD_MINOR_CONFM_HANDSFREE) || (minor == BTM_COD_MINOR_CAR_AUDIO)) ) {
@@ -5974,30 +6071,30 @@ static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC *p_dev_rec)
btsnd_hcic_write_auth_enable (TRUE);
}
}
} else {
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
/* If we got a PIN, use that, else try to get one */
if (btm_cb.pin_code_len) {
BTM_PINCodeReply (p_dev_rec->bd_addr, BTM_SUCCESS, btm_cb.pin_code_len, btm_cb.pin_code, p_dev_rec->trusted_mask);
} else {
/* pin was not supplied - pre-fetch pin code now */
if (btm_cb.api.p_pin_callback && ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0)) {
BTM_TRACE_DEBUG("%s() PIN code callback called\n", __func__);
if (btm_bda_to_acl(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR) == NULL) {
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
}
(btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
p_dev_rec->sec_bd_name, (p_dev_rec->p_cur_service == NULL) ? FALSE
: (p_dev_rec->p_cur_service->security_flags
& BTM_SEC_IN_MIN_16_DIGIT_PIN));
}
}
rv = TRUE;
} else if (btm_cb.pin_code_len) {
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
BTM_PINCodeReply (p_dev_rec->bd_addr, BTM_SUCCESS, btm_cb.pin_code_len, btm_cb.pin_code, p_dev_rec->trusted_mask);
rv = TRUE;
} else if (btm_cb.api.p_pin_callback) {
btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
/* pin was not supplied - pre-fetch pin code now */
if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0) {
BTM_TRACE_DEBUG("%s() PIN code callback called\n", __func__);
if (btm_bda_to_acl(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR) == NULL) {
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
}
(btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
p_dev_rec->sec_bd_name, (p_dev_rec->p_cur_service == NULL) ? FALSE
: (p_dev_rec->p_cur_service->security_flags
& BTM_SEC_IN_MIN_16_DIGIT_PIN));
}
rv = TRUE;
} else {
BTM_TRACE_WARNING ("%s() cannot prefetch PIN: no PIN supplied and no callback registered\n", __func__);
}
#endif ///CLASSIC_BT_INCLUDED == TRUE
#
return rv;
}
@@ -6016,6 +6113,10 @@ void btm_sec_auth_payload_tout (UINT8 *p, UINT16 hci_evt_len)
{
UINT16 handle;
if (hci_evt_len < 2) {
return;
}
STREAM_TO_UINT16 (handle, p);
handle = HCID_GET_HANDLE (handle);
@@ -6053,10 +6154,15 @@ static BOOLEAN btm_sec_queue_encrypt_request (BD_ADDR bd_addr, tBT_TRANSPORT tra
}
p_e->transport = transport;
memcpy(p_e->bd_addr, bd_addr, BD_ADDR_LEN);
fixed_queue_enqueue(btm_cb.sec_pending_q, p_e, FIXED_QUEUE_MAX_TIMEOUT);
return TRUE;
if (fixed_queue_enqueue(btm_cb.sec_pending_q, p_e, FIXED_QUEUE_MAX_TIMEOUT)) {
return TRUE;
}
}
if (p_e) {
osi_free(p_e);
p_e = NULL;
}
return FALSE;
}
@@ -6187,7 +6293,7 @@ static void btm_sec_check_pending_enc_req (tBTM_SEC_DEV_REC *p_dev_rec, tBT_TRA
(*p_e->p_callback) (p_dev_rec->bd_addr, transport, p_e->p_ref_data, res);
}
fixed_queue_try_remove_from_queue(btm_cb.sec_pending_q, (void *)p_e);
osi_free(fixed_queue_try_remove_from_queue(btm_cb.sec_pending_q, (void *)p_e));
}
}
}
@@ -1103,7 +1103,7 @@ void btm_inq_rmt_name_failed(void);
/* Inquiry related functions */
void btm_clr_inq_db (BD_ADDR p_bda);
void btm_inq_db_init (void);
void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode);
void btm_process_inq_results (UINT8 *p, UINT16 evt_len, UINT8 inq_res_mode);
void btm_process_inq_complete (UINT8 status, UINT8 mode);
void btm_process_cancel_complete(UINT8 status, UINT8 mode);
void btm_event_filter_complete (UINT8 *p);
@@ -1115,8 +1115,8 @@ BOOLEAN btm_inq_find_bdaddr (BD_ADDR p_bda);
BOOLEAN btm_lookup_eir(BD_ADDR_PTR p_rem_addr);
#if (CLASSIC_BT_INCLUDED == TRUE)
void btm_read_iscan_tx_power_complete (UINT8 *p);
void btm_write_inq_tx_power_complete (UINT8 *p);
void btm_read_iscan_tx_power_complete (UINT8 *p, UINT16 evt_len);
void btm_write_inq_tx_power_complete (UINT8 *p, UINT16 evt_len);
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
/* Internal functions provided by btm_bredr_pwr_ctrl.c
@@ -1153,12 +1153,12 @@ tBTM_STATUS btm_set_packet_types (tACL_CONN *p, UINT16 pkt_types);
void btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 clock_offset);
void btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role);
void btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable);
UINT16 btm_get_acl_disc_reason_code (void);
UINT8 btm_get_acl_disc_reason_code (void);
tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport);
void btm_read_remote_features_complete (UINT8 *p);
void btm_read_remote_ext_features_complete (UINT8 *p);
void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle);
void btm_read_remote_version_complete (UINT8 *p);
void btm_read_remote_version_complete (UINT8 *p, UINT16 evt_len);
void btm_establish_continue (tACL_CONN *p_acl_cb);
// btla-specific ++
@@ -1326,8 +1326,8 @@ void btm_io_capabilities_req (UINT8 *p);
void btm_io_capabilities_rsp (UINT8 *p);
#if (CLASSIC_BT_INCLUDED == TRUE)
void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p);
void btm_keypress_notif_evt (UINT8 *p);
void btm_simple_pair_complete (UINT8 *p);
void btm_keypress_notif_evt (UINT8 *p, UINT16 evt_len);
void btm_simple_pair_complete (UINT8 *p, UINT16 evt_len);
#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UINT8 key_type);
void btm_sec_link_key_request (UINT8 *p_bda);
@@ -67,10 +67,10 @@ extern void btm_ble_test_command_complete(UINT8 *p, UINT16 len);
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/********************************************************************************/
#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_inquiry_comp_evt (UINT8 *p);
static void btu_hcif_inquiry_result_evt (UINT8 *p);
static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p);
static void btu_hcif_extended_inquiry_result_evt (UINT8 *p);
static void btu_hcif_inquiry_comp_evt (UINT8 *p, UINT16 evt_len);
static void btu_hcif_inquiry_result_evt (UINT8 *p, UINT16 evt_len);
static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p, UINT16 evt_len);
static void btu_hcif_extended_inquiry_result_evt (UINT8 *p, UINT16 evt_len);
static void btu_hcif_connection_comp_evt (UINT8 *p);
static void btu_hcif_connection_request_evt (UINT8 *p);
@@ -89,7 +89,7 @@ static void btu_hcif_encryption_change_evt (UINT8 *p);
static void btu_hcif_read_rmt_features_comp_evt (UINT8 *p);
static void btu_hcif_read_rmt_ext_features_comp_evt (UINT8 *p);
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p);
static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p, UINT16 evt_len);
#if (CLASSIC_BT_INCLUDED == TRUE)
static void btu_hcif_qos_setup_comp_evt (UINT8 *p);
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
@@ -134,9 +134,9 @@ static void btu_hcif_io_cap_request_evt (UINT8 *p);
static void btu_hcif_io_cap_response_evt (UINT8 *p);
static void btu_hcif_user_conf_request_evt (UINT8 *p);
static void btu_hcif_user_passkey_request_evt (UINT8 *p);
static void btu_hcif_simple_pair_complete_evt (UINT8 *p);
static void btu_hcif_simple_pair_complete_evt (UINT8 *p, UINT16 evt_len);
static void btu_hcif_user_passkey_notif_evt (UINT8 *p);
static void btu_hcif_keypress_notif_evt (UINT8 *p);
static void btu_hcif_keypress_notif_evt (UINT8 *p, UINT16 evt_len);
#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
#if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE
static void btu_hcif_rem_oob_request_evt (UINT8 *p);
@@ -305,16 +305,16 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
switch (hci_evt_code) {
#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_INQUIRY_COMP_EVT:
btu_hcif_inquiry_comp_evt (p);
btu_hcif_inquiry_comp_evt (p, hci_evt_len);
break;
case HCI_INQUIRY_RESULT_EVT:
btu_hcif_inquiry_result_evt (p);
btu_hcif_inquiry_result_evt (p, hci_evt_len);
break;
case HCI_INQUIRY_RSSI_RESULT_EVT:
btu_hcif_inquiry_rssi_result_evt (p);
btu_hcif_inquiry_rssi_result_evt (p, hci_evt_len);
break;
case HCI_EXTENDED_INQUIRY_RESULT_EVT:
btu_hcif_extended_inquiry_result_evt (p);
btu_hcif_extended_inquiry_result_evt (p, hci_evt_len);
break;
case HCI_CONNECTION_COMP_EVT:
btu_hcif_connection_comp_evt (p);
@@ -357,7 +357,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
break;
#endif // #if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_READ_RMT_VERSION_COMP_EVT:
btu_hcif_read_rmt_version_comp_evt (p);
btu_hcif_read_rmt_version_comp_evt (p, hci_evt_len);
break;
#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_QOS_SETUP_COMP_EVT:
@@ -461,13 +461,13 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
#endif
#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_SIMPLE_PAIRING_COMPLETE_EVT:
btu_hcif_simple_pair_complete_evt (p);
btu_hcif_simple_pair_complete_evt (p, hci_evt_len);
break;
case HCI_USER_PASSKEY_NOTIFY_EVT:
btu_hcif_user_passkey_notif_evt (p);
break;
case HCI_KEYPRESS_NOTIFY_EVT:
btu_hcif_keypress_notif_evt (p);
btu_hcif_keypress_notif_evt (p, hci_evt_len);
break;
case HCI_LINK_SUPER_TOUT_CHANGED_EVT:
btu_hcif_link_supv_to_changed_evt (p);
@@ -842,11 +842,13 @@ void btu_hcif_send_host_rdy_for_data(void)
** Returns void
**
*******************************************************************************/
static void btu_hcif_inquiry_comp_evt (UINT8 *p)
static void btu_hcif_inquiry_comp_evt (UINT8 *p, UINT16 evt_len)
{
UINT8 status;
UINT8 status = HCI_ERR_HW_FAILURE;
STREAM_TO_UINT8 (status, p);
if (evt_len >= 1) {
STREAM_TO_UINT8 (status, p);
}
/* Tell inquiry processing that we are done */
btm_process_inq_complete(status, BTM_BR_INQUIRY_MASK);
@@ -862,10 +864,10 @@ static void btu_hcif_inquiry_comp_evt (UINT8 *p)
** Returns void
**
*******************************************************************************/
static void btu_hcif_inquiry_result_evt (UINT8 *p)
static void btu_hcif_inquiry_result_evt (UINT8 *p, UINT16 evt_len)
{
/* Store results in the cache */
btm_process_inq_results (p, BTM_INQ_RESULT_STANDARD);
btm_process_inq_results (p, evt_len, BTM_INQ_RESULT_STANDARD);
}
/*******************************************************************************
@@ -877,10 +879,10 @@ static void btu_hcif_inquiry_result_evt (UINT8 *p)
** Returns void
**
*******************************************************************************/
static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p)
static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p, UINT16 evt_len)
{
/* Store results in the cache */
btm_process_inq_results (p, BTM_INQ_RESULT_WITH_RSSI);
btm_process_inq_results (p, evt_len, BTM_INQ_RESULT_WITH_RSSI);
}
/*******************************************************************************
@@ -892,10 +894,10 @@ static void btu_hcif_inquiry_rssi_result_evt (UINT8 *p)
** Returns void
**
*******************************************************************************/
static void btu_hcif_extended_inquiry_result_evt (UINT8 *p)
static void btu_hcif_extended_inquiry_result_evt (UINT8 *p, UINT16 evt_len)
{
/* Store results in the cache */
btm_process_inq_results (p, BTM_INQ_RESULT_EXTENDED);
btm_process_inq_results (p, evt_len, BTM_INQ_RESULT_EXTENDED);
}
/*******************************************************************************
@@ -1097,7 +1099,6 @@ static void btu_hcif_rmt_name_request_comp_evt (UINT8 *p, UINT16 evt_len)
STREAM_TO_UINT8 (status, p);
STREAM_TO_BDADDR (bd_addr, p);
evt_len -= (1 + BD_ADDR_LEN);
btm_process_remote_name (bd_addr, p, evt_len, status);
@@ -1182,9 +1183,9 @@ static void btu_hcif_read_rmt_ext_features_comp_evt (UINT8 *p)
** Returns void
**
*******************************************************************************/
static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p)
static void btu_hcif_read_rmt_version_comp_evt (UINT8 *p, UINT16 evt_len)
{
btm_read_remote_version_complete (p);
btm_read_remote_version_complete (p, evt_len);
}
#if (CLASSIC_BT_INCLUDED == TRUE)
@@ -1346,10 +1347,10 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
#if (CLASSIC_BT_INCLUDED == TRUE)
case HCI_READ_INQ_TX_POWER_LEVEL:
btm_read_iscan_tx_power_complete (p);
btm_read_iscan_tx_power_complete (p, evt_len);
break;
case HCI_WRITE_INQ_TX_POWER_LEVEL:
btm_write_inq_tx_power_complete(p);
btm_write_inq_tx_power_complete(p, evt_len);
break;
case HCI_SET_AFH_CHANNELS:
btm_set_afh_channels_complete(p);
@@ -2438,9 +2439,9 @@ static void btu_hcif_user_passkey_request_evt (UINT8 *p)
** Returns void
**
*******************************************************************************/
static void btu_hcif_simple_pair_complete_evt (UINT8 *p)
static void btu_hcif_simple_pair_complete_evt (UINT8 *p, UINT16 evt_len)
{
btm_simple_pair_complete(p);
btm_simple_pair_complete(p, evt_len);
}
/*******************************************************************************
@@ -2466,9 +2467,9 @@ static void btu_hcif_user_passkey_notif_evt (UINT8 *p)
** Returns void
**
*******************************************************************************/
static void btu_hcif_keypress_notif_evt (UINT8 *p)
static void btu_hcif_keypress_notif_evt (UINT8 *p, UINT16 evt_len)
{
btm_keypress_notif_evt(p);
btm_keypress_notif_evt(p, evt_len);
}
#endif /* (CLASSIC_BT_INCLUDED == TRUE) */
@@ -41,6 +41,12 @@ tGAP_CB *gap_cb_ptr;
*******************************************************************************/
UINT8 GAP_SetTraceLevel (UINT8 new_level)
{
#if GAP_DYNAMIC_MEMORY == TRUE
if (!gap_cb_ptr) {
return GAP_INITIAL_TRACE_LEVEL;
}
#endif
if (new_level != 0xFF) {
gap_cb.trace_level = new_level;
}
@@ -298,12 +298,9 @@ UINT16 GAP_ConnClose (UINT16 gap_handle)
*******************************************************************************/
UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
{
tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
tGAP_CCB *p_ccb = NULL;
UINT16 copy_len;
if (!p_ccb) {
return (GAP_ERR_BAD_HANDLE);
}
if (!p_len) {
return (GAP_ERR_ILL_PARM);
}
@@ -312,6 +309,12 @@ UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT1
osi_mutex_global_lock();
p_ccb = gap_find_ccb_by_handle (gap_handle);
if (!p_ccb) {
osi_mutex_global_unlock();
return (GAP_ERR_BAD_HANDLE);
}
if (fixed_queue_is_empty(p_ccb->rx_queue)) {
osi_mutex_global_unlock();
return (GAP_NO_DATA_AVAIL);
@@ -363,18 +366,22 @@ UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT1
int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count)
{
tGAP_CCB *p_ccb;
int rc = GAP_INVALID_HANDLE;
int rc = GAP_ERR_BAD_HANDLE;
if (!p_rx_queue_count) {
return GAP_ERR_ILL_PARM;
}
*p_rx_queue_count = 0;
/* Check that handle is valid */
p_ccb = gap_find_ccb_by_handle (handle);
if (p_ccb) {
if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) {
*p_rx_queue_count = p_ccb->rx_queue_size;
rc = BT_PASS;
} else {
rc = GAP_ERR_BAD_STATE;
}
}
@@ -401,24 +408,32 @@ int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count)
*******************************************************************************/
UINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf)
{
tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
tGAP_CCB *p_ccb;
BT_HDR *p_buf;
if (!pp_buf) {
return (GAP_ERR_ILL_PARM);
}
osi_mutex_global_lock();
p_ccb = gap_find_ccb_by_handle (gap_handle);
if (!p_ccb) {
osi_mutex_global_unlock();
return (GAP_ERR_BAD_HANDLE);
}
p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->rx_queue, 0);
if (p_buf) {
*pp_buf = p_buf;
p_ccb->rx_queue_size -= p_buf->len;
osi_mutex_global_unlock();
*pp_buf = p_buf;
return (BT_PASS);
} else {
*pp_buf = NULL;
return (GAP_NO_DATA_AVAIL);
}
osi_mutex_global_unlock();
*pp_buf = NULL;
return (GAP_NO_DATA_AVAIL);
}
@@ -462,9 +477,6 @@ UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf)
}
/* Send the buffer through L2CAP */
#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
gap_send_event (gap_handle);
#else
while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->tx_queue, 0)) != NULL) {
UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
@@ -475,7 +487,6 @@ UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf)
return (GAP_ERR_BAD_STATE);
}
}
#endif
return (BT_PASS);
}
@@ -545,9 +556,6 @@ UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT
}
/* Send the buffer through L2CAP */
#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
gap_send_event (gap_handle);
#else
while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->tx_queue, 0)) != NULL)
{
UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
@@ -559,7 +567,6 @@ UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT
return (GAP_ERR_BAD_STATE);
}
}
#endif
return (BT_PASS);
}
@@ -580,14 +587,21 @@ UINT16 GAP_ConnReconfig (UINT16 gap_handle, tL2CAP_CFG_INFO *p_cfg)
{
tGAP_CCB *p_ccb = gap_find_ccb_by_handle (gap_handle);
if (!p_cfg) {
return GAP_ERR_ILL_PARM;
}
if (!p_ccb) {
return (GAP_ERR_BAD_HANDLE);
}
tL2CAP_CFG_INFO old_cfg = p_ccb->cfg;
p_ccb->cfg = *p_cfg;
if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) {
L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg);
if (!L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg)) {
p_ccb->cfg = old_cfg;
return GAP_ERR_BAD_STATE;
}
}
return (BT_PASS);
@@ -642,8 +656,8 @@ UINT16 GAP_ConnSetIdleTimeout (UINT16 gap_handle, UINT16 timeout)
**
** Parameters: handle - Handle of the connection returned by GAP_ConnOpen
**
** Returns BT_PASS - closed OK
** GAP_ERR_BAD_HANDLE - invalid handle
** Returns Pointer to remote BD_ADDR (UINT8 *) if connection exists,
** otherwise NULL.
**
*******************************************************************************/
UINT8 *GAP_ConnGetRemoteAddr (UINT16 gap_handle)
@@ -777,10 +791,12 @@ static void gap_checks_con_flags (tGAP_CCB *p_ccb)
GAP_TRACE_EVENT ("gap_checks_con_flags conn_flags:0x%x, ", p_ccb->con_flags);
/* if all the required con_flags are set, report the OPEN event now */
if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE) {
p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED) {
p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
if (p_ccb->p_callback) {
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
if (p_ccb->p_callback) {
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
}
}
}
}
@@ -882,8 +898,11 @@ static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
/* Remember the remote MTU size */
if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) {
local_mtu_size = p_ccb->ertm_info.user_tx_buf_size
- sizeof(BT_HDR) - L2CAP_MIN_OFFSET;
if (p_ccb->ertm_info.user_tx_buf_size > sizeof(BT_HDR) + L2CAP_MIN_OFFSET) {
local_mtu_size = p_ccb->ertm_info.user_tx_buf_size - sizeof(BT_HDR) - L2CAP_MIN_OFFSET;
} else {
local_mtu_size = L2CAP_MTU_SIZE;
}
} else {
local_mtu_size = L2CAP_MTU_SIZE;
}
@@ -999,9 +1018,15 @@ static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
}
if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED) {
fixed_queue_enqueue(p_ccb->rx_queue, p_msg, FIXED_QUEUE_MAX_TIMEOUT);
p_ccb->rx_queue_size += p_msg->len;
UINT16 msg_len = p_msg->len;
bool ok = fixed_queue_enqueue(p_ccb->rx_queue, p_msg, FIXED_QUEUE_MAX_TIMEOUT);
if (!ok) {
osi_free(p_msg);
return;
}
osi_mutex_global_lock();
p_ccb->rx_queue_size += msg_len;
osi_mutex_global_unlock();
/*
GAP_TRACE_EVENT ("gap_data_ind - rx_queue_size=%d, msg len=%d",
p_ccb->rx_queue_size, p_msg->len);
@@ -1135,7 +1160,13 @@ static tGAP_CCB *gap_allocate_ccb (void)
if (p_ccb->con_state == GAP_CCB_STATE_IDLE) {
memset (p_ccb, 0, sizeof (tGAP_CCB));
p_ccb->tx_queue = fixed_queue_new(QUEUE_SIZE_MAX);
if (!p_ccb->tx_queue) {
goto error;
}
p_ccb->rx_queue = fixed_queue_new(QUEUE_SIZE_MAX);
if (!p_ccb->rx_queue) {
goto error;
}
p_ccb->gap_handle = xx;
p_ccb->rem_mtu_size = L2CAP_MTU_SIZE;
@@ -1144,6 +1175,17 @@ static tGAP_CCB *gap_allocate_ccb (void)
}
}
return NULL;
error:
if (p_ccb && p_ccb->tx_queue) {
fixed_queue_free(p_ccb->tx_queue, NULL);
p_ccb->tx_queue = NULL;
}
if (p_ccb && p_ccb->rx_queue) {
fixed_queue_free(p_ccb->rx_queue, NULL);
p_ccb->rx_queue = NULL;
}
/* If here, no free CCB found */
return (NULL);
}
@@ -1165,6 +1207,7 @@ static void gap_release_ccb (tGAP_CCB *p_ccb)
UINT8 service_id = p_ccb->service_id;
/* Drop any buffers we may be holding */
osi_mutex_global_lock();
p_ccb->rx_queue_size = 0;
while (!fixed_queue_is_empty(p_ccb->rx_queue)) {
@@ -1172,6 +1215,7 @@ static void gap_release_ccb (tGAP_CCB *p_ccb)
}
fixed_queue_free(p_ccb->rx_queue, NULL);
p_ccb->rx_queue = NULL;
osi_mutex_global_unlock();
while (!fixed_queue_is_empty(p_ccb->tx_queue)) {
osi_free(fixed_queue_dequeue(p_ccb->tx_queue, 0));
@@ -1189,37 +1233,11 @@ static void gap_release_ccb (tGAP_CCB *p_ccb)
}
#if (SDP_INCLUDED == TRUE)
/* Free the security record for this PSM */
BTM_SecClrService(service_id);
if (service_id != 0) {
BTM_SecClrService(service_id);
}
#endif ///SDP_INCLUDED == TRUE
L2CA_DEREGISTER (psm);
}
#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
/*******************************************************************************
**
** Function gap_send_event
**
** Description Send BT_EVT_TO_GAP_MSG event to BTU task
**
** Returns None
**
*******************************************************************************/
void gap_send_event (UINT16 gap_handle)
{
BT_HDR *p_msg;
if ((p_msg = (BT_HDR *)osi_malloc(BT_HDR_SIZE)) != NULL) {
p_msg->event = BT_EVT_TO_GAP_MSG;
p_msg->len = 0;
p_msg->offset = 0;
p_msg->layer_specific = gap_handle;
GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
} else {
GAP_TRACE_ERROR("Unable to allocate message buffer for event.");
}
}
#endif /* (GAP_CONN_POST_EVT_INCLUDED == TRUE) */
#endif /* GAP_CONN_INCLUDED */
@@ -165,7 +165,10 @@ BOOLEAN btsnd_hcic_create_conn(BD_ADDR dest, UINT16 packet_types,
#endif
#if (SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE)
btm_acl_paging (p, dest);
#endif ///SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE
#else
HCI_FREE_CMD_BUF (p);
return (FALSE);
#endif
return (TRUE);
}
@@ -493,7 +496,10 @@ BOOLEAN btsnd_hcic_rmt_name_req (BD_ADDR bd_addr, UINT8 page_scan_rep_mode,
UINT16_TO_STREAM (pp, clock_offset);
#if (SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE)
btm_acl_paging (p, bd_addr);
#endif ///SMP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == TRUE
#else
HCI_FREE_CMD_BUF (p);
return (FALSE);
#endif
return (TRUE);
}
@@ -1370,7 +1376,7 @@ BOOLEAN btsnd_hcic_write_link_super_tout (UINT8 local_controller_id, UINT16 hand
return (TRUE);
}
BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac, LAP *const iac_lap)
BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac, const LAP *iac_lap)
{
BT_HDR *p;
UINT8 *pp;
@@ -1432,11 +1438,11 @@ BOOLEAN btsnd_hcic_sniff_sub_rate(UINT16 handle, UINT16 max_lat,
#endif /* BTM_SSR_INCLUDED */
/**** Extended Inquiry Response Commands ****/
void btsnd_hcic_write_ext_inquiry_response (BT_HDR *buffer, UINT8 fec_req)
BOOLEAN btsnd_hcic_write_ext_inquiry_response (BT_HDR *buffer, UINT8 fec_req)
{
BT_HDR *p;
if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_EXT_INQ_RESP)) == NULL) {
return;
return (FALSE);
}
UINT8 *pp = (UINT8 *)(p + 1);
@@ -1451,6 +1457,7 @@ void btsnd_hcic_write_ext_inquiry_response (BT_HDR *buffer, UINT8 fec_req)
memcpy(pp, buffer->data + 4, p->len - 4);
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
return (TRUE);
}
BOOLEAN btsnd_hcic_io_cap_req_reply (BD_ADDR bd_addr, UINT8 capability,
@@ -103,6 +103,12 @@ void HID_DevDeinit(void)
******************************************************************************/
uint8_t HID_DevSetTraceLevel(uint8_t new_level)
{
#if (HID_DYNAMIC_MEMORY)
if (!hidd_cb_ptr) {
return BT_TRACE_LEVEL_NONE;
}
#endif /* #if (HID_DYNAMIC_MEMORY) */
if (new_level != 0xFF) {
hd_cb.trace_level = new_level;
}
@@ -159,15 +165,20 @@ tHID_STATUS HID_DevDeregister(void)
{
HIDD_TRACE_API("%s", __func__);
if (!hd_cb.reg_flag)
if (!hd_cb.reg_flag) {
return (HID_ERR_NOT_REGISTERED);
}
if (hd_cb.pending_data) {
osi_free(hd_cb.pending_data);
hd_cb.pending_data = NULL;
}
hidd_conn_dereg();
hd_cb.reg_flag = FALSE;
return (HID_SUCCESS);
}
tHID_STATUS HID_DevSetSecurityLevel(uint8_t sec_lvl)
tHID_STATUS HID_DevSetSecurityLevel(uint16_t sec_lvl)
{
HIDD_TRACE_API("%s", __func__);
if (!BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_HIDD_SEC_CTRL, sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID,
@@ -203,6 +214,53 @@ tHID_STATUS HID_DevSetSecurityLevel(uint8_t sec_lvl)
return (HID_SUCCESS);
}
#define HIDD_MAX_DESCRIPTOR_LEN 2048
static size_t hidd_descriptor_list_buf_size(uint16_t desc_len)
{
size_t text_elem_len = (desc_len <= 255) ? (2 + desc_len) : (3 + desc_len);
size_t inner_len = 2 + text_elem_len;
return inner_len + ((inner_len <= 255) ? 2 : 3);
}
static uint8_t *hidd_build_descriptor_list(uint16_t desc_len, uint8_t *p_desc_data, uint16_t *p_list_len)
{
static uint8_t cdt = 0x22;
size_t text_elem_len = (desc_len <= 255) ? (2 + desc_len) : (3 + desc_len);
size_t inner_len = 2 + text_elem_len;
uint8_t *p_buf = (uint8_t *)osi_malloc(hidd_descriptor_list_buf_size(desc_len));
uint8_t *p;
if (p_buf == NULL) {
return NULL;
}
p = p_buf;
if (inner_len <= 255) {
UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
UINT8_TO_BE_STREAM(p, (uint8_t)inner_len);
} else {
UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
UINT16_TO_BE_STREAM(p, (uint16_t)inner_len);
}
UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
UINT8_TO_BE_STREAM(p, cdt);
if (desc_len <= 255) {
UINT8_TO_BE_STREAM(p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
UINT8_TO_BE_STREAM(p, (uint8_t)desc_len);
} else {
UINT8_TO_BE_STREAM(p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_WORD);
UINT16_TO_BE_STREAM(p, desc_len);
}
ARRAY_TO_BE_STREAM(p, p_desc_data, (int)desc_len);
*p_list_len = (uint16_t)(p - p_buf);
return p_buf;
}
/*******************************************************************************
*
* Function HID_DevAddRecord
@@ -219,6 +277,13 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char *p_name, char *p_description,
HIDD_TRACE_API("%s", __func__);
if (desc_len > HIDD_MAX_DESCRIPTOR_LEN) {
return HID_ERR_INVALID_PARAM;
}
if (desc_len > 0 && p_desc_data == NULL) {
return HID_ERR_INVALID_PARAM;
}
// Service Class ID List
if (result) {
uint16_t uuid = UUID_SERVCLASS_HUMAN_INTERFACE;
@@ -292,23 +357,16 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char *p_name, char *p_description,
result &= SDP_AddAttribute(handle, ATTR_ID_HID_VIRTUAL_CABLE, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_true);
result &= SDP_AddAttribute(handle, ATTR_ID_HID_RECONNECT_INITIATE, BOOLEAN_DESC_TYPE, 1, (uint8_t *)&bool_true);
{
static uint8_t cdt = 0x22;
uint8_t *p_buf;
uint8_t seq_len = 4 + desc_len;
p_buf = (uint8_t *)osi_malloc(2048);
uint16_t list_len;
p_buf = hidd_build_descriptor_list(desc_len, p_desc_data, &list_len);
if (p_buf == NULL) {
HIDD_TRACE_ERROR("%s: Buffer allocation failure for size = 2048 ", __func__);
return HID_ERR_NOT_REGISTERED;
HIDD_TRACE_ERROR("%s: Buffer allocation failure for descriptor list size = %u", __func__,
(unsigned)hidd_descriptor_list_buf_size(desc_len));
return HID_ERR_NO_RESOURCES;
}
p = p_buf;
UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
UINT8_TO_BE_STREAM(p, seq_len);
UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
UINT8_TO_BE_STREAM(p, cdt);
UINT8_TO_BE_STREAM(p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
UINT8_TO_BE_STREAM(p, desc_len);
ARRAY_TO_BE_STREAM(p, p_desc_data, (int)desc_len);
result &= SDP_AddAttribute(handle, ATTR_ID_HID_DESCRIPTOR_LIST, DATA_ELE_SEQ_DESC_TYPE, p - p_buf, p_buf);
result &= SDP_AddAttribute(handle, ATTR_ID_HID_DESCRIPTOR_LIST, DATA_ELE_SEQ_DESC_TYPE, list_len, p_buf);
osi_free(p_buf);
}
{
@@ -416,6 +474,7 @@ tHID_STATUS HID_DevUnplugDevice(BD_ADDR addr)
{
if (!memcmp(hd_cb.device.addr, addr, sizeof(BD_ADDR))) {
hd_cb.device.in_use = FALSE;
hd_cb.device.state = HIDD_DEV_NO_CONN;
hd_cb.device.conn.conn_state = HID_CONN_STATE_UNUSED;
hd_cb.device.conn.ctrl_cid = 0;
hd_cb.device.conn.intr_cid = 0;
@@ -480,6 +539,12 @@ tHID_STATUS HID_DevDisconnect(void)
******************************************************************************/
tHID_STATUS HID_DevSetIncomingPolicy(bool allow)
{
#if (HID_DYNAMIC_MEMORY)
if (!hidd_cb_ptr) {
return HID_ERR_NO_RESOURCES;
}
#endif /* #if (HID_DYNAMIC_MEMORY) */
hd_cb.allow_incoming = allow;
return HID_SUCCESS;
}
@@ -551,7 +616,14 @@ tHID_STATUS HID_DevGetDevice(BD_ADDR *addr)
tHID_STATUS HID_DevSetIncomingQos(uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size,
uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation)
{
#if (HID_DYNAMIC_MEMORY)
if (!hidd_cb_ptr) {
return HID_ERR_NO_RESOURCES;
}
#endif /* #if (HID_DYNAMIC_MEMORY) */
HIDD_TRACE_API("%s", __func__);
hd_cb.use_in_qos = TRUE;
hd_cb.in_qos.service_type = service_type;
hd_cb.in_qos.token_rate = token_rate;
@@ -573,7 +645,14 @@ tHID_STATUS HID_DevSetIncomingQos(uint8_t service_type, uint32_t token_rate, uin
tHID_STATUS HID_DevSetOutgoingQos(uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size,
uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation)
{
#if (HID_DYNAMIC_MEMORY)
if (!hidd_cb_ptr) {
return HID_ERR_NO_RESOURCES;
}
#endif /* #if (HID_DYNAMIC_MEMORY) */
HIDD_TRACE_API("%s", __func__);
hd_cb.l2cap_intr_cfg.qos_present = TRUE;
hd_cb.l2cap_intr_cfg.qos.service_type = service_type;
hd_cb.l2cap_intr_cfg.qos.token_rate = token_rate;
@@ -451,6 +451,10 @@ static void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result)
}
if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) {
HIDD_TRACE_EVENT("%s: INTR and CTRL disconnected", __func__);
if (hd_cb.pending_data) {
osi_free(hd_cb.pending_data);
hd_cb.pending_data = NULL;
}
hd_cb.device.state = HIDD_DEV_NO_CONN;
p_hcon->conn_state = HID_CONN_STATE_UNUSED;
if (hd_cb.pending_vc_unplug) {
@@ -667,6 +671,7 @@ tHID_STATUS hidd_conn_initiate(void)
if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq(HID_PSM_CONTROL, p_dev->addr)) == 0) {
HIDD_TRACE_WARNING("%s: could not start L2CAP connection", __func__);
hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL);
return HID_ERR_L2CAP_FAILED;
} else {
p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_CTRL;
}
@@ -68,7 +68,9 @@ tHID_STATUS HID_HostGetSDPRecord ( BD_ADDR addr, tSDP_DISCOVERY_DB *p_db, UINT32
uuid_list.uu.uuid16 = UUID_SERVCLASS_HUMAN_INTERFACE;
hh_cb.p_sdp_db = p_db;
SDP_InitDiscoveryDb (p_db, db_len, 1, &uuid_list, 0, NULL);
if (!SDP_InitDiscoveryDb (p_db, db_len, 1, &uuid_list, 0, NULL)) {
return HID_ERR_NO_RESOURCES;
}
if (SDP_ServiceSearchRequest (addr, p_db, hidh_search_callback)) {
hh_cb.sdp_cback = sdp_cback ;
@@ -558,11 +560,10 @@ tHID_STATUS HID_HostCloseDev( UINT8 dev_handle )
return HID_ERR_NO_CONNECTION;
}
hh_cb.devices[dev_handle].conn_tries = HID_HOST_MAX_CONN_RETRY + 1;
return hidh_conn_disconnect( dev_handle );
}
tHID_STATUS HID_HostSetSecurityLevel( char serv_name[], UINT8 sec_lvl )
tHID_STATUS HID_HostSetSecurityLevel( const char *serv_name, UINT8 sec_lvl )
{
if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HIDH_SEC_CTRL,
sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_SEC_CHN)) {
@@ -656,6 +657,11 @@ BOOLEAN HID_HostConnectOrig(UINT8 dev_handle)
BOOLEAN ret = FALSE;
do {
#if (HID_DYNAMIC_MEMORY)
if (!hidh_cb_ptr) {
break;
}
#endif
if (!hh_cb.reg_flag) {
break;
}
@@ -109,6 +109,7 @@ tHID_STATUS hidh_conn_reg (void)
}
for (xx = 0; xx < HID_HOST_MAX_DEVICES; xx++) {
memset(&hh_cb.devices[xx], 0, sizeof(tHID_HOST_DEV_CTB));
hh_cb.devices[xx].in_use = FALSE ;
hh_cb.devices[xx].delay_remove = FALSE;
hh_cb.devices[xx].conn.conn_state = HID_CONN_STATE_UNUSED;
@@ -515,7 +516,7 @@ static void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
}
if (p_hcon == NULL) {
HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid);
HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP cfg cfm, unknown CID: 0x%x", l2cap_cid);
return;
}
@@ -833,6 +834,7 @@ static void hidh_l2cif_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
UINT16 data, UINT8 report_id, BT_HDR *buf)
{
tHID_STATUS rc = HID_SUCCESS;
tHID_CONN *p_hcon = &hh_cb.devices[dhandle].conn;
BT_HDR *p_buf;
UINT8 *p_out;
@@ -845,17 +847,13 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
BOOLEAN blank_datc = FALSE;
if (!BTM_IsAclConnectionUp(hh_cb.devices[dhandle].addr, BT_TRANSPORT_BR_EDR)) {
if (buf) {
osi_free ((void *)buf);
}
return ( HID_ERR_NO_CONNECTION );
rc = HID_ERR_NO_CONNECTION;
goto error;
}
if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) {
if (buf) {
osi_free ((void *)buf);
}
return ( HID_ERR_CONGESTED );
rc = HID_ERR_CONGESTED;
goto error;
}
switch ( trans_type ) {
@@ -874,7 +872,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
buf_size = HID_INTERRUPT_BUF_SIZE;
break;
default:
return (HID_ERR_INVALID_PARAM) ;
rc = HID_ERR_INVALID_PARAM;
goto error;
}
if ( trans_type == HID_TRANS_SET_IDLE ) {
@@ -886,7 +885,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
do {
if ( buf == NULL || blank_datc ) {
if ((p_buf = (BT_HDR *)osi_malloc(buf_size)) == NULL) {
return (HID_ERR_NO_RESOURCES);
rc = HID_ERR_NO_RESOURCES;
goto error;
}
p_buf->offset = L2CAP_MIN_OFFSET;
@@ -896,7 +896,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
blank_datc = FALSE;
} else if ( (buf->len > (p_hcon->rem_mtu_size - 1))) {
if ((p_buf = (BT_HDR *)osi_malloc(buf_size)) == NULL) {
return (HID_ERR_NO_RESOURCES);
rc = HID_ERR_NO_RESOURCES;
goto error;
}
p_buf->offset = L2CAP_MIN_OFFSET;
@@ -904,11 +905,13 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
data_size = buf->len;
bytes_copied = p_hcon->rem_mtu_size - 1;
} else {
p_buf = buf ;
p_buf = buf;
p_buf->offset -= 1;
seg_req = FALSE;
data_size = buf->len;
bytes_copied = buf->len;
// The ownership of buf has been handed over to p_buf
buf = NULL;
}
p_out = (UINT8 *)(p_buf + 1) + p_buf->offset;
@@ -937,7 +940,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
/* Send the buffer through L2CAP */
if (L2CA_DataWrite(cid, p_buf) == L2CAP_DW_FAILED) {
return (HID_ERR_CONGESTED);
rc = HID_ERR_CONGESTED;
goto error;
}
if (data_size) {
@@ -950,6 +954,12 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
} while ((data_size != 0) || blank_datc ) ;
return (HID_SUCCESS);
error:
if (buf) {
osi_free ((void *)buf);
}
return rc;
}
/*******************************************************************************
**
@@ -1018,7 +1028,7 @@ BOOLEAN hidh_conn_is_orig(UINT8 dhandle)
**
** Description This function finds a connection control block based on CID
**
** Returns address of control block, or NULL if not found
** Returns index of connection, or HID_HOST_MAX_DEVICES if not found
**
*******************************************************************************/
static UINT8 find_conn_by_cid (UINT16 cid)
@@ -194,11 +194,15 @@ extern UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data,
**
** Function GAP_GetRxQueueCnt
**
** Description This function return number of bytes on the rx queue.
** Description Return the number of bytes waiting on the connection rx queue.
**
** Parameters: handle - Handle returned in the GAP_ConnOpen
** p_rx_queue_count - Pointer to return queue count in.
** Parameters: handle - Handle returned from GAP_ConnOpen
** p_rx_queue_count - Pointer to receive queue byte count
**
** Returns BT_PASS - success, count stored in *p_rx_queue_count
** GAP_ERR_ILL_PARM - p_rx_queue_count is NULL
** GAP_ERR_BAD_HANDLE - handle is invalid
** GAP_ERR_BAD_STATE - connection is not established
**
*******************************************************************************/
extern int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count);
@@ -411,7 +411,7 @@
#define HCI_BLE_SET_PAST_PARAMS (0x005C | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_DEFAULT_PAST_PARAMS (0x005D | HCI_GRP_BLE_CMDS)
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
#define HCI_BLE_READ_BUFFER_SZIE_V2 (0x0060 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_READ_BUFFER_SIZE_V2 (0x0060 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_ISO_READ_TX_SYNC (0x0061 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_ISO_SET_CIG_PARAMS (0x0062 | HCI_GRP_BLE_CMDS)
#define HCI_BLE_ISO_SET_CIG_PARAMS_TEST (0x0063 | HCI_GRP_BLE_CMDS)
@@ -435,7 +435,7 @@ BOOLEAN btsnd_hcic_sniff_sub_rate(UINT16 handle, UINT16 max_lat,
#endif /* BTM_SSR_INCLUDED */
/* Extended Inquiry Response */
void btsnd_hcic_write_ext_inquiry_response(BT_HDR *buffer, UINT8 fec_req);
BOOLEAN btsnd_hcic_write_ext_inquiry_response(BT_HDR *buffer, UINT8 fec_req);
#define HCIC_PARAM_SIZE_EXT_INQ_RESP 241
@@ -670,7 +670,7 @@ BOOLEAN btsnd_hcic_write_link_super_tout(UINT8 local_controller_id, UINT16 handl
/* Write Link Supervision Timeout */
BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac,
LAP *const iac_lap); /* Write Current IAC LAP */
const LAP *iac_lap); /* Write Current IAC LAP */
#define MAX_IAC_LAPS 0x40
@@ -111,7 +111,7 @@ extern tHID_STATUS HID_DevDeregister(void);
* Returns tHID_STATUS
*
******************************************************************************/
extern tHID_STATUS HID_DevSetSecurityLevel(uint8_t sec_lvl);
extern tHID_STATUS HID_DevSetSecurityLevel(uint16_t sec_lvl);
/*******************************************************************************
*
@@ -223,7 +223,7 @@ extern void HID_HostDeinit(void);
**
** Returns tHID_STATUS
*******************************************************************************/
extern tHID_STATUS HID_HostSetSecurityLevel( char serv_name[], UINT8 sec_lvl );
extern tHID_STATUS HID_HostSetSecurityLevel( const char *serv_name, UINT8 sec_lvl );
/*******************************************************************************
**
@@ -783,7 +783,7 @@ extern void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_H
extern void l2c_link_adjust_allocation (void);
extern void l2c_link_process_num_completed_pkts (UINT8 *p, UINT8 evt_len);
extern void l2c_link_process_num_completed_blocks (UINT8 controller_id, UINT8 *p, UINT16 evt_len);
extern void l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs);
extern void l2c_link_process_num_bufs (UINT16 num_lm_acl_bufs);
extern UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles);
extern void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status);
extern void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT transport, void *p_ref_data, UINT8 status);
@@ -286,8 +286,14 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e
p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
}
p_ccb->max_rx_mtu = p_ertm_info->user_rx_buf_size -
(L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
UINT16 overhead = L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN;
if (p_ccb->ertm_info.user_rx_buf_size > overhead) {
p_ccb->max_rx_mtu = p_ccb->ertm_info.user_rx_buf_size - overhead;
} else {
L2CAP_TRACE_ERROR ("L2CAP - Req rx mtu (0) invalid");
l2cu_release_ccb(p_ccb);
return (0);
}
}
@@ -435,8 +441,13 @@ BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 re
p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
}
p_ccb->max_rx_mtu = p_ertm_info->user_rx_buf_size -
(L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
UINT16 overhead = L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN;
if (p_ccb->ertm_info.user_rx_buf_size > overhead) {
p_ccb->max_rx_mtu = p_ccb->ertm_info.user_rx_buf_size - overhead;
} else {
L2CAP_TRACE_ERROR ("L2CAP - Rsp rx mtu invalid");
return (FALSE);
}
}
if (result == L2CAP_CONN_OK) {
@@ -685,7 +696,8 @@ BOOLEAN L2CA_Ping (BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB *p_callback)
BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_callback)
{
tL2C_LCB *p_lcb;
UINT8 *pp;
UINT8 *pp = NULL;
UINT16 len = 0;
L2CAP_TRACE_API ("L2CA_Echo() BDA: %08X%04X",
((p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) + (p_bd_addr[2] << 8) + (p_bd_addr[3])),
@@ -717,9 +729,12 @@ BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_cal
l2cb.p_echo_data_cb = p_callback;
/* Set the pointer to the beginning of the data */
pp = (UINT8 *)(p_data + 1) + p_data->offset;
if (p_data) {
pp = (UINT8 *)(p_data + 1) + p_data->offset;
len = p_data->len;
}
l2cu_adj_id(p_lcb, L2CAP_ADJ_BRCM_ID); /* Make sure not using Broadcom ID */
l2cu_send_peer_echo_req (p_lcb, pp, p_data->len);
l2cu_send_peer_echo_req (p_lcb, pp, len);
return (TRUE);
@@ -731,7 +746,7 @@ BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_cal
bool L2CA_GetIdentifiers(uint16_t lcid, uint16_t *rcid, uint16_t *handle)
{
tL2C_CCB *control_block = l2cu_find_ccb_by_cid(NULL, lcid);
if (!control_block) {
if (!control_block || !control_block->p_lcb) {
return false;
}
@@ -830,7 +845,7 @@ BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout, tBT_TRANSPO
} else {
for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
p_lcb = list_node(p_node);
if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED) && p_lcb->transport == transport) {
p_lcb->idle_timeout = timeout;
if (!p_lcb->ccb_queue.p_first_ccb) {
@@ -946,6 +961,8 @@ UINT16 L2CA_LocalLoopbackReq (UINT16 psm, UINT16 handle, BD_ADDR p_bd_addr)
/* Allocate a channel control block */
if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) {
L2CAP_TRACE_WARNING ("L2CAP - no CCB for L2CA_conn_req");
p_lcb->link_state = LST_DISCONNECTED;
l2cu_release_lcb(p_lcb);
return (0);
}
@@ -1047,7 +1064,7 @@ BOOLEAN L2CA_SendTestSFrame (UINT16 cid, UINT8 sup_type, UINT8 back_track)
return (FALSE);
}
p_ccb->fcrb.next_seq_expected -= back_track;
p_ccb->fcrb.next_seq_expected = (p_ccb->fcrb.next_seq_expected - back_track) & L2CAP_FCR_SEQ_MODULO;
l2c_fcr_send_S_frame (p_ccb, (UINT16)(sup_type & 3), (UINT16)(sup_type & (L2CAP_FCR_P_BIT | L2CAP_FCR_F_BIT)));
@@ -1172,14 +1189,13 @@ BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout)
if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
if (p_lcb->link_flush_tout != flush_tout) {
p_lcb->link_flush_tout = flush_tout;
L2CAP_TRACE_API ("L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
flush_tout, bd_addr[3], bd_addr[4], bd_addr[5]);
if (!btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to)) {
return (FALSE);
}
p_lcb->link_flush_tout = flush_tout;
}
} else {
L2CAP_TRACE_WARNING ("WARNING L2CA_SetFlushTimeout No lcb for bd_addr [...;%02x%02x%02x]",
@@ -1192,8 +1208,6 @@ BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout)
p_lcb = list_node(p_node);
if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
if (p_lcb->link_flush_tout != flush_tout) {
p_lcb->link_flush_tout = flush_tout;
L2CAP_TRACE_API ("L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
flush_tout, p_lcb->remote_bd_addr[3],
p_lcb->remote_bd_addr[4], p_lcb->remote_bd_addr[5]);
@@ -1201,6 +1215,7 @@ BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout)
if (!btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to)) {
return (FALSE);
}
p_lcb->link_flush_tout = flush_tout;
}
}
}
@@ -2123,7 +2138,7 @@ BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle
transport = BT_TRANSPORT_LE;
}
#endif
if (fixed_cid<L2CAP_FIRST_FIXED_CHNL) {
if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)) {
return (FALSE);
}
@@ -2169,6 +2184,11 @@ BOOLEAN L2CA_GetCurrentConfig (UINT16 lcid,
L2CAP_TRACE_API ("L2CA_GetCurrentConfig() CID: 0x%04x", lcid);
if (!pp_our_cfg || !p_our_cfg_bits || !pp_peer_cfg || !p_peer_cfg_bits) {
L2CAP_TRACE_ERROR ("L2CA_GetCurrentConfig() - NULL output pointer");
return FALSE;
}
p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
if (p_ccb) {
@@ -2269,7 +2289,7 @@ void l2cap_bqb_write_data(UINT16 cid)
BT_HDR *p_buf;
uint8_t *p;
if ((p_buf = (BT_HDR *)osi_malloc(SDP_DATA_BUF_SIZE)) != NULL) {
if ((p_buf = (BT_HDR *)osi_calloc(SDP_DATA_BUF_SIZE)) != NULL) {
p_buf->len = 30;
p_buf->offset = L2CAP_MIN_OFFSET;
p = (UINT8 *)(p_buf + 1) + p_buf->offset;
@@ -50,7 +50,7 @@ static void l2c_csm_w4_l2cap_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void
static void l2c_csm_w4_l2ca_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void *p_data);
#if (BT_TRACE_VERBOSE == TRUE)
static char *l2c_csm_get_event_name (UINT16 event);
static const char *l2c_csm_get_event_name (UINT16 event);
#endif
/*******************************************************************************
@@ -221,7 +221,7 @@ static void l2c_csm_closed (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
/* Need to have at least one compatible channel to continue */
if (!l2c_fcr_chk_chan_modes(p_ccb)) {
l2cu_release_ccb (p_ccb);
(*p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb)(local_cid, L2CAP_CONN_NO_LINK);
(*connect_cfm)(local_cid, L2CAP_CONN_NO_LINK);
} else {
l2cu_send_peer_connect_req (p_ccb);
btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CONNECT_TOUT);
@@ -757,13 +757,17 @@ static void l2c_csm_config (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
break;
case L2CEVT_L2CAP_CONFIG_RSP_NEG: /* Peer config error rsp */
/* Disable the Timer */
btu_stop_timer (&p_ccb->timer_entry);
/* If failure was channel mode try to renegotiate */
if (l2c_fcr_renegotiate_chan(p_ccb, p_cfg) == FALSE) {
L2CAP_TRACE_API ("L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x, Failure: %d", p_ccb->local_cid, p_cfg->result);
(*p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb)(p_ccb->local_cid, p_cfg);
if (p_ccb && p_ccb->in_use) {
/* Disable the Timer */
btu_stop_timer (&p_ccb->timer_entry);
tL2CA_CONFIG_CFM_CB *config_cfm = p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb;
/* If failure was channel mode try to renegotiate */
if (l2c_fcr_renegotiate_chan(p_ccb, p_cfg) == FALSE) {
L2CAP_TRACE_API ("L2CAP - Calling Config_Rsp_Cb(), CID: 0x%04x, Failure: %d", p_ccb->local_cid, p_cfg->result);
if (p_ccb->in_use) {
(*config_cfm)(p_ccb->local_cid, p_cfg);
}
}
}
break;
@@ -897,6 +901,7 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
tL2C_CHNL_STATE tempstate;
UINT8 tempcfgdone;
UINT8 cfg_result = L2CAP_PEER_CFG_DISCONNECT;
tL2CA_DISCONNECT_IND_CB *disconnect_ind = NULL;
#if (BT_TRACE_VERBOSE == TRUE)
L2CAP_TRACE_EVENT ("L2CAP - LCID: 0x%04x st: OPEN evt: %s",
@@ -919,9 +924,12 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */
L2CAP_TRACE_API ("L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed",
p_ccb->local_cid);
l2cu_release_ccb (p_ccb);
if (p_ccb->p_rcb) {
(*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(local_cid, FALSE);
disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
}
l2cu_release_ccb (p_ccb);
if (disconnect_ind) {
(*disconnect_ind)(local_cid, FALSE);
}
break;
@@ -985,6 +993,8 @@ static void l2c_csm_open (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */
if (p_data && (p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_DataInd_Cb)) {
(*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, (BT_HDR *)p_data);
} else if (p_data) {
osi_free(p_data);
}
break;
@@ -1136,7 +1146,6 @@ static void l2c_csm_w4_l2ca_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void
break;
}
}
#endif /// (L2CAP_COC_INCLUDED == TRUE)
#if (BT_TRACE_VERBOSE == TRUE)
/*******************************************************************************
@@ -1150,7 +1159,7 @@ static void l2c_csm_w4_l2ca_disconnect_rsp (tL2C_CCB *p_ccb, UINT16 event, void
** Returns pointer to the name
**
*******************************************************************************/
static char *l2c_csm_get_event_name (UINT16 event)
static const char *l2c_csm_get_event_name (UINT16 event)
{
switch (event) {
case L2CEVT_LP_CONNECT_CFM: /* Lower layer connect confirm */
@@ -1228,6 +1237,7 @@ static char *l2c_csm_get_event_name (UINT16 event)
}
}
#endif /* (BT_TRACE_VERBOSE == TRUE) */
#endif /// (L2CAP_COC_INCLUDED == TRUE)
/*******************************************************************************
@@ -256,7 +256,8 @@ void l2c_fcr_cleanup (tL2C_CCB *p_ccb)
#if (L2CAP_ERTM_STATS == TRUE)
if ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID) && (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) ) {
UINT32 dur = osi_time_get_os_boottime_ms() - p_ccb->fcrb.connect_tick_count;
char *p_str = (char *)osi_malloc(120);
UINT32 str_len = 120;
char *p_str = (char *)osi_malloc(str_len);
UINT16 i;
UINT32 throughput_avg, ack_delay_avg, ack_q_count_avg;
@@ -270,14 +271,14 @@ void l2c_fcr_cleanup (tL2C_CCB *p_ccb)
BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC,
"max_held_acks:%08u, in_cfg.fcr.tx_win_sz:%08u", p_ccb->fcrb.max_held_acks, p_ccb->peer_cfg.fcr.tx_win_sz );
if (p_str) {
sprintf(p_str, "Sent Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u",
snprintf(p_str, str_len, "Sent Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u",
p_ccb->fcrb.ertm_pkt_counts[0], p_ccb->fcrb.ertm_byte_counts[0],
(dur >= 10 ? (p_ccb->fcrb.ertm_byte_counts[0] * 100) / (dur / 10) : 0),
p_ccb->fcrb.s_frames_sent[0], p_ccb->fcrb.s_frames_sent[1], p_ccb->fcrb.s_frames_sent[2], p_ccb->fcrb.s_frames_sent[3]);
BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, "%s", p_str);
sprintf(p_str, "Rcvd Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u",
snprintf(p_str, str_len, "Rcvd Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u",
p_ccb->fcrb.ertm_pkt_counts[1], p_ccb->fcrb.ertm_byte_counts[1],
(dur >= 10 ? (p_ccb->fcrb.ertm_byte_counts[1] * 100) / (dur / 10) : 0),
p_ccb->fcrb.s_frames_rcvd[0], p_ccb->fcrb.s_frames_rcvd[1], p_ccb->fcrb.s_frames_rcvd[2], p_ccb->fcrb.s_frames_rcvd[3]);
@@ -295,7 +296,7 @@ void l2c_fcr_cleanup (tL2C_CCB *p_ccb)
continue;
}
sprintf(p_str, "[%02u] throughput: %5u, ack_delay avg:%3u, min:%3u, max:%3u, ack_q_count avg:%3u, min:%3u, max:%3u",
snprintf(p_str, str_len, "[%02u] throughput: %5u, ack_delay avg:%3u, min:%3u, max:%3u, ack_q_count avg:%3u, min:%3u, max:%3u",
i, p_ccb->fcrb.throughput[i],
p_ccb->fcrb.ack_delay_avg[i], p_ccb->fcrb.ack_delay_min[i], p_ccb->fcrb.ack_delay_max[i],
p_ccb->fcrb.ack_q_count_avg[i], p_ccb->fcrb.ack_q_count_min[i], p_ccb->fcrb.ack_q_count_max[i] );
@@ -343,7 +344,7 @@ BT_HDR *l2c_fcr_clone_buf (BT_HDR *p_buf, UINT16 new_offset, UINT16 no_of_bytes)
* NOTE: We allocate extra L2CAP_FCS_LEN octets, in case we need to put
* the FCS (Frame Check Sequence) at the end of the buffer.
*/
uint16_t buf_size = no_of_bytes + sizeof(BT_HDR) + new_offset + L2CAP_FCS_LEN;
UINT32 buf_size = no_of_bytes + sizeof(BT_HDR) + new_offset + L2CAP_FCS_LEN;
#if (L2CAP_ERTM_STATS == TRUE)
/*
* NOTE: If L2CAP_ERTM_STATS is enabled, we need 4 extra octets at the
@@ -351,6 +352,11 @@ BT_HDR *l2c_fcr_clone_buf (BT_HDR *p_buf, UINT16 new_offset, UINT16 no_of_bytes)
*/
buf_size += sizeof(uint32_t);
#endif
if (buf_size > L2CAP_MAX_BUF_SIZE) {
L2CAP_TRACE_ERROR ("l2c_fcr_clone_buf() buf_size invalid");
return NULL;
}
BT_HDR *p_buf2 = (BT_HDR *)osi_malloc(buf_size);
if (!p_buf2) {
L2CAP_TRACE_ERROR ("l2c_fcr_clone_buf() malloc failed");
@@ -372,7 +378,7 @@ BT_HDR *l2c_fcr_clone_buf (BT_HDR *p_buf, UINT16 new_offset, UINT16 no_of_bytes)
**
** Description This function checks if the CCB is flow controlled by peer.
**
** Returns The control word
** Returns TRUE if the CCB is flow controlled by peer, FALSE otherwise
**
*******************************************************************************/
BOOLEAN l2c_fcr_is_flow_controlled (tL2C_CCB *p_ccb)
@@ -1452,6 +1458,8 @@ static BOOLEAN retransmit_i_frames (tL2C_CCB *p_ccb, UINT8 tx_seq)
if (tx_seq == buf_seq) {
break;
}
p_buf = NULL;
}
}
@@ -224,8 +224,10 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda)
p_lcb->br_edr_create_con_retries = 0;
btu_stop_timer(&p_lcb->retry_timer_entry);
/* For all channels, send the event through their FSMs */
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
tL2C_CCB *pn = p_ccb->p_next_ccb;
l2c_csm_execute (p_ccb, L2CEVT_LP_CONNECT_CFM, &ci);
p_ccb = pn;
}
#endif ///CLASSIC_BT_INCLUDED == TRUE
if (p_lcb->p_echo_rsp_cb) {
@@ -607,10 +609,12 @@ BOOLEAN l2c_link_hci_qos_violation (UINT16 handle)
}
#if (CLASSIC_BT_INCLUDED == TRUE)
/* For all channels, tell the upper layer about it */
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
if (p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) {
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
tL2C_CCB *pn = p_ccb->p_next_ccb;
if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb) {
l2c_csm_execute (p_ccb, L2CEVT_LP_QOS_VIOLATION_IND, NULL);
}
p_ccb = pn;
}
#endif ///CLASSIC_BT_INCLUDED == TRUE
return (TRUE);
@@ -781,6 +785,7 @@ void l2c_info_timeout (tL2C_LCB *p_lcb)
{
tL2C_CCB *p_ccb;
#if (CLASSIC_BT_INCLUDED == TRUE)
tL2C_CCB *p_next_ccb;
tL2C_CONN_INFO ci;
#endif ///CLASSIC_BT_INCLUDED == TRUE
/* If we timed out waiting for info response, just continue using basic if allowed */
@@ -803,8 +808,10 @@ void l2c_info_timeout (tL2C_LCB *p_lcb)
ci.status = HCI_SUCCESS;
memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
p_next_ccb = p_ccb->p_next_ccb;
l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
p_ccb = p_next_ccb;
}
}
}
@@ -838,6 +845,10 @@ void l2c_link_adjust_allocation (void)
UINT16 high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
list_node_t *p_node = NULL;
if (controller_xmit_quota == 0) {
return;
}
/* If no links active, reset buffer quotas and controller buffers */
if (l2cb.num_links_active == 0) {
l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
@@ -976,7 +987,7 @@ void l2c_link_adjust_chnl_allocation (void)
/*******************************************************************************
**
** Function l2c_link_processs_num_bufs
** Function l2c_link_process_num_bufs
**
** Description This function is called when a "controller buffer size"
** event is first received from the controller. It updates
@@ -985,7 +996,7 @@ void l2c_link_adjust_chnl_allocation (void)
** Returns void
**
*******************************************************************************/
void l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs)
void l2c_link_process_num_bufs (UINT16 num_lm_acl_bufs)
{
l2cb.num_lm_acl_bufs = l2cb.controller_xmit_window = num_lm_acl_bufs;
@@ -1033,10 +1044,9 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status)
/* If here came form hci role change event */
p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
if (p_lcb) {
p_lcb->link_role = new_role;
/* Reset high priority link if needed */
if (hci_status == HCI_SUCCESS) {
p_lcb->link_role = new_role;
l2cu_set_acl_priority(bd_addr, p_lcb->acl_priority, TRUE);
}
}
@@ -1396,7 +1406,16 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
return FALSE;
}
if (acl_data_size == 0) {
osi_free(p_buf);
return FALSE;
}
num_segs = (p_buf->len - HCI_DATA_PREAMBLE_SIZE + acl_data_size - 1) / acl_data_size;
if (num_segs == 0) {
osi_free(p_buf);
return FALSE;
}
/* If doing round-robin, then only 1 segment each time */
@@ -1642,7 +1661,9 @@ void l2c_link_segments_xmitted (BT_HDR *p_msg)
if (p_lcb->link_state == LST_CONNECTED) {
/* Enqueue the buffer to the head of the transmit queue, and see */
/* if we can transmit anything more. */
list_prepend(p_lcb->link_xmit_data_q, p_msg);
if (!list_prepend(p_lcb->link_xmit_data_q, p_msg)) {
osi_free(p_msg);
}
p_lcb->partial_segment_being_sent = FALSE;
@@ -365,8 +365,9 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
tL2CAP_CFG_INFO cfg_info;
UINT16 rej_reason, rej_mtu, lcid, rcid, info_type;
tL2C_CCB *p_ccb;
tL2C_CCB *p_next_ccb;
tL2C_RCB *p_rcb;
BOOLEAN cfg_rej, cfg_bad, info_bad, pkt_size_rej = FALSE;
BOOLEAN cfg_rej, cfg_bad, pkt_size_rej = FALSE;
UINT16 cfg_rej_len, cmd_len;
UINT16 result;
tL2C_CONN_INFO ci;
@@ -467,8 +468,10 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
/* For all channels, send the event through their FSMs */
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
p_next_ccb = p_ccb->p_next_ccb;
l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
p_ccb = p_next_ccb;
}
}
break;
@@ -541,14 +544,14 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
break;
case L2CAP_CMD_CONFIG_REQ:
if (cmd_len < L2CAP_CONFIG_REQ_LEN) {
L2CAP_TRACE_WARNING ("L2CAP - cfg req too short, cmd_len: %d", cmd_len);
break;
}
p_cfg_end = p + cmd_len;
cfg_rej = FALSE;
cfg_rej_len = 0;
if ((p_cfg_end - p) < L2CAP_CONFIG_REQ_LEN) {
L2CAP_TRACE_WARNING ("L2CAP - cfg req too short, cmd_len: %d", cmd_len);
break;
}
STREAM_TO_UINT16 (lcid, p);
STREAM_TO_UINT16 (cfg_info.flags, p);
@@ -673,13 +676,12 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
break;
case L2CAP_CMD_CONFIG_RSP:
p_cfg_end = p + cmd_len;
cfg_bad = FALSE;
if ((p_cfg_end - p) < L2CAP_CONFIG_RSP_LEN) {
if (cmd_len < L2CAP_CONFIG_RSP_LEN) {
L2CAP_TRACE_WARNING ("L2CAP - cfg rsp too short, cmd_len: %d", cmd_len);
break;
}
p_cfg_end = p + cmd_len;
cfg_bad = FALSE;
STREAM_TO_UINT16 (lcid, p);
STREAM_TO_UINT16 (cfg_info.flags, p);
STREAM_TO_UINT16 (cfg_info.result, p);
@@ -876,10 +878,11 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
break;
case L2CAP_CMD_INFO_RSP:
info_bad = FALSE;
p_info_end = p + cmd_len;
{
BOOLEAN info_bad = FALSE;
if ((p_info_end - p) < L2CAP_INFO_RSP_LEN) {
p_info_end = p + cmd_len;
if ((p + L2CAP_INFO_RSP_LEN) > p_info_end) {
L2CAP_TRACE_WARNING ("L2CAP - cmd info rsp too short, cmd_len: %d", cmd_len);
break;
}
@@ -944,15 +947,14 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
}
}
#endif
if (info_bad) {
break;
}
ci.status = HCI_SUCCESS;
memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
p_next_ccb = p_ccb->p_next_ccb;
l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
p_ccb = p_next_ccb;
}
}
break;
@@ -408,6 +408,11 @@ UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 fla
}
}
if (p_buf->offset < L2CAP_UCD_OVERHEAD) {
osi_free(p_buf);
return L2CAP_DW_FAILED;
}
/* write PSM */
p_buf->offset -= L2CAP_UCD_OVERHEAD;
p_buf->len += L2CAP_UCD_OVERHEAD;
@@ -774,9 +779,15 @@ void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB *p_ccb)
*******************************************************************************/
BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB *p_ccb)
{
BT_HDR *p_buf = (BT_HDR*)fixed_queue_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q, 0);
BT_HDR *p_buf = NULL;
while ((p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_ccb->p_lcb->ucd_in_sec_pending_q)) != NULL) {
if (p_buf->len < L2CAP_UCD_OVERHEAD) {
fixed_queue_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q, 0);
osi_free(p_buf);
continue;
}
if (p_buf != NULL) {
UINT16 psm;
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
STREAM_TO_UINT16(psm, p)
@@ -787,6 +798,7 @@ BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB *p_ccb)
return (TRUE);
}
return (FALSE);
}
@@ -79,6 +79,10 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPOR
if (p_lcb) {
memset (p_lcb, 0, sizeof(tL2C_LCB));
list_ret = list_append(l2cb.p_lcb_pool, p_lcb);
if (!list_ret) {
osi_free(p_lcb);
return NULL;
}
}else {
L2CAP_TRACE_ERROR("Error in allocating L2CAP Link Control Block");
}
@@ -457,10 +461,14 @@ BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb)
*******************************************************************************/
BT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id)
{
BT_HDR *p_buf = (BT_HDR *)osi_malloc(L2CAP_CMD_BUF_SIZE);
BT_HDR *p_buf;
UINT8 *p;
if (!p_buf) {
if (len + BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD > L2CAP_CMD_BUF_SIZE) {
return NULL;
}
if ((p_buf = (BT_HDR *)osi_malloc(L2CAP_CMD_BUF_SIZE)) == NULL) {
return (NULL);
}
@@ -667,7 +675,7 @@ void l2cu_reject_connection (tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, U
UINT8 *p;
if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id)) == NULL ) {
L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_rsp");
return;
}
@@ -724,7 +732,7 @@ void l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16) (L2CAP_CONFIG_REQ_LEN + cfg_len),
L2CAP_CMD_CONFIG_REQ, p_ccb->local_id)) == NULL ) {
L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
L2CAP_TRACE_WARNING ("L2CAP - no buffer for cfg_req");
return;
}
@@ -822,7 +830,7 @@ void l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16)(L2CAP_CONFIG_RSP_LEN + cfg_len),
L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id)) == NULL ) {
L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
L2CAP_TRACE_WARNING ("L2CAP - no buffer for cfg_rsp");
return;
}
@@ -1015,6 +1023,10 @@ void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb)
BT_HDR *p_buf, *p_buf2;
UINT8 *p;
if (!p_ccb || !p_ccb->p_lcb) {
return;
}
/* Create an identifier for this packet */
p_ccb->p_lcb->id++;
l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
@@ -1034,7 +1046,7 @@ void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb)
/* Move all queued data packets to the LCB. In FCR mode, assume the higher
layer checks that all buffers are sent before disconnecting.
*/
if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) {
if (p_ccb->xmit_hold_q && (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE)) {
while ((p_buf2 = (BT_HDR *)fixed_queue_dequeue(p_ccb->xmit_hold_q, 0)) != NULL) {
l2cu_set_acl_hci_header (p_buf2, p_ccb);
l2c_link_check_send_pkts (p_ccb->p_lcb, p_ccb, p_buf2);
@@ -1224,14 +1236,11 @@ void l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type
#if (L2CAP_CONFORMANCE_TESTING == TRUE)
if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
&& (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC |
L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW |
&& (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
L2CAP_EXTFEA_UCD_RECEPTION )) )
#else
if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
&& (L2CAP_EXTFEA_SUPPORTED_MASK & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_FIXED_CHNLS |
L2CAP_EXTFEA_UCD_RECEPTION )) )
#endif
{
@@ -1481,6 +1490,10 @@ void l2cu_dequeue_ccb (tL2C_CCB *p_ccb)
*******************************************************************************/
void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority)
{
if ((priority >= L2CAP_NUM_CHNL_PRIORITY) || (p_ccb->ccb_priority >= L2CAP_NUM_CHNL_PRIORITY)) {
return;
}
if (p_ccb->ccb_priority != priority) {
/* If CCB is not the only guy on the queue */
if ( (p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL) ) {
@@ -1536,7 +1549,10 @@ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
if (p_ccb) {
memset (p_ccb, 0, sizeof(tL2C_CCB));
list_append(l2cb.p_ccb_pool, p_ccb);
if (!list_append(l2cb.p_ccb_pool, p_ccb)) {
osi_free(p_ccb);
return NULL;
}
}
}
}
@@ -1857,6 +1873,7 @@ tL2C_RCB *l2cu_allocate_rcb (UINT16 psm)
for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
if (!p_rcb->in_use) {
memset(p_rcb, 0, sizeof(tL2C_RCB));
p_rcb->in_use = TRUE;
p_rcb->psm = psm;
#if (L2CAP_UCD_INCLUDED == TRUE)
@@ -2679,7 +2696,10 @@ BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_af
UINT16_TO_STREAM (pp, p_lcb->handle);
UINT8_TO_STREAM (pp, vs_param);
BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
tBTM_STATUS status = BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
if (status != BTM_SUCCESS) {
return FALSE;
}
/* Adjust lmp buffer allocation for this channel if priority changed */
if (p_lcb->acl_priority != priority) {
@@ -2767,7 +2787,7 @@ void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
** Description This function allows the script wrapper to change the
** info resp mask for conformance testing.
**
** Returns pointer to CCB, or NULL if none
** Returns void
**
*******************************************************************************/
void l2cu_set_info_rsp_mask (UINT32 mask)
@@ -2846,9 +2866,9 @@ BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR
/* Set CID for the connection */
p_ccb->local_cid = fixed_cid;
p_ccb->remote_cid = fixed_cid;
#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
p_ccb->is_flushable = FALSE;
#endif
p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb;
@@ -2925,11 +2945,6 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
/* BTM SEC will make sure that link is release (probably after pairing is done) */
p_lcb->link_state = LST_DISCONNECTING;
timeout = 0xFFFF;
} else if ( (p_lcb->is_bonding)
&& (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) ) {
l2cu_process_fixed_disc_cback(p_lcb);
p_lcb->link_state = LST_DISCONNECTING;
timeout = L2CAP_LINK_DISCONNECT_TOUT;
} else {
/* probably no buffer to send disconnect */
timeout = BT_1SEC_TIMEOUT;
@@ -3036,7 +3051,8 @@ void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
#if (L2CAP_NUM_FIXED_CHNLS > 0)
/* Select peer channels mask to use depending on transport */
UINT8 peer_channel_mask = p_lcb->peer_chnl_mask[0];
UINT8 peer_chnl_mask[L2CAP_FIXED_CHNL_ARRAY_SIZE] = {0};
memcpy(peer_chnl_mask, p_lcb->peer_chnl_mask, sizeof(peer_chnl_mask));
// For LE, reset the stored peer channel mask
if (p_lcb->transport == BT_TRANSPORT_LE) {
@@ -3058,7 +3074,7 @@ void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
#endif
}
} else if ( (peer_channel_mask & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
} else if ( (peer_chnl_mask[(xx + L2CAP_FIRST_FIXED_CHNL) / 8] & (1 << ((xx + L2CAP_FIRST_FIXED_CHNL) % 8)))
&& (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) ) {
#if BLE_INCLUDED == TRUE
(*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
@@ -3246,6 +3262,11 @@ void l2cu_send_peer_ble_credit_based_conn_res (tL2C_CCB *p_ccb, UINT16 result)
UINT8 *p;
L2CAP_TRACE_DEBUG ("l2cu_send_peer_ble_credit_based_conn_res");
if (!p_ccb || !p_ccb->p_lcb) {
L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_conn_res - no link");
return;
}
if ((p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, p_ccb->remote_id)) == NULL )
{
@@ -3493,6 +3514,11 @@ tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle)
{
list_node_t *p_node = NULL;
tL2C_LCB *p_lcb = NULL;
if (!l2cb.p_lcb_pool) {
return NULL;
}
for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
p_lcb = list_node(p_node);
if ((p_lcb->in_use) && (p_lcb->handle == handle)) {
@@ -3693,11 +3719,11 @@ static tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb)
continue;
}
if (!fixed_queue_is_empty(p_ccb->fcrb.retrans_q))
if (!fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) {
return p_ccb;
}
if (fixed_queue_is_empty(p_ccb->xmit_hold_q))
if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
continue;
}
@@ -112,7 +112,11 @@ l2cap_client_t *l2cap_client_new(const l2cap_client_callbacks_t *callbacks, void
goto error;
}
list_append(l2cap_clients, ret);
if (!list_append(l2cap_clients, ret)) {
list_free(ret->outbound_fragments);
osi_free(ret);
return NULL;
}
return ret;
@@ -131,6 +135,11 @@ void l2cap_client_free(l2cap_client_t *client)
l2cap_client_disconnect(client);
list_free(client->outbound_fragments);
osi_free(client);
if (l2cap_clients && list_is_empty(l2cap_clients)) {
list_free(l2cap_clients);
l2cap_clients = NULL;
}
}
bool l2cap_client_connect(l2cap_client_t *client, const bt_bdaddr_t *remote_bdaddr, uint16_t psm)
@@ -150,7 +159,12 @@ bool l2cap_client_connect(l2cap_client_t *client, const bt_bdaddr_t *remote_bdad
return false;
}
L2CA_SetConnectionCallbacks(client->local_channel_id, &l2cap_callbacks);
if (!L2CA_SetConnectionCallbacks(client->local_channel_id, &l2cap_callbacks)) {
L2CA_DisconnectReq(client->local_channel_id);
client->local_channel_id = 0;
return false;
}
return true;
}
@@ -192,8 +206,16 @@ bool l2cap_client_write(l2cap_client_t *client, buffer_t *packet)
return false;
}
uint16_t cid = client->local_channel_id;
fragment_packet(client, packet);
dispatch_fragments(client);
client = find(cid);
if (!client || !l2cap_client_is_connected(client)) {
return false;
}
return true;
}
@@ -261,7 +283,9 @@ static void config_request_cb(uint16_t local_channel_id, tL2CAP_CFG_INFO *reques
}
// If we've configured both endpoints, let the listener know we've connected.
client->configured_peer = true;
if (response.result == L2CAP_CFG_OK) {
client->configured_peer = true;
}
if (l2cap_client_is_connected(client)) {
client->callbacks.connected(client, client->context);
}
@@ -355,7 +379,8 @@ static void congestion_cb(uint16_t local_channel_id, bool is_congested)
// Once that's done, if we're still decongested, notify the listener so it
// can start writing again.
dispatch_fragments(client);
if (!client->is_congested) {
client = find(local_channel_id);
if (client && !client->is_congested && l2cap_client_is_connected(client)) {
client->callbacks.write_ready(client, client->context);
}
}
@@ -372,6 +397,12 @@ static void read_ready_cb(uint16_t local_channel_id, BT_HDR *packet)
return;
}
if (packet->len == 0) {
L2CAP_TRACE_ERROR("%s zero packet length\n", __func__);
osi_free(packet);
return;
}
// TODO(sharvil): eliminate copy from BT_HDR.
buffer_t *buffer = buffer_new(packet->len);
if (!buffer) {
@@ -399,8 +430,10 @@ static void fragment_packet(l2cap_client_t *client, buffer_t *packet)
assert(client != NULL);
assert(packet != NULL);
bool ret = false;
// TODO(sharvil): eliminate copy into BT_HDR.
BT_HDR *bt_packet = osi_malloc(sizeof(BT_HDR) + buffer_length(packet) + L2CAP_MIN_OFFSET);
assert(bt_packet != NULL);
bt_packet->offset = L2CAP_MIN_OFFSET;
bt_packet->len = buffer_length(packet);
memcpy(bt_packet->data + bt_packet->offset, buffer_ptr(packet), buffer_length(packet));
@@ -408,7 +441,8 @@ static void fragment_packet(l2cap_client_t *client, buffer_t *packet)
for (;;) {
if (bt_packet->len <= client->remote_mtu) {
if (bt_packet->len > 0) {
list_append(client->outbound_fragments, bt_packet);
ret = list_append(client->outbound_fragments, bt_packet);
assert(ret);
} else {
osi_free(bt_packet);
}
@@ -416,11 +450,13 @@ static void fragment_packet(l2cap_client_t *client, buffer_t *packet)
}
BT_HDR *fragment = osi_malloc(sizeof(BT_HDR) + client->remote_mtu + L2CAP_MIN_OFFSET);
assert(fragment != NULL);
fragment->offset = L2CAP_MIN_OFFSET;
fragment->len = client->remote_mtu;
memcpy(fragment->data + fragment->offset, bt_packet->data + bt_packet->offset, client->remote_mtu);
list_append(client->outbound_fragments, fragment);
ret = list_append(client->outbound_fragments, fragment);
assert(ret);
bt_packet->offset += client->remote_mtu;
bt_packet->len -= client->remote_mtu;
@@ -444,6 +480,7 @@ static void dispatch_fragments(l2cap_client_t *client)
case L2CAP_DW_FAILED:
L2CAP_TRACE_ERROR("%s error writing data to L2CAP connection LCID 0x%04x; disconnecting.", __func__, client->local_channel_id);
l2cap_client_disconnect(client);
client->callbacks.disconnected(client, client->context);
return;
case L2CAP_DW_SUCCESS:
@@ -456,6 +493,10 @@ static l2cap_client_t *find(uint16_t local_channel_id)
{
assert(local_channel_id != 0);
if (!l2cap_clients) {
return NULL;
}
for (const list_node_t *node = list_begin(l2cap_clients); node != list_end(l2cap_clients); node = list_next(node)) {
l2cap_client_t *client = (l2cap_client_t *)list_node(node);
if (client->local_channel_id == local_channel_id) {